Skip to content

Commit

Permalink
fix(frbvoe): WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
tabbott36 committed May 10, 2024
1 parent 3bdeafe commit f085e07
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 70 deletions.
21 changes: 15 additions & 6 deletions frbvoe/backend/voe.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
from sanic.response import json as json_response
from sanic_ext import openapi

import picologging as logging
logging.basicConfig()
log = logging.getLogger()

from frbvoe.models.comet import Comet
from frbvoe.models.email import Email
from frbvoe.models.voe import VOEvent

voe = Blueprint("voe", url_prefix="/")


# Post at /create_voe
@voe.post("create_voe")
@openapi.response(201, description="Validates VOEvent data from a host observatory.")
# Add the validated payload to the MongoDB Database
async def create_voe(request: Request, voe_event: VOEvent):
async def create_voe(request: Request): #TODO: Shiny, should I add voe_event: VOEvent?
"""Process a VOEvent.
Args:
Expand All @@ -34,12 +37,18 @@ async def create_voe(request: Request, voe_event: VOEvent):
PyMongoError: If there is an error with the PyMongo library.
"""
log.info("Processing VOEvent")
voe = VOEvent(**request.json)
print(voe.json())



# Send VOEvent to Comet
comet_report = Comet(voe_event.model_dump())
comet_report.send
# comet_report = Comet(**request.json)
# comet_report.send

# Send VOEvent to Email
email_report = Email(voe_event.model_dump())
email_report = Email(**request.json)
email_report.send

# Add VOEvent to MongoDB
Expand All @@ -48,7 +57,7 @@ async def create_voe(request: Request, voe_event: VOEvent):
# Document -> VOEvent Payload Dict.
mongo = request.app.ctx.mongo
try:
insert_result = await mongo["frbvoe"]["voe"].insert_one(voe_event.model_dump())
insert_result = await mongo["frbvoe"]["voe"].insert_one(voe.model_dump())
except (Exception, PyMongoError) as mongo_error:
logger.error(f"{mongo_error} on /voe")
return json_response({"message": mongo_error}, status=500)
Expand Down
7 changes: 4 additions & 3 deletions frbvoe/models/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ class Email(VOEvent):
email_password (SecretStr) : VOEvent author email account password. Optional.
"""

email_password: SecretStr = Field(
default=None, description="VOEvent author email account password. Optional."
)
# email_password: SecretStr = Field(
# default=None,
# description="VOEvent author email account password. Optional."
# )

@property
def send(email_report: Dict[str, Any]):
Expand Down
51 changes: 34 additions & 17 deletions frbvoe/models/voe.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from typing import Literal, Optional

import picologging as logging
from pydantic import EmailStr, Field, StrictFloat, StrictInt, StrictStr
from pydantic import EmailStr, Field, StrictFloat, StrictInt, StrictStr, BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict
from sanic import Request

logging.basicConfig()
log = logging.getLogger()


class VOEvent(BaseSettings):
class VOEvent(BaseModel): #BaseSettings
"""VOEvent Object.
Args:
Expand Down Expand Up @@ -57,26 +57,38 @@ class VOEvent(BaseSettings):
VOEvent: VOEvent object.
"""

model_config = SettingsConfigDict( # TODO: Shiny is this needed?
title="FRB VOEvent",
validate_assignment=True,
validate_return=True,
revalidate_instances="always",
# This parameter ignores any extra fields that are not defined in the model
extra="ignore",
)
# model_config = SettingsConfigDict( # TODO: Shiny is this needed?
# title="FRB VOEvent",
# validate_assignment=True,
# validate_return=True,
# revalidate_instances="always",
# # This parameter ignores any extra fields that are not defined in the model
# extra="ignore",
# )
kind: Literal[
"detection",
"subsequent",
"retraction",
"update",
] = Field(..., description="Which kind of VOEvent. Required.", example="detection")
] = Field(
...,
description="Which kind of VOEvent. Required.",
example="detection"
)
observatory_name: StrictStr = Field(
..., description="Name of the host observatory. Required.", example="CHIME"
)
date: datetime = Field(
...,
gt=datetime(2024, 1, 1), # release date of frb-voe
description="Name of the host observatory. Required.",
example="CHIME"
)
# date: datetime = Field(
# ...,
# gt=datetime(2024, 1, 1), # release date of frb-voe
# description="Detection time of the FRB. Required.",
# example="2020-01-13 16:55:08.844845",
# )
date : StrictStr = Field(
...,
# release date of frb-voe
description="Detection time of the FRB. Required.",
example="2020-01-13 16:55:08.844845",
)
Expand Down Expand Up @@ -167,16 +179,20 @@ class VOEvent(BaseSettings):
example=13.8,
)
flux: float = Field(
default=None, description="Flux of the FRB in Jy. Optional.", example=4.9
default=None,
description="Flux of the FRB in Jy. Optional.",
example=4.9
)
right_ascension: float = Field(
default=None,
ge=0.0,
le=360.0,
description="""Right acension of the FRB in degrees
in degrees (0 < RA < 360). Required.""",
example=55.2938,
)
declination: float = Field(
default=None,
ge=-90.0,
le=90.0,
description="Declination of the FRB in degrees (-90 ≤ Dec ≤ 90). Required.",
Expand All @@ -198,6 +214,7 @@ class VOEvent(BaseSettings):
website: Optional[StrictStr] = Field(
default=None,
description="Link to the host observatory website. Optional.",
example="https://host_observatory.com/"
)
tns_name: Optional[StrictStr] = Field(
default=None,
Expand All @@ -215,7 +232,7 @@ def payload(self):
log.info("Returning VOEvent payload")
return self.dict()

@staticmethod
@staticmethod #TODO: Shiny what's this for?
async def compile(request: Request):
"""Extracts data from request and returns object.
Expand Down
90 changes: 48 additions & 42 deletions frbvoe/utilities/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def send_email(email_report: Dict[str, Any]):
Raises:
None
"""
email_report = email_report.model_dump()
subject = f"{email_report['observatory_name']}_VOE_{email_report['kind']}"
if email_report["kind"] in ["detection", "subsequent"]:
email_message = f"""
Expand All @@ -48,36 +49,6 @@ def send_email(email_report: Dict[str, Any]):
\n
\t\ttsys: {email_report['tsys']} K\n
\n
\t\tbackend: {email_report['backend']}\n
\n
\tevent parameters:\n
\t\tevent_no: {email_report['internal_id']}\n
\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
\n
\t\tsnr: {email_report['snr']}\n
\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
\n\n
HOW\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.
Expand Down Expand Up @@ -125,8 +96,8 @@ def send_email(email_report: Dict[str, Any]):
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@physics.mcgill.ca" # TODO: load from DB
smtp_server = "smtp.example.com" # Change to the appropriate server if needed
smtp_port = 587 # Change to the appropriate port if needed

# Create a message
Expand All @@ -135,17 +106,52 @@ def send_email(email_report: Dict[str, Any]):
message["To"] = receiver_email
message["Subject"] = subject
message.attach(MIMEText(email_message, "plain"))

#print email message
print(email_message)

# # Connect to the SMTP server
# server = smtplib.SMTP(smtp_server, smtp_port)
# server.starttls() # Secure the connection
# # server.login(email_report["email"], email_report["email_password"])
# server.login("username", "password") # TODO: load from DB
# # Send the email
# server.send_message(message)

# # Quit the server
# server.quit()
status = "Success"

# Connect to the SMTP server
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls() # Secure the connection
server.login(email_report["email"], email_report["email_password"])
return status

# Send the email
server.send_message(message)

# Quit the server
server.quit()
status = "Success"

return status
# \t\tbackend: {email_report['backend']}\n
# \n
# \tevent parameters:\n
# \t\tevent_no: {email_report['internal_id']}\n
# \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
# \n
# \t\tsnr: {email_report['snr']}\n
# \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
# \n\n
# HOW\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
Loading

0 comments on commit f085e07

Please sign in to comment.