diff --git a/lib/controllers/environment.py b/lib/controllers/environment.py index 747e93b..f11d8c6 100644 --- a/lib/controllers/environment.py +++ b/lib/controllers/environment.py @@ -36,7 +36,7 @@ def __init__(self, env: Env): self._env = env @property - async def env(self) -> Env: + def env(self) -> Env: return self._env @env.setter diff --git a/lib/repositories/__init__.py b/lib/repositories/__init__.py new file mode 100644 index 0000000..87e5b46 --- /dev/null +++ b/lib/repositories/__init__.py @@ -0,0 +1,6 @@ +# lib/controllers/__init__.py + + +def parse_error(e): + exc_str = f"{e}".replace("\n", " ").replace(" ", " ") + return exc_str diff --git a/lib/repositories/environment.py b/lib/repositories/environment.py index 8632b65..53a1ea7 100644 --- a/lib/repositories/environment.py +++ b/lib/repositories/environment.py @@ -1,101 +1,138 @@ +import logging +from datetime import datetime from typing import Union -from pymongo.results import InsertOneResult -from pymongo.results import DeleteResult +from lib.repositories import parse_error from lib.models.environment import Env from lib.repositories.repo import Repository class EnvRepository(Repository): """ - Environment repository + Enables database CRUD operations with models.Env Init Attributes: - environment: Env object - env_id: Environment id + environment: models.Env + env_id: str - Enables CRUD operations on environment objects """ def __init__(self, environment: Env = None, env_id: str = None): super().__init__("environments") - self.environment = environment + self._env = environment if env_id: - self.env_id = env_id + self._env_id = env_id else: - self.env_id = self.environment.__hash__() + self._env_id = hash(self._env) - def __del__(self): - super().__del__() + @property + def env(self) -> "Env": + return self._env - async def create_env(self) -> "InsertOneResult": - """ - Creates a environment in the database + @env.setter + def env(self, environment: "Env"): + self._env = environment + + @property + def env_id(self) -> "str": + return self._env_id + + @env_id.setter + def env_id(self, env_id: "str"): + self._env_id = env_id - Args: - rocketpy_env: rocketpy environment object + async def create_env(self): + """ + Creates a non-existing models.Env in the database Returns: - InsertOneResult: result of the insert operation + None """ - if not await self.get_env(): - try: - environment_to_dict = self.environment.dict() - environment_to_dict["env_id"] = self.env_id - return await self.collection.insert_one(environment_to_dict) - except Exception as e: - raise Exception(f"Error creating environment: {str(e)}") from e - finally: - self.__del__() - else: - return InsertOneResult(acknowledged=True, inserted_id=None) + env_exists = await self.get_env() + if env_exists: + return + + try: + environment_to_dict = self.env.dict() + environment_to_dict["env_id"] = self.env_id + await self.collection.insert_one(environment_to_dict) + except Exception as e: + exc_str = parse_error(e) + logging.error( + f"[{datetime.now()}] repositories.environment.create_env: {exc_str}" + ) + raise Exception(f"Error creating environment: {str(e)}") from e + finally: + logging.info( + f"[{datetime.now()}] Call to repositories.environment.create_env completed; states: Env {hash(self.env)}, EnvID {self.env_id}" + ) + self.close_connection() - async def update_env(self) -> "Union[int, None]": + async def update_env(self): """ - Updates a environment in the database + Updates a models.Env in the database Returns: - int: environment id + None """ try: - environment_to_dict = self.environment.dict() - environment_to_dict["env_id"] = self.environment.__hash__() - + environment_to_dict = self.env.dict() + environment_to_dict["env_id"] = hash(self.env) await self.collection.update_one( {"env_id": self.env_id}, {"$set": environment_to_dict} ) - self.env_id = environment_to_dict["env_id"] - return self.env_id except Exception as e: + exc_str = parse_error(e) + logging.error( + f"[{datetime.now()}] repositories.environment.update_env: {exc_str}" + ) raise Exception(f"Error updating environment: {str(e)}") from e + else: + return finally: - self.__del__() + logging.info( + f"[{datetime.now()}] Call to repositories.environment.update_env completed; states: Env {hash(self.env)}, EnvID {self.env_id}" + ) + self.close_connection() async def get_env(self) -> "Union[Env, None]": """ - Gets a environment from the database + Gets a models.Env from the database Returns: - models.Env: Model environment object + models.Env """ try: - environment = await self.collection.find_one({"env_id": self.env_id}) - if environment is not None: - return Env.parse_obj(environment) - return None + read_env = await self.collection.find_one({"env_id": self.env_id}) except Exception as e: + logging.error( + f"[{datetime.now()}] repositories.environment.get_env: {str(e)}" + ) raise Exception(f"Error getting environment: {str(e)}") from e + else: + return Env.parse_obj(read_env) if read_env else None + finally: + logging.info( + f"[{datetime.now()}] Call to repositories.environment.get_env completed; states: Env {hash(self.env)}, EnvID {self.env_id}" + ) + self.close_connection() - async def delete_env(self) -> "DeleteResult": + async def delete_env(self): """ - Deletes a environment from the database + Deletes a models.Env from the database Returns: - DeleteResult: result of the delete operation + None """ try: - return await self.collection.delete_one({"env_id": self.env_id}) + await self.collection.delete_one({"env_id": self.env_id}) except Exception as e: + logging.error( + f"[{datetime.now()}] repositories.environment.delete_env: {str(e)}" + ) raise Exception(f"Error deleting environment: {str(e)}") from e finally: - self.__del__() + logging.info( + f"[{datetime.now()}] Call to repositories.environment.delete_env completed; states: Env {hash(self.env)}, EnvID {self.env_id}" + ) + self.close_connection() diff --git a/lib/repositories/repo.py b/lib/repositories/repo.py index 24401c4..bbdee80 100644 --- a/lib/repositories/repo.py +++ b/lib/repositories/repo.py @@ -1,3 +1,4 @@ +import logging from motor.motor_asyncio import AsyncIOMotorClient from pymongo.server_api import ServerApi from lib.secrets import secrets_instance @@ -25,5 +26,6 @@ def __init__(self, collection: str): self.db = self.client.rocketpy self.collection = self.db[collection] - def __del__(self): + def close_connection(self) -> None: + logging.info(f"[{datetime.now()}] Closing connection to database") self.client.close() diff --git a/pyproject.toml b/pyproject.toml index f5544bf..1ba712f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,3 @@ -[build-system] -requires = ["setuptools", "setuptools_scm"] -build-backend = "setuptools.build_meta" - -[tool.setuptools.dynamic] -dependencies = {file = ["requirements.txt"]} - [project] name = "Infinity-API" version = "1.1.0" @@ -19,12 +12,15 @@ maintainers = [ {name = "Luiz Mota", email = "luiz.mota1999@usp.br"} ] readme = "README.md" -keywords = ["rocketpy", "rocket flight", "simulation", "rocket", "flight"] +keywords = ["rocketpy", "rocket flight", "simulation", "API"] classifiers = [ "Development Status :: Alpha", "Programming Language :: Python" ] +[tool.setuptools.dynamic] +dependencies = { file = ["requirements.txt"] } + [project.urls] Homepage = "http://api.rocketpy.org/" Documentation = "http://api.rocketpy.org/docs" diff --git a/requirements.txt b/requirements.txt index 7dd605c..be65cb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,4 @@ pymongo jsonpickle gunicorn uvicorn -git+https://github.com/RocketPy-Team/RocketPy +rocketpy