Skip to content

Naive usage of fastapi is broken #933

@vpetrovykh

Description

@vpetrovykh
  • Gel Version: 6.10+b9cb801
  • Gel CLI Version: 6.10+b9cb801
  • OS Version: Ubuntu 25.04

Schema:

 module default {
   type Person {
     required name: str {
       constraint exclusive;
     }
     required email: str {
       constraint exclusive;
     }
   }
 }

Code:

import fastapi
import gel.fastapi
from models import default


app = fastapi.FastAPI()
gel.fastapi.gelify(app)


class NamedPerson(default.Person.__shapes__.RequiredId):
    name: default.Person.__defs__.name


@app.get("/person/named", response_model=NamedPerson)
async def named_person(
    db: gel.fastapi.Client,
    email: str,
):
    person = await db.get(
        default.Person.select(
            id=True,
            name=True,
        ).filter(
            email=email
        )
    )

    return person

Attempting to call the endpoint with a valid Person email results in this error:

Traceback (most recent call last):
  File "/home/victor/dev/magicstack/gel-python/gel/_internal/_qbmodel/_pydantic/_models.py", line 1034, in __getattr__
    field = cls.__pydantic_fields__[name]
            ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
KeyError: '__gel_changed_fields__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/victor/dev/magicstack/gel-python/gel/_internal/_qbmodel/_pydantic/_models.py", line 1223, in <lambda>
    lambda obj, _ser, info: obj.model_dump(
                            ^^^^^^^^^^^^^^^
  File "/home/victor/dev/magicstack/gel-python/gel/_internal/_qbmodel/_pydantic/_models.py", line 1268, in model_dump
    _pydantic_utils.massage_model_dump_kwargs(
  File "/home/victor/dev/magicstack/gel-python/gel/_internal/_qbmodel/_pydantic/_utils.py", line 180, in massage_model_dump_kwargs
    and not model.__gel_changed_fields__
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/victor/dev/magicstack/gel-python/gel/_internal/_qbmodel/_pydantic/_models.py", line 1041, in __getattr__
    return ll_getattr(self, name)
           ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NamedPerson' object has no attribute '__gel_changed_fields__'. Did you mean: '__gel_get_changed_fields__'?

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 63, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/routing.py", line 716, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/routing.py", line 736, in app
    await route.handle(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/routing.py", line 290, in handle
    await self.app(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/routing.py", line 78, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/starlette/routing.py", line 75, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/fastapi/routing.py", line 328, in app
    content = await serialize_response(
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/fastapi/routing.py", line 182, in serialize_response
    return field.serialize(
           ^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/fastapi/_compat.py", line 152, in serialize
    return self._type_adapter.dump_python(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/victor/.virtualenvs/fast2/lib/python3.12/site-packages/pydantic/type_adapter.py", line 572, in dump_python
    return self.serializer.to_python(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.PydanticSerializationError: Error calling function `<lambda>`: AttributeError: 'NamedPerson' object has no attribute '__gel_changed_fields__'

This used to work some time ago and seems like a bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions