From 15a8b8682330443c6ffdb955b5552cc9ea311404 Mon Sep 17 00:00:00 2001 From: berkay Date: Sun, 23 Mar 2025 21:44:50 +0300 Subject: [PATCH] updated Bank Services --- BankServices/EmailService/.python-version | 1 + BankServices/EmailService/Dockerfile | 25 ++ BankServices/EmailService/README.md | 0 BankServices/EmailService/app.py | 132 +++++++ BankServices/EmailService/config.py | 24 ++ BankServices/EmailService/pyproject.toml | 11 + BankServices/ParserService/.python-version | 1 + BankServices/ParserService/Dockerfile | 25 ++ BankServices/ParserService/README.md | 0 BankServices/ParserService/app.py | 96 +++++ BankServices/ParserService/pyproject.toml | 13 + BankServices/ReadMe.md | 49 +++ BankServices/SenderService/.python-version | 1 + BankServices/SenderService/Dockerfile | 23 ++ BankServices/SenderService/README.md | 0 BankServices/SenderService/app.py | 11 + BankServices/SenderService/pyproject.toml | 11 + BankServices/WriterService/.python-version | 1 + BankServices/WriterService/Dockerfile | 28 ++ BankServices/WriterService/README.md | 0 BankServices/WriterService/app.py | 77 ++++ BankServices/WriterService/model.py | 18 + BankServices/WriterService/pyproject.toml | 14 + BankServices/WriterService/uv.lock | 362 ++++++++++++++++++ README.md | 2 +- .../controllers/mixin_controllers.py | 20 +- docker-compose.yml | 144 ++++--- pyproject.toml | 3 + uv.lock | 104 +++++ 29 files changed, 1138 insertions(+), 58 deletions(-) create mode 100644 BankServices/EmailService/.python-version create mode 100644 BankServices/EmailService/Dockerfile create mode 100644 BankServices/EmailService/README.md create mode 100644 BankServices/EmailService/app.py create mode 100644 BankServices/EmailService/config.py create mode 100644 BankServices/EmailService/pyproject.toml create mode 100644 BankServices/ParserService/.python-version create mode 100644 BankServices/ParserService/Dockerfile create mode 100644 BankServices/ParserService/README.md create mode 100644 BankServices/ParserService/app.py create mode 100644 BankServices/ParserService/pyproject.toml create mode 100644 BankServices/ReadMe.md create mode 100644 BankServices/SenderService/.python-version create mode 100644 BankServices/SenderService/Dockerfile create mode 100644 BankServices/SenderService/README.md create mode 100644 BankServices/SenderService/app.py create mode 100644 BankServices/SenderService/pyproject.toml create mode 100644 BankServices/WriterService/.python-version create mode 100644 BankServices/WriterService/Dockerfile create mode 100644 BankServices/WriterService/README.md create mode 100644 BankServices/WriterService/app.py create mode 100644 BankServices/WriterService/model.py create mode 100644 BankServices/WriterService/pyproject.toml create mode 100644 BankServices/WriterService/uv.lock diff --git a/BankServices/EmailService/.python-version b/BankServices/EmailService/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/BankServices/EmailService/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/BankServices/EmailService/Dockerfile b/BankServices/EmailService/Dockerfile new file mode 100644 index 0000000..4dc17ca --- /dev/null +++ b/BankServices/EmailService/Dockerfile @@ -0,0 +1,25 @@ +FROM python:3.12-slim + +WORKDIR / + +# Install system dependencies and Poetry +RUN apt-get update && apt-get install -y --no-install-recommends gcc \ + && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry + +# Copy Poetry configuration +COPY /BankServices/EmailService/pyproject.toml ./pyproject.toml + +# Configure Poetry and install dependencies with optimizations +RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main \ + && pip cache purge && rm -rf ~/.cache/pypoetry + +# Copy application code +ADD /BankServices/EmailService / +ADD /Configs /Configs +ADD /Services/MongoService /Services/MongoService + +# Set Python path to include app directory +ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 + +# Run the application using the configured uvicorn server +CMD ["poetry", "run", "python", "app.py"] diff --git a/BankServices/EmailService/README.md b/BankServices/EmailService/README.md new file mode 100644 index 0000000..e69de29 diff --git a/BankServices/EmailService/app.py b/BankServices/EmailService/app.py new file mode 100644 index 0000000..e63ef82 --- /dev/null +++ b/BankServices/EmailService/app.py @@ -0,0 +1,132 @@ +import time +import arrow + +from typing import TypeVar +from config import Config + +from redbox import EmailBox +from redbox.query import FROM, UNSEEN, OR + +from Services.MongoService.provider import MongoProvider +from Configs.mongo import MongoConfig + + +host = Config.EMAIL_HOST +port = Config.EMAIL_PORT +username = Config.EMAIL_USERNAME +password = Config.EMAIL_PASSWORD + +authorized_iban = Config.AUTHORIZE_IBAN +authorized_iban_cleaned = authorized_iban.replace("-", "") +mongo_prefix = "CollectedData" +delimiter = "|" + +# banks_mails = mailbox.search(from_=filter_mail, unseen=True) bununla denemeyin +# banks_mails = mailbox.search(FROM(filter_mail) & UNSEEN) + + +T = TypeVar("T") + + +def check_payload_already_exists_mongo_database(filename: str, mongo_provider) -> bool: + find_one_result = mongo_provider.find_one(filter_query={ + "filename": filename + }) + if find_one_result: + return True + return False + + +def write_payload_to_mongo_database(payload, filename: str, mail_info:dict, mongo_provider) -> bool: + insert_one_result = mongo_provider.insert_one(document={ + "filename": filename, + "payload": payload, + "stage": "read", + "created_at": str(arrow.now()), **mail_info + }) + if insert_one_result.acknowledged: + return True + return False + + +def read_email_and_write_to_mongo_database(email_message, mail_info: dict) -> bool: + with MongoProvider.mongo_client() as mongo_client: + mongo_provider = MongoProvider( + client=mongo_client, + database=MongoConfig.DATABASE_NAME, + storage_reason=[mongo_prefix, str(arrow.now().date())], + ) + if email_message.is_multipart(): # Check if email has multipart content + for part in email_message.walk(): # Each part can be an attachment + content_disposition = part.get("Content-Disposition") + if content_disposition and "attachment" in content_disposition: + if filename := part.get_filename(): + file_exists = not check_payload_already_exists_mongo_database( + filename=filename, mongo_provider=mongo_provider + ) + is_iban_in_filename = authorized_iban_cleaned in str(filename) + if is_iban_in_filename and file_exists: + if payload := part.get_payload(decode=True): + return write_payload_to_mongo_database( + payload=payload, + filename=filename, + mongo_provider=mongo_provider, + mail_info=mail_info + ) + else: # Handle non-multipart email, though this is rare for emails with attachments + content_disposition = email_message.get("Content-Disposition") + if content_disposition and "attachment" in content_disposition: + if filename := email_message.get_filename(): + file_exists = not check_payload_already_exists_mongo_database( + filename=filename, + mongo_provider=mongo_provider, + ) + is_iban_in_filename= authorized_iban_cleaned in str(filename) + if is_iban_in_filename and file_exists: + payload = email_message.get_payload(decode=True) + return write_payload_to_mongo_database( + payload=payload, + filename=filename, + mongo_provider=mongo_provider, + mail_info=mail_info, + ) + return False + + +def app(): + box = EmailBox(host=host, port=port, username=username, password=password) + if not box: + return Exception("Mailbox not found") + + box.connect() + mail_folders = box.mailfolders + filter_mail = OR(FROM(Config.MAILBOX), FROM(Config.MAIN_MAIL)) + filter_print = f"{Config.MAILBOX} & {Config.MAIN_MAIL}" + + for folder in mail_folders: + if folder.name == "INBOX": + banks_mails = folder.search(filter_mail & UNSEEN) + print( + f"Service is reading mailbox [{username}] with mail sender [{filter_print}] with count : {len(banks_mails)}" + ) + + for banks_mail in banks_mails or []: + if email_message := banks_mail.email: + headers = {k.lower(): v for k, v in banks_mail.headers.items()} + mail_info = { + "from": headers['from'], + "to": headers['to'], + "subject": headers['subject'], + "date": str(headers['date']), + } + read_email_and_write_to_mongo_database( + email_message=email_message, mail_info=mail_info + ) + + +if __name__ == "__main__": + + while True: + print('Running email service...') + app() + time.sleep(Config.EMAIL_SLEEP) diff --git a/BankServices/EmailService/config.py b/BankServices/EmailService/config.py new file mode 100644 index 0000000..d45adc0 --- /dev/null +++ b/BankServices/EmailService/config.py @@ -0,0 +1,24 @@ + +class Config: + # IP_ADDRESS: str = "http://10.10.2.46:41575/internal/isbank/retreive" + SERVICE_TIMING: int = 900 # 15 min + + # CONTAINERS_PATH: str = "/service_app_banks" + # UNREAD_PATH: str = f"{CONTAINERS_PATH}/isbank/unread/" + # PARSED_PATH: str = f"{CONTAINERS_PATH}/isbank/parsed/parsed_data.json" + # ARCHIVE_PATH: str = f"{CONTAINERS_PATH}/isbank/archive/" + # INCOMING_PATH: str = f"{CONTAINERS_PATH}/isbank/unread" + # COMPLETED_PATH: str = f"{CONTAINERS_PATH}/isbank/completed" + + MAILBOX: str = "bilgilendirme@ileti.isbank.com.tr" + + MAIN_MAIL: str = "karatay.berkay@gmail.com" + INFO_MAIL = "mehmet.karatay@hotmail.com" + + EMAIL_HOST: str = "10.10.2.34" + # EMAIL_USERNAME: str = "karatay@mehmetkaratay.com.tr" + EMAIL_USERNAME: str = "isbank@mehmetkaratay.com.tr" + EMAIL_PORT: int = 993 + EMAIL_PASSWORD: str = "system" + EMAIL_SLEEP: int = 60 + AUTHORIZE_IBAN: str = "4245-0093333" diff --git a/BankServices/EmailService/pyproject.toml b/BankServices/EmailService/pyproject.toml new file mode 100644 index 0000000..9c2ab9c --- /dev/null +++ b/BankServices/EmailService/pyproject.toml @@ -0,0 +1,11 @@ +[project] +name = "emailservice" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "arrow>=1.3.0", + "pymongo>=4.11.3", + "redbox>=0.2.1", +] diff --git a/BankServices/ParserService/.python-version b/BankServices/ParserService/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/BankServices/ParserService/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/BankServices/ParserService/Dockerfile b/BankServices/ParserService/Dockerfile new file mode 100644 index 0000000..3c0ae01 --- /dev/null +++ b/BankServices/ParserService/Dockerfile @@ -0,0 +1,25 @@ +FROM python:3.12-slim + +WORKDIR / + +# Install system dependencies and Poetry +RUN apt-get update && apt-get install -y --no-install-recommends gcc \ + && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry + +# Copy Poetry configuration +COPY /BankServices/ParserService/pyproject.toml ./pyproject.toml + +# Configure Poetry and install dependencies with optimizations +RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main \ + && pip cache purge && rm -rf ~/.cache/pypoetry + +# Copy application code +ADD /BankServices/ParserService / +ADD /Configs /Configs +ADD /Services/MongoService /Services/MongoService + +# Set Python path to include app directory +ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 + +# Run the application using the configured uvicorn server +CMD ["poetry", "run", "python", "app.py"] diff --git a/BankServices/ParserService/README.md b/BankServices/ParserService/README.md new file mode 100644 index 0000000..e69de29 diff --git a/BankServices/ParserService/app.py b/BankServices/ParserService/app.py new file mode 100644 index 0000000..ac17f65 --- /dev/null +++ b/BankServices/ParserService/app.py @@ -0,0 +1,96 @@ +import time +import arrow +import io +import datetime + +from pandas import DataFrame, read_excel +from Services.MongoService.provider import MongoProvider + +from unidecode import unidecode +from Configs.mongo import MongoConfig + + +mongo_prefix = "CollectedData" +delimiter = "|" + + +def collect_excel_files_from_mongo_database(mongo_provider) -> list: + return mongo_provider.find_many(filter_query={"stage": "read"}) + + +def update_parsed_data_to_mongo_database(mongo_provider, collected_data_dict: dict, filename: str) -> None: + if collected_data_dict: + payload = collected_data_dict[filename] + if payload: + print('filename, payload', filename, payload) + mongo_provider.update_one( + filter_query={"filename": filename}, + update_data={"$set": {"parsed": payload, "stage": "parsed"}}, + ) + return + mongo_provider.update_one( + filter_query={"filename": filename}, + update_data={"$set": {"parsed": None, "stage": "not found"}}, + ) + return + + +def parse_excel_file(excel_frame: DataFrame, excel_name: str) -> dict: + iban, data_dict = "", {} + for row in excel_frame.itertuples(): + if "IBAN" in str(row[3]).upper(): + iban = str(row[5]).replace(" ", "") + if not str(row[1]) == "nan" and not str(row[2]) == "nan": + if len(str(row[1]).split("/")) > 2: + data_dict[excel_name] = dict( + iban=str(iban), + bank_date=arrow.get(datetime.datetime.strptime( + str(row[1]), "%d/%m/%Y-%H:%M:%S" + )).__str__(), + channel_branch=unidecode(str(row[3])), + currency_value=( + float(str(row[4]).replace(",", "")) if row[4] else 0 + ), + balance=float(str(row[5]).replace(",", "")) if row[5] else 0, + additional_balance=( + float(str(row[6]).replace(",", "")) if row[6] else 0 + ), + process_name=str(row[7]), + process_type=unidecode(str(row[8])), + process_comment=unidecode(str(row[9])), + bank_reference_code=str(row[15]), + ) + return data_dict + + +def app(): + print("Hello from parserservice!") + with MongoProvider.mongo_client() as mongo_client: + mongo_provider = MongoProvider( + client=mongo_client, + database=MongoConfig.DATABASE_NAME, + storage_reason=[mongo_prefix, str(arrow.now().date())], + ) + results = collect_excel_files_from_mongo_database(mongo_provider) + if not results: + print("No results found.") + return + + for result in results: + filename, payload = result.get("filename"), result.get("payload") + + # Create an in-memory file-like object + excel_frame = DataFrame(read_excel(io.BytesIO(payload))) + + # Extract IBAN and root info from the xl file + collected_data_dict = parse_excel_file(excel_frame, filename) + update_parsed_data_to_mongo_database( + mongo_provider=mongo_provider, collected_data_dict=collected_data_dict, filename=filename + ) + + +if __name__ == "__main__": + + while True: + app() + time.sleep(60) diff --git a/BankServices/ParserService/pyproject.toml b/BankServices/ParserService/pyproject.toml new file mode 100644 index 0000000..1110075 --- /dev/null +++ b/BankServices/ParserService/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "parserservice" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "arrow>=1.3.0", + "pandas>=2.2.3", + "pymongo>=4.11.3", + "unidecode>=1.3.8", + "xlrd>=2.0.1", +] diff --git a/BankServices/ReadMe.md b/BankServices/ReadMe.md new file mode 100644 index 0000000..82bb45d --- /dev/null +++ b/BankServices/ReadMe.md @@ -0,0 +1,49 @@ +# BankServices + +### Requires the following environment variables to be set: +* Postgres Service and Dependency +* MongoDB Service and Dependency +* Email Service and Dependency + +/Configs +/Services + +```bash +uv init && uv add psycopg2-binary pymongo redbox +``` + +### Reader Service +Reads given Mailbox and writes payload to MongoDB with the following format: +Writes email payload to MongoDB with the following format: +Collection Name: CollectedData|{XXXX-XX-XX} +```json +{ + "email_id": "XXXXXXXXXXXXXXXX", + "payload": {} +} +``` + +### Parser Service +Reads email payload from MongoDB and parses the payload to extract the following fields: +Writes parsed payload to MongoDB with the following format: +```json +{ + "email_id": "XXXXXXXXXXXXXXXX", + "iban": "XXXXXXXXXXXXXXXX", + "bank_date": "XXXX-XX-XX", + "channel_branch": "", + "balance": "", + "additional_balance": "", + "process_name": "", + "process_type": "", + "process_comment": "", + "bank_reference_code": "" +} +``` + +### Sender Service +Reads parsed payload from MongoDB and writes to PostgresDb AccountRecords: + + +### Email Service +Reads saved row from PostgresDb AccountRecords and sends email to the given email address with the following format: diff --git a/BankServices/SenderService/.python-version b/BankServices/SenderService/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/BankServices/SenderService/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/BankServices/SenderService/Dockerfile b/BankServices/SenderService/Dockerfile new file mode 100644 index 0000000..77091cd --- /dev/null +++ b/BankServices/SenderService/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3.12-slim + +WORKDIR / + +# Install system dependencies and Poetry +RUN apt-get update && apt-get install -y --no-install-recommends gcc \ + && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry + +# Copy Poetry configuration +COPY /BankServices/SenderService/pyproject.toml ./pyproject.toml + +# Configure Poetry and install dependencies with optimizations +RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main \ + && pip cache purge && rm -rf ~/.cache/pypoetry + +# Copy application code +ADD /BankServices/SenderService / + +# Set Python path to include app directory +ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 + +# Run the application using the configured uvicorn server +CMD ["poetry", "run", "python", "app.py"] diff --git a/BankServices/SenderService/README.md b/BankServices/SenderService/README.md new file mode 100644 index 0000000..e69de29 diff --git a/BankServices/SenderService/app.py b/BankServices/SenderService/app.py new file mode 100644 index 0000000..c89fe15 --- /dev/null +++ b/BankServices/SenderService/app.py @@ -0,0 +1,11 @@ +import time + + +def app(): + print("Hello from sender service!") + + +if __name__ == "__main__": + while True: + app() + time.sleep(5) diff --git a/BankServices/SenderService/pyproject.toml b/BankServices/SenderService/pyproject.toml new file mode 100644 index 0000000..8a5c4e8 --- /dev/null +++ b/BankServices/SenderService/pyproject.toml @@ -0,0 +1,11 @@ +[project] +name = "senderservice" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "psycopg2-binary>=2.9.10", + "pymongo>=4.11.3", + "redbox>=0.2.1", +] diff --git a/BankServices/WriterService/.python-version b/BankServices/WriterService/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/BankServices/WriterService/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/BankServices/WriterService/Dockerfile b/BankServices/WriterService/Dockerfile new file mode 100644 index 0000000..f20e585 --- /dev/null +++ b/BankServices/WriterService/Dockerfile @@ -0,0 +1,28 @@ +FROM python:3.12-slim + +WORKDIR / + +# Install system dependencies and Poetry +RUN apt-get update && apt-get install -y --no-install-recommends gcc \ + && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry + +# Copy Poetry configuration +COPY /BankServices/WriterService/pyproject.toml ./pyproject.toml + +# Configure Poetry and install dependencies with optimizations +RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main \ + && pip cache purge && rm -rf ~/.cache/pypoetry + +# Copy application code +ADD /BankServices/WriterService / +ADD /Configs /Configs +ADD /Services/MongoService /Services/MongoService +ADD /Services/PostgresService /Services/PostgresService +ADD /Schemas /Schemas +ADD /Commons /Commons + +# Set Python path to include app directory +ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 + +# Run the application using the configured uvicorn server +CMD ["poetry", "run", "python", "app.py"] diff --git a/BankServices/WriterService/README.md b/BankServices/WriterService/README.md new file mode 100644 index 0000000..e69de29 diff --git a/BankServices/WriterService/app.py b/BankServices/WriterService/app.py new file mode 100644 index 0000000..2696a2d --- /dev/null +++ b/BankServices/WriterService/app.py @@ -0,0 +1,77 @@ +import time +import arrow + +from Schemas import AccountRecords, BuildIbans +from Services.MongoService.provider import MongoProvider +from model import BankReceive +from Configs.mongo import MongoConfig + + +mongo_prefix = "CollectedData" +delimiter = "|" + + +def collect_parsed_data_from_mongo_database(mongo_provider) -> list: + return mongo_provider.find_many(filter_query={"stage": "parsed"}) + + +def write_parsed_data_to_account_records( + file: str, data_dict: dict, collection_name: str, mongo_provider +): + db_session = AccountRecords.new_session() + data_dict["bank_balance"] = data_dict.pop("balance") + data_dict["import_file_name"] = collection_name + data_dict = BankReceive(**data_dict).model_dump() + bank_date = arrow.get(str(data_dict["bank_date"])) + data_dict["bank_date_w"] = bank_date.weekday() + data_dict["bank_date_m"] = bank_date.month + data_dict["bank_date_d"] = bank_date.day + data_dict["bank_date_y"] = bank_date.year + data_dict["bank_date"] = str(bank_date) + if build_iban := BuildIbans.filter_by_one(iban=data_dict["iban"], db=db_session).data: + data_dict.update( + { + "build_id": build_iban.build_id, + "build_uu_id": build_iban.build_uu_id, + } + ) + if found_record := AccountRecords.filter_one( + AccountRecords.bank_date == data_dict["bank_date"], + AccountRecords.iban == data_dict["iban"], + AccountRecords.bank_reference_code == data_dict["bank_reference_code"], + AccountRecords.bank_balance == data_dict["bank_balance"], + db=db_session, + ).data: + print("already @database record", found_record.id) + else: + new_account_record = AccountRecords.find_or_create(db=db_session, **data_dict) + new_account_record.is_confirmed = True + new_account_record.save(db=db_session) + mongo_provider.update_one( + filter_query={"filename": file}, + update_data={"$set": {"stage": "completed"}}, + ) + + +if __name__ == "__main__": + print('Writer Service is running') + while True: + with MongoProvider.mongo_client() as mongo_client: + provider = MongoProvider( + client=mongo_client, + database=MongoConfig.DATABASE_NAME, + storage_reason=[mongo_prefix, str(arrow.now().date())], + ) + results = collect_parsed_data_from_mongo_database(mongo_provider=provider) + for result in results: + parsed_data = result.get("parsed") + file_name = result.get("filename") + if not parsed_data: + continue + write_parsed_data_to_account_records( + data_dict=parsed_data, + collection_name=provider.collection.name, + mongo_provider=provider, + file=file_name + ) + time.sleep(60) diff --git a/BankServices/WriterService/model.py b/BankServices/WriterService/model.py new file mode 100644 index 0000000..f71c68b --- /dev/null +++ b/BankServices/WriterService/model.py @@ -0,0 +1,18 @@ +from typing import Optional +from pydantic import BaseModel + + +class BankReceive(BaseModel): + import_file_name: str + iban: str + bank_date: str + channel_branch: str + currency: Optional[str] = "TL" + currency_value: float + bank_balance: float + additional_balance: float + process_name: str + process_type: str + process_comment: str + bank_reference_code: str + diff --git a/BankServices/WriterService/pyproject.toml b/BankServices/WriterService/pyproject.toml new file mode 100644 index 0000000..ebda667 --- /dev/null +++ b/BankServices/WriterService/pyproject.toml @@ -0,0 +1,14 @@ +[project] +name = "readerservice" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "arrow>=1.3.0", + "fastapi>=0.115.11", + "psycopg2-binary>=2.9.10", + "pymongo>=4.11.3", + "redbox>=0.2.1", + "sqlalchemy-mixins>=2.0.5", +] diff --git a/BankServices/WriterService/uv.lock b/BankServices/WriterService/uv.lock new file mode 100644 index 0000000..3a62c76 --- /dev/null +++ b/BankServices/WriterService/uv.lock @@ -0,0 +1,362 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 }, +] + +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, +] + +[[package]] +name = "dnspython" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 }, +] + +[[package]] +name = "fastapi" +version = "0.115.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/28/c5d26e5860df807241909a961a37d45e10533acef95fc368066c7dd186cd/fastapi-0.115.11.tar.gz", hash = "sha256:cc81f03f688678b92600a65a5e618b93592c65005db37157147204d8924bf94f", size = 294441 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/5d/4d8bbb94f0dbc22732350c06965e40740f4a92ca560e90bb566f4f73af41/fastapi-0.115.11-py3-none-any.whl", hash = "sha256:32e1541b7b74602e4ef4a0260ecaf3aadf9d4f19590bba3e1bf2ac4666aa2c64", size = 94926 }, +] + +[[package]] +name = "greenlet" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, + { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, + { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, + { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, + { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, + { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, + { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, + { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, + { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, + { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, + { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, + { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, + { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, + { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, + { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, + { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, + { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, + { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, + { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, + { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, + { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, + { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, + { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, + { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "psycopg2-binary" +version = "2.9.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771 }, + { url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336 }, + { url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637 }, + { url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097 }, + { url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776 }, + { url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968 }, + { url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334 }, + { url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722 }, + { url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132 }, + { url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312 }, + { url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191 }, + { url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031 }, + { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699 }, + { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245 }, + { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631 }, + { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140 }, + { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762 }, + { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967 }, + { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326 }, + { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, + { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, + { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, + { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, +] + +[[package]] +name = "pydantic" +version = "2.10.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, +] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, +] + +[[package]] +name = "pymongo" +version = "4.11.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/e6/cdb1105c14a86aa2b1663a6cccc6bf54722bb12fb5d479979628142dde42/pymongo-4.11.3.tar.gz", hash = "sha256:b6f24aec7c0cfcf0ea9f89e92b7d40ba18a1e18c134815758f111ecb0122e61c", size = 2054848 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/cf/c606c9d889d8f34dcf80455e045854ef2fa187c439b22a6d30357790c12a/pymongo-4.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5f48b7faf4064e5f484989608a59503b11b7f134ca344635e416b1b12e7dc255", size = 895374 }, + { url = "https://files.pythonhosted.org/packages/c6/f5/287e84ba6c8e34cb13f798e7e859b4dcbc5fab99261f91202a8027f62ba6/pymongo-4.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:722f22bf18d208aa752591bde93e018065641711594e7a2fef0432da429264e8", size = 895063 }, + { url = "https://files.pythonhosted.org/packages/0e/ba/fe8964ec3f8d7348e9cd6a11864e1e84b2be62ea98ca0ba01a4f5b4d417d/pymongo-4.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5be1b35c4897626327c4e8bae14655807c2bc710504fa790bc19a72403142264", size = 1673722 }, + { url = "https://files.pythonhosted.org/packages/92/89/925b7160c517b66c80d05b36f63d4cc0d0ff23f01b5150b55936b5fab097/pymongo-4.11.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14f9e4d2172545798738d27bc6293b972c4f1f98cce248aa56e1e62c4c258ca7", size = 1737946 }, + { url = "https://files.pythonhosted.org/packages/f8/97/bcedba78ddbc1b8837bf556da55eb08a055e93b331722ecd1dad602a3427/pymongo-4.11.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd3f7bafe441135f58d2b91a312714f423e15fed5afe3854880c8c61ad78d3ce", size = 1706981 }, + { url = "https://files.pythonhosted.org/packages/d7/ce/63719be395ec29b8f71fd267014af4957736b5297a1f51f76ef32d05a0cf/pymongo-4.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73de1b9f416a2662ba95b4b49edc963d47b93760a7e2b561b932c8099d160151", size = 1676948 }, + { url = "https://files.pythonhosted.org/packages/c1/36/de366cee39e6c2e64d824d1f2e5672381ec766c51224304d1aebf7db3507/pymongo-4.11.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e24268e2d7ae96eab12161985b39e75a75185393134fc671f4bb1a16f50bf6f4", size = 1636072 }, + { url = "https://files.pythonhosted.org/packages/07/48/34751291a152e8098b4cf6f467046f00edd71b695d5cf6be1b15778cda63/pymongo-4.11.3-cp312-cp312-win32.whl", hash = "sha256:33a936d3c1828e4f52bed3dad6191a3618cc28ab056e2770390aec88d9e9f9ea", size = 864025 }, + { url = "https://files.pythonhosted.org/packages/96/8a/604fab1e1f45deb0dc19e06053369e7db44e3d1359a39e0fe376bdb95b41/pymongo-4.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:c4673d8ef0c8ef712491a750adf64f7998202a82abd72be5be749749275b3edb", size = 882290 }, + { url = "https://files.pythonhosted.org/packages/01/f1/19f8a81ca1ef180983b89e24f8003863612aea358a06d7685566ccc18a87/pymongo-4.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5e53b98c9700bb69f33a322b648d028bfe223ad135fb04ec48c0226998b80d0e", size = 949622 }, + { url = "https://files.pythonhosted.org/packages/67/9a/ae232aa9379a9e6cf325facf0f65176d70520d6a16807f4de2e1ccfb76ec/pymongo-4.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8464aff011208cf86eae28f4a3624ebc4a40783634e119b2b35852252b901ef3", size = 949299 }, + { url = "https://files.pythonhosted.org/packages/70/6d/1ddef8b6c6d598fe21c917d93c49a6304611a252a07e98a9b7e70e1b995b/pymongo-4.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3742ffc1951bec1450a5a6a02cfd40ddd4b1c9416b36c70ae439a532e8be0e05", size = 1937616 }, + { url = "https://files.pythonhosted.org/packages/13/9c/e735715789a876140f453def1b2015948708d224f1728f9b8412b6e495d2/pymongo-4.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a29294b508975a5dfd384f4b902cd121dc2b6e5d55ea2be2debffd2a63461cd9", size = 2015041 }, + { url = "https://files.pythonhosted.org/packages/fc/d3/cf41e9ce81644de9d8db54cc039823863e7240e021466ae093edc061683a/pymongo-4.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:051c741586ab6efafe72e027504ac4e5f01c88eceec579e4e1a438a369a61b0c", size = 1978716 }, + { url = "https://files.pythonhosted.org/packages/be/c8/c3f15c6cc5a9e0a75d18ae86209584cb14fdca017197def9741bff19c151/pymongo-4.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b05e03a327cdef28ec2bb72c974d412d308f5cf867a472ef17f9ac95d18ec05", size = 1939524 }, + { url = "https://files.pythonhosted.org/packages/1b/0d/613cd91c736325d05d2d5d389d06ed899bcdce5a265cb486b948729bf1eb/pymongo-4.11.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dafeddf1db51df19effd0828ae75492b15d60c7faec388da08f1fe9593c88e7a", size = 1888960 }, + { url = "https://files.pythonhosted.org/packages/e7/eb/b1e9cf2e03a47c4f35ffc5db1cb0ed0f92c5fe58c6f5f04d5a2da9d6bb77/pymongo-4.11.3-cp313-cp313-win32.whl", hash = "sha256:40c55afb34788ae6a6b8c175421fa46a37cfc45de41fe4669d762c3b1bbda48e", size = 910370 }, + { url = "https://files.pythonhosted.org/packages/77/f3/023f12ee9028f341880016fd6251255bf755f70730440ad11bf745f5f9e4/pymongo-4.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:a5b8b7ba9614a081d1f932724b7a6a20847f6c9629420ae81ce827db3b599af2", size = 932930 }, + { url = "https://files.pythonhosted.org/packages/d3/c7/0a145cc66fc756cea547b948150583357e5518cfa60b3ad0d3266d3ee168/pymongo-4.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0f23f849693e829655f667ea18b87bf34e1395237eb45084f3495317d455beb2", size = 1006138 }, + { url = "https://files.pythonhosted.org/packages/81/88/4ed3cd03d2f7835393a72ed87f5e9186f6fc54bcb0e9b7f718424c0b5db8/pymongo-4.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:62bcfa88deb4a6152a7c93bedd1a808497f6c2881424ca54c3c81964a51c5040", size = 1006125 }, + { url = "https://files.pythonhosted.org/packages/91/a9/d86844a9aff958c959e84b8223b9d226c3b39a71f2f2fbf2aa3a4a748212/pymongo-4.11.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2eaa0233858f72074bf0319f5034018092b43f19202bd7ecb822980c35bfd623", size = 2266315 }, + { url = "https://files.pythonhosted.org/packages/1d/06/fff82b09382a887dab6207bb23778395c5986a5ddab6f55905ebdd82e10c/pymongo-4.11.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a434e081017be360595237cd1aeac3d047dd38e8785c549be80748608c1d4ca", size = 2353538 }, + { url = "https://files.pythonhosted.org/packages/5d/f7/ff5399baee5888eb686c1508d28b4e9d82b9da5ca63215f958356dee4016/pymongo-4.11.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e8aa65a9e4a989245198c249816d86cb240221861b748db92b8b3a5356bd6f1", size = 2312410 }, + { url = "https://files.pythonhosted.org/packages/b0/4d/1746ee984b229eddf5f768265b553a90b31b2395fb5ae1d30d28e430a862/pymongo-4.11.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0a91004029d1fc9e66a800e6da4170afaa9b93bcf41299e4b5951b837b3467a", size = 2263706 }, + { url = "https://files.pythonhosted.org/packages/1c/dc/5d4154c5baf62af9ffb9391cf41848a87cda97798f92e4336730690be7d5/pymongo-4.11.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b992904ac78cb712b42c4b7348974ba1739137c1692cdf8bf75c3eeb22881a4", size = 2202724 }, + { url = "https://files.pythonhosted.org/packages/72/15/c18fcc456fdcb793714776da273fc4cba4579f21818f2219e23ff9512314/pymongo-4.11.3-cp313-cp313t-win32.whl", hash = "sha256:45e18bda802d95a2aed88e487f06becc3bd0b22286a25aeca8c46b8c64980dbb", size = 959256 }, + { url = "https://files.pythonhosted.org/packages/7d/64/11d87df61cdca4fef90388af592247e17f3d31b15a909780f186d2739592/pymongo-4.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:07d40b831590bc458b624f421849c2b09ad2b9110b956f658b583fe01fe01c01", size = 987855 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "readerservice" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "arrow" }, + { name = "fastapi" }, + { name = "psycopg2-binary" }, + { name = "pymongo" }, + { name = "redbox" }, + { name = "sqlalchemy-mixins" }, +] + +[package.metadata] +requires-dist = [ + { name = "arrow", specifier = ">=1.3.0" }, + { name = "fastapi", specifier = ">=0.115.11" }, + { name = "psycopg2-binary", specifier = ">=2.9.10" }, + { name = "pymongo", specifier = ">=4.11.3" }, + { name = "redbox", specifier = ">=0.2.1" }, + { name = "sqlalchemy-mixins", specifier = ">=2.0.5" }, +] + +[[package]] +name = "redbox" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/33/42dbfd394d8099079d31dc0f98afca62bc6cc9635ea1ccab1029fefdc6ff/redbox-0.2.1.tar.gz", hash = "sha256:17005f8cfe8acba992b649e5682b2dd4bff937d67df3fd8496e187cae4f19d60", size = 219953 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/24/9f8330b5ce5a64cd97ae2d3a00d1d5cb9096c54ac2e56a05d7a5812709b8/redbox-0.2.1-py3-none-any.whl", hash = "sha256:14906668345c7e76db367d6d40347c2dcb5de2a5167f96d08f06f95c0a908f71", size = 16507 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.39" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/8e/e77fcaa67f8b9f504b4764570191e291524575ddbfe78a90fc656d671fdc/sqlalchemy-2.0.39.tar.gz", hash = "sha256:5d2d1fe548def3267b4c70a8568f108d1fed7cbbeccb9cc166e05af2abc25c22", size = 9644602 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/86/b2cb432aeb00a1eda7ed33ce86d943c2452dc1642f3ec51bfe9eaae9604b/sqlalchemy-2.0.39-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c457a38351fb6234781d054260c60e531047e4d07beca1889b558ff73dc2014b", size = 2107210 }, + { url = "https://files.pythonhosted.org/packages/bf/b0/b2479edb3419ca763ba1b587161c292d181351a33642985506a530f9162b/sqlalchemy-2.0.39-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:018ee97c558b499b58935c5a152aeabf6d36b3d55d91656abeb6d93d663c0c4c", size = 2097599 }, + { url = "https://files.pythonhosted.org/packages/58/5e/c5b792a4abcc71e68d44cb531c4845ac539d558975cc61db1afbc8a73c96/sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5493a8120d6fc185f60e7254fc056a6742f1db68c0f849cfc9ab46163c21df47", size = 3247012 }, + { url = "https://files.pythonhosted.org/packages/e0/a8/055fa8a7c5f85e6123b7e40ec2e9e87d63c566011d599b4a5ab75e033017/sqlalchemy-2.0.39-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2cf5b5ddb69142511d5559c427ff00ec8c0919a1e6c09486e9c32636ea2b9dd", size = 3257851 }, + { url = "https://files.pythonhosted.org/packages/f6/40/aec16681e91a22ddf03dbaeb3c659bce96107c5f47d2a7c665eb7f24a014/sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f03143f8f851dd8de6b0c10784363712058f38209e926723c80654c1b40327a", size = 3193155 }, + { url = "https://files.pythonhosted.org/packages/21/9d/cef697b137b9eb0b66ab8e9cf193a7c7c048da3b4bb667e5fcea4d90c7a2/sqlalchemy-2.0.39-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06205eb98cb3dd52133ca6818bf5542397f1dd1b69f7ea28aa84413897380b06", size = 3219770 }, + { url = "https://files.pythonhosted.org/packages/57/05/e109ca7dde837d8f2f1b235357e4e607f8af81ad8bc29c230fed8245687d/sqlalchemy-2.0.39-cp312-cp312-win32.whl", hash = "sha256:7f5243357e6da9a90c56282f64b50d29cba2ee1f745381174caacc50d501b109", size = 2077567 }, + { url = "https://files.pythonhosted.org/packages/97/c6/25ca068e38c29ed6be0fde2521888f19da923dbd58f5ff16af1b73ec9b58/sqlalchemy-2.0.39-cp312-cp312-win_amd64.whl", hash = "sha256:2ed107331d188a286611cea9022de0afc437dd2d3c168e368169f27aa0f61338", size = 2103136 }, + { url = "https://files.pythonhosted.org/packages/32/47/55778362642344324a900b6b2b1b26f7f02225b374eb93adc4a363a2d8ae/sqlalchemy-2.0.39-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe193d3ae297c423e0e567e240b4324d6b6c280a048e64c77a3ea6886cc2aa87", size = 2102484 }, + { url = "https://files.pythonhosted.org/packages/1b/e1/f5f26f67d095f408138f0fb2c37f827f3d458f2ae51881546045e7e55566/sqlalchemy-2.0.39-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:79f4f502125a41b1b3b34449e747a6abfd52a709d539ea7769101696bdca6716", size = 2092955 }, + { url = "https://files.pythonhosted.org/packages/c5/c2/0db0022fc729a54fc7aef90a3457bf20144a681baef82f7357832b44c566/sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a10ca7f8a1ea0fd5630f02feb055b0f5cdfcd07bb3715fc1b6f8cb72bf114e4", size = 3179367 }, + { url = "https://files.pythonhosted.org/packages/33/b7/f33743d87d0b4e7a1f12e1631a4b9a29a8d0d7c0ff9b8c896d0bf897fb60/sqlalchemy-2.0.39-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b0a1c7ed54a5361aaebb910c1fa864bae34273662bb4ff788a527eafd6e14d", size = 3192705 }, + { url = "https://files.pythonhosted.org/packages/c9/74/6814f31719109c973ddccc87bdfc2c2a9bc013bec64a375599dc5269a310/sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52607d0ebea43cf214e2ee84a6a76bc774176f97c5a774ce33277514875a718e", size = 3125927 }, + { url = "https://files.pythonhosted.org/packages/e8/6b/18f476f4baaa9a0e2fbc6808d8f958a5268b637c8eccff497bf96908d528/sqlalchemy-2.0.39-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c08a972cbac2a14810463aec3a47ff218bb00c1a607e6689b531a7c589c50723", size = 3154055 }, + { url = "https://files.pythonhosted.org/packages/b4/60/76714cecb528da46bc53a0dd36d1ccef2f74ef25448b630a0a760ad07bdb/sqlalchemy-2.0.39-cp313-cp313-win32.whl", hash = "sha256:23c5aa33c01bd898f879db158537d7e7568b503b15aad60ea0c8da8109adf3e7", size = 2075315 }, + { url = "https://files.pythonhosted.org/packages/5b/7c/76828886d913700548bac5851eefa5b2c0251ebc37921fe476b93ce81b50/sqlalchemy-2.0.39-cp313-cp313-win_amd64.whl", hash = "sha256:4dabd775fd66cf17f31f8625fc0e4cfc5765f7982f94dc09b9e5868182cb71c0", size = 2099175 }, + { url = "https://files.pythonhosted.org/packages/7b/0f/d69904cb7d17e65c65713303a244ec91fd3c96677baf1d6331457fd47e16/sqlalchemy-2.0.39-py3-none-any.whl", hash = "sha256:a1c6b0a5e3e326a466d809b651c63f278b1256146a377a528b6938a279da334f", size = 1898621 }, +] + +[[package]] +name = "sqlalchemy-mixins" +version = "2.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/90/a920aa06a038677dde522dd8d7bc168eedd5fd3331ba1c759bf91ccd28d3/sqlalchemy_mixins-2.0.5.tar.gz", hash = "sha256:85197fc3682c4bf9c35671fb3d10282a0973b19cd2ff2b6791d601cbfb0fb89e", size = 20186 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/4d/8d97e3ec646e8732ea8d33fb33068cab97d0bc5a0e3f46c93174e2d3d3eb/sqlalchemy_mixins-2.0.5-py3-none-any.whl", hash = "sha256:9067b630744741b472aa91d92494cc5612ed2d29c66729a5a4a1d3fbbeccd448", size = 17578 }, +] + +[[package]] +name = "starlette" +version = "0.46.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 }, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] diff --git a/README.md b/README.md index 1f3371e..1e3e197 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -uv add arrow alembic fastapi uvicorn sqlalchemy-mixins redis psycopg2-binary pymongo rsa redmail unidecode textdistance pandas faker requests cryptography +uv add arrow redbox alembic fastapi uvicorn sqlalchemy-mixins redis psycopg2-binary pymongo rsa redmail unidecode textdistance pandas faker requests cryptography user_creds_create user_creds_update diff --git a/Services/PostgresService/controllers/mixin_controllers.py b/Services/PostgresService/controllers/mixin_controllers.py index c8965f0..d5d00b0 100644 --- a/Services/PostgresService/controllers/mixin_controllers.py +++ b/Services/PostgresService/controllers/mixin_controllers.py @@ -62,7 +62,6 @@ class CrudMixin(BasicMixin): expiry_starts: Mapped[TIMESTAMP] = mapped_column( TIMESTAMP(timezone=True), server_default=func.now(), - nullable=False, comment="Record validity start timestamp", ) expiry_ends: Mapped[TIMESTAMP] = mapped_column( @@ -110,6 +109,10 @@ class CrudCollection(CrudMixin): comment="Last update timestamp", ) + # Cryptographic and user tracking + cryp_uu_id: Mapped[str] = mapped_column( + String, nullable=True, index=True, comment="Cryptographic UUID" + ) created_by: Mapped[str] = mapped_column( String, nullable=True, comment="Creator name" ) @@ -122,8 +125,17 @@ class CrudCollection(CrudMixin): updated_by_id: Mapped[int] = mapped_column( Integer, nullable=True, comment="Last modifier ID" ) + confirmed_by: Mapped[str] = mapped_column( + String, nullable=True, comment="Confirmer name" + ) + confirmed_by_id: Mapped[int] = mapped_column( + Integer, nullable=True, comment="Confirmer ID" + ) # Status flags + is_confirmed: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Record confirmation status" + ) replication_id: Mapped[int] = mapped_column( SmallInteger, server_default="0", comment="Replication identifier" ) @@ -133,3 +145,9 @@ class CrudCollection(CrudMixin): active: Mapped[bool] = mapped_column( Boolean, server_default="1", comment="Record active status" ) + is_notification_send: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Notification sent flag" + ) + is_email_send: Mapped[bool] = mapped_column( + Boolean, server_default="0", comment="Email sent flag" + ) diff --git a/docker-compose.yml b/docker-compose.yml index 8d508e8..7cfb2a5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,65 +1,97 @@ services: +# +# commercial_mongo_service: +# container_name: commercial_mongo_service +# image: "bitnami/mongodb:latest" +## image: "bitnami/mongodb:4.4.1-debian-10-r3" +# networks: +# - network_store_services +# environment: +# - MONGODB_DISABLE_ENFORCE_AUTH=true +# - MONGODB_ROOT_PASSWORD=root +# - MONGODB_DATABASE=mongo_database +# - MONGODB_USERNAME=mongo_user +# - MONGODB_PASSWORD=mongo_password +# - MONGO_INITDB_ROOT_USERNAME=mongo_user +# - MONGO_INITDB_ROOT_PASSWORD=mongo_password +# - MONGO_INITDB_DATABASE=mongo_database +# volumes: +# - wag_commercial_mongodb_data:/bitnami/mongodb +# ports: +# - "11110:27017" +# +# commercial_memory_service: +# container_name: commercial_memory_service +# image: 'bitnami/redis:latest' +# restart: on-failure +# environment: +# - REDIS_HOST=commercial_redis_service +# - REDIS_PASSWORD=commercial_redis_password +# - REDIS_PORT=6379 +# - REDIS_DB=0 +# networks: +# - network_store_services +# ports: +# - "11112:6379" +# +# postgres_commercial: +# image: 'bitnami/postgresql:latest' +# container_name: postgres_commercial +# restart: on-failure +# networks: +# - network_store_services +# environment: +# - POSTGRES_DB=wag_database +# - POSTGRES_USER=berkay_wag_user +# - POSTGRES_PASSWORD=berkay_wag_user_password +# depends_on: +# - commercial_mongo_service +# ports: +# - "5434:5432" +# volumes: +# - wag_postgres_commercial_data:/bitnami/postgresql - commercial_mongo_service: - container_name: commercial_mongo_service - image: "bitnami/mongodb:latest" -# image: "bitnami/mongodb:4.4.1-debian-10-r3" - networks: - - network_store_services - environment: - - MONGODB_DISABLE_ENFORCE_AUTH=true - - MONGODB_ROOT_PASSWORD=root - - MONGODB_DATABASE=mongo_database - - MONGODB_USERNAME=mongo_user - - MONGODB_PASSWORD=mongo_password - - MONGO_INITDB_ROOT_USERNAME=mongo_user - - MONGO_INITDB_ROOT_PASSWORD=mongo_password - - MONGO_INITDB_DATABASE=mongo_database - volumes: - - wag_commercial_mongodb_data:/bitnami/mongodb - ports: - - "11110:27017" - - commercial_memory_service: - container_name: commercial_memory_service - image: 'bitnami/redis:latest' - restart: on-failure - environment: - - REDIS_HOST=commercial_redis_service - - REDIS_PASSWORD=commercial_redis_password - - REDIS_PORT=6379 - - REDIS_DB=0 - networks: - - network_store_services - ports: - - "11112:6379" - - postgres_commercial: - image: 'bitnami/postgresql:latest' - container_name: postgres_commercial - restart: on-failure - networks: - - network_store_services - environment: - - POSTGRES_DB=wag_database - - POSTGRES_USER=berkay_wag_user - - POSTGRES_PASSWORD=berkay_wag_user_password - depends_on: - - commercial_mongo_service - ports: - - "5434:5432" - volumes: - - wag_postgres_commercial_data:/bitnami/postgresql - - test_server: - container_name: test_server + email_service: + container_name: email_service build: context: . - dockerfile: EmptyRunner/Dockerfile + dockerfile: BankServices/EmailService/Dockerfile networks: - network_store_services - depends_on: - - postgres_commercial + + parser_service: + container_name: parser_service + build: + context: . + dockerfile: BankServices/ParserService/Dockerfile + networks: + - network_store_services + + writer_service: + container_name: writer_service + build: + context: . + dockerfile: BankServices/WriterService/Dockerfile + networks: + - network_store_services +# +# sender_service: +# container_name: sender_service +# build: +# context: . +# dockerfile: BankServices/SenderService/Dockerfile +# networks: +# - network_store_services + +# test_server: +# container_name: test_server +# build: +# context: . +# dockerfile: EmptyRunner/Dockerfile +# networks: +# - network_store_services +# depends_on: +# - postgres_commercial # wag_management_service: # container_name: wag_management_service diff --git a/pyproject.toml b/pyproject.toml index a7793df..912bbb8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,3 +21,6 @@ dependencies = [ "unidecode>=1.3.8", "uvicorn>=0.34.0", ] + +[tool.uv.workspace] +members = ["BankServices/EmailService", "BankServices/ParserService", "BankServices/ReaderService", "BankServices/SenderService"] diff --git a/uv.lock b/uv.lock index f6e08a0..7a78e65 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,15 @@ version = 1 requires-python = ">=3.12" +[manifest] +members = [ + "emailservice", + "parserservice", + "readerservice", + "senderservice", + "wag-services-and-backend-latest", +] + [[package]] name = "alembic" version = "1.15.1" @@ -193,6 +202,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 }, ] +[[package]] +name = "emailservice" +version = "0.1.0" +source = { virtual = "BankServices/EmailService" } +dependencies = [ + { name = "arrow" }, + { name = "pymongo" }, + { name = "redbox" }, +] + +[package.metadata] +requires-dist = [ + { name = "arrow", specifier = ">=1.3.0" }, + { name = "pymongo", specifier = ">=4.11.3" }, + { name = "redbox", specifier = ">=0.2.1" }, +] + [[package]] name = "faker" version = "37.0.2" @@ -404,6 +430,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436 }, ] +[[package]] +name = "parserservice" +version = "0.1.0" +source = { virtual = "BankServices/ParserService" } +dependencies = [ + { name = "arrow" }, + { name = "pandas" }, + { name = "pymongo" }, + { name = "unidecode" }, + { name = "xlrd" }, +] + +[package.metadata] +requires-dist = [ + { name = "arrow", specifier = ">=1.3.0" }, + { name = "pandas", specifier = ">=2.2.3" }, + { name = "pymongo", specifier = ">=4.11.3" }, + { name = "unidecode", specifier = ">=1.3.8" }, + { name = "xlrd", specifier = ">=2.0.1" }, +] + [[package]] name = "psycopg2-binary" version = "2.9.10" @@ -556,6 +603,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 }, ] +[[package]] +name = "readerservice" +version = "0.1.0" +source = { virtual = "BankServices/ReaderService" } +dependencies = [ + { name = "arrow" }, + { name = "psycopg2-binary" }, + { name = "pymongo" }, + { name = "redbox" }, +] + +[package.metadata] +requires-dist = [ + { name = "arrow", specifier = ">=1.3.0" }, + { name = "psycopg2-binary", specifier = ">=2.9.10" }, + { name = "pymongo", specifier = ">=4.11.3" }, + { name = "redbox", specifier = ">=0.2.1" }, +] + +[[package]] +name = "redbox" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/33/42dbfd394d8099079d31dc0f98afca62bc6cc9635ea1ccab1029fefdc6ff/redbox-0.2.1.tar.gz", hash = "sha256:17005f8cfe8acba992b649e5682b2dd4bff937d67df3fd8496e187cae4f19d60", size = 219953 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/24/9f8330b5ce5a64cd97ae2d3a00d1d5cb9096c54ac2e56a05d7a5812709b8/redbox-0.2.1-py3-none-any.whl", hash = "sha256:14906668345c7e76db367d6d40347c2dcb5de2a5167f96d08f06f95c0a908f71", size = 16507 }, +] + [[package]] name = "redis" version = "5.2.1" @@ -592,6 +670,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] +[[package]] +name = "senderservice" +version = "0.1.0" +source = { virtual = "BankServices/SenderService" } +dependencies = [ + { name = "psycopg2-binary" }, + { name = "pymongo" }, + { name = "redbox" }, +] + +[package.metadata] +requires-dist = [ + { name = "psycopg2-binary", specifier = ">=2.9.10" }, + { name = "pymongo", specifier = ">=4.11.3" }, + { name = "redbox", specifier = ">=0.2.1" }, +] + [[package]] name = "six" version = "1.17.0" @@ -771,3 +866,12 @@ requires-dist = [ { name = "unidecode", specifier = ">=1.3.8" }, { name = "uvicorn", specifier = ">=0.34.0" }, ] + +[[package]] +name = "xlrd" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/b3/19a2540d21dea5f908304375bd43f5ed7a4c28a370dc9122c565423e6b44/xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88", size = 100259 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/0c/c2a72d51fe56e08a08acc85d13013558a2d793028ae7385448a6ccdfae64/xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd", size = 96531 }, +]