edgedb-python icon indicating copy to clipboard operation
edgedb-python copied to clipboard

Model variants aren't working as FastAPI `response_model`

Open vpetrovykh opened this issue 5 months ago • 0 comments

Describe the bug Using a model derived from a __variant__ as response_model causes object has no attribute '__gel_changed_fields__' PydanticSerializationError.

Reproduction

  1. create a new venv
  2. pip install "fastapi[standard]"
  3. for the gel-python master branch pip install -Uve ".[test]"
  4. gel init
  5. Use this schema:
    module default {
      type User {
        required name: str {
          constraint exclusive;
        }
        multi friends: User;
      }
    }
    
  6. gel migration create
  7. gel migrate
  8. gel query 'insert User{name := "Alice"}'
  9. gel generate py/models (this is so FastAPI code has models to import)
  10. create main.py
    import fastapi
    import gel.fastapi
    import uuid
    
    from pydantic import BaseModel
    from models import default
    
    app = fastapi.FastAPI()
    g = gel.fastapi.gelify(app)
    
    
    class MyUser(BaseModel):
        id: uuid.UUID
        name: str
        email: str
    
    
    class BaseUser(default.User.__variants__.Base):
        name: default.User.__typeof__.name
        email: default.User.__typeof__.email
    
    
    @app.get("/myuser/", response_model=list[MyUser])
    async def get_users(name: str):
        db = g.client
        q = default.User.filter(
            name=name,
        )
    
        return await db.query(q)
    
    
    @app.get("/baseuser/", response_model=list[BaseUser])
    async def broken_get_users(name: str):
        db = g.client
        q = default.User.filter(
            name=name,
        )
    
        return await db.query(q)
    

Try these 2 endpoints:

  • curl -X 'GET' 'http://127.0.0.1:8000/myuser/?name=Alice' -H 'accept: application/json'
  • curl -X 'GET' 'http://127.0.0.1:8000/baseuser/?name=Alice' -H 'accept: application/json'

The baseuser one should cause an error:

...
pydantic_core._pydantic_core.PydanticSerializationError: Error calling function `<lambda>`: AttributeError: 'BaseUser' object has no attribute '__gel_changed_fields__'

Expected behavior There should not be any difference in how these endpoints work.

Versions (please complete the following information):

  • OS: Ubuntu
  • EdgeDB version: Gel 6.9+77bc1f3
  • EdgeDB CLI version: repl 7.7.0+3788f53
  • gel-python version: master (c7aea17d877961ae81b1e661d66746aadab1ffff)
  • Python version: 3.12.9

vpetrovykh avatar Jul 17 '25 19:07 vpetrovykh