diff --git a/.github/workflows/test_app.yml b/.github/workflows/test_app.yml index 5694198..d94c486 100644 --- a/.github/workflows/test_app.yml +++ b/.github/workflows/test_app.yml @@ -19,10 +19,15 @@ jobs: with: python-version: '3.12.10' - - name: Install dependencies + - name: Install Poetry run: | python -m pip install --upgrade pip - pip install -r requirements.txt + pip install poetry + + - name: Install dependencies + run: | + poetry config virtualenvs.create false + poetry install --no-interaction --no-ansi --no-root - name: Lint application run: | diff --git a/README.md b/README.md index 8bb40f3..6410362 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,15 @@ REST API для управления рецептами, ингредиентами и списками покупок. Пользователь может сохранять рецепты, создавать из них списки покупок. +## 🛠️ Используемые технологии -## ⚙️ Функциональность: - -- 📐 Аннотации типов и валидация данных - -- 🗃️ Асинхронные запросы к БД с SQLAlchemy 2.0 - -- 🗝️ Аутентификация через `fastapi-users` - -- 📦 API для работы с рецептами и ингредиентами - -- 🔁 Связи: - - `User ↔ Profile` (один к одному) - `User ↔ Recipes` (один ко многим) - `Recipes ↔ Products` (многие ко многим) - -- 📄 Alembic миграции - -- 📝 Автоматическая OpenAPI-документация (`/docs`, `/redoc`) - -- 🐳 Docker/Docker Compose - -- 🧪 Юнит и интеграционные тесты - +- **Бэкенд**: FastAPI +- **ORM**: SQLAlchemy 2.0 + Alembic +- **Валидация**: Pydantic +- **СУБД**: PostgreSQL +- **Контейнеризация**: Docker + Docker Compose + Poetry +- **Тестирование**: Pytest +- **Фронтенд**: Jinja + HTML/CSS/JS (Free Template Simple House) ## 🚧 В разработке: @@ -39,6 +23,52 @@ REST API для управления рецептами, ингредиента `User ↔ ShoppingLists` (один ко многим) `ShoppingLists ↔ Products` (многие ко многим) +## 📡 Эндпоинты + +### 🔸 Auth +- `POST /api/v1/auth/login` — Аутентификация пользователя. +- `POST /api/v1/auth/logout` — Выход из системы. +- `POST /api/v1/auth/register` — Регистрация нового пользователя. +- `POST /api/v1/auth/request-verify-token` — Запрос токена верификации. +- `POST /api/v1/auth/verify` — Подтверждение email. +- `POST /api/v1/auth/forgot-password` — Запрос сброса пароля. +- `POST /api/v1/auth/reset-password` — Сброс пароля. + +### 🔸 Users +- `GET /api/v1/users/me` — Получение текущего пользователя. +- `PATCH /api/v1/users/me` — Обновление профиля. +- `GET /api/v1/users/{id}` — Получение пользователя по ID. +- `PATCH /api/v1/users/{id}` — Обновление пользователя. +- `DELETE /api/v1/users/{id}` — Удаление пользователя. + +### 🔸 Messages +- `GET /api/v1/messages` — Получение публичных сообщений. +- `GET /api/v1/messages/secrets` — Получение приватных сообщений. + +### 🔸 Products +- `GET /api/v1/products/` — Получение списка продуктов. +- `POST /api/v1/products/` — Создание продукта. +- `GET /api/v1/products/{product_id}/` — Получение продукта по ID. +- `PUT /api/v1/products/{product_id}/` — Полное обновление продукта. +- `DELETE /api/v1/products/{product_id}/` — Удаление продукта. + +### 🔸 Recipes +- `GET /api/v1/recipes/` — Получение списка рецептов. +- `POST /api/v1/recipes/` — Создание рецепта. +- `GET /api/v1/recipes/{recipe_id}/` — Получение рецепта по ID. +- `PUT /api/v1/recipes/{recipe_id}/` — Полное обновление рецепта. +- `PATCH /api/v1/recipes/{recipe_id}/` — Частичное обновление рецепта +- `DELETE /api/v1/recipes/{recipe_id}/` — Удаление рецепта. +- `POST /api/v1/recipes/upload/recipe-image` — Загрузка изображения рецепта. + +### 🔸 Views +- `GET /Home` — Главная страница. +- `GET /login` — Страница входа. +- `GET /register` — Страница регистрации. +- `GET /profile` — Страница профиля. +- `GET /profile_info` — Информация о пользователе и его рецептах. +- `GET /recipes` — Страница создания рецепта. + ## 🐳 Установка и запуск с Docker: ### 🔹 1. Клонируйте репозиторий и перейдите в директорию проекта: @@ -114,86 +144,4 @@ make stop ### 🔹 7. 🧪 Запуск тестов: ``` make test -``` - -## ⚙️ Установка и запуск без Docker: - -### 🔹 1. Клонируйте репозиторий и перейдите в директорию проекта: -``` -git clone https://github.com/MaxBakshaev/FastAPI-Recipe-And-Grocery-Planner.git -``` -``` -cd FastAPI-Recipe-And-Grocery-Planner -``` - -### 🔹 2. Создайте и активируйте виртуальное окружение: -``` -python -m venv venv -``` - -Для Linux или macOS: -``` -source venv/bin/activate -``` -Для Windows: -``` -venv\Scripts\activate -``` - -### 🔹 3. Установите зависимости: -``` -pip install -r requirements.txt -``` - -### 🔹 4. Настройка окружения: - -4.1. Создайте БД вручную в PostgreSQL. - -4.2. Укажите свои данные в `app/.env.template`: - -✏️ Замените в APP_CONFIG__DB__URL: - -- `user` — имя пользователя БД -- `pwd` — пароль -- `DBname` — название БД - -🔑 Сгенерируйте секретные ключи и добавьте в APP_CONFIG__ACCESS_TOKEN__RESET_PASSWORD_TOKEN_SECRET и APP_CONFIG__ACCESS_TOKEN__VERIFICATION_TOKEN_SECRET: - -``` -python -c "import secrets; print(secrets.token_urlsafe(32))" -``` - -### 🔹 5. Перейдите в каталог `app` и примените миграции: -``` -cd app -``` -``` -alembic upgrade head -``` -Вернитесь в корневую директорию: -``` -cd .. -``` - -### 🔹 6. Запустите сервер: -``` -python app/main.py -``` - -Для отключения сервера используйте команду: -``` -Ctrl + C -``` - -### 🔹 7. Откройте в браузере: - -- 🏠 Приложение: http://127.0.0.1:8000/ - -- 📚 Swagger UI: http://127.0.0.1:8000/docs - -- 📘 Redoc: http://127.0.0.1:8000/redoc - -### 🔹 8. 🧪 Запуск тестов: -``` -pytest app/tests ``` \ No newline at end of file diff --git a/app/actions/create_superuser.py b/app/actions/create_superuser.py index 6a989ee..0a6da16 100644 --- a/app/actions/create_superuser.py +++ b/app/actions/create_superuser.py @@ -4,10 +4,10 @@ import contextlib from os import getenv -from api.dependencies.authentication import get_users_db, get_user_manager -from core.authentication import UserManager -from core.models import db_helper, User -from core.schemas import UserCreate +from app.api.dependencies.authentication import get_users_db, get_user_manager +from app.core.authentication import UserManager +from app.core.models import db_helper, User +from app.core.schemas import UserCreate get_users_db_context = contextlib.asynccontextmanager(get_users_db) diff --git a/app/alembic/env.py b/app/alembic/env.py index 8b2f2ba..81f2f5e 100644 --- a/app/alembic/env.py +++ b/app/alembic/env.py @@ -7,8 +7,8 @@ from alembic import context -from core.config import settings -from core.models import Base +from app.core.config import settings +from app.core.models import Base # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/app/api/__init__.py b/app/api/__init__.py index d4f8fc4..824a8b1 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -from core.config import settings +from app.core.config import settings from .api_v1 import router as router_api_v1 router = APIRouter( diff --git a/app/api/api_v1/__init__.py b/app/api/api_v1/__init__.py index f1486bd..5013f56 100644 --- a/app/api/api_v1/__init__.py +++ b/app/api/api_v1/__init__.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends from fastapi.security import HTTPBearer -from core.config import settings +from app.core.config import settings from .auth import router as auth_router from .users import router as users_router diff --git a/app/api/api_v1/auth.py b/app/api/api_v1/auth.py index bf9018b..4175a67 100644 --- a/app/api/api_v1/auth.py +++ b/app/api/api_v1/auth.py @@ -7,11 +7,11 @@ from fastapi import APIRouter -from core.schemas import UserCreate, UserRead +from app.core.schemas import UserCreate, UserRead from .fastapi_users import fastapi_users_bearer -from api.dependencies.authentication import authentication_backend_bearer -from core.config import settings +from app.api.dependencies.authentication import authentication_backend_bearer +from app.core.config import settings router = APIRouter( prefix=settings.api.v1.auth, diff --git a/app/api/api_v1/fastapi_users.py b/app/api/api_v1/fastapi_users.py index 2fe31cb..bfeb5f5 100644 --- a/app/api/api_v1/fastapi_users.py +++ b/app/api/api_v1/fastapi_users.py @@ -1,9 +1,9 @@ from fastapi_users import FastAPIUsers -from core.models import User -from core.types.user_id import UserIdType +from app.core.models import User +from app.core.types.user_id import UserIdType -from api.dependencies.authentication import ( +from app.api.dependencies.authentication import ( authentication_backend_bearer, authentication_backend_cookie, get_user_manager, diff --git a/app/api/api_v1/messages.py b/app/api/api_v1/messages.py index 6981ebe..84565f1 100644 --- a/app/api/api_v1/messages.py +++ b/app/api/api_v1/messages.py @@ -1,13 +1,13 @@ from typing import Annotated from fastapi import APIRouter, Depends -from api.api_v1.fastapi_users import ( +from app.api.api_v1.fastapi_users import ( current_active_user_bearer, current_active_super_user_bearer, ) -from core.config import settings -from core.models import User -from core.schemas import UserRead +from app.core.config import settings +from app.core.models import User +from app.core.schemas import UserRead router = APIRouter( prefix=settings.api.v1.messages, diff --git a/app/api/api_v1/mixins.py b/app/api/api_v1/mixins.py index 172884f..7ae47c5 100644 --- a/app/api/api_v1/mixins.py +++ b/app/api/api_v1/mixins.py @@ -1,5 +1,5 @@ -from core.models import Recipe -from core.schemas import ProductInRecipe, RecipeResponse +from app.core.models import Recipe +from app.core.schemas import ProductInRecipe, RecipeResponse def map_recipe_to_response(recipe: Recipe) -> RecipeResponse: diff --git a/app/api/api_v1/products.py b/app/api/api_v1/products.py index d1efa7d..e825765 100644 --- a/app/api/api_v1/products.py +++ b/app/api/api_v1/products.py @@ -2,10 +2,10 @@ from fastapi import APIRouter, Depends, HTTPException, Path, status from sqlalchemy.ext.asyncio import AsyncSession -from crud import products -from core.models import db_helper -from core.schemas import Product, ProductCreate, ProductUpdate -from core.config import settings +from app.crud import products +from app.core.models import db_helper +from app.core.schemas import Product, ProductCreate, ProductUpdate +from app.core.config import settings router = APIRouter( prefix=settings.api.v1.products, diff --git a/app/api/api_v1/recipes.py b/app/api/api_v1/recipes.py index ca9e509..8c995d3 100644 --- a/app/api/api_v1/recipes.py +++ b/app/api/api_v1/recipes.py @@ -3,12 +3,12 @@ from typing import List from sqlalchemy.ext.asyncio import AsyncSession -from api.api_v1.fastapi_users import current_active_user_bearer -from api.api_v1.mixins import map_recipe_to_response -from crud import recipes -from core.config import settings -from core.models import db_helper, User -from core.schemas import ( +from app.api.api_v1.fastapi_users import current_active_user_bearer +from app.api.api_v1.mixins import map_recipe_to_response +from app.crud import recipes +from app.core.config import settings +from app.core.models import db_helper, User +from app.core.schemas import ( RecipeCreateRequest, RecipeResponse, RecipeUpdateRequest, diff --git a/app/api/api_v1/users.py b/app/api/api_v1/users.py index fedcdb4..6e33fba 100644 --- a/app/api/api_v1/users.py +++ b/app/api/api_v1/users.py @@ -2,9 +2,9 @@ from fastapi import APIRouter -from api.api_v1.fastapi_users import fastapi_users_bearer -from core.config import settings -from core.schemas import UserRead, UserUpdate +from app.api.api_v1.fastapi_users import fastapi_users_bearer +from app.core.config import settings +from app.core.schemas import UserRead, UserUpdate router = APIRouter( prefix=settings.api.v1.users, diff --git a/app/api/dependencies/authentication/access_tokens.py b/app/api/dependencies/authentication/access_tokens.py index abc04fe..f91c00e 100644 --- a/app/api/dependencies/authentication/access_tokens.py +++ b/app/api/dependencies/authentication/access_tokens.py @@ -2,7 +2,7 @@ from fastapi import Depends -from core.models import db_helper, AccessToken +from app.core.models import db_helper, AccessToken if TYPE_CHECKING: from sqlalchemy.ext.asyncio import AsyncSession diff --git a/app/api/dependencies/authentication/backend.py b/app/api/dependencies/authentication/backend.py index 1051ef8..dd19301 100644 --- a/app/api/dependencies/authentication/backend.py +++ b/app/api/dependencies/authentication/backend.py @@ -3,7 +3,7 @@ from fastapi_users.authentication import AuthenticationBackend from .strategy import get_database_strategy -from core.authentication import bearer_transport, cookie_transport +from app.core.authentication import bearer_transport, cookie_transport authentication_backend_bearer = AuthenticationBackend( name="access-tokens-db", diff --git a/app/api/dependencies/authentication/strategy.py b/app/api/dependencies/authentication/strategy.py index 8401379..0e86d01 100644 --- a/app/api/dependencies/authentication/strategy.py +++ b/app/api/dependencies/authentication/strategy.py @@ -3,11 +3,11 @@ from fastapi import Depends from fastapi_users.authentication.strategy.db import DatabaseStrategy -from core.config import settings +from app.core.config import settings from .access_tokens import get_access_tokens_db if TYPE_CHECKING: - from core.models import AccessToken + from app.core.models import AccessToken from fastapi_users.authentication.strategy.db import AccessTokenDatabase diff --git a/app/api/dependencies/authentication/user_manager.py b/app/api/dependencies/authentication/user_manager.py index 1e1d0c4..6493628 100644 --- a/app/api/dependencies/authentication/user_manager.py +++ b/app/api/dependencies/authentication/user_manager.py @@ -2,7 +2,7 @@ from fastapi import Depends -from core.authentication import UserManager +from app.core.authentication import UserManager from .users import get_users_db if TYPE_CHECKING: diff --git a/app/api/dependencies/authentication/users.py b/app/api/dependencies/authentication/users.py index 4152337..cc384f6 100644 --- a/app/api/dependencies/authentication/users.py +++ b/app/api/dependencies/authentication/users.py @@ -2,7 +2,7 @@ from fastapi import Depends -from core.models import db_helper, User +from app.core.models import db_helper, User if TYPE_CHECKING: from sqlalchemy.ext.asyncio import AsyncSession diff --git a/app/core/authentication/transport.py b/app/core/authentication/transport.py index f75e349..e39cd9a 100644 --- a/app/core/authentication/transport.py +++ b/app/core/authentication/transport.py @@ -2,7 +2,7 @@ from fastapi_users.authentication import BearerTransport, CookieTransport -from core.config import settings +from app.core.config import settings cookie_transport = CookieTransport( cookie_name="access_token", diff --git a/app/core/authentication/user_manager.py b/app/core/authentication/user_manager.py index 4ff0f78..a86b8d8 100644 --- a/app/core/authentication/user_manager.py +++ b/app/core/authentication/user_manager.py @@ -3,9 +3,9 @@ from fastapi_users import BaseUserManager, IntegerIDMixin -from core.config import settings -from core.types.user_id import UserIdType -from core.models import User +from app.core.config import settings +from app.core.types.user_id import UserIdType +from app.core.models import User if TYPE_CHECKING: from fastapi import Request diff --git a/app/core/models/access_token.py b/app/core/models/access_token.py index 4dc2e43..f5ef6dd 100644 --- a/app/core/models/access_token.py +++ b/app/core/models/access_token.py @@ -7,7 +7,7 @@ from sqlalchemy import Integer, ForeignKey from sqlalchemy.orm import Mapped, mapped_column -from core.types.user_id import UserIdType +from app.core.types.user_id import UserIdType from .base import Base if TYPE_CHECKING: diff --git a/app/core/models/base.py b/app/core/models/base.py index 6e5c71f..0eeb35a 100644 --- a/app/core/models/base.py +++ b/app/core/models/base.py @@ -1,8 +1,8 @@ from sqlalchemy import MetaData from sqlalchemy.orm import DeclarativeBase, declared_attr -from core.config import settings -from utils import camel_case_to_snake_case +from app.core.config import settings +from app.utils import camel_case_to_snake_case class Base(DeclarativeBase): diff --git a/app/core/models/db_helper.py b/app/core/models/db_helper.py index fe7c570..4a4c301 100644 --- a/app/core/models/db_helper.py +++ b/app/core/models/db_helper.py @@ -7,7 +7,7 @@ AsyncSession, ) -from core.config import settings +from app.core.config import settings class DatabaseHelper: diff --git a/app/core/models/profile.py b/app/core/models/profile.py index 99bf0cf..8ebbf21 100644 --- a/app/core/models/profile.py +++ b/app/core/models/profile.py @@ -1,8 +1,8 @@ from sqlalchemy import String, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship -from core.models import User -from core.types.user_id import UserIdType +from app.core.models import User +from app.core.types.user_id import UserIdType from .base import Base from .mixins.id_int_pk import IdIntPkMixin diff --git a/app/core/models/user.py b/app/core/models/user.py index 21dc185..4fd7178 100644 --- a/app/core/models/user.py +++ b/app/core/models/user.py @@ -7,7 +7,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship from . import Base -from core.types.user_id import UserIdType +from app.core.types.user_id import UserIdType from .mixins.id_int_pk import IdIntPkMixin if TYPE_CHECKING: diff --git a/app/core/schemas/user.py b/app/core/schemas/user.py index 4656394..edb3284 100644 --- a/app/core/schemas/user.py +++ b/app/core/schemas/user.py @@ -2,7 +2,7 @@ from fastapi_users import schemas -from core.types.user_id import UserIdType +from app.core.types.user_id import UserIdType class UserRead(schemas.BaseUser[UserIdType]): diff --git a/app/crud/products.py b/app/crud/products.py index bbead4e..f1a3d2f 100644 --- a/app/crud/products.py +++ b/app/crud/products.py @@ -2,8 +2,8 @@ from sqlalchemy.engine import Result from sqlalchemy.ext.asyncio import AsyncSession -from core.models import Product -from core.schemas import ProductCreate, ProductUpdate +from app.core.models import Product +from app.core.schemas import ProductCreate, ProductUpdate async def get_products(session: AsyncSession) -> list[Product]: diff --git a/app/crud/recipes.py b/app/crud/recipes.py index 0f9b209..1a632da 100644 --- a/app/crud/recipes.py +++ b/app/crud/recipes.py @@ -5,8 +5,8 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload -from core.schemas import ProductInfo -from core.models import Product, Recipe, RecipeProductAssociation +from app.core.schemas import ProductInfo +from app.core.models import Product, Recipe, RecipeProductAssociation async def get_recipes_with_products(session: AsyncSession) -> list[Recipe]: diff --git a/app/crud/users.py b/app/crud/users.py index 80d0335..252fa3a 100644 --- a/app/crud/users.py +++ b/app/crud/users.py @@ -4,9 +4,9 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from core.authentication import UserManager -from core.schemas import UserCreate -from core.models import User, Profile +from app.core.authentication import UserManager +from app.core.schemas import UserCreate +from app.core.models import User, Profile async def get_all_users( diff --git a/app/main.py b/app/main.py index 0bf3d97..22d8dd0 100644 --- a/app/main.py +++ b/app/main.py @@ -6,10 +6,10 @@ from fastapi.staticfiles import StaticFiles import uvicorn -from api import router as api_router -from core.config import settings -from core.models import db_helper -from views import router as views_router +from app.api import router as api_router +from app.core.config import settings +from app.core.models import db_helper +from app.views import router as views_router @asynccontextmanager diff --git a/app/tests/test_api_products.py b/app/tests/test_api_products.py index 5f106b0..1c3bcf5 100644 --- a/app/tests/test_api_products.py +++ b/app/tests/test_api_products.py @@ -3,7 +3,7 @@ import pytest_asyncio from main import application -from core.schemas import Product +from app.core.schemas import Product @pytest_asyncio.fixture diff --git a/app/tests/test_db.py b/app/tests/test_db.py index 8b535ce..e134bdd 100644 --- a/app/tests/test_db.py +++ b/app/tests/test_db.py @@ -2,7 +2,7 @@ from sqlalchemy.ext.asyncio import AsyncSession -from core.models import db_helper +from app.core.models import db_helper @pytest.mark.asyncio diff --git a/app/tests/test_main.py b/app/tests/test_main.py index 80bd553..dd8a30e 100644 --- a/app/tests/test_main.py +++ b/app/tests/test_main.py @@ -2,7 +2,7 @@ from fastapi.testclient import TestClient from main import application, run -from core.config import settings +from app.core.config import settings client = TestClient(application) diff --git a/app/tests/test_utils.py b/app/tests/test_utils.py index 3a173f5..9058d7d 100644 --- a/app/tests/test_utils.py +++ b/app/tests/test_utils.py @@ -1,4 +1,4 @@ -from utils import camel_case_to_snake_case +from app.utils import camel_case_to_snake_case def test_camel_case_to_snake_case(): diff --git a/app/views/views.py b/app/views/views.py index f196124..6703444 100644 --- a/app/views/views.py +++ b/app/views/views.py @@ -4,9 +4,9 @@ from sqlalchemy.orm import selectinload from sqlalchemy.ext.asyncio import AsyncSession -from api.api_v1.fastapi_users import current_active_user_bearer -from core.models import db_helper, Recipe, User -from utils.templates import templates +from app.api.api_v1.fastapi_users import current_active_user_bearer +from app.core.models import db_helper, Recipe, User +from app.utils.templates import templates router = APIRouter(tags=["Views"]) diff --git a/docker/Dockerfile b/docker/Dockerfile index e7dfd80..3573e1d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,15 +2,20 @@ FROM python:3.12.10 WORKDIR /app -COPY ../requirements.txt requirements.txt -RUN pip3 install --upgrade setuptools -RUN pip3 install --no-cache-dir -r requirements.txt -COPY .. . -RUN chmod 755 . +RUN pip3 install --no-cache-dir poetry + +COPY pyproject.toml poetry.lock ./ + +RUN poetry config virtualenvs.create false && \ + poetry install --no-interaction --no-ansi --no-root + +COPY app ./app + +RUN mkdir -p /app/static /app/static/uploads COPY docker/wait-for-it.sh /app/wait-for-it.sh RUN chmod +x /app/wait-for-it.sh ENV PYTHONPATH=/app -CMD ["python", "app/main.py"] \ No newline at end of file +CMD ["uvicorn", "app.main:application", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c099874..06463a7 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -7,11 +7,11 @@ x-common: &common env_file: - ../app/.env environment: - - PYTHONPATH=/app/app + - PYTHONPATH=/app volumes: - - ../app:/app/app - - ../static:/app/static - - ../uploads:/app/static/uploads + - ../app:/app/app:delegated + - ../static:/app/static:delegated + - ../uploads:/app/static/uploads:delegated working_dir: /app services: @@ -29,7 +29,8 @@ services: <<: *common ports: - "8000:8000" - command: ["./wait-for-it.sh", "postgres:5432", "--", "uvicorn", "app.main:application", "--host", "0.0.0.0", "--port", "8000"] + command: ["./wait-for-it.sh", "postgres:5432", "--", + "uvicorn", "app.main:application", "--host", "0.0.0.0", "--port", "8000"] alembic: <<: *common diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 225f0c7..0000000 --- a/requirements.txt +++ /dev/null @@ -1,55 +0,0 @@ -alembic==1.16.4 ; python_version == "3.12" -annotated-types==0.7.0 ; python_version == "3.12" -anyio==4.10.0 ; python_version == "3.12" -argon2-cffi-bindings==25.1.0 ; python_version == "3.12" -argon2-cffi==23.1.0 ; python_version == "3.12" -asyncpg==0.30.0 ; python_version == "3.12" -bcrypt==4.3.0 ; python_version == "3.12" -certifi==2025.8.3 ; python_version == "3.12" -cffi==2.0.0b1 ; python_version == "3.12" -click==8.2.1 ; python_version == "3.12" -colorama==0.4.6 ; python_version == "3.12" and (sys_platform == "win32" or platform_system == "Windows") -cryptography==45.0.6 ; python_version == "3.12" -dnspython==2.7.0 ; python_version == "3.12" -email-validator==2.2.0 ; python_version == "3.12" -fastapi-users-db-sqlalchemy==7.0.0 ; python_version == "3.12" -fastapi-users==14.0.1 ; python_version == "3.12" -fastapi-users[sqlalchemy]==14.0.1 ; python_version == "3.12" -fastapi==0.116.1 ; python_version == "3.12" -flake8==7.3.0 ; python_version == "3.12" -greenlet==3.2.4 ; python_version == "3.12" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32") -h11==0.16.0 ; python_version == "3.12" -httpcore==1.0.9 ; python_version == "3.12" -httpx==0.28.1 ; python_version == "3.12" -idna==3.10 ; python_version == "3.12" -iniconfig==2.1.0 ; python_version == "3.12" -jinja2==3.1.6 ; python_version == "3.12" -makefun==1.16.0 ; python_version == "3.12" -mako==1.3.10 ; python_version == "3.12" -markupsafe==3.0.2 ; python_version == "3.12" -mccabe==0.7.0 ; python_version == "3.12" -orjson==3.11.3 ; python_version == "3.12" -packaging==25.0 ; python_version == "3.12" -passlib==1.7.4 ; python_version == "3.12" -pluggy==1.6.0 ; python_version == "3.12" -pwdlib[argon2,bcrypt]==0.2.1 ; python_version == "3.12" -pycodestyle==2.14.0 ; python_version == "3.12" -pycparser==2.22 ; implementation_name != "PyPy" and python_version == "3.12" -pydantic-core==2.33.2 ; python_version == "3.12" -pydantic-settings==2.10.1 ; python_version == "3.12" -pydantic==2.11.7 ; python_version == "3.12" -pydantic[email]==2.11.7 ; python_version == "3.12" -pyflakes==3.4.0 ; python_version == "3.12" -pygments==2.19.2 ; python_version == "3.12" -pyjwt[crypto]==2.10.1 ; python_version == "3.12" -pytest-asyncio==1.1.0 ; python_version == "3.12" -pytest==8.4.1 ; python_version == "3.12" -python-dotenv==1.1.1 ; python_version == "3.12" -python-multipart==0.0.20 ; python_version == "3.12" -sniffio==1.3.1 ; python_version == "3.12" -sqlalchemy==2.0.43 ; python_version == "3.12" -sqlalchemy[asyncio]==2.0.43 ; python_version == "3.12" -starlette==0.47.3 ; python_version == "3.12" -typing-extensions==4.14.1 ; python_version == "3.12" -typing-inspection==0.4.1 ; python_version == "3.12" -uvicorn[standart]==0.35.0 ; python_version == "3.12"