diff --git a/frbvoe/models/comet.py b/frbvoe/models/comet.py index 909478f..5a0f860 100644 --- a/frbvoe/models/comet.py +++ b/frbvoe/models/comet.py @@ -6,7 +6,7 @@ from pydantic import Field from frbvoe.models.voe import VOEvent -from frbvoe.utilities.comet import report, retract, update +from frbvoe.utilities.comet import send logging.basicConfig() log = logging.getLogger() @@ -24,7 +24,7 @@ class Comet(VOEvent): ) @property - def report(comet_report: Dict[str, Any]): + def send_xml(comet_report: Dict[str, Any]): """Sends a report using the given VOEvent and comet URL. Args: @@ -32,16 +32,4 @@ def report(comet_report: Dict[str, Any]): comet_url (str): The URL of the comet to send the report to. """ log.info("Sending VOE payload to Comet as a report.") - report(comet_report) - - @property - def retract(comet_report: Dict[str, Any]): - """Retract the FRB from the Comet server.""" - log.info("Sending VOE payload to Comet as a retraction.") - retract(comet_report) - - @property - def update(comet_report: Dict[str, Any]): - """Update the FRB on the Comet server.""" - log.info("Sending VOE payload to Comet as an update.") - update(comet_report) + send(comet_report) diff --git a/frbvoe/models/email.py b/frbvoe/models/email.py index d579bd1..ed42bb6 100644 --- a/frbvoe/models/email.py +++ b/frbvoe/models/email.py @@ -1,7 +1,8 @@ """format a VOE for a TNS submission.""" -import picologging as logging from typing import Any, Dict + +import picologging as logging from pydantic import Field, SecretStr, StrictStr from frbvoe.models.voe import VOEvent @@ -17,16 +18,17 @@ class Email(VOEvent): Tokenized Attributes: email_password (SecretStr) : VOEvent author email account password. Optional. """ + email_password: SecretStr = Field( - default=None, - description="VOEvent author email account password. Optional." + default=None, description="VOEvent author email account password. Optional." ) update_message: StrictStr = Field( default=None, - description="Custom email message to send in an update VOEvent. Optional." + description="Custom email message to send in an update VOEvent. Optional.", ) + @property - def send_to_subscribers(email_report: Dict[str, Any]): + def send_email(email_report: Dict[str, Any]): """Sends the VOEvent email. Args: @@ -36,4 +38,4 @@ def send_to_subscribers(email_report: Dict[str, Any]): status (str): The status of the email. """ log.info("Emailing VOE payload to subscribers.") - send(email_report) \ No newline at end of file + send(email_report) diff --git a/frbvoe/models/tns.py b/frbvoe/models/tns.py index be84216..6713f0c 100644 --- a/frbvoe/models/tns.py +++ b/frbvoe/models/tns.py @@ -37,15 +37,12 @@ class TNS(VOEvent): description="API key for the TNS. Required.", ) tns_report_id: int = Field( - ..., - description="Report ID for the TNS submission. Required." - ) - tns_bot_name: SecretStr = Field( - ..., - description="Name of the TNS bot. Required." + ..., description="Report ID for the TNS submission. Required." ) + tns_bot_name: SecretStr = Field(..., description="Name of the TNS bot. Required.") + @property - def submit(tns_report: Dict[str, Any]): #TODO + def submit(tns_report: Dict[str, Any]): # TODO """Submits a VOEvent to the TNS API. Args: diff --git a/frbvoe/models/voe.py b/frbvoe/models/voe.py index 47f5801..f56a3c6 100644 --- a/frbvoe/models/voe.py +++ b/frbvoe/models/voe.py @@ -56,7 +56,7 @@ class VOEvent(BaseSettings): VOEvent: VOEvent object. """ - model_config = SettingsConfigDict( #TODO: Shiny, do I need this since there are no tokens used? + model_config = SettingsConfigDict( # TODO: Shiny is this needed? title="FRB VOEvent", validate_assignment=True, validate_return=True, @@ -115,7 +115,7 @@ class VOEvent(BaseSettings): gt=0.0, description="Central frequency of the observatory in MHz. Optional.", example=600, - ) + ) npol: StrictInt = Field( default=None, gt=0, @@ -127,7 +127,7 @@ class VOEvent(BaseSettings): gt=0, description="Bits per sample of the observatory. Optional.", example=8, - ) + ) gain: float = Field( default=None, description="Gain of the observatory in dB. Optional.", @@ -203,7 +203,8 @@ class VOEvent(BaseSettings): description="Transient Name Server name of the FRB. Optional.", example="FRB20210826A", ) - @property + + @property # this just makes "payload" an attribute of the class def payload(self): """Return the VOEvent payload.""" log.info("Returning VOEvent payload") diff --git a/frbvoe/utilities/comet.py b/frbvoe/utilities/comet.py index b487b1c..279b261 100644 --- a/frbvoe/utilities/comet.py +++ b/frbvoe/utilities/comet.py @@ -1,7 +1,9 @@ """Comet VOEvent broker.""" +import voeventparse as vp -def report(voevent): + +def send(voevent): """Report the FRB to the Comet server.""" # # Format the Comet request # voevent["role"] = "observation" @@ -13,34 +15,7 @@ def report(voevent): # return True # else: # return False - return voevent - - -def retract(voevent): - """Retract the FRB from the Comet server.""" - # # Format the Comet request - # voevent["role"] = "retraction" - # voevent["stream"] = "chime-frb" - # # Send the VOEvent to the Comet server - # response = requests.post(comet_url, json=voevent) - # # Check if the request was successful - # if response.status_code == 200: - # return True - # else: - # return False - pass - + vp.dump(voevent=voevent, xml_declaration=False, file="temp_voe.txt") + # TODO send to comet -def update(voeventl): - """Update the FRB on the Comet server.""" - # # Format the Comet request - # voevent["role"] = "update" - # voevent["stream"] = "chime-frb" - # # Send the VOEvent to the Comet server - # response = requests.post(comet_url, json=voevent) - # # Check if the request was successful - # if response.status_code == 200: - # return True - # else: - # return False - pass + return voevent diff --git a/frbvoe/utilities/email.py b/frbvoe/utilities/email.py index 9ca27dd..069e03e 100644 --- a/frbvoe/utilities/email.py +++ b/frbvoe/utilities/email.py @@ -1,25 +1,30 @@ """this function sends an email.""" import smtplib -import picologging as logging -from typing import Any, Dict from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText +from typing import Any, Dict + +import picologging as logging logging.basicConfig() log = logging.getLogger() + def send(email_report: Dict[str, Any]): - """Send the VOEvent via email. + """Sends an email with the provided email_report. Args: - voevent: The VOEvent to be sent. - sender_email: The email address of the sender. - password: The password of the sender's email account. - subject: The subject of the email. - message: The message to be sent via email. + email_report (Dict[str, Any]): + A dictionary containing the email report information. + + Returns: + str: The status of the email sending process. + Returns "Success" if the email was sent successfully. + + Raises: + None """ - subject = f"{email_report.observatory_name}_VOE_{email_report.kind}" if email_report.kind in ["detection", "subsequent"]: email_message = f""" @@ -27,54 +32,61 @@ def send(email_report: Dict[str, Any]): \n WHO\n Produced: {email_report.date}\n - \tVOEvent IVORN: ivo://ca.chimenet.frb/FRB-DETECTION-#2024-05-01-02:28:38.969602UTC+0000_8b25b68ebd77 #TODO\n + \tVOEvent IVORN: #TODO\n \n WHAT\n \tobservatory parameters:\n - \t\tsampling_time: {email_report.sampling_time if not None} s\n + \t\tsampling_time: {email_report.sampling_time} s\n \n - \t\tbandwidth: {email_report.bandwidth if not None} MHz\n + \t\tbandwidth: {email_report.bandwidth} MHz\n \n - \t\tcentre_frequency: {email_report.central_frequency if not None} MHz\n + \t\tcentre_frequency: {email_report.central_frequency} MHz\n \n - \t\tnpol: {email_report.npol if not None}\n + \t\tnpol: {email_report.npol}\n \n - \t\tbits_per_sample: {email_report.bits_per_sample if not None}\n + \t\tbits_per_sample: {email_report.bits_per_sample}\n \n - \t\ttsys: {email_report.tsys if not None} K\n + \t\ttsys: {email_report.tsys} K\n \n - \t\tbackend: {email_report.backend if not None}\n + \t\tbackend: {email_report.backend}\n \n \tevent parameters:\n - \t\tevent_no: {email_report.internal_id if not None}\n + \t\tevent_no: {email_report.internal_id}\n \n - \t\tknown_source_name: {email_report.tns_name if not None}\n + \t\tknown_source_name: {email_report.tns_name}\n \n \t\tdm: {email_report.dm} +/- {email_report.dm_error} pc/cm^3\n \n - \t\ttimestamp_utc: {email_report.date} +/- {email_report.sampling_time}\n #TODO + \t\ttimestamp_utc: {email_report.date} + +/- {email_report.sampling_time}\n #TODO \n \t\tsnr: {email_report.snr}\n \n - \t\tpos_error_deg_95: {email_report.pos_error_deg_95} degrees\n + \t\tpos_error_deg_95: {email_report.pos_error_deg_95} degrees\n \n\n WHERE and WHEN\n \tCoordinate system: {email_report.coordinate_system}\n \tTimestamp [UTC]: {email_report.date}\n - \tLocalization: ({email_report.ra}, {email_report.dec}) +/- {email_report.pos_error_deg_95} degrees (J2000)\n + \tLocalization: ({email_report.ra}, {email_report.dec}) + +/- {email_report.pos_error_deg_95} degrees (J2000)\n \n\n HOW\n - \tDescription: information regarding the host observatory can be found here: {email_report.website}\n + \tDescription: information regarding the host observatory can be found here: + {email_report.website}\n \n\n WHY\n \tImportance: {email_report.importance}\n \n\n ********** - This email was generated automatically by the {email_report.observatory_name} frb-voe Service. Please direct comments, questions, and concerns to {email_report.email}. + This email was generated automatically by the + {email_report.observatory_name} frb-voe Service. + Please direct comments, questions, and concerns to {email_report.email}. -- - You are receiving this email because you are currently a subscriber to the public {email_report.observatory_name} frb-voe Service. To unsubscribe, please contact {email_report.email}. + You are receiving this email because you are currently a subscriber to + the public {email_report.observatory_name} frb-voe Service. To unsubscribe, + please contact {email_report.email}. """ if email_report.kind == "retraction": email_message = f""" @@ -82,41 +94,47 @@ def send(email_report: Dict[str, Any]): \n WHO\n Produced: {email_report.date}\n - \tVOEvent IVORN: ivo://ca.chimenet.frb/FRB-DETECTION-#2024-05-01-02:28:38.969602UTC+0000_8b25b68ebd77 #TODO\n + \tVOEvent IVORN: #TODO\n \n WHAT\n WHERE and WHEN\n \tCoordinate system: {email_report.coordinate_system}\n \tTimestamp [UTC]: {email_report.date}\n - \tLocalization: ({email_report.ra}, {email_report.dec}) +/- {email_report.pos_error_deg_95} degrees (J2000)\n + \tLocalization: ({email_report.ra}, {email_report.dec}) + +/- {email_report.pos_error_deg_95} degrees (J2000)\n \n\n HOW\n - \tDescription: Human-issued retraction. For more information, see: {email_report.website}\n + \tDescription: Human-issued retraction. For more information, + see: {email_report.website}\n \n\n WHY\n CITATIONS\n \t{email_report.internal_id}\n ********** - This email was generated automatically by the {email_report.observatory_name} frb-voe Service. Please direct comments, questions, and concerns to {email_report.email}. + This email was generated automatically by the + {email_report.observatory_name} frb-voe Service. + Please direct comments, questions, and concerns to {email_report.email}. -- - You are receiving this email because you are currently a subscriber to the public {email_report.observatory_name} frb-voe Service. To unsubscribe, please contact {email_report.email}. + You are receiving this email because you are currently a subscriber to + the public {email_report.observatory_name} frb-voe Service. + To unsubscribe, please contact {email_report.email}. """ if email_report.kind == "update": - email_message = {email_report.update_message} + email_message = {email_report.update_message} # Email configuration - receiver_email = "thomas.abbott@mail.mcgill.ca" #TODO: load from DB - smtp_server = "smtp.example.com" #TODO: Shiny what should this be? + receiver_email = "thomas.abbott@mail.mcgill.ca" # TODO: load from DB + smtp_server = "smtp.example.com" # TODO: Shiny what should this be? smtp_port = 587 # Change to the appropriate port if needed # Create a message message = MIMEMultipart() - message['From'] = email_report.email - message['To'] = receiver_email - message['Subject'] = subject - message.attach(MIMEText(email_message, 'plain')) + message["From"] = email_report.email + message["To"] = receiver_email + message["Subject"] = subject + message.attach(MIMEText(email_message, "plain")) # Connect to the SMTP server server = smtplib.SMTP(smtp_server, smtp_port) @@ -128,7 +146,6 @@ def send(email_report: Dict[str, Any]): # Quit the server server.quit() - status = "Success" - - return status \ No newline at end of file + + return status