diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 68ca285..533f264 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -34,7 +34,7 @@ jobs: ports: - 6379:6379 sqldb: - image: postgres:17 + image: postgres:18.6 env: POSTGRES_USER: panettone POSTGRES_PASSWORD: secret diff --git a/Makefile b/Makefile index e738138..f214840 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,11 @@ docker-create-db-migration: ## Create a new alembic database migration. Example # ==================================================================================== # TESTING # ==================================================================================== +.PHONY: test +test: ## Run project tests locally with Compose dependencies + docker compose -f compose.yml up -d --wait postgres redis + POSTGRES_HOST=127.0.0.1 REDIS_HOST=127.0.0.1 uv run --frozen pytest tests --durations=0 -vv + .PHONY: docker-test docker-test: ## Run project tests docker compose -f compose.yml run --rm api1 pytest tests --durations=0 -vv diff --git a/README.md b/README.md index 94e8864..a321257 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,9 @@ ## About The Project -This demonstration application showcases the powerful integration of [FastAPI](https://fastapi.tiangolo.com/)—a modern, high-performance web framework—with [Pydantic 2.0](https://github.com/pydantic/pydantic) for robust data validation. The backend architecture is further reinforced by leveraging the [SQLAlchemy ORM](https://www.sqlalchemy.org/) along with an asynchronous connection to a [PostgreSQL 17](https://www.postgresql.org/docs/17/release.html) relational database. High-throughput communication across the stack is achieved using the [asyncpg](https://github.com/MagicStack/asyncpg) database client library, delivering an efficient, non-blocking interface to process database transactions seamlessly within Python's asyncio event loop. +This demonstration application showcases the powerful integration of [FastAPI](https://fastapi.tiangolo.com/)—a modern, high-performance web framework—with [Pydantic 2.0](https://github.com/pydantic/pydantic) for robust data validation. The backend architecture is further reinforced by leveraging the [SQLAlchemy ORM](https://www.sqlalchemy.org/) along with an asynchronous connection to a [PostgreSQL 18](https://www.postgresql.org/docs/18/release.html) relational database. High-throughput communication across the stack is achieved using the [asyncpg](https://github.com/MagicStack/asyncpg) database client library, delivering an efficient, non-blocking interface to process database transactions seamlessly within Python's asyncio event loop. + +PostgreSQL 18 uses `/var/lib/postgresql` for its persistent data volume. Existing PostgreSQL 17 data must be migrated with `pg_upgrade` or a dump and restore before using the updated Compose configurations. ### Built With [![FastAPI][fastapi.tiangolo.com]][fastapi-url] @@ -232,10 +234,11 @@ generator yielding text chunks, plus `aclose()`) in a new class - e.g. wrapping return it from `build_chat_agent` for a new `backend` value. No changes are needed in `app/api/chat.py` or the session manager. -Run the tests for this service locally with: +Run the full test suite locally with: ```shell -pytest tests/api/test_chat_ws.py -vv +make test ``` +This starts PostgreSQL and Redis with Docker Compose, then points host-side tests at their published localhost ports.
@@ -377,27 +380,27 @@ I've included a few of my favorites to kick things off! [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 [linkedin-url]: https://www.linkedin.com/in/ordinary-hobbit/ -[fastapi.tiangolo.com]: https://img.shields.io/badge/FastAPI-0.124.4-009485?style=for-the-badge&logo=fastapi&logoColor=white +[fastapi.tiangolo.com]: https://img.shields.io/badge/FastAPI-0.159.1-009485?style=for-the-badge&logo=fastapi&logoColor=white [fastapi-url]: https://fastapi.tiangolo.com/ -[pydantic.com]: https://img.shields.io/badge/Pydantic-2.12.5-e92063?style=for-the-badge&logo=pydantic&logoColor=white +[pydantic.com]: https://img.shields.io/badge/Pydantic-2.14.1-e92063?style=for-the-badge&logo=pydantic&logoColor=white [pydantic-url]: https://docs.pydantic.dev/latest/ -[sqlalchemy.org]: https://img.shields.io/badge/SQLAlchemy-2.0.45-bb0000?color=bb0000&style=for-the-badge&logo=python&logoColor=white +[sqlalchemy.org]: https://img.shields.io/badge/SQLAlchemy-2.1.6-bb0000?color=bb0000&style=for-the-badge&logo=python&logoColor=white [sqlalchemy-url]: https://docs.sqlalchemy.org/en/20/ -[uvicorn.org]: https://img.shields.io/badge/Uvicorn-0.38.0-2094f3?style=for-the-badge&logo=python&logoColor=white +[uvicorn.org]: https://img.shields.io/badge/Uvicorn-0.54.0-2094f3?style=for-the-badge&logo=python&logoColor=white [uvicorn-url]: https://www.uvicorn.org/ -[asyncpg.github.io]: https://img.shields.io/badge/asyncpg-0.31.0-2e6fce?style=for-the-badge&logo=postgresql&logoColor=white +[asyncpg.github.io]: https://img.shields.io/badge/asyncpg-0.32.0-2e6fce?style=for-the-badge&logo=postgresql&logoColor=white [asyncpg-url]: https://magicstack.github.io/asyncpg/current/ -[pytest.org]: https://img.shields.io/badge/pytest-9.0.2-fff?style=for-the-badge&logo=pytest&logoColor=white +[pytest.org]: https://img.shields.io/badge/pytest-9.1.1-fff?style=for-the-badge&logo=pytest&logoColor=white [pytest-url]: https://docs.pytest.org/en/9.0.x/ -[alembic.sqlalchemy.org]: https://img.shields.io/badge/alembic-1.17.2-6BA81E?style=for-the-badge&logo=python&logoColor=white +[alembic.sqlalchemy.org]: https://img.shields.io/badge/alembic-1.20.1-6BA81E?style=for-the-badge&logo=python&logoColor=white [alembic-url]: https://alembic.sqlalchemy.org/en/latest/ -[rich.readthedocs.io]: https://img.shields.io/badge/rich-14.2.0-009485?style=for-the-badge&logo=rich&logoColor=white +[rich.readthedocs.io]: https://img.shields.io/badge/rich-15.0.0-009485?style=for-the-badge&logo=rich&logoColor=white [rich-url]: https://rich.readthedocs.io/en/latest/ -[redis.io]: https://img.shields.io/badge/redis-7.1.0-dc382d?style=for-the-badge&logo=redis&logoColor=white +[redis.io]: https://img.shields.io/badge/redis-8.1.0-dc382d?style=for-the-badge&logo=redis&logoColor=white [redis-url]: https://redis.io/ -[structlog.org]: https://img.shields.io/badge/structlog-25.5.0-000000?style=for-the-badge&logo=python&logoColor=white +[structlog.org]: https://img.shields.io/badge/structlog-26.1.0-000000?style=for-the-badge&logo=python&logoColor=white [structlog-url]: https://www.structlog.org/en/stable/ [rotoger]: https://img.shields.io/badge/rotoger-0.3.0-00bfff?style=for-the-badge&logo=python&logoColor=white [rotoger-url]: https://github.com/tinyplugins/rotoger -[granian]: https://img.shields.io/badge/granian-2.6.0-4f6cb4?style=for-the-badge&logo=rust&logoColor=white +[granian]: https://img.shields.io/badge/granian-2.8.5-4f6cb4?style=for-the-badge&logo=rust&logoColor=white [granian-url]: https://github.com/emmett-framework/granian diff --git a/compose-ha.yml b/compose-ha.yml index 36a2a78..25946a3 100644 --- a/compose-ha.yml +++ b/compose-ha.yml @@ -54,7 +54,7 @@ services: context: ./db dockerfile: Dockerfile volumes: - - panettone_postgres_data:/var/lib/postgresql/data + - panettone_postgres_data:/var/lib/postgresql - ./db/create.sql:/docker-entrypoint-initdb.d/create.sql env_file: - .env diff --git a/compose.yml b/compose.yml index 9e5c5cb..885ddf4 100644 --- a/compose.yml +++ b/compose.yml @@ -31,7 +31,7 @@ services: context: ./db dockerfile: Dockerfile volumes: - - panettone_postgres_data:/var/lib/postgresql/data + - panettone_postgres_data:/var/lib/postgresql - ./db/create.sql:/docker-entrypoint-initdb.d/create.sql env_file: - .env diff --git a/db/Dockerfile b/db/Dockerfile index 7b2ae09..24544cf 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -1,5 +1,5 @@ # pull official base image -FROM postgres:17.7-alpine +FROM postgres:18.6-alpine WORKDIR /home/gx/code diff --git a/granian-compose.yml b/granian-compose.yml index 9e71292..1e08a0e 100644 --- a/granian-compose.yml +++ b/granian-compose.yml @@ -30,7 +30,7 @@ services: context: ./db dockerfile: Dockerfile volumes: - - fastapi_postgres_data:/var/lib/postgresql/data + - fastapi_postgres_data:/var/lib/postgresql - ./db/create.sql:/docker-entrypoint-initdb.d/create.sql env_file: - .env diff --git a/valkey-compose.yml b/valkey-compose.yml index 0ee4f6b..f67030f 100644 --- a/valkey-compose.yml +++ b/valkey-compose.yml @@ -24,7 +24,7 @@ services: context: ./db dockerfile: Dockerfile volumes: - - fastapi_postgres_data:/var/lib/postgresql/data + - fastapi_postgres_data:/var/lib/postgresql env_file: - .env ports: