diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ccca191 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +# виртуальное окружение +venv/ +.venv/ + +# кэш питона +__pycache__/ +*.pyc +*.pyo +*.pyd +*.pytest_cache + +# IDE и редакторы +.vscode/ +.idea/ + +# OS мусор +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/src/docker/__init__.py b/docker/__init__.py similarity index 100% rename from src/docker/__init__.py rename to docker/__init__.py diff --git a/docker/compose-dev.yaml b/docker/compose-dev.yaml new file mode 100644 index 0000000..674ee9c --- /dev/null +++ b/docker/compose-dev.yaml @@ -0,0 +1,76 @@ +name: excel-project + +services: + backend-dev: + profiles: ["dev"] + image: "${DOCKER_REGISTRY:-local}/excel-dev:${IMAGE_TAG:-local}" + container_name: backend-dev + build: + dockerfile: ./docker/dockerfile + context: ../ + target: dev + init: true #Manage processes and reap zombies + ipc: private #Inter-Process Communication (IPC) namespace for high-performance applications + volumes: + - type: bind + source: ../src + target: /home/excel-project/src + - type: bind + source: ../main.py + target: /home/excel-project/main.py + - type: bind + source: ../configs + target: /home/excel-project/configs + - type: bind + source: ../DB + target: /home/excel-project/DB + - type: bind + source: ../upload + target: /home/excel-project/upload + - type: bind + source: ../upload_bad + target: /home/excel-project/upload_bad + - type: bind + source: ../upload_finished + target: /home/excel-project/upload_finished + networks: + - backend + ports: + - "80:8000" + entrypoint: ["./entrypoint.sh", "--dev"] + + backend-prod: + profiles: ["prod"] + image: "${DOCKER_REGISTRY:-local}/excel-prod:${IMAGE_TAG:-local}" + container_name: backend-prod + build: + dockerfile: ./docker/dockerfile + context: ../ + target: prod + init: true #Manage processes and reap zombies + ipc: private #Inter-Process Communication (IPC) namespace for high-performance applications + volumes: + - type: bind + source: ../configs + target: /home/excel-project/configs + - type: bind + source: ../DB + target: /home/excel-project/DB + - type: bind + source: ../upload + target: /home/excel-project/upload + - type: bind + source: ../upload_bad + target: /home/excel-project/upload_bad + - type: bind + source: ../upload_finished + target: /home/excel-project/upload_finished + networks: + - backend + restart: unless-stopped + ports: + - "80:8000" + +networks: + backend: + name: "${BACKEND_NETWORK:-backend_network}" \ No newline at end of file diff --git a/docker/dockerfile b/docker/dockerfile new file mode 100644 index 0000000..36e24b2 --- /dev/null +++ b/docker/dockerfile @@ -0,0 +1,41 @@ +# --- Stage 1: Python Backend dev --- +FROM python:3.14-slim AS dev + +LABEL org.opencontainers.image.title="the-great-excel-project-dev" +LABEL org.opencontainers.image.source="https://git.homyk.space/MH.Dmitrii/The_Great_Excel_Project" + +WORKDIR /home/excel-project + +COPY pyproject.toml poetry.lock docker/entrypoint.sh ./ + +RUN chmod +x ./entrypoint.sh + +RUN pip install --no-cache-dir --break-system-packages poetry \ + && poetry config virtualenvs.create false \ + && poetry install --no-root --no-interaction + +# --- Stage 2: Python Backend prod --- + +FROM python:3.14-slim AS prod + +LABEL org.opencontainers.image.title="the-great-excel-project-prod" +LABEL org.opencontainers.image.source="https://git.homyk.space/MH.Dmitrii/The_Great_Excel_Project" + +WORKDIR /home/excel-project + +COPY pyproject.toml poetry.lock main.py docker/entrypoint.sh ./ +COPY src/ ./src/ + +RUN chmod +x ./entrypoint.sh + +RUN pip install --no-cache-dir --break-system-packages poetry \ + && poetry config virtualenvs.create false \ + && poetry install --no-root --no-interaction --only main + +RUN groupadd --gid 1000 appuser \ + && useradd --uid 1000 --gid appuser --shell /bin/bash --create-home appuser \ + && chown -R appuser:appuser /home/excel-project + +USER appuser + +ENTRYPOINT ["./entrypoint.sh", "--prod"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100644 index 0000000..dffbbed --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +MODE="" +WORKERS="" + +while [ -n "$1" ]; do +case "$1" in + --dev) MODE="dev" ;; + --prod) MODE="prod" ;; + --workers) + shift + WORKERS="$1" + ;; + *) echo "$1 is not an option" ;; +esac +shift +done + +if [ -z "$MODE" ]; then + echo "Usage: entrypoint.sh --dev|--prod [--workers N]" + exit 1 +fi + +if [ "$MODE" = "dev" ]; then + WORKERS="${WORKERS:-1}" + exec gunicorn \ + --workers "$WORKERS" \ + --worker-class uvicorn.workers.UvicornWorker \ + --worker-connections 1000 \ + --reload \ + --bind 0.0.0.0:8000 \ + main:app +else + WORKERS="${WORKERS:-4}" + exec gunicorn \ + --workers "$WORKERS" \ + --worker-class uvicorn.workers.UvicornWorker \ + --worker-connections 1000 \ + --bind 0.0.0.0:8000 \ + main:app +fi \ No newline at end of file diff --git a/main.py b/main.py index 729793b..de56560 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ +from contextlib import asynccontextmanager from pathlib import Path -import uvicorn +# import uvicorn from fastapi import FastAPI from src.web.protected_routes.auth_routes import router as protected_router @@ -8,7 +9,15 @@ from src.web.protected_routes.protected_user_action_routes import ( router as protected_user_action_routes, ) -app=FastAPI(root_path="/") + +@asynccontextmanager +async def lifespan(app: FastAPI): + create_dirs() + yield + print("shutting down") + + +app=FastAPI(root_path="/", lifespan=lifespan) app.include_router(router=protected_router) app.include_router(router=protected_user_action_routes) @@ -26,11 +35,4 @@ def create_dirs(): "./upload_finished") for x in dirs_to_create: - Path(x).mkdir(parents=True, exist_ok=True) - -def main(): - create_dirs() - uvicorn.run("main:app", reload=True) - -if __name__=="__main__": - main() \ No newline at end of file + Path(x).mkdir(parents=True, exist_ok=True) \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index e3db45f..5484c4f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -42,7 +42,7 @@ version = "2.16.0" description = "Allure pytest integration" optional = false python-versions = "*" -groups = ["main"] +groups = ["dev"] files = [ {file = "allure_pytest-2.16.0-py3-none-any.whl", hash = "sha256:e5035a3b1f541b0c2ee566822df6fec20e0628b8536780e5bdfe39060ac0c71b"}, {file = "allure_pytest-2.16.0.tar.gz", hash = "sha256:3cc883595b1ce4280b0b9a5fdaa0ce3bb5cdbaa1b43c7269d8b82e825e6e107c"}, @@ -58,7 +58,7 @@ version = "2.16.0" description = "Contains the API for end users as well as helper functions and classes to build Allure adapters for Python test frameworks" optional = false python-versions = ">=3.6" -groups = ["main"] +groups = ["dev"] files = [ {file = "allure_python_commons-2.16.0-py3-none-any.whl", hash = "sha256:6d42a500078aca8a2e68823075c1ffc2396987bb268d62b19af82390b205ce88"}, {file = "allure_python_commons-2.16.0.tar.gz", hash = "sha256:ecdc92bafea074bab96b5f2c4eb3100825340188f5aece608ae80eced709b36f"}, @@ -116,7 +116,7 @@ version = "3.0.2" description = "Annotate AST trees with source code positions" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933"}, {file = "asttokens-3.0.2.tar.gz", hash = "sha256:3ecdbd8f2cc195f53ccada3a613538bb5f9ef6f6869129f13e03c30a677b8fe2"}, @@ -132,7 +132,7 @@ version = "26.1.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309"}, {file = "attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"}, @@ -221,7 +221,7 @@ version = "2026.7.22" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["dev"] files = [ {file = "certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"}, {file = "certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55"}, @@ -233,7 +233,7 @@ version = "3.4.9" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["dev"] files = [ {file = "charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a"}, {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616"}, @@ -351,12 +351,12 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main"] -markers = "sys_platform == \"win32\" or platform_system == \"Windows\"" +groups = ["main", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +markers = {main = "platform_system == \"Windows\"", dev = "sys_platform == \"win32\""} [[package]] name = "coverage" @@ -364,7 +364,7 @@ version = "7.15.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "coverage-7.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b5bd92ff1ec22e535eab0de75fa6db021992791f461a2aceb7822c625a1187d"}, {file = "coverage-7.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44826758cfe73fcd0e6af5deb4ba6d5417cc1d13df3acb35c93484a11160f846"}, @@ -468,7 +468,7 @@ version = "5.3.1" description = "Decorators for Humans" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "decorator-5.3.1-py3-none-any.whl", hash = "sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c"}, {file = "decorator-5.3.1.tar.gz", hash = "sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82"}, @@ -480,7 +480,7 @@ version = "0.7.1" description = "XML bomb protection for Python stdlib modules" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -groups = ["main"] +groups = ["dev"] files = [ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, @@ -548,7 +548,7 @@ version = "2.2.1" description = "Get the currently executing AST node of a frame, and other information" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"}, {file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"}, @@ -715,7 +715,7 @@ version = "3.2.4" description = "HTTPie: modern, user-friendly command-line HTTP client for the API era." optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["dev"] files = [ {file = "httpie-3.2.4-py3-none-any.whl", hash = "sha256:4bd0435cc4b9bca59501bc65089de96f3e93b393803f32a81951db62050ebf0b"}, {file = "httpie-3.2.4.tar.gz", hash = "sha256:302ad436c3dc14fd0d1b19d4572ef8d62b146bcd94b505f3c2521f701e2e7a2a"}, @@ -743,7 +743,7 @@ version = "3.18" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"}, {file = "idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848"}, @@ -758,7 +758,7 @@ version = "2.3.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, @@ -770,7 +770,7 @@ version = "9.15.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.11" -groups = ["main"] +groups = ["dev"] files = [ {file = "ipython-9.15.0-py3-none-any.whl", hash = "sha256:515ad9c3cdf0c932a5a9f6245419e8aba706b7bd03c3e1d3a1c83d9351d6aa6e"}, {file = "ipython-9.15.0.tar.gz", hash = "sha256:da2819ce2aa83135257df830660b1176d986c3d2876db24df01974fa955b2756"}, @@ -803,7 +803,7 @@ version = "1.1.1" description = "Defines a variety of Pygments lexers for highlighting IPython code." optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"}, {file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"}, @@ -818,7 +818,7 @@ version = "0.20.0" description = "An autocompletion tool for Python that can be used for text editors." optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67"}, {file = "jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011"}, @@ -857,7 +857,7 @@ version = "4.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a"}, {file = "markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49"}, @@ -980,7 +980,7 @@ version = "0.2.2" description = "Inline Matplotlib backend for Jupyter" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6"}, {file = "matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79"}, @@ -998,7 +998,7 @@ version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" -groups = ["main"] +groups = ["dev"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -1010,7 +1010,7 @@ version = "6.7.1" description = "multidict implementation" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "multidict-6.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c93c3db7ea657dd4637d57e74ab73de31bccefe144d3d4ce370052035bc85fb5"}, {file = "multidict-6.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:974e72a2474600827abaeda71af0c53d9ebbc3c2eb7da37b37d7829ae31232d8"}, @@ -1220,7 +1220,7 @@ version = "26.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"}, {file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"}, @@ -1324,7 +1324,7 @@ version = "0.8.7" description = "A Python Parser" optional = false python-versions = ">=3.6" -groups = ["main"] +groups = ["dev"] files = [ {file = "parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c"}, {file = "parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1"}, @@ -1340,7 +1340,7 @@ version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." optional = false python-versions = "*" -groups = ["main"] +groups = ["dev"] markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, @@ -1356,7 +1356,7 @@ version = "26.1.2" description = "The PyPA recommended tool for installing Python packages." optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "pip-26.1.2-py3-none-any.whl", hash = "sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab"}, {file = "pip-26.1.2.tar.gz", hash = "sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605"}, @@ -1368,7 +1368,7 @@ version = "1.6.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, @@ -1384,7 +1384,7 @@ version = "3.0.52" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, @@ -1399,7 +1399,7 @@ version = "7.2.2" description = "Cross-platform lib for process and system monitoring." optional = false python-versions = ">=3.6" -groups = ["main"] +groups = ["dev"] markers = "sys_platform != \"emscripten\" and sys_platform != \"cygwin\"" files = [ {file = "psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b"}, @@ -1435,7 +1435,7 @@ version = "0.7.0" description = "Run a subprocess in a pseudo terminal" optional = false python-versions = "*" -groups = ["main"] +groups = ["dev"] markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\"" files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, @@ -1448,7 +1448,7 @@ version = "0.2.3" description = "Safely evaluate AST nodes without side effects" optional = false python-versions = "*" -groups = ["main"] +groups = ["dev"] files = [ {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"}, {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"}, @@ -1655,7 +1655,7 @@ version = "2.20.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"}, {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"}, @@ -1670,7 +1670,7 @@ version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main"] +groups = ["dev"] files = [ {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, @@ -1683,7 +1683,7 @@ version = "9.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c"}, {file = "pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313"}, @@ -1705,7 +1705,7 @@ version = "1.4.0" description = "Pytest support for asyncio" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1"}, {file = "pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42"}, @@ -1724,7 +1724,7 @@ version = "7.1.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678"}, {file = "pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2"}, @@ -1744,7 +1744,7 @@ version = "3.15.1" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d"}, {file = "pytest_mock-3.15.1.tar.gz", hash = "sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f"}, @@ -1827,7 +1827,7 @@ version = "2.34.2" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0"}, {file = "requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed"}, @@ -1850,7 +1850,7 @@ version = "1.0.0" description = "A utility belt for advanced users of python-requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main"] +groups = ["dev"] files = [ {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, @@ -1865,7 +1865,7 @@ version = "15.0.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.9.0" -groups = ["main"] +groups = ["dev"] files = [ {file = "rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb"}, {file = "rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36"}, @@ -1915,7 +1915,7 @@ version = "83.0.0" description = "Most extensible Python build backend with support for C/C++ extension modules" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3"}, {file = "setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef"}, @@ -2045,7 +2045,7 @@ version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" optional = false python-versions = "*" -groups = ["main"] +groups = ["dev"] files = [ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, @@ -2083,7 +2083,7 @@ version = "5.15.1" description = "Traitlets Python configuration system" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["dev"] files = [ {file = "traitlets-5.15.1-py3-none-any.whl", hash = "sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92"}, {file = "traitlets-5.15.1.tar.gz", hash = "sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722"}, @@ -2139,7 +2139,7 @@ version = "2.7.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["dev"] files = [ {file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"}, {file = "urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c"}, @@ -2176,7 +2176,7 @@ version = "0.8.2" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = ">=3.8" -groups = ["main"] +groups = ["dev"] files = [ {file = "wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85"}, {file = "wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda"}, @@ -2185,4 +2185,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.13" -content-hash = "9f5afa235b9e6861253603be40e4b5c3ae8d59b6d8bff7669d4e7670183ff336" +content-hash = "6881b7672e5e0ed6a48d6416f117209ba1d0aefaf3b14db1ccec48360ebc22cb" diff --git a/pyproject.toml b/pyproject.toml index 08181ad..0ae8685 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,9 @@ authors = [ license = "MH.Dmitrii's project" readme = "README.md" requires-python = ">=3.13" + dependencies = [ "alembic (>=1.18.5,<2.0.0)", - "pytest (>=9.1.1,<10.0.0)", "uvicorn (>=0.51.0,<0.52.0)", "gunicorn (>=26.0.0,<27.0.0)", "fastapi (>=0.139.1,<0.140.0)", @@ -21,16 +21,18 @@ dependencies = [ "bcrypt (>=5.0.0,<6.0.0)", "python-jose (>=3.5.0,<4.0.0)", "python-multipart (>=0.0.32,<0.0.33)", - "ipython (>=9.15.0,<10.0.0)", - "httpie (>=3.2.4,<4.0.0)", - "pytest-cov (>=7.1.0,<8.0.0)", - "allure-pytest (>=2.16.0,<3.0.0)", - "pytest-mock (>=3.15.1,<4.0.0)", "aiosqlite (>=0.22.1,<0.23.0)", - "greenlet (>=3.5.4,<4.0.0)", - "pytest-asyncio (>=1.4.0,<2.0.0)" + "greenlet (>=3.5.4,<4.0.0)" ] +[tool.poetry.group.dev.dependencies] +pytest = ">=9.1.1,<10.0.0" +pytest-cov = ">=7.1.0,<8.0.0" +pytest-mock = ">=3.15.1,<4.0.0" +allure-pytest = ">=2.16.0,<3.0.0" +ipython = ">=9.15.0,<10.0.0" +httpie = ">=3.2.4,<4.0.0" +pytest-asyncio = ">=1.4.0,<2.0.0" [build-system] requires = ["poetry-core>=2.0.0,<3.0.0"] diff --git a/src/docker/docker-compose.yml b/src/docker/docker-compose.yml deleted file mode 100644 index e69de29..0000000 diff --git a/src/docker/dockerfile b/src/docker/dockerfile deleted file mode 100644 index e69de29..0000000