Skip to content

Commit

Permalink
1. Enhancement for FastAPI lifespan support (#1371)
Browse files Browse the repository at this point in the history
    2. fix: pydantic v2 pydantic_model_creator nullable field not optional. (#1454)
  • Loading branch information
waketzheng committed Sep 25, 2023
1 parent c030c9c commit 8bd02db
Show file tree
Hide file tree
Showing 13 changed files with 578 additions and 424 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ Changelog
0.20
====

0.20.1
------
Added
^^^^^
- Enhancement for FastAPI lifespan support (#1371)
Fixed
^^^^^
- Fix pydantic v2 pydantic_model_creator nullable field not optional. (#1454)

0.20.0
------
Added
Expand Down
2 changes: 1 addition & 1 deletion docs/contrib/fastapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Tortoise-ORM FastAPI integration
================================

We have a lightweight integration util ``tortoise.contrib.fastapi`` which has a single function ``register_tortoise`` which sets up Tortoise-ORM on startup and cleans up on teardown.
We have a lightweight integration util ``tortoise.contrib.fastapi`` which has a function ``register_tortoise`` that sets up Tortoise-ORM on startup and cleans up on teardown (or in lifespan function).

FastAPI is basically Starlette & Pydantic, but in a very specific way.

Expand Down
4 changes: 4 additions & 0 deletions examples/blacksheep/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import tortoise
from tortoise import fields, models
from tortoise.contrib.pydantic import pydantic_model_creator

if tortoise.__version__ >= "0.20":
raise RuntimeError("blacksheep not support pydantic V2, use tortoise-orm<0.20 instead!")


class Users(models.Model):
id = fields.UUIDField(pk=True)
Expand Down
31 changes: 18 additions & 13 deletions examples/fastapi/main.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
# pylint: disable=E0611,E0401
from contextlib import asynccontextmanager
from typing import List

from fastapi import FastAPI
from models import User_Pydantic, UserIn_Pydantic, Users
from pydantic import BaseModel
from starlette.exceptions import HTTPException

from tortoise.contrib.fastapi import register_tortoise
from tortoise.contrib.fastapi import RegisterTortoise

app = FastAPI(title="Tortoise ORM FastAPI example")

@asynccontextmanager
async def lifespan(app):
async with RegisterTortoise(
app,
db_url="sqlite://:memory:",
modules={"models": ["models"]},
generate_schemas=True,
add_exception_handlers=True,
):
yield


app = FastAPI(title="Tortoise ORM FastAPI example", lifespan=lifespan)


class Status(BaseModel):
Expand All @@ -22,7 +36,7 @@ async def get_users():

@app.post("/users", response_model=User_Pydantic)
async def create_user(user: UserIn_Pydantic):
user_obj = await Users.create(**user.dict(exclude_unset=True))
user_obj = await Users.create(**user.model_dump(exclude_unset=True))
return await User_Pydantic.from_tortoise_orm(user_obj)


Expand All @@ -33,7 +47,7 @@ async def get_user(user_id: int):

@app.put("/user/{user_id}", response_model=User_Pydantic)
async def update_user(user_id: int, user: UserIn_Pydantic):
await Users.filter(id=user_id).update(**user.dict(exclude_unset=True))
await Users.filter(id=user_id).update(**user.model_dump(exclude_unset=True))
return await User_Pydantic.from_queryset_single(Users.get(id=user_id))


Expand All @@ -43,12 +57,3 @@ async def delete_user(user_id: int):
if not deleted_count:
raise HTTPException(status_code=404, detail=f"User {user_id} not found")
return Status(message=f"Deleted user {user_id}")


register_tortoise(
app,
db_url="sqlite://:memory:",
modules={"models": ["models"]},
generate_schemas=True,
add_exception_handlers=True,
)
2 changes: 1 addition & 1 deletion examples/pydantic/recursive.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async def run():
await _2_1.gets_talked_to.add(_2_2, _1_1, loose)

p = await Employee_Pydantic.from_tortoise_orm(await Employee.get(name="Root"))
print(p.json(indent=4))
print(p.model_dump_json(indent=4))


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion examples/pydantic/tutorial_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async def run():
# As Python dict with Python objects (e.g. datetime)
print(tourpy.model_dump())
# As serialised JSON (e.g. datetime is ISO8601 string representation)
print(tourpy.json(indent=4))
print(tourpy.model_dump_json(indent=4))


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion examples/pydantic/tutorial_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def run():
# Note that the root element is 'root' that contains the root element.
print(tourpy.model_dump())
# As serialised JSON (e.g. datetime is ISO8601 string representation)
print(tourpy.json(indent=4))
print(tourpy.model_dump_json(indent=4))


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions examples/pydantic/tutorial_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ async def run():
tourpy = await Tournament_Pydantic.from_tortoise_orm(tournament)

# As serialised JSON
print(tourpy.json(indent=4))
print(tourpy.model_dump_json(indent=4))

# Serialise Event
eventpy = await Event_Pydantic.from_tortoise_orm(event)

# As serialised JSON
print(eventpy.json(indent=4))
print(eventpy.model_dump_json(indent=4))


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion examples/pydantic/tutorial_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async def run():
tourpy = await Tournament_Pydantic.from_tortoise_orm(tournament)

# As serialised JSON
print(tourpy.json(indent=4))
print(tourpy.model_dump_json(indent=4))


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit 8bd02db

Please sign in to comment.