From e6da82595ab1569f922eae6d5791ba89b8e79a3b Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 21 Mar 2025 16:22:12 +0100 Subject: [PATCH] docs: Add docstrings for the store manager and main Refs: OPS-68 --- docs/auto_docu.sh | 0 senju/haiku.py | 9 ++---- senju/main.py | 66 ++++++++++++++++++++++++++++++++++++++- senju/store_manager.py | 70 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 8 deletions(-) mode change 100644 => 100755 docs/auto_docu.sh diff --git a/docs/auto_docu.sh b/docs/auto_docu.sh old mode 100644 new mode 100755 diff --git a/senju/haiku.py b/senju/haiku.py index 734cbc4..151647f 100644 --- a/senju/haiku.py +++ b/senju/haiku.py @@ -19,21 +19,16 @@ def foobar(): @dataclass class Haiku: - """ - A class representing a haiku poem with three lines. - - Attributes: - lines (list[str]): A list containing the three lines of the haiku. - """ lines: list[str] def get_json(self): - """ + """ Converts the haiku lines to a JSON string. Returns: str: A JSON string representation of the haiku lines. """ + return json.dumps(self.lines) @staticmethod diff --git a/senju/main.py b/senju/main.py index 663a7c5..575dc73 100644 --- a/senju/main.py +++ b/senju/main.py @@ -24,11 +24,28 @@ def foobar(): @app.route("/") def index_view(): + """ + Render the main index page of the application. + + Returns: + Text: The index.html template with title "Senju". + """ + return render_template("index.html", title="Senju") @app.route("/haiku/") def haiku_index_view(): + """ + Redirect to the most recently created haiku. + + Returns: + Response: Redirects to the haiku_view route with the latest haiku ID. + + Raises: + KeyError: If no haikus exist in the store yet. + """ + haiku_id: int | None = store.get_id_of_latest_haiku() if haiku_id is None: # TODO: add "empty haiku list" error page @@ -38,7 +55,23 @@ def haiku_index_view(): @app.route("/haiku/") def haiku_view(haiku_id): - """test""" + """ + Display a specific haiku by its ID. + + Loads the haiku with the given ID from the store and renders it using + the haiku.html template. If no haiku is found with the provided ID, + raises a KeyError. + + Args: + haiku_id (int): The ID of the haiku to display. + + Returns: + Text: The haiku.html template with the haiku data in context. + + Raises: + KeyError: If no haiku exists with the given ID. + """ + haiku: Haiku | None = store.load_haiku(haiku_id) if haiku is None: # TODO: add "haiku not found" page @@ -55,6 +88,13 @@ def haiku_view(haiku_id): @app.route("/prompt") def prompt_view(): + """ + Render the haiku generation prompt page. + + Returns: + Text: The prompt.html template with title "Haiku generation". + """ + return render_template( "prompt.html", title="Haiku generation" @@ -63,6 +103,12 @@ def prompt_view(): @app.route("/scan") def scan_view(): + """ + Render the image scanning page. + + Returns: + Text: The scan.html template with title "Image scanning". + """ return render_template( "scan.html", title="Image scanning" @@ -71,6 +117,17 @@ def scan_view(): @app.route("/api/v1/haiku", methods=['POST']) def generate_haiku(): + """ + API endpoint to generate a new haiku based on the provided prompt. + + Accepts POST requests with JSON data containing a 'prompt' field. + Generates a haiku using the prompt, saves it to the store, and returns the ID. + + Returns: + str: The ID of the newly created haiku if method is POST. + tuple: Error message and status code 405 if method is not POST. + """ + if request.method == 'POST': json_data = request.get_json() prompt = json_data["prompt"] @@ -83,6 +140,13 @@ def generate_haiku(): @app.route('/favicon.ico') def favicon(): + """ + Serve the favicon.ico file from the static directory. + + Returns: + Response: The favicon.ico file with the appropriate MIME type. + """ + return send_from_directory(os.path.join(app.root_path, 'static/img'), 'favicon.ico', mimetype='image/vnd.microsoft.icon') diff --git a/senju/store_manager.py b/senju/store_manager.py index 72a4561..8e418cd 100644 --- a/senju/store_manager.py +++ b/senju/store_manager.py @@ -25,13 +25,43 @@ class StoreManager: logger: Logger def __init__(self, path_to_db: Path = DEFAULT_DB_PATH) -> None: + """ + Initialize the StoreManager with a database path. + + Args: + path_to_db (Path, optional): Path to the TinyDB database file. + Defaults to DEFAULT_DB_PATH. + """ self._db = TinyDB(path_to_db) self.logger = Logger(__name__) def _query(self, query: QueryImpl) -> list[dict]: + """ + Execute a query against the database. + + Args: + query (QueryImpl): TinyDB query to execute. + + Returns: + list[dict]: List of documents matching the query. + """ + return self._db.search(query) def _load(self, id: int) -> Optional[dict]: + """ + Load a document by its ID. + + Args: + id (int): Document ID to load. + + Returns: + Optional[dict]: The document if found, None otherwise. + + Logs: + Warning if document with specified ID is not found. + """ + try: return self._db.get(doc_id=id) except IndexError as e: @@ -39,9 +69,29 @@ class StoreManager: return None def _save(self, data: dict) -> int: + """ + Save a document to the database. + + Args: + data (dict): Document data to save. + + Returns: + int: The document ID of the saved document. + """ + return self._db.insert(data) def load_haiku(self, key: int) -> Optional[Haiku]: + """ + Load a haiku by its ID. + + Args: + key (int): The ID of the haiku to load. + + Returns: + Optional[Haiku]: A Haiku object if found, None otherwise. + """ + raw_haiku: dict | None = self._load(key) if raw_haiku is None: return None @@ -49,9 +99,29 @@ class StoreManager: return h def save_haiku(self, data: Haiku) -> int: + """ + Save a haiku to the database. + + Args: + data (Haiku): The Haiku object to save. + + Returns: + int: The document ID of the saved haiku. + """ + return self._save(data.__dict__) def get_id_of_latest_haiku(self) -> Optional[int]: + """ + Get the ID of the most recently added haiku. + + Returns: + Optional[int]: The ID of the latest haiku if any exists, None otherwise. + + Logs: + Error if the database is empty. + """ + try: id = self._db.all()[-1].doc_id return id