mirror of
https://github.com/grillazz/fastapi-sqlalchemy-asyncpg.git
synced 2025-08-26 16:40:40 +03:00
Merge pull request #197 from grillazz/195-switch-project-to-uv
This commit is contained in:
commit
3f4f1efb35
4
.github/workflows/build-and-test.yml
vendored
4
.github/workflows/build-and-test.yml
vendored
@ -54,6 +54,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
- name: Lint with ruff
|
||||||
|
run: uv run --frozen ruff check .
|
||||||
|
|
||||||
- name: Test with python ${{ matrix.python-version }}
|
- name: Test with python ${{ matrix.python-version }}
|
||||||
run: uv run --frozen pytest
|
run: uv run --frozen pytest
|
||||||
|
|
||||||
|
|
||||||
|
2
Makefile
2
Makefile
@ -39,7 +39,7 @@ safety: ## Check project and dependencies with safety https://github.com/pyupio/
|
|||||||
|
|
||||||
.PHONY: py-upgrade
|
.PHONY: py-upgrade
|
||||||
py-upgrade: ## Upgrade project py files with pyupgrade library for python version 3.10
|
py-upgrade: ## Upgrade project py files with pyupgrade library for python version 3.10
|
||||||
pyupgrade --py312-plus `find app -name "*.py"`
|
pyupgrade --py313-plus `find app -name "*.py"`
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: ## Lint project code.
|
lint: ## Lint project code.
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, status, Request, Depends, Query
|
from fastapi import APIRouter, Depends, Query, Request, status
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
from starlette.concurrency import run_in_threadpool
|
from starlette.concurrency import run_in_threadpool
|
||||||
|
|
||||||
from app.services.smtp import SMTPEmailService
|
from app.services.smtp import SMTPEmailService
|
||||||
|
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
|
||||||
logger = AppLogger().get_logger()
|
logger = AppLogger().get_logger()
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import io
|
import io
|
||||||
from fastapi import APIRouter, Depends, status, UploadFile, HTTPException
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
|
||||||
import polars as pl
|
import polars as pl
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException, UploadFile, status
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
|
@ -3,8 +3,6 @@ from typing import Annotated
|
|||||||
from fastapi import APIRouter, Depends, Query
|
from fastapi import APIRouter, Depends, Query
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from fastapi_cache.decorator import cache
|
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
from app.models.shakespeare import Paragraph
|
from app.models.shakespeare import Paragraph
|
||||||
|
|
||||||
@ -14,7 +12,6 @@ router = APIRouter(prefix="/v1/shakespeare")
|
|||||||
@router.get(
|
@router.get(
|
||||||
"/",
|
"/",
|
||||||
)
|
)
|
||||||
@cache(namespace="test-2", expire=60)
|
|
||||||
async def find_paragraph(
|
async def find_paragraph(
|
||||||
character: Annotated[str, Query(description="Character name")],
|
character: Annotated[str, Query(description="Character name")],
|
||||||
db_session: AsyncSession = Depends(get_db),
|
db_session: AsyncSession = Depends(get_db),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from fastapi import APIRouter, Depends, HTTPException, status, Request
|
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, status, Request, HTTPException, Form
|
from fastapi import APIRouter, Depends, Form, HTTPException, Request, status
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.database import get_db
|
from app.database import get_db
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.schemas.user import UserSchema, UserResponse, UserLogin, TokenResponse
|
from app.schemas.user import TokenResponse, UserLogin, UserResponse, UserSchema
|
||||||
from app.services.auth import create_access_token
|
from app.services.auth import create_access_token
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from pydantic import PostgresDsn, RedisDsn, computed_field, BaseModel
|
from pydantic import BaseModel, PostgresDsn, RedisDsn, computed_field
|
||||||
from pydantic_core import MultiHostUrl
|
from pydantic_core import MultiHostUrl
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from collections.abc import AsyncGenerator
|
from collections.abc import AsyncGenerator
|
||||||
|
|
||||||
from sqlalchemy.ext.asyncio import create_async_engine
|
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||||||
from sqlalchemy.ext.asyncio import async_sessionmaker
|
|
||||||
|
|
||||||
from app.config import settings as global_settings
|
from app.config import settings as global_settings
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
30
app/main.py
30
app/main.py
@ -1,25 +1,22 @@
|
|||||||
import asyncpg
|
from contextlib import asynccontextmanager
|
||||||
from apscheduler.eventbrokers.redis import RedisEventBroker
|
|
||||||
from apscheduler.datastores.sqlalchemy import SQLAlchemyDataStore
|
|
||||||
from fastapi import FastAPI, Depends
|
|
||||||
from fastapi_cache import FastAPICache
|
|
||||||
from fastapi_cache.backends.redis import RedisBackend
|
|
||||||
|
|
||||||
|
import asyncpg
|
||||||
|
from apscheduler import AsyncScheduler
|
||||||
|
from apscheduler.datastores.sqlalchemy import SQLAlchemyDataStore
|
||||||
|
from apscheduler.eventbrokers.redis import RedisEventBroker
|
||||||
|
from fastapi import Depends, FastAPI
|
||||||
|
|
||||||
|
from app.api.health import router as health_router
|
||||||
from app.api.nonsense import router as nonsense_router
|
from app.api.nonsense import router as nonsense_router
|
||||||
from app.api.shakespeare import router as shakespeare_router
|
from app.api.shakespeare import router as shakespeare_router
|
||||||
from app.api.stuff import router as stuff_router
|
from app.api.stuff import router as stuff_router
|
||||||
|
from app.api.user import router as user_router
|
||||||
from app.config import settings as global_settings
|
from app.config import settings as global_settings
|
||||||
from app.database import engine
|
from app.database import engine
|
||||||
from app.utils.logging import AppLogger
|
from app.redis import get_redis
|
||||||
from app.api.user import router as user_router
|
|
||||||
from app.api.health import router as health_router
|
|
||||||
from app.redis import get_redis, get_cache
|
|
||||||
from app.services.auth import AuthBearer
|
from app.services.auth import AuthBearer
|
||||||
from app.services.scheduler import SchedulerMiddleware
|
from app.services.scheduler import SchedulerMiddleware
|
||||||
|
from app.utils.logging import AppLogger
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
from apscheduler import AsyncScheduler
|
|
||||||
|
|
||||||
logger = AppLogger().get_logger()
|
logger = AppLogger().get_logger()
|
||||||
|
|
||||||
@ -32,10 +29,7 @@ async def lifespan(_app: FastAPI):
|
|||||||
_postgres_dsn = global_settings.postgres_url.unicode_string()
|
_postgres_dsn = global_settings.postgres_url.unicode_string()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Initialize the cache with the redis connection
|
# TODO: cache with the redis connection
|
||||||
redis_cache = await get_cache()
|
|
||||||
FastAPICache.init(RedisBackend(redis_cache), prefix="fastapi-cache")
|
|
||||||
# logger.info(FastAPICache.get_cache_status_header())
|
|
||||||
# Initialize the postgres connection pool
|
# Initialize the postgres connection pool
|
||||||
_app.postgres_pool = await asyncpg.create_pool(
|
_app.postgres_pool = await asyncpg.create_pool(
|
||||||
dsn=_postgres_dsn,
|
dsn=_postgres_dsn,
|
||||||
|
@ -2,9 +2,10 @@ from typing import Any
|
|||||||
|
|
||||||
from asyncpg import UniqueViolationError
|
from asyncpg import UniqueViolationError
|
||||||
from fastapi import HTTPException, status
|
from fastapi import HTTPException, status
|
||||||
from sqlalchemy.exc import SQLAlchemyError, IntegrityError
|
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import declared_attr, DeclarativeBase
|
from sqlalchemy.orm import DeclarativeBase, declared_attr
|
||||||
|
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
|
||||||
logger = AppLogger().get_logger()
|
logger = AppLogger().get_logger()
|
||||||
|
@ -4,7 +4,7 @@ from fastapi import HTTPException, status
|
|||||||
from sqlalchemy import String, select
|
from sqlalchemy import String, select
|
||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import mapped_column, Mapped
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
from app.models.base import Base
|
from app.models.base import Base
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ from sqlalchemy import (
|
|||||||
)
|
)
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from app.models.base import Base
|
from app.models.base import Base
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from sqlalchemy import String, select, ForeignKey
|
from sqlalchemy import ForeignKey, String, select
|
||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import mapped_column, Mapped, relationship, joinedload
|
from sqlalchemy.orm import Mapped, joinedload, mapped_column, relationship
|
||||||
|
|
||||||
from app.models.base import Base
|
from app.models.base import Base
|
||||||
from app.models.nonsense import Nonsense
|
from app.models.nonsense import Nonsense
|
||||||
|
@ -3,10 +3,10 @@ from typing import Any
|
|||||||
|
|
||||||
import bcrypt
|
import bcrypt
|
||||||
from pydantic import SecretStr
|
from pydantic import SecretStr
|
||||||
from sqlalchemy import String, LargeBinary, select, Column
|
from sqlalchemy import Column, LargeBinary, String, select
|
||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import mapped_column, Mapped
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
from app.models.base import Base
|
from app.models.base import Base
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, ConfigDict
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
config = ConfigDict(from_attributes=True)
|
config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, ConfigDict
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
config = ConfigDict(from_attributes=True)
|
config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from pydantic import BaseModel, Field, EmailStr, ConfigDict, SecretStr
|
from pydantic import BaseModel, ConfigDict, EmailStr, Field, SecretStr
|
||||||
|
|
||||||
config = ConfigDict(from_attributes=True)
|
config = ConfigDict(from_attributes=True)
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
|
from fastapi import HTTPException, Request
|
||||||
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
|
|
||||||
from app.config import settings as global_settings
|
from app.config import settings as global_settings
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
|
|
||||||
from fastapi import Request, HTTPException
|
|
||||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
|
||||||
logger = AppLogger().get_logger()
|
logger = AppLogger().get_logger()
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from attrs import define
|
|
||||||
|
|
||||||
from sqlalchemy import text
|
|
||||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
|
||||||
from apscheduler import AsyncScheduler
|
from apscheduler import AsyncScheduler
|
||||||
from apscheduler.triggers.interval import IntervalTrigger
|
from apscheduler.triggers.interval import IntervalTrigger
|
||||||
|
from attrs import define
|
||||||
|
from sqlalchemy import text
|
||||||
|
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||||
|
|
||||||
from app.database import AsyncSessionFactory
|
from app.database import AsyncSessionFactory
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
from attrs import define, field
|
|
||||||
import smtplib
|
import smtplib
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
|
||||||
from app.config import settings as global_settings
|
from attrs import define, field
|
||||||
|
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
|
|
||||||
|
from app.config import settings as global_settings
|
||||||
from app.utils.logging import AppLogger
|
from app.utils.logging import AppLogger
|
||||||
from app.utils.singleton import SingletonMetaNoArgs
|
from app.utils.singleton import SingletonMetaNoArgs
|
||||||
|
|
||||||
|
|
||||||
logger = AppLogger().get_logger()
|
logger = AppLogger().get_logger()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from sqlalchemy.dialects import postgresql
|
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
|
||||||
def compile_sql_or_scalar(func):
|
def compile_sql_or_scalar(func):
|
||||||
"""
|
"""
|
||||||
|
@ -3,7 +3,6 @@ import logging
|
|||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.logging import RichHandler
|
from rich.logging import RichHandler
|
||||||
|
|
||||||
|
|
||||||
from app.utils.singleton import SingletonMeta
|
from app.utils.singleton import SingletonMeta
|
||||||
|
|
||||||
|
|
||||||
@ -21,5 +20,5 @@ class RichConsoleHandler(RichHandler):
|
|||||||
def __init__(self, width=200, style=None, **kwargs):
|
def __init__(self, width=200, style=None, **kwargs):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
console=Console(color_system="256", width=width, style=style, stderr=True),
|
console=Console(color_system="256", width=width, style=style, stderr=True),
|
||||||
**kwargs
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from locust import HttpUser, task, between
|
from locust import HttpUser, between, task
|
||||||
|
|
||||||
|
|
||||||
class Stuff(HttpUser):
|
class Stuff(HttpUser):
|
||||||
|
@ -5,30 +5,71 @@ description = "A modern FastAPI application with SQLAlchemy 2.0 and AsyncPG for
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi[all]>=0.115.6",
|
"fastapi[all]>=0.115.11",
|
||||||
"pydantic[email]>=2.10.3",
|
"pydantic[email]>=2.10.6",
|
||||||
"pydantic-settings>=2.7.0",
|
"pydantic-settings>=2.8.1",
|
||||||
"sqlalchemy>=2.0.36",
|
"sqlalchemy>=2.0.38",
|
||||||
"uvicorn[standard]>=0.34.0",
|
"uvicorn[standard]>=0.34.0",
|
||||||
"asyncpg>=0.30.0",
|
"asyncpg>=0.30.0",
|
||||||
"alembic>=1.14.0",
|
"alembic>=1.15.1",
|
||||||
"httpx>=0.28.1",
|
"httpx>=0.28.1",
|
||||||
"pytest>=8.3.4",
|
"pytest>=8.3.5",
|
||||||
"pytest-cov>=6.0.0",
|
"pytest-cov>=6.0.0",
|
||||||
"uvloop>=0.21.0",
|
"uvloop>=0.21.0",
|
||||||
"httptools>=0.6.4",
|
"httptools>=0.6.4",
|
||||||
"rich>=13.9.4",
|
"rich>=13.9.4",
|
||||||
"pyjwt[cryptography]>=2.10.1",
|
"pyjwt>=2.10.1",
|
||||||
"redis>=5.2.1",
|
"redis>=5.2.1",
|
||||||
"bcrypt>=4.2.1",
|
"bcrypt>=4.3.0",
|
||||||
"polars>=1.17.1",
|
"polars>=1.24.0",
|
||||||
"python-multipart>=0.0.20",
|
"python-multipart>=0.0.20",
|
||||||
"fastexcel>=0.12.0",
|
"fastexcel>=0.13.0",
|
||||||
"fastapi-cache2>=0.2.1",
|
|
||||||
"inline-snapshot>=0.17.0",
|
"inline-snapshot>=0.17.0",
|
||||||
"dirty-equals>=0.8.0",
|
"dirty-equals>=0.8.0",
|
||||||
"polyfactory>=2.18.1",
|
"polyfactory>=2.18.1",
|
||||||
"granian>=1.7.0",
|
"granian>=1.7.0",
|
||||||
"apscheduler[redis,sqlalchemy]>=4.0.0a5",
|
"apscheduler[redis,sqlalchemy]>=4.0.0a5",
|
||||||
"pendulum @ git+https://github.com/sdispater/pendulum.git@develop"
|
]
|
||||||
]
|
|
||||||
|
[tool.uv]
|
||||||
|
dev-dependencies = [
|
||||||
|
"ruff>=0.9.10",
|
||||||
|
"devtools[pygments]>=0.12.2",
|
||||||
|
"pyupgrade>=3.19.1",
|
||||||
|
"ipython>=9.0.2",
|
||||||
|
"sqlacodegen>=3.0.0",
|
||||||
|
"tryceratops>=2.4.1",
|
||||||
|
"locust>=2.33.0"
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
strict = true
|
||||||
|
exclude = ["venv", ".venv", "alembic"]
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
target-version = "py313"
|
||||||
|
exclude = ["alembic"]
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = [
|
||||||
|
"E", # pycodestyle errors
|
||||||
|
"W", # pycodestyle warnings
|
||||||
|
"F", # pyflakes
|
||||||
|
"I", # isort
|
||||||
|
"B", # flake8-bugbear
|
||||||
|
"C4", # flake8-comprehensions
|
||||||
|
"UP", # pyupgrade
|
||||||
|
"ARG001", # unused arguments in functions
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
"E501", # line too long, handled by black
|
||||||
|
"B008", # do not perform function calls in argument defaults
|
||||||
|
"W191", # indentation contains tabs
|
||||||
|
"B904", # Allow raising exceptions without from e, for HTTPException
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint.pyupgrade]
|
||||||
|
# Preserve types, even if a file imports `from __future__ import annotations`.
|
||||||
|
keep-runtime-typing = true
|
@ -1,9 +1,9 @@
|
|||||||
import pytest
|
|
||||||
from httpx import AsyncClient
|
|
||||||
from starlette import status
|
|
||||||
import jwt
|
import jwt
|
||||||
|
import pytest
|
||||||
|
from dirty_equals import IsPositiveFloat, IsStr, IsUUID
|
||||||
|
from httpx import AsyncClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
from dirty_equals import IsStr, IsUUID, IsPositiveFloat
|
from starlette import status
|
||||||
|
|
||||||
pytestmark = pytest.mark.anyio
|
pytestmark = pytest.mark.anyio
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from anyio import Path
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from anyio import Path
|
||||||
from fastapi import status
|
from fastapi import status
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
from dirty_equals import IsUUID
|
||||||
from fastapi import status
|
from fastapi import status
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
from inline_snapshot import snapshot
|
from inline_snapshot import snapshot
|
||||||
from dirty_equals import IsUUID
|
|
||||||
|
|
||||||
from polyfactory.factories.pydantic_factory import ModelFactory
|
from polyfactory.factories.pydantic_factory import ModelFactory
|
||||||
|
|
||||||
from app.schemas.stuff import StuffSchema
|
from app.schemas.stuff import StuffSchema
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
from collections.abc import AsyncGenerator
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from httpx import AsyncClient, ASGITransport
|
from httpx import ASGITransport, AsyncClient
|
||||||
|
|
||||||
from app.database import engine
|
from app.database import engine
|
||||||
from app.main import app
|
from app.main import app
|
||||||
@ -28,13 +31,11 @@ async def start_db():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
async def client(start_db) -> AsyncClient:
|
async def client(start_db) -> AsyncGenerator[AsyncClient, Any]: # noqa: ARG001
|
||||||
|
|
||||||
transport = ASGITransport(
|
transport = ASGITransport(
|
||||||
app=app,
|
app=app,
|
||||||
)
|
)
|
||||||
async with AsyncClient(
|
async with AsyncClient(
|
||||||
# app=app,
|
|
||||||
base_url="http://testserver/v1",
|
base_url="http://testserver/v1",
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
transport=transport,
|
transport=transport,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user