diff --git a/fideslog/api/database/registrations.py b/fideslog/api/database/registrations.py index 8d8c6b0..e7d1762 100644 --- a/fideslog/api/database/registrations.py +++ b/fideslog/api/database/registrations.py @@ -38,8 +38,8 @@ def create(database: Session, registration: Registration) -> None: client_id=registration.client_id, email=registration.email, organization=registration.organization, - created_at=datetime.now(timezone.utc), - updated_at=datetime.now(timezone.utc), + created_at=registration.created_at, + updated_at=registration.updated_at, ) ) diff --git a/fideslog/api/schemas/registration.py b/fideslog/api/schemas/registration.py index 54fa923..a8b7b70 100644 --- a/fideslog/api/schemas/registration.py +++ b/fideslog/api/schemas/registration.py @@ -1,6 +1,6 @@ # pylint: disable= no-self-argument, no-self-use -from datetime import datetime +from datetime import datetime, timezone from pydantic import BaseModel, EmailStr, Field, validator @@ -23,11 +23,11 @@ class Registration(BaseModel): description="The organization in which the user is registered.", ) created_at: datetime = Field( - None, + datetime.now(tz=timezone.utc), description="The UTC timestamp when the registration occurred, in ISO 8601 format. Must include the UTC timezone, and represent a datetime in the past.", ) updated_at: datetime = Field( - None, + datetime.now(tz=timezone.utc), description="The UTC timestamp when the registration was last updated, in ISO 8601 format. Must include the UTC timezone, and represent a datetime in the past.", ) diff --git a/fideslog/sdk/python/client.py b/fideslog/sdk/python/client.py index e8a7a90..e9723cd 100644 --- a/fideslog/sdk/python/client.py +++ b/fideslog/sdk/python/client.py @@ -92,7 +92,14 @@ def register(self, registration: Registration) -> None: """ __set_event_loop() - run(self.__send(registration)) + run(self.send_async(registration)) + + async def register_async(self, registration: Registration) -> None: + """ + Asynchronously record a new `Registration`. + """ + + await self.send_async(registration) def send(self, event: AnalyticsEvent) -> None: """ @@ -100,7 +107,38 @@ def send(self, event: AnalyticsEvent) -> None: """ __set_event_loop() - run(self.__send(event)) + run(self.send_async(event)) + + async def send_async( + self, + event_or_registration: Union[AnalyticsEvent, Registration], + ) -> None: + """ + Asynchronously record a new `AnalyticsEvent` or `Registration`. + """ + + async with ClientSession( + self.server_url, + headers=REQUIRED_HEADERS, + timeout=ClientTimeout(connect=3.05, total=120), + ) as session: + try: + async with session.post( + url=( + "/events" + if isinstance(event_or_registration, AnalyticsEvent) + else "/registrations" + ), + json=self.__get_request_payload(event_or_registration), + ) as resp: + resp.raise_for_status() + + except ClientConnectionError as err: + raise UnreachableServerError(err.__str__()) from err + except ClientResponseError as err: + raise AnalyticsSendError(err.message, err.status) from err + except Exception as err: + raise UnknownError(err) from err def __get_request_payload( self, @@ -153,34 +191,3 @@ def __get_analytics_payload(self, event: AnalyticsEvent) -> Dict: payload[extra] = event_dict[extra] return payload - - async def __send( - self, - event_or_registration: Union[AnalyticsEvent, Registration], - ) -> None: - """ - Asynchronously record a new `AnalyticsEvent` or `Registration`. - """ - - async with ClientSession( - self.server_url, - headers=REQUIRED_HEADERS, - timeout=ClientTimeout(connect=3.05, total=120), - ) as session: - try: - async with session.post( - url=( - "/events" - if isinstance(event_or_registration, AnalyticsEvent) - else "/registrations" - ), - json=self.__get_request_payload(event_or_registration), - ) as resp: - resp.raise_for_status() - - except ClientConnectionError as err: - raise UnreachableServerError(err.__str__()) from err - except ClientResponseError as err: - raise AnalyticsSendError(err.message, err.status) from err - except Exception as err: - raise UnknownError(err) from err diff --git a/fideslog/sdk/python/registration.py b/fideslog/sdk/python/registration.py index 1a750da..d578de6 100644 --- a/fideslog/sdk/python/registration.py +++ b/fideslog/sdk/python/registration.py @@ -8,12 +8,20 @@ class Registration: Represents a user registering their information. """ - def __init__(self, email: str, organization: str) -> None: + def __init__( + self, + email: str, + organization: str, + created_at: datetime = datetime.now(tz=timezone.utc), + updated_at: datetime = datetime.now(tz=timezone.utc), + ) -> None: """ Define a new user registration. :param email: The user's email address. :param organization: The user's organization. + :param created_at: The UTC timestamp when the registration occurred, in ISO 8601 format. Must include the UTC timezone, and represent a datetime in the past. + :param updated_at: The UTC timestamp when the registration was last updated, in ISO 8601 format. Must include the UTC timezone, and represent a datetime in the past. """ try: @@ -23,8 +31,8 @@ def __init__(self, email: str, organization: str) -> None: assert len(organization) > 0, "organization must be provided" self.organization = organization - self.created_at = datetime.now(timezone.utc) - self.updated_at = datetime.now(timezone.utc) + self.created_at = created_at + self.updated_at = updated_at except AssertionError as err: raise InvalidEventError(str(err)) from None