Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ jobs:
PYTHONDEVMODE: 1
- name: Test FastAPI/Blacksheep/Sanic Examples
run: |
PYTHONPATH=$DEST_FASTAPI uv run --frozen pytest $PYTEST_ARGS $DEST_FASTAPI/_tests.py
PYTHONPATH=$DEST_FASTAPI uv run --frozen tortoise -c config.TORTOISE_ORM migrate
PYTHONPATH=$DEST_FASTAPI uv run --frozen pytest $PYTEST_ARGS_SEQ $DEST_FASTAPI/_tests.py
rm -f $DEST_FASTAPI/db.sqlite3
PYTHONPATH=$DEST_BLACKSHEEP uv run --frozen pytest $PYTEST_ARGS $DEST_BLACKSHEEP/_tests.py
PYTHONPATH=$DEST_SANIC uv run --frozen pytest $PYTEST_ARGS $DEST_SANIC/_tests.py
env:
Expand All @@ -67,6 +69,7 @@ jobs:
DEST_SANIC: examples/sanic
PYTHONDEVMODE: 1
PYTEST_ARGS: "-n auto --cov=tortoise --cov-append --cov-branch --tb=native -q"
PYTEST_ARGS_SEQ: "--cov=tortoise --cov-append --cov-branch --tb=native -q"
- name: Test Comprehensive Migrations Example
run: |
cd examples/comprehensive_migrations_project
Expand Down
7 changes: 3 additions & 4 deletions examples/fastapi/_tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# mypy: no-disallow-untyped-decorators
# pylint: disable=E0611,E0401
import multiprocessing
import os
from collections.abc import AsyncGenerator
from concurrent.futures import ProcessPoolExecutor
from contextlib import asynccontextmanager
Expand All @@ -13,11 +12,10 @@
from asgi_lifespan import LifespanManager
from httpx import ASGITransport, AsyncClient

from tortoise.contrib.test import MEMORY_SQLITE
from tortoise.contrib.test import truncate_all_models
from tortoise.fields.data import JSON_LOADS
from tortoise.timezone import UTC, localtime

os.environ["DB_URL"] = MEMORY_SQLITE
try:
from config import register_orm
from main import app
Expand All @@ -42,7 +40,6 @@ def anyio_backend() -> str:

@asynccontextmanager
async def client_manager(app, base_url="http://test", **kw) -> ClientManagerType:
app.state.testing = True
async with LifespanManager(app):
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url=base_url, **kw) as c:
Expand All @@ -52,6 +49,7 @@ async def client_manager(app, base_url="http://test", **kw) -> ClientManagerType
@pytest.fixture(scope="module")
async def client() -> ClientManagerType:
async with client_manager(app) as c:
await truncate_all_models()
yield c


Expand All @@ -62,6 +60,7 @@ async def client_east() -> ClientManagerType:
async with client_manager(app_east) as c:
ctx = app_east.state._tortoise_context
with ctx: # Enter context to make it current via contextvar
await truncate_all_models()
yield c


Expand Down
6 changes: 5 additions & 1 deletion examples/fastapi/config.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import os
from functools import partial
from pathlib import Path

from tortoise.config import AppConfig, DBUrlConfig, TortoiseConfig
from tortoise.contrib.fastapi import RegisterTortoise

BASE_DIR = Path(__file__).resolve().parent
DEFAULT_DB_URL = f"sqlite://{BASE_DIR / 'db.sqlite3'}"

# Single source of truth for Tortoise ORM configuration
TORTOISE_ORM = TortoiseConfig(
connections={"default": DBUrlConfig(url=os.getenv("DB_URL", "sqlite://db.sqlite3"))},
connections={"default": DBUrlConfig(url=os.getenv("DB_URL", DEFAULT_DB_URL))},
apps={
"models": AppConfig(
models=["models"],
Expand Down
37 changes: 4 additions & 33 deletions examples/fastapi/main.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
# pylint: disable=E0611,E0401
import os
from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager

from config import register_orm
from fastapi import FastAPI
from routers import router as users_router

from examples.fastapi.config import register_orm
from tortoise import Tortoise
from tortoise.backends.base.config_generator import generate_config
from tortoise.contrib.fastapi import RegisterTortoise, tortoise_exception_handlers
from tortoise.contrib.fastapi import tortoise_exception_handlers


@asynccontextmanager
async def lifespan_test(app: FastAPI) -> AsyncGenerator[None, None]:
config = generate_config(
os.getenv("TORTOISE_TEST_DB", "sqlite://:memory:"),
app_modules={"models": ["models"]},
testing=True,
connection_label="models",
)
async with RegisterTortoise(
app=app,
config=config,
generate_schemas=True,
_create_db=True,
):
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
async with register_orm(app):
# db connected
yield
# app teardown
# db connections closed
await Tortoise._drop_databases()


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
if getattr(app.state, "testing", None):
async with lifespan_test(app) as _:
yield
else:
# app startup
async with register_orm(app):
# db connected
yield
# app teardown
# db connections closed


app = FastAPI(
Expand Down
3 changes: 0 additions & 3 deletions examples/fastapi/main_custom_timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@

@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
# app startup
# Disable global fallback since this is the secondary app in tests
# (main app already uses global fallback). Context is stored in app.state.
async with register_orm(
app,
use_tz=True,
Expand Down