From 4b06c4fb1f6e3b02e8a1fd641f0605f0c55627cf Mon Sep 17 00:00:00 2001 From: wowlikon Date: Mon, 22 Dec 2025 11:34:25 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20docker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 41 ++++++++++++++++----------- README.md | 70 ++++++++++++++++++++++++++++++++++------------ data.py | 2 +- docker-compose.yml | 57 +++++++++++++++++++++++++++++-------- poetry.lock | 12 ++++---- pyproject.toml | 4 +-- 6 files changed, 131 insertions(+), 55 deletions(-) diff --git a/Dockerfile b/Dockerfile index e8d8370..2ce05bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,29 @@ -FROM python:3.13 as requirements-stage -WORKDIR /tmp -RUN pip install poetry -RUN poetry self add poetry-plugin-export -COPY ./pyproject.toml ./poetry.lock* /tmp/ -RUN poetry export -f requirements.txt --output requirements.txt --with dev --without-hashes +FROM python:3.12-slim -FROM python:3.13 ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 -RUN apt-get update \ - && apt-get -y install gcc postgresql \ - && apt-get clean # netcat - -RUN pip install --upgrade pip - WORKDIR /code -COPY --from=requirements-stage /tmp/requirements.txt ./requirements.txt -RUN pip install --no-cache-dir --upgrade -r ./requirements.txt -COPY . . -ENV PYTHONPATH=. + +RUN apt-get update \ + && apt-get -y install gcc libpq-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN pip install poetry +RUN poetry config virtualenvs.create false + +COPY ./pyproject.toml ./poetry.lock* /code/ + +RUN poetry install --with dev --no-root --no-interaction + +COPY ./library_service /code/library_service +COPY ./alembic.ini /code/ +COPY ./data.py /code/ + +RUN useradd app && chown -R app:app /code +USER app + +ENV PYTHONPATH=/code + +CMD ["uvicorn", "library_service.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/README.md b/README.md index 04dfa50..1a3f662 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ 5. Запустите приложение: ```bash - docker compose up api + docker compose up api -d ``` Для создания новых миграций: ```bash - docker compose run --rm -T api alembic revision --autogenerate -m "Migration name" + alembic revision --autogenerate -m "Migration name" ``` Для запуска тестов: @@ -50,6 +50,11 @@ docker compose up test ``` +Для добавление данных для примера используйте: + ```bash + python data.py + ``` + ### **Эндпоинты API** **Авторы** @@ -100,37 +105,66 @@ ```mermaid erDiagram - AUTHOR { - int id PK "ID автора" - string name "Имя автора" + USER { + int id PK + string username UK + string email UK + string full_name + string password + boolean is_active + boolean is_verified + } + + USER_ROLE { + int user_id FK + string role + } + + LOAN { + int id PK + int book_id FK + int user_id FK + datetime borrowed_at + datetime due_date + datetime returned_at } BOOK { - int id PK "ID книги" - string title "Название книги" - string description "Описание книги" + int id PK + string title + string description + } + + AUTHOR { + int id PK + string name + string bio } GENRE { - int id PK "ID жанра" - string name "Название жанра" + int id PK + string name } AUTHOR_BOOK { - int author_id FK "ID автора" - int book_id FK "ID книги" + int author_id FK + int book_id FK } GENRE_BOOK { - int genre_id FK "ID жанра" - int book_id FK "ID книги" + int genre_id FK + int book_id FK } - AUTHOR ||--o{ AUTHOR_BOOK : "писал" - BOOK ||--o{ AUTHOR_BOOK : "написан" + USER ||--o{ USER_ROLE : "имеет роли" + USER ||--o{ LOAN : "берёт книги" + LOAN }o--|| BOOK : "выдача" - BOOK ||--o{ GENRE_BOOK : "принадлежит" - GENRE ||--o{ GENRE_BOOK : "содержит" + AUTHOR ||--o{ AUTHOR_BOOK : "пишет" + AUTHOR_BOOK }o--|| BOOK : "авторство" + + GENRE ||--o{ GENRE_BOOK : "содержит" + GENRE_BOOK }o--|| BOOK : "жанр" ``` diff --git a/data.py b/data.py index 2e107d8..2b0739e 100644 --- a/data.py +++ b/data.py @@ -3,7 +3,7 @@ from typing import Optional # Конфигурация USERNAME = "admin" -PASSWORD = "GzwQMe3j2DsPRKpL2DVw6A" +PASSWORD = "your-password-here" BASE_URL = "http://localhost:8000" diff --git a/docker-compose.yml b/docker-compose.yml index cd46558..66999fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,28 +1,63 @@ services: db: - container_name: db image: postgres:17 - ports: - - 5432:5432 - # volumes: - # - ./data/db:/var/lib/postgresql/data + container_name: db + restart: unless-stopped + logging: + options: + max-size: "10m" + max-file: "3" + volumes: + - ./data/db:/var/lib/postgresql/data + networks: + - proxy env_file: - ./.env + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 api: - container_name: api build: . - command: bash -c "alembic upgrade head && uvicorn library_service.main:app --host 0.0.0.0 --port 8000 --reload" + container_name: api + restart: unless-stopped + command: bash -c "uvicorn library_service.main:app --host 0.0.0.0 --port 8000" + logging: + options: + max-size: "10m" + max-file: "3" + networks: + - proxy + env_file: + - ./.env volumes: - .:/code - ports: - - "8000:8000" - # depends_on: - # - db + depends_on: + db: + condition: service_healthy tests: container_name: tests build: . command: bash -c "pytest tests" + restart: unless-stopped + logging: + options: + max-size: "10m" + max-file: "3" + networks: + - proxy + env_file: + - ./.env volumes: - .:/code + depends_on: + db: + condition: service_healthy + +networks: + proxy: # Рекомендуется использовать через реверс-прокси + name: proxy + external: true diff --git a/poetry.lock b/poetry.lock index 1477661..97f431e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. [[package]] name = "aiofiles" @@ -1969,14 +1969,14 @@ files = [ [[package]] name = "uvicorn" -version = "0.34.3" +version = "0.40.0" description = "The lightning-fast ASGI server." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885"}, - {file = "uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a"}, + {file = "uvicorn-0.40.0-py3-none-any.whl", hash = "sha256:c6c8f55bc8bf13eb6fa9ff87ad62308bbbc33d0b67f84293151efe87e0d5f2ee"}, + {file = "uvicorn-0.40.0.tar.gz", hash = "sha256:839676675e87e73694518b5574fd0f24c9d97b46bea16df7b8c05ea1a51071ea"}, ] [package.dependencies] @@ -2247,4 +2247,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = "^3.12" -content-hash = "a8d44f0decfa3ba437e998207c16ca7429ee42e930e8aa1d40f87231e71f219f" +content-hash = "6048c7b120fbeb4533a1e858a87eb09aec68e5da569ca821b9e41ecabf220a9e" diff --git a/pyproject.toml b/pyproject.toml index 36b5601..88a56b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "LibraryAPI" -version = "0.2.0" +version = "0.3.0" description = "Это простое API для управления авторами, книгами и их жанрами." authors = ["wowlikon"] readme = "README.md" @@ -9,11 +9,11 @@ packages = [{ include = "library_service" }] [tool.poetry.dependencies] python = "^3.12" fastapi = { extras = ["all"], version = "^0.115.12" } +uvicorn = { extras = ["standard"], version = "^0.40.0" } psycopg2-binary = "^2.9.10" alembic = "^1.16.1" python-dotenv = "^0.21.0" sqlmodel = "^0.0.24" -uvicorn = "^0.34.3" jinja2 = "^3.1.6" toml = "^0.10.2" python-jose = {extras = ["cryptography"], version = "^3.5.0"}