Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🏭 Factories #8

Merged
merged 8 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__pycache__

# Development sqlite db
chowda.sqlite
*.sqlite
5 changes: 1 addition & 4 deletions chowda/app.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from fastapi import FastAPI
from sqlalchemy import create_engine
from starlette.responses import HTMLResponse
from starlette.routing import Route
from starlette_admin.contrib.sqlmodel import Admin, ModelView

from sqlmodel import SQLModel

from .config import ENGINE_URI
from .models import User, MediaFile, Collection, ClamsApp, Pipeline, Batch, ClamsEvent
from ._version import __version__

engine = create_engine(ENGINE_URI, connect_args={'check_same_thread': False}, echo=True)
from .db import engine


def init_database() -> None:
Expand Down
12 changes: 12 additions & 0 deletions chowda/db.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even creating the async engine throws the same sqlalchemy.exc.InvalidRequestError, hence the protection.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from sqlalchemy import create_engine
from .config import ENGINE_URI

engine = create_engine(ENGINE_URI, connect_args={'check_same_thread': False}, echo=True)


def create_async_engine():
from sqlmodel.ext.asyncio.session import AsyncEngine

return AsyncEngine(
create_engine(ENGINE_URI, connect_args={'check_same_thread': False}, echo=True)
)
86 changes: 86 additions & 0 deletions chowda/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from chowda.db import engine
from chowda.models import (
MediaFile,
Collection,
ClamsApp,
User,
MediaFileCollectionLink,
MediaFileBatchLink,
Pipeline,
ClamsEvent,
)
from pydantic_factories import (
ModelFactory,
SyncPersistenceProtocol,
AsyncPersistenceProtocol,
)
from typing import TypeVar, List
from pydantic import BaseModel
from sqlmodel import Session
from sqlmodel.ext.asyncio.session import AsyncSession

T = TypeVar("T", bound=BaseModel)


class SyncPersistenceHandler(SyncPersistenceProtocol[T]):
def save(self, data: T) -> T:
with Session(engine) as session:
session.add(data)
session.commit()

def save_many(self, data: List[T]) -> List[T]:
with Session(engine) as session:
for d in data:
session.add(d)
session.commit()


class AsyncPersistenceHandler(AsyncPersistenceProtocol[T]):
async def save(self, data: T) -> T:
async with AsyncSession(engine) as session:
session.add(data)
await session.commit()

async def save_many(self, data: List[T]) -> List[T]:
async with AsyncSession(engine) as session:
for d in data:
session.add(d)
await session.commit()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shamelessly copied from fastapi/sqlmodel#161 (comment)

Unfortunately, running it gives me:

sqlalchemy.exc.InvalidRequestError: The asyncio extension requires an async driver to be used. The loaded 'pysqlite' is not async.

But I think that's enough proof it works, so we should include it and we'll test it when we swap out for an async driver.



class ChowdaFactory(ModelFactory):
__allow_none_optionals__ = False
__sync_persistence__ = SyncPersistenceHandler
__async_persistence__ = AsyncPersistenceHandler


class MediaFileFactory(ChowdaFactory):
__model__ = MediaFile


class CollectionFactory(ChowdaFactory):
__model__ = Collection


class ClamsAppFactory(ChowdaFactory):
__model__ = ClamsApp


class UserFactory(ChowdaFactory):
__model__ = User


class MediaFileCollectionLinkFactory(ChowdaFactory):
__model__ = MediaFileCollectionLink


class MediaFileBatchLinkFactory(ChowdaFactory):
__model__ = MediaFileBatchLink


class PipelineFactory(ChowdaFactory):
__model__ = Pipeline


class ClamsEventFactory(ChowdaFactory):
__model__ = ClamsEvent
137 changes: 98 additions & 39 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pydantic = {extras = ["email"], version = "^1.10.5"}
uvicorn = "^0.20.0"
black = "^23.1.0"
flake8 = "^6.0.0"
pydantic-factories = "^1.17.2"

[tool.poetry.group.test]
optional = true
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ starlette-admin
uvicorn
sqlmodel
pydantic[email]
pydantic-factories