Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FastAPI / Pydantic circular references in separate files

I would love to use a schema that looks something like the following in FastAPI:

from __future__ import annotations
from typing import List
from pydantic import BaseModel


class Project(BaseModel):
    members: List[User]


class User(BaseModel):
    projects: List[Project]


Project.update_forward_refs()

but in order to keep my project structure clean, I would ofc. like to define these in separate files. How could I do this without creating a circular reference?

With the code above the schema generation in FastAPI works fine, I just dont know how to separate it out into separate files. In a later step I would then instead of using attributes use @propertys to define the getters for these objects in subclasses of them. But for the OpenAPI doc generation, I need this combined - I think.

like image 605
Nils Ziehn Avatar asked Aug 14 '20 22:08

Nils Ziehn


Video Answer


1 Answers

There are three cases when circular dependency may work in Python:

  • Top of module: import package.module
  • Bottom of module: from package.module import attribute
  • Top of function: works both

In your situation, the second case "bottom of module" will help. Because you need to use update_forward_refs function to resolve pydantic postponed annotations like this:

# project.py
from typing import List
from pydantic import BaseModel


class Project(BaseModel):
    members: "List[User]"


from user import User
Project.update_forward_refs()
# user.py
from typing import List
from pydantic import BaseModel


class User(BaseModel):
    projects: "List[Project]"


from project import Project
User.update_forward_refs()

Nonetheless, I would strongly discourage you from intentionally introducing circular dependencies

like image 127
alex_noname Avatar answered Sep 25 '22 19:09

alex_noname