From a5b601665f8e5fbec25018dac5cc705a00bec044 Mon Sep 17 00:00:00 2001 From: "Poornachandra.A.N" Date: Thu, 12 Feb 2026 14:38:49 +0530 Subject: [PATCH 01/11] move folders into sample --- pyproject.toml | 5 +-- src/__init__.py | 2 +- src/api/__init__.py | 3 -- src/sample/__init__.py | 2 +- src/sample/__main__.py | 29 +--------------- src/sample/api/__init__.py | 3 ++ src/{ => sample}/api/fast_api.py | 6 ++-- src/sample/cli.py | 2 +- src/{ => sample}/db/__init__.py | 0 src/{ => sample}/db/connection.py | 4 +-- src/{ => sample}/features/__init__.py | 0 src/{ => sample}/features/greeting.py | 4 +-- src/sample/streamlit_app.py | 8 ++--- src/sample/utils/__init__.py | 4 +++ src/{ => sample}/utils/_version.py | 28 +++++++-------- src/{ => sample}/utils/constants.py | 2 +- src/{ => sample}/utils/debug.py | 34 +++++++++--------- src/{ => sample}/utils/faq.py | 0 src/{ => sample}/utils/helper.py | 0 src/{ => sample}/utils/lint.py | 46 ++++++++++++------------- src/{ => sample}/utils/load_messages.py | 2 +- src/{ => sample}/utils/messages.py | 0 src/{ => sample}/utils/templates.py | 0 src/utils/__init__.py | 4 --- 24 files changed, 79 insertions(+), 109 deletions(-) delete mode 100644 src/api/__init__.py create mode 100644 src/sample/api/__init__.py rename src/{ => sample}/api/fast_api.py (93%) rename src/{ => sample}/db/__init__.py (100%) rename src/{ => sample}/db/connection.py (95%) rename src/{ => sample}/features/__init__.py (100%) rename src/{ => sample}/features/greeting.py (76%) create mode 100644 src/sample/utils/__init__.py rename src/{ => sample}/utils/_version.py (97%) rename src/{ => sample}/utils/constants.py (97%) rename src/{ => sample}/utils/debug.py (96%) rename src/{ => sample}/utils/faq.py (100%) rename src/{ => sample}/utils/helper.py (100%) rename src/{ => sample}/utils/lint.py (95%) rename src/{ => sample}/utils/load_messages.py (95%) rename src/{ => sample}/utils/messages.py (100%) rename src/{ => sample}/utils/templates.py (100%) delete mode 100644 src/utils/__init__.py diff --git a/pyproject.toml b/pyproject.toml index 1c1c4b5..44c6217 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,16 +23,13 @@ dependencies = [ [tool.poetry] packages = [ { include = "sample", from = "src" }, - { include = "features", from = "src" }, - { include = "utils", from = "src" }, - { include = "api", from = "src" }, { include = "assets/images/logo.png", from = "src" }, ] [project.scripts] sample = "sample.cli:cli" -lint = "utils.lint:main" +lint = "sample.utils.lint:main" [tool.poetry.group.dev.dependencies] diff --git a/src/__init__.py b/src/__init__.py index 0ed1344..bdf1df2 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -1,3 +1,3 @@ -from utils._version import get_version +from sample.utils._version import get_version __version__ = get_version() diff --git a/src/api/__init__.py b/src/api/__init__.py deleted file mode 100644 index 0ed1344..0000000 --- a/src/api/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from utils._version import get_version - -__version__ = get_version() diff --git a/src/sample/__init__.py b/src/sample/__init__.py index 143c9a4..20ec7fe 100644 --- a/src/sample/__init__.py +++ b/src/sample/__init__.py @@ -1,3 +1,3 @@ -from utils._version import get_version +from sample.utils._version import get_version __version__ = get_version() diff --git a/src/sample/__main__.py b/src/sample/__main__.py index c8ff3c2..c2eddd7 100644 --- a/src/sample/__main__.py +++ b/src/sample/__main__.py @@ -5,33 +5,6 @@ import logging import subprocess from pathlib import Path -import click - -logging.basicConfig(level=logging.INFO) - - -@click.group(invoke_without_command=True) -@click.option("--version", is_flag=True, help="Show the Sample version and exit.") -@click.pass_context -def cli(ctx, version): - """Sample command-line tools.""" - if version: - click.echo(__version__) - ctx.exit() - - -@cli.command() -def dev(): - """Run the Sample Streamlit app.""" - main() - - -@cli.command() -def api(): - """Run the Sample FastAPI backend.""" - from api.fast_api import start - - start() def main(): @@ -83,4 +56,4 @@ def main(): if __name__ == "__main__": - cli() + main() diff --git a/src/sample/api/__init__.py b/src/sample/api/__init__.py new file mode 100644 index 0000000..20ec7fe --- /dev/null +++ b/src/sample/api/__init__.py @@ -0,0 +1,3 @@ +from sample.utils._version import get_version + +__version__ = get_version() diff --git a/src/api/fast_api.py b/src/sample/api/fast_api.py similarity index 93% rename from src/api/fast_api.py rename to src/sample/api/fast_api.py index 0d56f34..0b4b3cf 100644 --- a/src/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -2,8 +2,8 @@ from fastapi.responses import HTMLResponse from pydantic import BaseModel from . import __version__ -from utils.constants import DEFAULT_GREETING -from utils.helper import normalize_name +from sample.utils.constants import DEFAULT_GREETING +from sample.utils.helper import normalize_name app = FastAPI( title="sample API", @@ -94,7 +94,7 @@ def start(): import uvicorn print(f"๐Ÿงต {__version__}\n") - uvicorn.run("api.fast_api:app", host="127.0.0.1", port=5000, reload=True) + uvicorn.run("sample.api.fast_api:app", host="127.0.0.1", port=5000, reload=True) if __name__ == "__main__": diff --git a/src/sample/cli.py b/src/sample/cli.py index 93d1a1f..98fd6b7 100644 --- a/src/sample/cli.py +++ b/src/sample/cli.py @@ -23,6 +23,6 @@ def dev(): @cli.command() def api(): """Run the Sample FastAPI backend.""" - from api.fast_api import start + from sample.api.fast_api import start start() diff --git a/src/db/__init__.py b/src/sample/db/__init__.py similarity index 100% rename from src/db/__init__.py rename to src/sample/db/__init__.py diff --git a/src/db/connection.py b/src/sample/db/connection.py similarity index 95% rename from src/db/connection.py rename to src/sample/db/connection.py index a7a824e..f4bb6a1 100644 --- a/src/db/connection.py +++ b/src/sample/db/connection.py @@ -4,7 +4,7 @@ from pymongo.database import Database from pymongo.collection import Collection import io -from utils.constants import MONGO_CONFIG +from sample.utils.constants import MONGO_CONFIG mongo_client: Optional[MongoClient] db: Optional[Database] @@ -43,4 +43,4 @@ def pil_to_bytes(pil_image): buf = io.BytesIO() pil_image.save(buf, format="PNG") buf.seek(0) - return buf \ No newline at end of file + return buf diff --git a/src/features/__init__.py b/src/sample/features/__init__.py similarity index 100% rename from src/features/__init__.py rename to src/sample/features/__init__.py diff --git a/src/features/greeting.py b/src/sample/features/greeting.py similarity index 76% rename from src/features/greeting.py rename to src/sample/features/greeting.py index f580f9a..2b591d8 100644 --- a/src/features/greeting.py +++ b/src/sample/features/greeting.py @@ -1,10 +1,10 @@ import streamlit as st -from utils.constants import ( +from sample.utils.constants import ( APP_TITLE, DEFAULT_GREETING ) -from utils.helper import normalize_name +from sample.utils.helper import normalize_name def greet(): diff --git a/src/sample/streamlit_app.py b/src/sample/streamlit_app.py index 5095189..3caad77 100644 --- a/src/sample/streamlit_app.py +++ b/src/sample/streamlit_app.py @@ -8,10 +8,10 @@ sys.path.append(package_root) # --- Imports --- -from utils.constants import COMPANY_LOGO, FAQ_TITLE -from utils.faq import faq_page -from utils.load_messages import get_msg -from features.greeting import greet +from sample.utils.constants import COMPANY_LOGO, FAQ_TITLE +from sample.utils.faq import faq_page +from sample.utils.load_messages import get_msg +from sample.features.greeting import greet MSG = get_msg("MAIN_APP") diff --git a/src/sample/utils/__init__.py b/src/sample/utils/__init__.py new file mode 100644 index 0000000..ec9c27a --- /dev/null +++ b/src/sample/utils/__init__.py @@ -0,0 +1,4 @@ +from sample.db.connection import mongo_client + +if mongo_client: + print("MongoDB connected successfully.") diff --git a/src/utils/_version.py b/src/sample/utils/_version.py similarity index 97% rename from src/utils/_version.py rename to src/sample/utils/_version.py index 128e32b..84a4e39 100644 --- a/src/utils/_version.py +++ b/src/sample/utils/_version.py @@ -1,14 +1,14 @@ -# use this to update version in setup.py automatically -# when building the package, so that we don't have to maintain version in two places - -try: - from importlib.metadata import PackageNotFoundError, version -except ImportError: # Python <3.8 - from importlib.metadata import PackageNotFoundError, version - - -def get_version() -> str: - try: - return version("sample") # must match pyproject.toml [project].name - except PackageNotFoundError: - return "0.0.0" +# use this to update version in setup.py automatically +# when building the package, so that we don't have to maintain version in two places + +try: + from importlib.metadata import PackageNotFoundError, version +except ImportError: # Python <3.8 + from importlib.metadata import PackageNotFoundError, version + + +def get_version() -> str: + try: + return version("sample") # must match pyproject.toml [project].name + except PackageNotFoundError: + return "0.0.0" diff --git a/src/utils/constants.py b/src/sample/utils/constants.py similarity index 97% rename from src/utils/constants.py rename to src/sample/utils/constants.py index 5fc28ea..1ce4699 100644 --- a/src/utils/constants.py +++ b/src/sample/utils/constants.py @@ -11,7 +11,7 @@ FAQ_TITLE = "FAQs" # --- Asset paths --- -PROJECT_ROOT = Path(__file__).parent.parent +PROJECT_ROOT = Path(__file__).parents[2] ASSETS_DIR = PROJECT_ROOT / "assets" / "images" COMPANY_LOGO = ASSETS_DIR / "logo.png" diff --git a/src/utils/debug.py b/src/sample/utils/debug.py similarity index 96% rename from src/utils/debug.py rename to src/sample/utils/debug.py index e11261f..3babaf0 100644 --- a/src/utils/debug.py +++ b/src/sample/utils/debug.py @@ -1,17 +1,17 @@ -import os -import sys -from pathlib import Path - -CURRENT_PATH = os.path.dirname(__file__) - -SRC_PATH = os.path.dirname(os.path.abspath(__file__)) - -print("SRC PATH", SRC_PATH) - -# Get the root directory of the project -PROJECT_ROOT = Path(__file__).resolve().parent.parent - -print(f"Project Root: {PROJECT_ROOT}") -print(f"Current script path: {CURRENT_PATH}") -print(f"Working directory: {os.getcwd()}") -print(f"Command used: {sys.argv[0]}") +import os +import sys +from pathlib import Path + +CURRENT_PATH = os.path.dirname(__file__) + +SRC_PATH = os.path.dirname(os.path.abspath(__file__)) + +print("SRC PATH", SRC_PATH) + +# Get the root directory of the project +PROJECT_ROOT = Path(__file__).resolve().parent.parent + +print(f"Project Root: {PROJECT_ROOT}") +print(f"Current script path: {CURRENT_PATH}") +print(f"Working directory: {os.getcwd()}") +print(f"Command used: {sys.argv[0]}") diff --git a/src/utils/faq.py b/src/sample/utils/faq.py similarity index 100% rename from src/utils/faq.py rename to src/sample/utils/faq.py diff --git a/src/utils/helper.py b/src/sample/utils/helper.py similarity index 100% rename from src/utils/helper.py rename to src/sample/utils/helper.py diff --git a/src/utils/lint.py b/src/sample/utils/lint.py similarity index 95% rename from src/utils/lint.py rename to src/sample/utils/lint.py index bcd363f..8247281 100644 --- a/src/utils/lint.py +++ b/src/sample/utils/lint.py @@ -1,23 +1,23 @@ -import subprocess -import sys - -commands = [ - ["black", "."], - ["flake8", "."], - ["mypy", "."], - ["ruff", "check", "."], -] - - -def main(): - for cmd in commands: - print(f"\n๐Ÿš€ Running: {' '.join(cmd)}") - result = subprocess.run(["poetry", "run"] + cmd) - if result.returncode != 0: - print(f"โŒ Command failed: {' '.join(cmd)}") - sys.exit(result.returncode) - print("\nโœ… All linters passed successfully!") - - -if __name__ == "__main__": - main() +import subprocess +import sys + +commands = [ + ["black", "."], + ["flake8", "."], + ["mypy", "."], + ["ruff", "check", "."], +] + + +def main(): + for cmd in commands: + print(f"\n๐Ÿš€ Running: {' '.join(cmd)}") + result = subprocess.run(["poetry", "run"] + cmd) + if result.returncode != 0: + print(f"โŒ Command failed: {' '.join(cmd)}") + sys.exit(result.returncode) + print("\nโœ… All linters passed successfully!") + + +if __name__ == "__main__": + main() diff --git a/src/utils/load_messages.py b/src/sample/utils/load_messages.py similarity index 95% rename from src/utils/load_messages.py rename to src/sample/utils/load_messages.py index a35c171..ad14ba5 100644 --- a/src/utils/load_messages.py +++ b/src/sample/utils/load_messages.py @@ -3,7 +3,7 @@ import importlib -# auto-collect static and text blocks from utils.static +# auto-collect static and text blocks from sample.utils.static _static_module = importlib.import_module("utils.templates") _TEMPLATE_MAP = {} for name, val in vars(_static_module).items(): diff --git a/src/utils/messages.py b/src/sample/utils/messages.py similarity index 100% rename from src/utils/messages.py rename to src/sample/utils/messages.py diff --git a/src/utils/templates.py b/src/sample/utils/templates.py similarity index 100% rename from src/utils/templates.py rename to src/sample/utils/templates.py diff --git a/src/utils/__init__.py b/src/utils/__init__.py deleted file mode 100644 index 42ca9c6..0000000 --- a/src/utils/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from db.connection import mongo_client - -if mongo_client: - print("MongoDB connected successfully.") \ No newline at end of file From 9706ebb1ab73aed096b2c431cae540be02d11836 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 21:14:50 +0530 Subject: [PATCH 02/11] [TZP-260007]: refactor: update import statements and adjust sys.path for module resolution --- .gitignore | 4 ++-- src/sample/api/fast_api.py | 9 ++++++++- src/sample/features/greeting.py | 5 +---- src/sample/streamlit_app.py | 12 +++++++----- src/sample/utils/__init__.py | 2 +- src/sample/utils/constants.py | 3 ++- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index b7faf40..e3c60c0 100644 --- a/.gitignore +++ b/.gitignore @@ -137,9 +137,9 @@ celerybeat.pid # Environments .env .envrc -.venv +.venv** env/ -venv/ +venv**/ ENV/ env.bak/ venv.bak/ diff --git a/src/sample/api/fast_api.py b/src/sample/api/fast_api.py index 0b4b3cf..17ea947 100644 --- a/src/sample/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -1,10 +1,17 @@ +import sys +from pathlib import Path + from fastapi import FastAPI, HTTPException, Request from fastapi.responses import HTMLResponse from pydantic import BaseModel -from . import __version__ + from sample.utils.constants import DEFAULT_GREETING from sample.utils.helper import normalize_name +sys.path.append(str(Path(__file__).resolve().parent.parent)) + +from . import __version__ + app = FastAPI( title="sample API", description="API endpoints for Sample with rate limiting", diff --git a/src/sample/features/greeting.py b/src/sample/features/greeting.py index 2b591d8..2e92903 100644 --- a/src/sample/features/greeting.py +++ b/src/sample/features/greeting.py @@ -1,9 +1,6 @@ import streamlit as st -from sample.utils.constants import ( - APP_TITLE, - DEFAULT_GREETING -) +from sample.utils.constants import APP_TITLE, DEFAULT_GREETING from sample.utils.helper import normalize_name diff --git a/src/sample/streamlit_app.py b/src/sample/streamlit_app.py index 3caad77..2a0ca35 100644 --- a/src/sample/streamlit_app.py +++ b/src/sample/streamlit_app.py @@ -1,17 +1,19 @@ import sys from pathlib import Path + import streamlit as st +from sample.features.greeting import greet + +# --- Imports --- +from sample.utils.constants import COMPANY_LOGO, FAQ_TITLE +from sample.utils.faq import faq_page +from sample.utils.load_messages import get_msg # --- Path setup --- package_root = str(Path(__file__).parent) if package_root not in sys.path: sys.path.append(package_root) -# --- Imports --- -from sample.utils.constants import COMPANY_LOGO, FAQ_TITLE -from sample.utils.faq import faq_page -from sample.utils.load_messages import get_msg -from sample.features.greeting import greet MSG = get_msg("MAIN_APP") diff --git a/src/sample/utils/__init__.py b/src/sample/utils/__init__.py index ec9c27a..715cafe 100644 --- a/src/sample/utils/__init__.py +++ b/src/sample/utils/__init__.py @@ -1,4 +1,4 @@ from sample.db.connection import mongo_client if mongo_client: - print("MongoDB connected successfully.") + print("MongoDB connected successfully.") diff --git a/src/sample/utils/constants.py b/src/sample/utils/constants.py index 1ce4699..62a5285 100644 --- a/src/sample/utils/constants.py +++ b/src/sample/utils/constants.py @@ -5,7 +5,6 @@ import logging - APP_TITLE = ":blue[Greeting Feature]" DEFAULT_GREETING = "Hello" FAQ_TITLE = "FAQs" @@ -15,6 +14,7 @@ ASSETS_DIR = PROJECT_ROOT / "assets" / "images" COMPANY_LOGO = ASSETS_DIR / "logo.png" + def safe_get(secret_path: str, env_key: str = "", default: str = "") -> str: """ Safely retrieve a configuration value from: @@ -57,6 +57,7 @@ def safe_get(secret_path: str, env_key: str = "", default: str = "") -> str: ) return value + MONGODB_URI = safe_get("mongodb.MONGODB_URI", "MONGODB_URI") DATABASE_NAME = safe_get("mongodb.DATABASE_NAME", "DATABASE_NAME") From afe60d8809e083bcd50def1cf6828f92f436f746 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 23:05:37 +0530 Subject: [PATCH 03/11] [TZP-260007]: feat: add bs4 dependency and update package groups in poetry.lock refactor: clean up logging in constants.py --- poetry.lock | 21 ++++++++++++++++++--- pyproject.toml | 1 + src/sample/utils/constants.py | 7 ++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1e3e98b..d2030b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -145,7 +145,7 @@ version = "4.14.3" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb"}, {file = "beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"}, @@ -258,6 +258,21 @@ docs = ["Sphinx (>=3.3.1)", "doc8 (>=0.8.1)", "sphinx-rtd-theme (>=0.5.0)", "sph linting = ["black", "isort", "pycodestyle"] testing = ["pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)"] +[[package]] +name = "bs4" +version = "0.0.2" +description = "Dummy package for Beautiful Soup (beautifulsoup4)" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "bs4-0.0.2-py2.py3-none-any.whl", hash = "sha256:abf8742c0805ef7f662dce4b51cca104cffe52b835238afc169142ab9b3fbccc"}, + {file = "bs4-0.0.2.tar.gz", hash = "sha256:a48685c58f50fe127722417bae83fe6badf500d54b55f7e39ffe43b798653925"}, +] + +[package.dependencies] +beautifulsoup4 = "*" + [[package]] name = "cachecontrol" version = "0.14.4" @@ -3348,7 +3363,7 @@ version = "2.8.1" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" -groups = ["dev"] +groups = ["main", "dev"] files = [ {file = "soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434"}, {file = "soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350"}, @@ -3808,4 +3823,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.13" -content-hash = "ea32b3573fb2acedd9c775395f3a0f1d263f0df7b5d9ee91dcd6aeff6db13165" +content-hash = "d648a7de89cba1cadf4cc18909d5fe7255a92f4f51b23495cf778884a501e89a" diff --git a/pyproject.toml b/pyproject.toml index 44c6217..cd0246f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "python-box (>=7.3.2,<8.0.0)", "uvicorn (>=0.40.0,<0.41.0)", "pymongo (>=4.15.5,<5.0.0)", + "bs4 (>=0.0.2,<0.0.3)", ] diff --git a/src/sample/utils/constants.py b/src/sample/utils/constants.py index 62a5285..bf4e9c2 100644 --- a/src/sample/utils/constants.py +++ b/src/sample/utils/constants.py @@ -1,9 +1,9 @@ +import logging import os from pathlib import Path from typing import Any -import streamlit as st -import logging +import streamlit as st APP_TITLE = ":blue[Greeting Feature]" DEFAULT_GREETING = "Hello" @@ -61,9 +61,6 @@ def safe_get(secret_path: str, env_key: str = "", default: str = "") -> str: MONGODB_URI = safe_get("mongodb.MONGODB_URI", "MONGODB_URI") DATABASE_NAME = safe_get("mongodb.DATABASE_NAME", "DATABASE_NAME") -print("MongoDB URI:", MONGODB_URI) -print("Database Name:", DATABASE_NAME) - MONGO_CONFIG = { "MONGODB_URI": MONGODB_URI, "DATABASE_NAME": DATABASE_NAME, From 0649aeb65c77d97873cee6ed3bf9bfe60f6108d8 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 23:10:58 +0530 Subject: [PATCH 04/11] [TZP-260007]: refactor: enhance MongoDB connection handling and remove redundant checks --- src/sample/db/connection.py | 73 ++++++++++++++++++++++-------------- src/sample/utils/__init__.py | 4 -- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/sample/db/connection.py b/src/sample/db/connection.py index f4bb6a1..35dd58b 100644 --- a/src/sample/db/connection.py +++ b/src/sample/db/connection.py @@ -1,35 +1,50 @@ -from datetime import datetime -from typing import Optional -from pymongo import MongoClient -from pymongo.database import Database -from pymongo.collection import Collection import io +from datetime import datetime + from sample.utils.constants import MONGO_CONFIG -mongo_client: Optional[MongoClient] -db: Optional[Database] -collection: Optional[Collection] -fabric_collection: Optional[Collection] -processing_times_collection: Optional[Collection] - -# Initialize MongoDB connections with error handling -try: - mongo_client = MongoClient(MONGO_CONFIG["MONGODB_URI"]) - db = mongo_client[MONGO_CONFIG["DATABASE_NAME"]] -except KeyError as e: - print(f"MongoDB Configuration Error: Missing key {e}") - mongo_client = None - db = None - collection = None - -except Exception as e: - print(f"MongoDB Connection Error: {e}") - mongo_client = None - db = None - - -def save_to_mongodb(data: dict, collection): - """Insert processed JSON data into MongoDB""" +_mongo_client = None +_db = None + + +def connect_db(): + """ + Connect to MongoDB and return the Database object. + Requires pymongo to be installed via the 'mongo' extra. + """ + global _mongo_client, _db + + if _db is not None: + return _db + + try: + from pymongo import MongoClient + except ImportError as e: + raise RuntimeError( + "Mongo support not installed. " + "Install with: pip install sample[mongo] or poetry install --extras 'mongo'" + ) from e + + try: + uri = MONGO_CONFIG["MONGODB_URI"] + name = MONGO_CONFIG["DATABASE_NAME"] + print("Mongo URI =", repr(uri)) + + _mongo_client = MongoClient(uri, serverSelectionTimeoutMS=3000) + # Force an actual connection attempt + _mongo_client.admin.command("ping") + _db = _mongo_client[name] + print("MongoDB connected successfully.") + return _db + + except KeyError as e: + raise RuntimeError(f"MongoDB Configuration Error: Missing key {e}") + + except Exception as e: + raise RuntimeError(f"MongoDB Connection Error: {e}") + + +def save_to_mongodb(data, collection): try: data["created_at"] = datetime.now() result = collection.insert_one(data) diff --git a/src/sample/utils/__init__.py b/src/sample/utils/__init__.py index 715cafe..e69de29 100644 --- a/src/sample/utils/__init__.py +++ b/src/sample/utils/__init__.py @@ -1,4 +0,0 @@ -from sample.db.connection import mongo_client - -if mongo_client: - print("MongoDB connected successfully.") From d39cbeeb5e4dfb82ebdcd42150017c8ce98338d2 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 23:15:13 +0530 Subject: [PATCH 05/11] [TZP-260007]: refactor: reorganize imports in __main__.py and remove unnecessary whitespace in greeting.py --- src/sample/__main__.py | 8 ++++++-- src/sample/features/greeting.py | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sample/__main__.py b/src/sample/__main__.py index c2eddd7..4b06a87 100644 --- a/src/sample/__main__.py +++ b/src/sample/__main__.py @@ -1,17 +1,21 @@ # sample/__main__.py -from . import __version__ -import sys import logging import subprocess +import sys from pathlib import Path +from sample.db.connection import connect_db + +from . import __version__ + def main(): """ Entrypoint for the Streamlit 'dev' app. """ print("๐Ÿท๏ธ Sample version:", __version__) + connect_db() logging.info("Starting sample dev script...") # Paths diff --git a/src/sample/features/greeting.py b/src/sample/features/greeting.py index 2e92903..9224ed6 100644 --- a/src/sample/features/greeting.py +++ b/src/sample/features/greeting.py @@ -1,5 +1,4 @@ import streamlit as st - from sample.utils.constants import APP_TITLE, DEFAULT_GREETING from sample.utils.helper import normalize_name From ddfcd1aac9b8fa35468087844a15b6c66f373481 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 23:38:55 +0530 Subject: [PATCH 06/11] [TZP-260007]: refactor: update environment configuration and enhance MongoDB connection handling --- .gitignore | 2 +- README.md | 16 +++++++++--- poetry.lock | 31 +++++++++++++++++++++++- pyproject.toml | 1 + src/sample/__main__.py | 3 --- src/sample/db/connection.py | 1 - src/sample/features/greeting.py | 2 ++ src/sample/utils/config.py | 15 ++++++++++++ src/sample/utils/constants.py | 43 ++++++++++++++------------------- 9 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 src/sample/utils/config.py diff --git a/.gitignore b/.gitignore index e3c60c0..7edb4b8 100644 --- a/.gitignore +++ b/.gitignore @@ -135,7 +135,7 @@ celerybeat.pid *.sage.py # Environments -.env +.env** .envrc .venv** env/ diff --git a/README.md b/README.md index 044da87..dca3549 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,8 @@ poetry config virtualenvs.path /your/desired/path Ensure below files are configured (create if not exist) properly to run the project; -- `.env.local`, -- `.env`, and -- `.streamlit/secrets.toml` +- `.env.development` +- `.env.production` ## Install Dependencies @@ -51,6 +50,17 @@ poetry install ## How to Run +## Configure ENVIRONMENT + +setup `.env.development` and `.env.production` in project root + +```bash + # for local configuration(linux) + export ENV=development + # for production(linux) + export ENV=production +``` + ## Run Streamlit App ```bash diff --git a/poetry.lock b/poetry.lock index d2030b8..f8052c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -739,6 +739,20 @@ files = [ {file = "docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968"}, ] +[[package]] +name = "dotenv" +version = "0.9.9" +description = "Deprecated package" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9"}, +] + +[package.dependencies] +python-dotenv = "*" + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -2913,6 +2927,21 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.2.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61"}, + {file = "python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pytz" version = "2025.2" @@ -3823,4 +3852,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.13" -content-hash = "d648a7de89cba1cadf4cc18909d5fe7255a92f4f51b23495cf778884a501e89a" +content-hash = "cead136354a917cfd06b321602258f2431bf882405d11f3fff75b658eb194473" diff --git a/pyproject.toml b/pyproject.toml index cd0246f..199a6ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ dependencies = [ "uvicorn (>=0.40.0,<0.41.0)", "pymongo (>=4.15.5,<5.0.0)", "bs4 (>=0.0.2,<0.0.3)", + "dotenv (>=0.9.9,<0.10.0)", ] diff --git a/src/sample/__main__.py b/src/sample/__main__.py index 4b06a87..3527081 100644 --- a/src/sample/__main__.py +++ b/src/sample/__main__.py @@ -5,8 +5,6 @@ import sys from pathlib import Path -from sample.db.connection import connect_db - from . import __version__ @@ -15,7 +13,6 @@ def main(): Entrypoint for the Streamlit 'dev' app. """ print("๐Ÿท๏ธ Sample version:", __version__) - connect_db() logging.info("Starting sample dev script...") # Paths diff --git a/src/sample/db/connection.py b/src/sample/db/connection.py index 35dd58b..a96e670 100644 --- a/src/sample/db/connection.py +++ b/src/sample/db/connection.py @@ -28,7 +28,6 @@ def connect_db(): try: uri = MONGO_CONFIG["MONGODB_URI"] name = MONGO_CONFIG["DATABASE_NAME"] - print("Mongo URI =", repr(uri)) _mongo_client = MongoClient(uri, serverSelectionTimeoutMS=3000) # Force an actual connection attempt diff --git a/src/sample/features/greeting.py b/src/sample/features/greeting.py index 9224ed6..3a8154a 100644 --- a/src/sample/features/greeting.py +++ b/src/sample/features/greeting.py @@ -1,4 +1,5 @@ import streamlit as st +from sample.db.connection import connect_db from sample.utils.constants import APP_TITLE, DEFAULT_GREETING from sample.utils.helper import normalize_name @@ -7,6 +8,7 @@ def greet(): st.header(APP_TITLE) name = st.text_input("Enter your name") + connect_db() clean_name = normalize_name(name) diff --git a/src/sample/utils/config.py b/src/sample/utils/config.py new file mode 100644 index 0000000..9735d77 --- /dev/null +++ b/src/sample/utils/config.py @@ -0,0 +1,15 @@ +import os + +from dotenv import load_dotenv + + +def load_env(): + env = os.getenv("ENV", "development") + + file_map = { + "production": ".env.production", + "development": ".env.development", + } + + load_dotenv(file_map.get(env, ".env.development"), override=True) + return env diff --git a/src/sample/utils/constants.py b/src/sample/utils/constants.py index bf4e9c2..3f56109 100644 --- a/src/sample/utils/constants.py +++ b/src/sample/utils/constants.py @@ -1,13 +1,17 @@ import logging import os from pathlib import Path -from typing import Any -import streamlit as st +from sample.utils.config import load_env +load_env() APP_TITLE = ":blue[Greeting Feature]" DEFAULT_GREETING = "Hello" FAQ_TITLE = "FAQs" +logging.basicConfig( + level=logging.INFO, # or DEBUG + format="%(asctime)s - %(levelname)s - %(message)s", +) # --- Asset paths --- PROJECT_ROOT = Path(__file__).parents[2] @@ -26,23 +30,6 @@ def safe_get(secret_path: str, env_key: str = "", default: str = "") -> str: """ value = default source = "default" - secrets_file = Path(".streamlit/secrets.toml") - - # Only try accessing secrets if the file exists - if secrets_file.exists(): - try: - secrets_dict: dict[str, Any] = dict(st.secrets) # Convert to plain dict - val = secrets_dict - - for key in secret_path.split("."): - val = ( - val.get(key, {}) if isinstance(val, dict) else getattr(val, key, {}) - ) - if val and val != {}: - value = str(val) - source = "secrets" - except Exception as e: - logging.debug(f"Could not retrieve secret '{secret_path}': {e}") # If secrets not used, fallback to env if source != "secrets" and env_key: @@ -58,10 +45,16 @@ def safe_get(secret_path: str, env_key: str = "", default: str = "") -> str: return value -MONGODB_URI = safe_get("mongodb.MONGODB_URI", "MONGODB_URI") -DATABASE_NAME = safe_get("mongodb.DATABASE_NAME", "DATABASE_NAME") +def get_mongo_config(): + return { + "MONGODB_URI": safe_get("mongodb.MONGODB_URI", "MONGODB_URI"), + "DATABASE_NAME": safe_get("mongodb.DATABASE_NAME", "DATABASE_NAME"), + } + -MONGO_CONFIG = { - "MONGODB_URI": MONGODB_URI, - "DATABASE_NAME": DATABASE_NAME, -} +MONGO_CONFIG = get_mongo_config() +# === Environment Selection === +ENVIRONMENT = safe_get("env.ENVIRONMENT", "ENVIRONMENT", "development").lower() +logging.info(f"Environment: {ENVIRONMENT}", extra={"color": "yellow"}) +logging.info(f"Project root: {PROJECT_ROOT}", extra={"color": "yellow"}) +print("PID:", os.getpid()) From 6490c9664decbf8b6053c9feebbd9b0595c253f9 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Thu, 12 Feb 2026 23:50:16 +0530 Subject: [PATCH 07/11] [TZP-260007]: refactor: integrate database connection in the FastAPI startup --- src/sample/api/fast_api.py | 3 ++- src/sample/utils/constants.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sample/api/fast_api.py b/src/sample/api/fast_api.py index 17ea947..9fa4b88 100644 --- a/src/sample/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -4,7 +4,7 @@ from fastapi import FastAPI, HTTPException, Request from fastapi.responses import HTMLResponse from pydantic import BaseModel - +from sample.db.connection import connect_db from sample.utils.constants import DEFAULT_GREETING from sample.utils.helper import normalize_name @@ -101,6 +101,7 @@ def start(): import uvicorn print(f"๐Ÿงต {__version__}\n") + connect_db() uvicorn.run("sample.api.fast_api:app", host="127.0.0.1", port=5000, reload=True) diff --git a/src/sample/utils/constants.py b/src/sample/utils/constants.py index 3f56109..f6af0fd 100644 --- a/src/sample/utils/constants.py +++ b/src/sample/utils/constants.py @@ -57,4 +57,3 @@ def get_mongo_config(): ENVIRONMENT = safe_get("env.ENVIRONMENT", "ENVIRONMENT", "development").lower() logging.info(f"Environment: {ENVIRONMENT}", extra={"color": "yellow"}) logging.info(f"Project root: {PROJECT_ROOT}", extra={"color": "yellow"}) -print("PID:", os.getpid()) From a9fc39bf809e996d4136ab256a0646222f3425f1 Mon Sep 17 00:00:00 2001 From: Heisenberg208 Date: Fri, 13 Feb 2026 21:25:46 +0530 Subject: [PATCH 08/11] [TZP-260007]: refactor: remove local environment configuration file --- .env.local | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .env.local diff --git a/.env.local b/.env.local deleted file mode 100644 index c25c366..0000000 --- a/.env.local +++ /dev/null @@ -1,5 +0,0 @@ -#Note specify the values within double-quotes("") -ENVIRONMENT=development - -MONGODB_URI="mongodb://:@127.0.0.1:27017/?retryWrites=true&w=majority&appName=sample" -DATABASE_NAME="sample" From fa5c3b5098a80d5ed46953574d5a5150c5362976 Mon Sep 17 00:00:00 2001 From: "Poornachandra.A.N" Date: Fri, 13 Feb 2026 20:07:57 +0530 Subject: [PATCH 09/11] refactor: implement greeting endpoint using APIRouter for better organization --- src/sample/api/fast_api.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sample/api/fast_api.py b/src/sample/api/fast_api.py index 9fa4b88..c87a886 100644 --- a/src/sample/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -1,7 +1,7 @@ import sys from pathlib import Path -from fastapi import FastAPI, HTTPException, Request +from fastapi import APIRouter, FastAPI, HTTPException, Request from fastapi.responses import HTMLResponse from pydantic import BaseModel from sample.db.connection import connect_db @@ -26,7 +26,7 @@ }, ) - +greet_router = APIRouter(prefix="/api/v1", tags=["V1"]) class GreetRequest(BaseModel): name: str @@ -87,7 +87,7 @@ def health_check(): return {"status": "ok"} -@app.post("/greet", response_model=GreetResponse) +@greet_router.post("/greet", response_model=GreetResponse) def greet_user(payload: GreetRequest): clean_name = normalize_name(payload.name) @@ -96,6 +96,8 @@ def greet_user(payload: GreetRequest): return {"message": f"{DEFAULT_GREETING}, {clean_name} ๐Ÿ‘‹"} +app.include_router(greet_router) + def start(): import uvicorn From fb9f17d5ae189bb8b50f9e22c8a378674196cf68 Mon Sep 17 00:00:00 2001 From: "Poornachandra.A.N" Date: Sat, 14 Feb 2026 08:31:11 +0530 Subject: [PATCH 10/11] chore: update dependencies and add configuration for deptry --- poetry.lock | 262 ++++++++++++++++++++++--------------- pyproject.toml | 6 + src/sample/api/fast_api.py | 3 + 3 files changed, 164 insertions(+), 107 deletions(-) diff --git a/poetry.lock b/poetry.lock index f8052c2..7b43c5b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -695,6 +695,39 @@ files = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] +[[package]] +name = "deptry" +version = "0.24.0" +description = "A command line utility to check for unused, missing and transitive dependencies in a Python project." +optional = false +python-versions = ">=3.10" +groups = ["dev"] +files = [ + {file = "deptry-0.24.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:a575880146bab671a62babb9825b85b4f1bda8aeaade4fcb59f9262caf91d6c7"}, + {file = "deptry-0.24.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:00ec34b968a13c03a5268ce0211f891ace31851d916415e0a748fae9596c00d5"}, + {file = "deptry-0.24.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ddfedafafe5cbfce31a50d4ea99d7b9074edcd08b9b94350dc739e2fb6ed7f9"}, + {file = "deptry-0.24.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd22fa2dbbdf4b38061ca9504f2a6ce41ec14fa5c9fe9b0b763ccc1275efebd5"}, + {file = "deptry-0.24.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:0fbe50a2122d79cec53fdfd73a7092c05f316555a1139bcbacf3432572675977"}, + {file = "deptry-0.24.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:92bd8d331a5a6f8e6247436bc6fe384bcf86a8d69fe33442d195996fb9b20547"}, + {file = "deptry-0.24.0-cp39-abi3-win_amd64.whl", hash = "sha256:94b354848130d45e16d3a3039ae8177bce33828f62028c4ff8f2e1b04f7182ba"}, + {file = "deptry-0.24.0-cp39-abi3-win_arm64.whl", hash = "sha256:ea58709e5f3aa77c0737d8fb76166b7703201cf368fbbb14072ccda968b6703a"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6ae96785aaee5540c144306506f1480dcfa4d096094e6bd09dc8c9a9bfda1d46"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:4267d74a600ac7fdd05a0d3e219c9386670db0d3bb316ae7b94c9b239d1187cb"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a047e53b76c36737f8bb392bb326fb66c6af4bedafeaa4ad274c7ed82e91862"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841bf35d62e1facc0c244b9430455705249cc93552ed4964d367befe9be6a313"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5152ffa478e62f9aea9df585ce49d758087fd202f6d92012216aa0ecad22c267"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:68d90735042c169e2a12846ac5af9e20d0ad1a5a7a894a9e4eb0bd8f3c655add"}, + {file = "deptry-0.24.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:03d375db3e56821803aeca665dbb4c2fd935024310350cc18e8d8b6421369d2b"}, + {file = "deptry-0.24.0.tar.gz", hash = "sha256:852e88af2087e03cdf9ece6916f3f58b74191ab51cc8074897951bd496ee7dbb"}, +] + +[package.dependencies] +click = ">=8.0.0,<9" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +packaging = ">=23.2" +requirements-parser = ">=0.11.0,<1" +tomli = {version = ">=2.0.1", markers = "python_full_version < \"3.11.0\""} + [[package]] name = "dnspython" version = "2.8.0" @@ -2181,103 +2214,103 @@ files = [ [[package]] name = "pillow" -version = "12.0.0" +version = "12.1.1" description = "Python Imaging Library (fork)" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "pillow-12.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:3adfb466bbc544b926d50fe8f4a4e6abd8c6bffd28a26177594e6e9b2b76572b"}, - {file = "pillow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1ac11e8ea4f611c3c0147424eae514028b5e9077dd99ab91e1bd7bc33ff145e1"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d49e2314c373f4c2b39446fb1a45ed333c850e09d0c59ac79b72eb3b95397363"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7b2a63fd6d5246349f3d3f37b14430d73ee7e8173154461785e43036ffa96ca"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d64317d2587c70324b79861babb9c09f71fbb780bad212018874b2c013d8600e"}, - {file = "pillow-12.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d77153e14b709fd8b8af6f66a3afbb9ed6e9fc5ccf0b6b7e1ced7b036a228782"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32ed80ea8a90ee3e6fa08c21e2e091bba6eda8eccc83dbc34c95169507a91f10"}, - {file = "pillow-12.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c828a1ae702fc712978bda0320ba1b9893d99be0badf2647f693cc01cf0f04fa"}, - {file = "pillow-12.0.0-cp310-cp310-win32.whl", hash = "sha256:bd87e140e45399c818fac4247880b9ce719e4783d767e030a883a970be632275"}, - {file = "pillow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:455247ac8a4cfb7b9bc45b7e432d10421aea9fc2e74d285ba4072688a74c2e9d"}, - {file = "pillow-12.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:6ace95230bfb7cd79ef66caa064bbe2f2a1e63d93471c3a2e1f1348d9f22d6b7"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0fd00cac9c03256c8b2ff58f162ebcd2587ad3e1f2e397eab718c47e24d231cc"}, - {file = "pillow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3475b96f5908b3b16c47533daaa87380c491357d197564e0ba34ae75c0f3257"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:110486b79f2d112cf6add83b28b627e369219388f64ef2f960fef9ebaf54c642"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5269cc1caeedb67e6f7269a42014f381f45e2e7cd42d834ede3c703a1d915fe3"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa5129de4e174daccbc59d0a3b6d20eaf24417d59851c07ebb37aeb02947987c"}, - {file = "pillow-12.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bee2a6db3a7242ea309aa7ee8e2780726fed67ff4e5b40169f2c940e7eb09227"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:90387104ee8400a7b4598253b4c406f8958f59fcf983a6cea2b50d59f7d63d0b"}, - {file = "pillow-12.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc91a56697869546d1b8f0a3ff35224557ae7f881050e99f615e0119bf934b4e"}, - {file = "pillow-12.0.0-cp311-cp311-win32.whl", hash = "sha256:27f95b12453d165099c84f8a8bfdfd46b9e4bda9e0e4b65f0635430027f55739"}, - {file = "pillow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:b583dc9070312190192631373c6c8ed277254aa6e6084b74bdd0a6d3b221608e"}, - {file = "pillow-12.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:759de84a33be3b178a64c8ba28ad5c135900359e85fb662bc6e403ad4407791d"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371"}, - {file = "pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953"}, - {file = "pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79"}, - {file = "pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba"}, - {file = "pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0"}, - {file = "pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a"}, - {file = "pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4"}, - {file = "pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5"}, - {file = "pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e"}, - {file = "pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27"}, - {file = "pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79"}, - {file = "pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098"}, - {file = "pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905"}, - {file = "pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3"}, - {file = "pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a"}, - {file = "pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee"}, - {file = "pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef"}, - {file = "pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9"}, - {file = "pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b"}, - {file = "pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2"}, - {file = "pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b"}, - {file = "pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e"}, - {file = "pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9"}, - {file = "pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab"}, - {file = "pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b"}, - {file = "pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b"}, - {file = "pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6"}, - {file = "pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca"}, - {file = "pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8"}, - {file = "pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4"}, - {file = "pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52"}, - {file = "pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a"}, - {file = "pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b22bd8c974942477156be55a768f7aa37c46904c175be4e158b6a86e3a6b7ca8"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:805ebf596939e48dbb2e4922a1d3852cfc25c38160751ce02da93058b48d252a"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cae81479f77420d217def5f54b5b9d279804d17e982e0f2fa19b1d1e14ab5197"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeaefa96c768fc66818730b952a862235d68825c178f1b3ffd4efd7ad2edcb7c"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09f2d0abef9e4e2f349305a4f8cc784a8a6c2f58a8c4892eea13b10a943bd26e"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdee52571a343d721fb2eb3b090a82d959ff37fc631e3f70422e0c2e029f3e76"}, - {file = "pillow-12.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b290fd8aa38422444d4b50d579de197557f182ef1068b75f5aa8558638b8d0a5"}, - {file = "pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"}, + {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"}, + {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"}, + {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"}, + {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"}, + {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"}, + {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"}, + {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"}, + {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"}, + {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"}, + {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"}, + {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"}, + {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"}, + {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"}, + {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"}, + {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"}, + {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"}, + {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"}, + {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"}, + {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"}, + {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"}, + {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"}, + {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"}, ] [package.extras] @@ -2418,22 +2451,22 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "6.33.2" +version = "6.33.5" description = "" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d"}, - {file = "protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4"}, - {file = "protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872"}, - {file = "protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f"}, - {file = "protobuf-6.33.2-cp39-cp39-win32.whl", hash = "sha256:7109dcc38a680d033ffb8bf896727423528db9163be1b6a02d6a49606dcadbfe"}, - {file = "protobuf-6.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:2981c58f582f44b6b13173e12bb8656711189c2a70250845f264b877f00b1913"}, - {file = "protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c"}, - {file = "protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4"}, + {file = "protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b"}, + {file = "protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c"}, + {file = "protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd"}, + {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0"}, + {file = "protobuf-6.33.5-cp39-cp39-win32.whl", hash = "sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c"}, + {file = "protobuf-6.33.5-cp39-cp39-win_amd64.whl", hash = "sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a"}, + {file = "protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02"}, + {file = "protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c"}, ] [[package]] @@ -3146,6 +3179,21 @@ files = [ [package.dependencies] requests = ">=2.0.1,<3.0.0" +[[package]] +name = "requirements-parser" +version = "0.13.0" +description = "This is a small Python module for parsing Pip requirement files." +optional = false +python-versions = "<4.0,>=3.8" +groups = ["dev"] +files = [ + {file = "requirements_parser-0.13.0-py3-none-any.whl", hash = "sha256:2b3173faecf19ec5501971b7222d38f04cb45bb9d87d0ad629ca71e2e62ded14"}, + {file = "requirements_parser-0.13.0.tar.gz", hash = "sha256:0843119ca2cb2331de4eb31b10d70462e39ace698fd660a915c247d2301a4418"}, +] + +[package.dependencies] +packaging = ">=23.2" + [[package]] name = "rfc3986" version = "2.0.0" @@ -3694,14 +3742,14 @@ files = [ [[package]] name = "urllib3" -version = "2.6.2" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, - {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] @@ -3852,4 +3900,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.13" -content-hash = "cead136354a917cfd06b321602258f2431bf882405d11f3fff75b658eb194473" +content-hash = "a84161e61d7038911ac4ec9ff6673c66f3ad6f6fd9da3dbf134dd99cabbf456e" diff --git a/pyproject.toml b/pyproject.toml index 199a6ed..f64fc70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,8 @@ dependencies = [ "pymongo (>=4.15.5,<5.0.0)", "bs4 (>=0.0.2,<0.0.3)", "dotenv (>=0.9.9,<0.10.0)", + "pydantic (>=2.12.5,<3.0.0)", + "click (>=8.3.1,<9.0.0)", ] @@ -43,6 +45,7 @@ pipreqs = "0.5.0" ruff = "0.5.3" twine = "^6.2.0" vulture = "^2.3" +deptry = "^0.24.0" [tool.flake8] max_line_length = 190 @@ -61,3 +64,6 @@ ignore = [] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.deptry] +known_first_party = ["sample"] diff --git a/src/sample/api/fast_api.py b/src/sample/api/fast_api.py index c87a886..556ffa7 100644 --- a/src/sample/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -27,6 +27,8 @@ ) greet_router = APIRouter(prefix="/api/v1", tags=["V1"]) + + class GreetRequest(BaseModel): name: str @@ -96,6 +98,7 @@ def greet_user(payload: GreetRequest): return {"message": f"{DEFAULT_GREETING}, {clean_name} ๐Ÿ‘‹"} + app.include_router(greet_router) From bdb5db96bb8d2067323eebb529c6a53167fab86a Mon Sep 17 00:00:00 2001 From: "Poornachandra.A.N" Date: Sat, 14 Feb 2026 10:49:43 +0530 Subject: [PATCH 11/11] refactor: add tags to version, root, and health check endpoints for better organization --- src/sample/api/fast_api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sample/api/fast_api.py b/src/sample/api/fast_api.py index 556ffa7..e9467aa 100644 --- a/src/sample/api/fast_api.py +++ b/src/sample/api/fast_api.py @@ -37,12 +37,12 @@ class GreetResponse(BaseModel): message: str -@app.get("/version") +@app.get("/version",tags=["Meta"]) def version(): return {"version": app.version} -@app.get("/", response_class=HTMLResponse) +@app.get("/", response_class=HTMLResponse,tags=["Meta"]) async def read_root(request: Request): return """ @@ -84,7 +84,7 @@ async def read_root(request: Request): """ -@app.get("/health") +@app.get("/health",tags=["Meta"]) def health_check(): return {"status": "ok"}