diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..66a27f6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: CI + +on: + push: + pull_request: + +jobs: + build-fastapi: + name: FastAPI CI + + runs-on: ubuntu-latest + + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + ACCESS_SECRET_KEY: ${{ secrets.ACCESS_SECRET_KEY }} + RESET_PASSWORD_SECRET_KEY: ${{ secrets.RESET_PASSWORD_SECRET_KEY }} + VERIFICATION_SECRET_KEY: ${{ secrets.VERIFICATION_SECRET_KEY }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Poetry with pip + run: pip install poetry + + - name: Configure Poetry + working-directory: ./fastapi_backend + run: poetry config virtualenvs.create false + + - name: Install dependencies + working-directory: ./fastapi_backend + run: poetry install + + - name: Run tests + working-directory: ./fastapi_backend + run: poetry run pytest \ No newline at end of file diff --git a/.pre-commit-config.docker.yaml b/.pre-commit-config.docker.yaml index c41b695..a849060 100644 --- a/.pre-commit-config.docker.yaml +++ b/.pre-commit-config.docker.yaml @@ -31,7 +31,7 @@ repos: hooks: - id: generate-openapi-schema name: generate OpenAPI schema - entry: sh -c 'docker compose run --rm --no-deps -T backend poetry run python -m commands.generate_openapi_schema' + entry: sh -c 'docker compose run --rm --no-deps -T backend poetry run python -m app.commands.generate_openapi_schema' language: system pass_filenames: false - id: generate-frontend-client diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 38af71a..ce6a4f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: hooks: - id: generate-openapi-schema name: generate OpenAPI schema - entry: sh -c 'cd fastapi_backend && poetry run python -m commands.generate_openapi_schema' + entry: sh -c 'cd fastapi_backend && poetry run python -m app.commands.generate_openapi_schema' language: system pass_filenames: false - id: generate-frontend-client diff --git a/fastapi_backend/__init__.py b/fastapi_backend/app/__init__.py similarity index 100% rename from fastapi_backend/__init__.py rename to fastapi_backend/app/__init__.py diff --git a/fastapi_backend/alembic.ini b/fastapi_backend/app/alembic.ini similarity index 100% rename from fastapi_backend/alembic.ini rename to fastapi_backend/app/alembic.ini diff --git a/fastapi_backend/alembic/README b/fastapi_backend/app/alembic/README similarity index 100% rename from fastapi_backend/alembic/README rename to fastapi_backend/app/alembic/README diff --git a/fastapi_backend/alembic/env.py b/fastapi_backend/app/alembic/env.py similarity index 98% rename from fastapi_backend/alembic/env.py rename to fastapi_backend/app/alembic/env.py index a0cd363..6226792 100644 --- a/fastapi_backend/alembic/env.py +++ b/fastapi_backend/app/alembic/env.py @@ -6,7 +6,7 @@ from sqlalchemy.ext.asyncio import async_engine_from_config from alembic import context -from src.models import Base +from app.src.models import Base # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/fastapi_backend/alembic/script.py.mako b/fastapi_backend/app/alembic/script.py.mako similarity index 100% rename from fastapi_backend/alembic/script.py.mako rename to fastapi_backend/app/alembic/script.py.mako diff --git a/fastapi_backend/alembic/versions/402d067a8b92_added_user_table.py b/fastapi_backend/app/alembic/versions/402d067a8b92_added_user_table.py similarity index 100% rename from fastapi_backend/alembic/versions/402d067a8b92_added_user_table.py rename to fastapi_backend/app/alembic/versions/402d067a8b92_added_user_table.py diff --git a/fastapi_backend/commands/__init__.py b/fastapi_backend/app/commands/__init__.py similarity index 100% rename from fastapi_backend/commands/__init__.py rename to fastapi_backend/app/commands/__init__.py diff --git a/fastapi_backend/commands/generate_openapi_schema.py b/fastapi_backend/app/commands/generate_openapi_schema.py similarity index 89% rename from fastapi_backend/commands/generate_openapi_schema.py rename to fastapi_backend/app/commands/generate_openapi_schema.py index 70f68c6..3e5b1c8 100644 --- a/fastapi_backend/commands/generate_openapi_schema.py +++ b/fastapi_backend/app/commands/generate_openapi_schema.py @@ -1,6 +1,6 @@ import json from pathlib import Path -from src.main import app +from app.src.main import app import os from dotenv import load_dotenv @@ -14,13 +14,13 @@ def generate_openapi_schema(output_file): schema = app.openapi() output_path = Path(output_file) - updated_schema = _remove_operation_id_tag(schema) + updated_schema = remove_operation_id_tag(schema) output_path.write_text(json.dumps(updated_schema, indent=2)) print(f"OpenAPI schema saved to {output_file}") -def _remove_operation_id_tag(schema): +def remove_operation_id_tag(schema): """ Removes the tag prefix from the operation IDs in the OpenAPI schema. diff --git a/fastapi_backend/src/__init__.py b/fastapi_backend/app/src/__init__.py similarity index 100% rename from fastapi_backend/src/__init__.py rename to fastapi_backend/app/src/__init__.py diff --git a/fastapi_backend/src/config.py b/fastapi_backend/app/src/config.py similarity index 100% rename from fastapi_backend/src/config.py rename to fastapi_backend/app/src/config.py diff --git a/fastapi_backend/src/database.py b/fastapi_backend/app/src/database.py similarity index 100% rename from fastapi_backend/src/database.py rename to fastapi_backend/app/src/database.py diff --git a/fastapi_backend/src/main.py b/fastapi_backend/app/src/main.py similarity index 100% rename from fastapi_backend/src/main.py rename to fastapi_backend/app/src/main.py diff --git a/fastapi_backend/src/models.py b/fastapi_backend/app/src/models.py similarity index 100% rename from fastapi_backend/src/models.py rename to fastapi_backend/app/src/models.py diff --git a/fastapi_backend/src/schemas.py b/fastapi_backend/app/src/schemas.py similarity index 100% rename from fastapi_backend/src/schemas.py rename to fastapi_backend/app/src/schemas.py diff --git a/fastapi_backend/src/users.py b/fastapi_backend/app/src/users.py similarity index 100% rename from fastapi_backend/src/users.py rename to fastapi_backend/app/src/users.py diff --git a/fastapi_backend/src/utils.py b/fastapi_backend/app/src/utils.py similarity index 100% rename from fastapi_backend/src/utils.py rename to fastapi_backend/app/src/utils.py diff --git a/fastapi_backend/tests/__init__.py b/fastapi_backend/app/tests/__init__.py similarity index 100% rename from fastapi_backend/tests/__init__.py rename to fastapi_backend/app/tests/__init__.py diff --git a/fastapi_backend/tests/commands/__init__.py b/fastapi_backend/app/tests/commands/__init__.py similarity index 100% rename from fastapi_backend/tests/commands/__init__.py rename to fastapi_backend/app/tests/commands/__init__.py diff --git a/fastapi_backend/tests/commands/files/openapi_test.json b/fastapi_backend/app/tests/commands/files/openapi_test.json similarity index 100% rename from fastapi_backend/tests/commands/files/openapi_test.json rename to fastapi_backend/app/tests/commands/files/openapi_test.json diff --git a/fastapi_backend/tests/commands/files/openapi_test_output.json b/fastapi_backend/app/tests/commands/files/openapi_test_output.json similarity index 100% rename from fastapi_backend/tests/commands/files/openapi_test_output.json rename to fastapi_backend/app/tests/commands/files/openapi_test_output.json diff --git a/fastapi_backend/tests/commands/test_generate_openapi_schema.py b/fastapi_backend/app/tests/commands/test_generate_openapi_schema.py similarity index 83% rename from fastapi_backend/tests/commands/test_generate_openapi_schema.py rename to fastapi_backend/app/tests/commands/test_generate_openapi_schema.py index 581d87d..cf83f48 100644 --- a/fastapi_backend/tests/commands/test_generate_openapi_schema.py +++ b/fastapi_backend/app/tests/commands/test_generate_openapi_schema.py @@ -3,9 +3,9 @@ import pytest from pathlib import Path -from commands.generate_openapi_schema import ( - _remove_operation_id_tag, +from app.commands.generate_openapi_schema import ( generate_openapi_schema, + remove_operation_id_tag, ) @@ -27,13 +27,13 @@ def expected_output_schema(): def test_remove_operation_id_tag(sample_openapi_schema, expected_output_schema): - cleaned_schema = _remove_operation_id_tag(sample_openapi_schema) + cleaned_schema = remove_operation_id_tag(sample_openapi_schema) assert cleaned_schema == expected_output_schema @pytest.fixture def mock_app(mocker): - app = mocker.patch("commands.generate_openapi_schema.app") + app = mocker.patch("app.commands.generate_openapi_schema.app") app.openapi.return_value = { "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, @@ -44,7 +44,7 @@ def mock_app(mocker): def test_generate_openapi_schema(mocker, mock_app): mock_remove_operation_id_tag = mocker.patch( - "commands.generate_openapi_schema._remove_operation_id_tag" + "app.commands.generate_openapi_schema.remove_operation_id_tag" ) mock_remove_operation_id_tag.return_value = {"mocked_schema": True} diff --git a/fastapi_backend/tests/main/__init__.py b/fastapi_backend/app/tests/main/__init__.py similarity index 100% rename from fastapi_backend/tests/main/__init__.py rename to fastapi_backend/app/tests/main/__init__.py diff --git a/fastapi_backend/tests/main/test_main.py b/fastapi_backend/app/tests/main/test_main.py similarity index 99% rename from fastapi_backend/tests/main/test_main.py rename to fastapi_backend/app/tests/main/test_main.py index 3b58a26..4343a4b 100644 --- a/fastapi_backend/tests/main/test_main.py +++ b/fastapi_backend/app/tests/main/test_main.py @@ -2,7 +2,7 @@ from fastapi import status from fastapi.testclient import TestClient from fastapi_users.router import ErrorCode -from src.main import app +from app.src.main import app class TestPasswordValidation: diff --git a/fastapi_backend/tests/utils/__init__.py b/fastapi_backend/app/tests/utils/__init__.py similarity index 100% rename from fastapi_backend/tests/utils/__init__.py rename to fastapi_backend/app/tests/utils/__init__.py diff --git a/fastapi_backend/tests/utils/test_utils.py b/fastapi_backend/app/tests/utils/test_utils.py similarity index 84% rename from fastapi_backend/tests/utils/test_utils.py rename to fastapi_backend/app/tests/utils/test_utils.py index 6f7f4d8..1546df3 100644 --- a/fastapi_backend/tests/utils/test_utils.py +++ b/fastapi_backend/app/tests/utils/test_utils.py @@ -1,5 +1,5 @@ from fastapi.routing import APIRoute -from src.utils import simple_generate_unique_route_id +from app.src.utils import simple_generate_unique_route_id def test_simple_generate_unique_route_id(mocker): diff --git a/fastapi_backend/watcher.py b/fastapi_backend/app/watcher.py similarity index 99% rename from fastapi_backend/watcher.py rename to fastapi_backend/app/watcher.py index d4b6af8..4eb0954 100644 --- a/fastapi_backend/watcher.py +++ b/fastapi_backend/app/watcher.py @@ -7,7 +7,7 @@ from threading import Timer WATCHER_REGEX_PATTERN = re.compile(r"(main|schemas)\.py$") -APP_PATH = "src" +APP_PATH = "app/src" class MyHandler(FileSystemEventHandler): diff --git a/fastapi_backend/start.sh b/fastapi_backend/start.sh index a439248..93658e2 100755 --- a/fastapi_backend/start.sh +++ b/fastapi_backend/start.sh @@ -2,12 +2,12 @@ if [ -f /.dockerenv ]; then echo "Running in Docker" - fastapi dev src/main.py --host 0.0.0.0 --port 8000 --reload & - python watcher.py + fastapi dev app/src/main.py --host 0.0.0.0 --port 8000 --reload & + python app/watcher.py else echo "Running locally with Poetry" - poetry run fastapi dev src/main.py --host 0.0.0.0 --port 8000 --reload & - poetry run python watcher.py + poetry run fastapi dev app/src/main.py --host 0.0.0.0 --port 8000 --reload & + poetry run python app/watcher.py fi wait \ No newline at end of file