Git Product home page Git Product logo

rafsaf / minimal-fastapi-postgres-template Goto Github PK

View Code? Open in Web Editor NEW
395.0 4.0 47.0 1.21 MB

minimal-fastapi-postgres-template based on official template but rewritten

Home Page: https://minimal-fastapi-postgres-template.rafsaf.pl

License: MIT License

Dockerfile 1.97% Python 97.00% Shell 0.10% Mako 0.93%
asyncio fastapi postgresql python sqlalchemy fastapi-template template boilerplate fastapi-boilerplate postgres

minimal-fastapi-postgres-template's Introduction

Live example License Python 3.12 Ruff Tests

Check out online example: https://minimal-fastapi-postgres-template.rafsaf.pl, it's 100% code used in template (docker image) with added my domain and https only.

Minimal async FastAPI + PostgreSQL template

Features

  • Template repository
  • SQLAlchemy 2.0, async queries, best possible autocompletion support
  • PostgreSQL 16 database under asyncpg, docker-compose.yml
  • Full Alembic migrations setup
  • Refresh token endpoint (not only access like in official template)
  • Ready to go Dockerfile with uvicorn webserver as an example
  • Poetry, mypy, pre-commit hooks with ruff
  • Perfect pytest asynchronous test setup with +40 tests and full coverage

template-fastapi-minimal-openapi-example

Quickstart

1. Create repository from a template

See docs.

2. Install dependecies with Poetry

cd your_project_name

### Poetry install (python3.12)
poetry install

Note, be sure to use python3.12 with this template with either poetry or standard venv & pip, if you need to stick to some earlier python version, you should adapt it yourself (remove new versions specific syntax for example str | int for python < 3.10)

3. Setup database and migrations

### Setup database
docker-compose up -d

### Run Alembic migrations
alembic upgrade head

4. Now you can run app

### And this is it:
uvicorn app.main:app --reload

You should then use git init (if needed) to initialize git repository and access OpenAPI spec at http://localhost:8000/ by default. To customize docs url, cors and allowed hosts settings, read section about it.

5. Activate pre-commit

pre-commit is de facto standard now for pre push activities like isort or black or its nowadays replacement ruff.

Refer to .pre-commit-config.yaml file to see my current opinionated choices.

# Install pre-commit
pre-commit install --install-hooks

# Run on all files
pre-commit run --all-files

6. Running tests

Note, it will create databases for session and run tests in many processes by default (using pytest-xdist) to speed up execution, based on how many CPU are available in environment.

For more details about initial database setup, see logic app/tests/conftest.py file, fixture_setup_new_test_database function.

Moreover, there is coverage pytest plugin with required code coverage level 100%.

# see all pytest configuration flags in pyproject.toml
pytest

About

This project is heavily based on the official template https://github.com/tiangolo/full-stack-fastapi-postgresql (and on my previous work: link1, link2), but as it now not too much up-to-date, it is much easier to create new one than change official. I didn't like some of conventions over there also (crud and db folders for example or schemas with bunch of files). This template aims to be as much up-to-date as possible, using only newest python versions and libraries versions.

2.0 style SQLAlchemy API is good enough so there is no need to write everything in crud and waste our time... The core folder was also rewritten. There is great base for writting tests in tests, but I didn't want to write hundreds of them, I noticed that usually after changes in the structure of the project, auto tests are useless and you have to write them from scratch anyway (delete old ones...), hence less than more. Similarly with the User model, it is very modest, with just id (uuid), email and password_hash, because it will be adapted to the project anyway.

2024 update:

The template was adpoted to my current style and knowledge, the test based expanded to cover more, added mypy, ruff and test setup was completly rewritten to have three things:

  • run test in paraller in many processes for speed
  • transactions rollback after every test
  • create test databases instead of having another in docker-compose.yml

Step by step example - POST and GET endpoints

I always enjoy to have some kind of an example in templates (even if I don't like it much, some parts may be useful and save my time...), so let's create two example endpoints:

  • POST endpoint /pets/create for creating Pets with relation to currently logged User
  • GET endpoint /pets/me for fetching all user's pets.

1. Create SQLAlchemy model

We will add Pet model to app/models.py.

# app/models.py

(...)

class Pet(Base):
    __tablename__ = "pet"

    id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    user_id: Mapped[str] = mapped_column(
        ForeignKey("user_account.user_id", ondelete="CASCADE"),
    )
    pet_name: Mapped[str] = mapped_column(String(50), nullable=False)

Note, we are using super powerful SQLAlchemy feature here - Mapped and mapped_column were first introduced in SQLAlchemy 2.0, if this syntax is new for you, read carefully "what's new" part of documentation https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html.


2. Create and apply alembic migration

### Use below commands in root folder in virtualenv ###

# if you see FAILED: Target database is not up to date.
# first use alembic upgrade head

# Create migration with alembic revision
alembic revision --autogenerate -m "create_pet_model"


# File similar to "2022050949_create_pet_model_44b7b689ea5f.py" should appear in `/alembic/versions` folder


# Apply migration using alembic upgrade
alembic upgrade head

# (...)
# INFO  [alembic.runtime.migration] Running upgrade d1252175c146 -> 44b7b689ea5f, create_pet_model

PS. Note, alembic is configured in a way that it work with async setup and also detects specific column changes if using --autogenerate flag.


3. Create request and response schemas

There are only 2 files: requests.py and responses.py in schemas folder and I would keep it that way even for few dozen of endpoints. Not to mention this is opinionated.

# app/schemas/requests.py

(...)


class PetCreateRequest(BaseRequest):
    pet_name: str
# app/schemas/responses.py

(...)


class PetResponse(BaseResponse):
    id: int
    pet_name: str
    user_id: str

4. Create endpoints

# app/api/endpoints/pets.py

from fastapi import APIRouter, Depends, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api import deps
from app.models import Pet, User
from app.schemas.requests import PetCreateRequest
from app.schemas.responses import PetResponse

router = APIRouter()


@router.post(
    "/create",
    response_model=PetResponse,
    status_code=status.HTTP_201_CREATED,
    description="Creates new pet. Only for logged users.",
)
async def create_new_pet(
    data: PetCreateRequest,
    session: AsyncSession = Depends(deps.get_session),
    current_user: User = Depends(deps.get_current_user),
) -> Pet:
    new_pet = Pet(user_id=current_user.user_id, pet_name=data.pet_name)

    session.add(new_pet)
    await session.commit()

    return new_pet


@router.get(
    "/me",
    response_model=list[PetResponse],
    status_code=status.HTTP_200_OK,
    description="Get list of pets for currently logged user.",
)
async def get_all_my_pets(
    session: AsyncSession = Depends(deps.get_session),
    current_user: User = Depends(deps.get_current_user),
) -> list[Pet]:
    pets = await session.scalars(
        select(Pet).where(Pet.user_id == current_user.user_id).order_by(Pet.pet_name)
    )

    return list(pets.all())

Also, we need to add newly created endpoints to router.

# app/api/api.py

(...)

from app.api.endpoints import auth, pets, users

(...)

api_router.include_router(pets.router, prefix="/pets", tags=["pets"])

5. Write tests

We will write two really simple tests in combined file inside newly created app/tests/test_pets folder.

# app/tests/test_pets/test_pets.py

from fastapi import status
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession

from app.main import app
from app.models import Pet, User


async def test_create_new_pet(
    client: AsyncClient, default_user_headers: dict[str, str], default_user: User
) -> None:
    response = await client.post(
        app.url_path_for("create_new_pet"),
        headers=default_user_headers,
        json={"pet_name": "Tadeusz"},
    )
    assert response.status_code == status.HTTP_201_CREATED

    result = response.json()
    assert result["user_id"] == default_user.user_id
    assert result["pet_name"] == "Tadeusz"


async def test_get_all_my_pets(
    client: AsyncClient,
    default_user_headers: dict[str, str],
    default_user: User,
    session: AsyncSession,
) -> None:
    pet1 = Pet(user_id=default_user.user_id, pet_name="Pet_1")
    pet2 = Pet(user_id=default_user.user_id, pet_name="Pet_2")

    session.add(pet1)
    session.add(pet2)
    await session.commit()

    response = await client.get(
        app.url_path_for("get_all_my_pets"),
        headers=default_user_headers,
    )
    assert response.status_code == status.HTTP_200_OK

    assert response.json() == [
        {
            "user_id": pet1.user_id,
            "pet_name": pet1.pet_name,
            "id": pet1.id,
        },
        {
            "user_id": pet2.user_id,
            "pet_name": pet2.pet_name,
            "id": pet2.id,
        },
    ]

Design

Deployment strategies - via Docker image

This template has by default included Dockerfile with Uvicorn webserver, because it's simple and just for showcase purposes, with direct relation to FastAPI and great ease of configuration. You should be able to run container(s) (over :8000 port) and then need to setup the proxy, loadbalancer, with https enbaled, so the app stays behind it.

If you prefer other webservers for FastAPI, check out Nginx Unit, Daphne, Hypercorn.

Docs URL, CORS and Allowed Hosts

There are some opinionated default settings in /app/main.py for documentation, CORS and allowed hosts.

  1. Docs

    app = FastAPI(
        title="minimal fastapi postgres template",
        version="6.0.0",
        description="https://github.com/rafsaf/minimal-fastapi-postgres-template",
        openapi_url="/openapi.json",
        docs_url="/",
    )

    Docs page is simpy / (by default in FastAPI it is /docs). You can change it completely for the project, just as title, version, etc.

  2. CORS

    app.add_middleware(
        CORSMiddleware,
        allow_origins=[str(origin) for origin in config.settings.BACKEND_CORS_ORIGINS],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    If you are not sure what are CORS for, follow https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS. React and most frontend frameworks nowadays operate on http://localhost:3000 thats why it's included in BACKEND_CORS_ORIGINS in .env file, before going production be sure to include your frontend domain here, like https://my-fontend-app.example.com.

  3. Allowed Hosts

    app.add_middleware(TrustedHostMiddleware, allowed_hosts=config.settings.ALLOWED_HOSTS)

    Prevents HTTP Host Headers attack, you shoud put here you server IP or (preferably) full domain under it's accessible like example.com. By default in .env there are two most popular records: ALLOWED_HOSTS=["localhost", "127.0.0.1"]

License

The code is under MIT License. It's here for educational purposes, created mainly to have a place where up-to-date Python and FastAPI software lives. Do whatever you want with this code.

minimal-fastapi-postgres-template's People

Contributors

dependabot[bot] avatar jashwant avatar mrtrick avatar rafsaf avatar rosstitmarsh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

minimal-fastapi-postgres-template's Issues

MariaDB support

I got feedback that support for MariaDB would be nice to have, I'm a little PostgreSQL biased, but MariaDB is awesome too.

  • #38 first
  • new option choice in cookiecutter for db
  • some jinja ifs in docker-compose files and for sqlalchemy engine code
  • maybe some other things will show up, not sure db session changes or if alembic configuration would survive it

Pytest options in pyproject.toml

@rafsaf hello !
Could you please explain what does the following keys means ?

[tool.pytest.ini_options]
addopts = "-vv -n auto --cov --cov-report xml --cov-report term-missing --cov-fail-under=100"

From my understanding, -n auto sets number of workers to auto(based on CPU), and --cov --cov-report xml --cov-report term-missing --cov-fail-under=100 we're using for coverage information, but what about -vv ?

`ValueError: invalid literal for int() with base 10: '5432:5432'`

I'm trying to run the example in ECS to help someone understand an ECS based deployment.

I have set the following env vars:

"environment": [
                    {
                        "name": "DEFAULT_SQLALCHEMY_DATABASE_URI",
                        "value": db_uri
                    },
                    {
                        "name": "DEFAULT_DATABASE_DB",
                        "value": database.db_name,
                    },
                    {
                        "name": "DEFAULT_DATABASE_HOSTNAME",
                        "value": database.endpoint,
                    },
                    {
                        "name": "DEFAULT_DATABASE_USER",
                        "value": database.username,
                    },
                    {
                        "name": "DEFAULT_DATABASE_PASSWORD",
                        "value": database.password,
                    },
                    {
                        "name": "DEFAULT_DATABASE_PORT",
                        "value": "5432",
                    },
                    {
                        "name": "FIRST_SUPERUSER_EMAIL",
                        "value": "[email protected]",
                    },
                    {
                        "name": "FIRST_SUPERUSER_PASSWORD",
                        "value": "correct-horse-battery-stable",
                    },
                    {
                        "name": "SECRET_KEY",
                        "value": "super-secret",
                    }
                ],

Unfortunately, no matter what I seem to do, the port doesn't seem to be set correctly:

ValueError: invalid literal for int() with base 10: '5432:5432'

Fix for running docker-compose.dev.yml

In the file:
minimal-fastapi-postgres-template/{{cookiecutter.project_name}}/template_minimal/docker-compose.dev.yml
row 5 instruction is slightly off:

- # docker-compose up -f docker-compose.dev.yml -d
+ # docker-compose -f docker-compose.dev.yml up -d

I got the answer from here:
docker-archive/toolbox#721

I couldn't make a PR, so I hope this will do :)

unsupported operand type(s) for |: type and type

$ bash init.sh 
Run migrations
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
Create initial data in DB
Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/laptop/playground/backend/api/app/initial_data.py", line 12, in <module>
    from app.core import config, security
  File "/home/laptop/playground/backend/api/app/core/security.py", line 55, in <module>
    def generate_access_token_response(subject: str | int):
TypeError: unsupported operand type(s) for |: 'type' and 'type'

The following line throws an error during executing bash init.sh

class JWTTokenPayload(BaseModel):
    sub: str | int #-----> This line
    refresh: bool
    issued_at: int
    expires_at: int

I fixed it by using sub: str and modifying the other related methods.

What's wrong with sub: str | int ?

Where to deploy?

Hi - Where should I deploy this? Where is your example project being deployed? Are there any instructions?

Thanks

Request: Get List of items.

With this as an example, how would you return a list of items?

`@router.get("/", response_model=List[schemas.Cat])
async def read_cat(
cat: schemas.Cat,
session: AsyncSession = Depends(deps.get_session),
current_user: models.User = Depends(deps.get_current_user),
) -> List:
"""
Get cats.
"""

return cat`

How to show the docs in browser?

Hello

I'm running the backend locally directly using

uvicorn app.main:app --reload

with the output

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [84691] using statreload
INFO: Started server process [84702]
INFO: Waiting for application startup.
INFO: Application startup complete.

How can I see the specification in the browser?

`experimental_fastapi_users_template` has incomplete dependencies

Hi
For experimental_fastapi_users_template:

  • pyproject.toml doesn't include fastapi_users package. It's only available in requirements.txt.

  • Also, when I first installed the latest fastapi_users version, the code doesn't run because of api changes. BaseUser class and similar are not in fastapi_users.models but in fastapi_users.schemas now. Unfortunately I don't know how to fix missing BaseUserDB class.

  • Another thing is that I needed to install greenlet for the repo to work on my M1 mac.

I know it's experimental but after comparing all the available templates I like this one the most so wanted to share.

Duplicate refresh-token endpoint in minimal example

Method refresh_token2 in /template_minimal/app/api/endpoints/auth.py is overwriting the endpoint /refresh-token in /docs and the response_model schemas.UserCreate is incorrect.

Looks like a typo. I submitted a pull request to remove it.

@router.post("/refresh-token", response_model=schemas.Token)
async def refresh_token(
    input: schemas.TokenRefresh, session: AsyncSession = Depends(deps.get_session)
):
    """
    OAuth2 compatible token, get an access token for future requests using refresh token
    """
    try:
        payload = jwt.decode(
            input.refresh_token,
            config.settings.SECRET_KEY,
            algorithms=[security.ALGORITHM],
        )
        token_data = schemas.TokenPayload(**payload)
    except (jwt.JWTError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    if not token_data.refresh:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    result = await session.execute(select(User).where(User.id == token_data.sub))
    user: Optional[User] = result.scalars().first()

    if user is None:
        raise HTTPException(status_code=404, detail="User not found")

    access_token, expire_at = security.create_access_token(user.id)
    refresh_token, refresh_expire_at = security.create_refresh_token(user.id)
    return {
        "token_type": "bearer",
        "access_token": access_token,
        "expire_at": expire_at,
        "refresh_token": refresh_token,
        "refresh_expire_at": refresh_expire_at,
    }


@router.post("/refresh-token", response_model=schemas.UserCreate)
async def refresh_token2(
    input: schemas.TokenRefresh, session: AsyncSession = Depends(deps.get_session)
):
    """
    OAuth2 compatible token, get an access token for future requests using refresh token
    """
    try:
        payload = jwt.decode(
            input.refresh_token,
            config.settings.SECRET_KEY,
            algorithms=[security.ALGORITHM],
        )
        token_data = schemas.TokenPayload(**payload)
    except (jwt.JWTError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    if not token_data.refresh:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    result = await session.execute(select(User).where(User.id == token_data.sub))
    user: Optional[User] = result.scalars().first()

    if user is None:
        raise HTTPException(status_code=404, detail="User not found")

    access_token, expire_at = security.create_access_token(user.id)
    refresh_token, refresh_expire_at = security.create_refresh_token(user.id)
    return {
        "token_type": "bearer",
        "access_token": access_token,
        "expire_at": expire_at,
        "refresh_token": refresh_token,
        "refresh_expire_at": refresh_expire_at,
    }
    

Celery support

Could you embed celery into this project? Would be pretty nice to have a message broker or something in this template.

[Feature Request] Supporting SQLModel

May you please add SQLModel supporting in this template or at least create a branch specifically for it?

We discussed since two days ago about SQLModel. I'm completely with SQLModel against duplicating codes for models (SQLAlchemy) and schemas (Pydantic) because IMHO duplicating code is kind of insanity. When I read about SQLModel for the first time I was really impressed (and I'm still) while you have some concerns about which are absolutely correct but may I think ignoring SQLModel completely is not fair for this fantastic package specially when you compare the neat syntax with the weird SQLAlchemy one.

In case you refused my request. I encourage you to add some wiki page or an example (2nd version of Pet ex.) in README.md shows how to use this template with SQLModel.

docker run failed

great template!

docker run -d -p 8000:8000 .. yields the error message below

INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started parent process [8]
Process SpawnProcess-1:
Process SpawnProcess-2:
Traceback (most recent call last):
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/venv/lib/python3.12/site-packages/uvicorn/_subprocess.py", line 78, in subprocess_started
    target(sockets=sockets)
  File "/venv/lib/python3.12/site-packages/uvicorn/server.py", line 62, in run
    return asyncio.run(self.serve(sockets=sockets))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
  File "/venv/lib/python3.12/site-packages/uvicorn/server.py", line 69, in serve
    config.load()
  File "/venv/lib/python3.12/site-packages/uvicorn/config.py", line 433, in load
    self.loaded_app = import_from_string(self.app)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.12/site-packages/uvicorn/importer.py", line 19, in import_from_string
    module = importlib.import_module(module_str)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/build/app/main.py", line 5, in <module>
    from app.api.api_router import api_router, auth_router
  File "/build/app/api/api_router.py", line 4, in <module>
    from app.api.endpoints import auth, users, patient_status
  File "/build/app/api/endpoints/auth.py", line 11, in <module>
    from app.api import api_messages, deps
  File "/build/app/api/deps.py", line 10, in <module>
    from app.core import database_session
  File "/build/app/core/database_session.py", line 31, in <module>
    _ASYNC_ENGINE = new_async_engine(get_settings().sqlalchemy_database_uri)
                                     ^^^^^^^^^^^^^^
  File "/build/app/core/config.py", line 70, in get_settings
    return Settings()  # type: ignore
           ^^^^^^^^^^
  File "/venv/lib/python3.12/site-packages/pydantic_settings/main.py", line 84, in __init__
    super().__init__(
  File "/venv/lib/python3.12/site-packages/pydantic/main.py", line 171, in __init__
    self.__pydantic_validator__.validate_python(data, self_instance=self)
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/usr/local/lib/python3.12/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
pydantic_core._pydantic_core.ValidationError: 2 validation errors for Settings
security
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/missing
database
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/missing
  File "/venv/lib/python3.12/site-packages/uvicorn/_subprocess.py", line 78, in subprocess_started
    target(sockets=sockets)
  File "/venv/lib/python3.12/site-packages/uvicorn/server.py", line 62, in run
    return asyncio.run(self.serve(sockets=sockets))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
  File "/venv/lib/python3.12/site-packages/uvicorn/server.py", line 69, in serve
    config.load()
  File "/venv/lib/python3.12/site-packages/uvicorn/config.py", line 433, in load
    self.loaded_app = import_from_string(self.app)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venv/lib/python3.12/site-packages/uvicorn/importer.py", line 19, in import_from_string
    module = importlib.import_module(module_str)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/build/app/main.py", line 5, in <module>
    from app.api.api_router import api_router, auth_router
  File "/build/app/api/api_router.py", line 4, in <module>
    from app.api.endpoints import auth, users, patient_status
  File "/build/app/api/endpoints/auth.py", line 11, in <module>
    from app.api import api_messages, deps
  File "/build/app/api/deps.py", line 10, in <module>
    from app.core import database_session
  File "/build/app/core/database_session.py", line 31, in <module>
    _ASYNC_ENGINE = new_async_engine(get_settings().sqlalchemy_database_uri)
                                     ^^^^^^^^^^^^^^
  File "/build/app/core/config.py", line 70, in get_settings
    return Settings()  # type: ignore
           ^^^^^^^^^^
  File "/venv/lib/python3.12/site-packages/pydantic_settings/main.py", line 84, in __init__
    super().__init__(
  File "/venv/lib/python3.12/site-packages/pydantic/main.py", line 171, in __init__
    self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 2 validation errors for Settings
security
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/missing
database
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/missing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.