Issue 1:
Hello all, I'm new to FastAPI but I believe this is the right place to be posting this even though the issues I believe stems from Pydantic as I'm using it in the context of FastAPI. I'm running this in Pycharm 2020.2 but have also tried it outside of an IDE.

Description

I've seen similar issues about self-referencing Pydantic models causing RecursionError: maximum recursion depth exceeded in comparison but as far as I can tell there are no self referencing models included.

The code runs successfully until the function in audit.py tries to return the output from the model. I'm willing to state that its most likely something I've coded wrong so I've listed this as a question.

The output is created correctly and I have checked this with debugging but the output is not returned and creates a 500 http status code when running from http://127.0.0.1/docs#/audit/audit_api_v1_audit__post.

Thanks in advance and thank you for creating this wonderful framework!

Environment

OS: Windows 10

FastAPI Version: 0.61.1

Pydantic Version: 1.6.1

Uvicorn Version: 0.11.8

Python Version: 3.7.1

Pycharm Version: 2020.2

App

main.py

""
import uvicorn
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware

from app.api.routes.router import api_router
from app.core.logging import init_logging
from app.core.config import settings

init_logging()

def get_app() -> FastAPI:
application = FastAPI(title=settings.APP_NAME, version=settings.APP_VERSION, debug=settings.DEBUG)

if settings.BACKEND_CORS_ORIGINS:
# middleware support for cors
application.add_middleware(
CORSMiddleware,
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
application.include_router(api_router, prefix=settings.API_V1_STR)
return application

app = get_app()

if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=80)

router.py

from fastapi import APIRouter

from app.api.routes import audit

api_router = APIRouter()
api_router.include_router(audit.router, tags=["audit"], prefix="/audit")

audit.py

import validators
from fastapi import APIRouter, HTTPException
from loguru import logger

from app.api.dependencies.audit import analyzer
from app.schemas.audit import AuditPayload, AuditResult

router = APIRouter()

@router.post("/", response_model=AuditResult, name="audit", status_code=200)
async def post_audit(payload: AuditPayload) -> AuditResult:
logger.info("Audit request received")
# validate URL
try:
logger.info("Validating URL")
validators.url(payload.url)
except HTTPException:
HTTPException(status_code=404, detail="Invalid URL.")
logger.exception("HTTPException - Invalid URL")

# generate output from route audit.py
logger.info("Running audit analysis. This could take up to 10 minutes. Maybe grab a coffee...")
analyzed_output = analyzer.analyze(url=payload.url,
brand=payload.brand,
twitter_screen_name=payload.twitter_screen_name,
facebook_page_name=payload.facebook_page_name,
instagram_screen_name=payload.instagram_screen_name,
youtube_user_name=payload.youtube_user_name,
ignore_robots=payload.ignore_robots,
ignore_sitemap=payload.ignore_sitemap,
google_analytics_view_id=payload.google_analytics_view_id)
output = AuditResult(**analyzed_output)
return output

audit_models.py.

from pydantic import BaseModel

class AuditPayload(BaseModel):
url: str
brand: str
twitter_screen_name: str
facebook_page_name: str
instagram_screen_name: str
youtube_user_name: str
ignore_robots: bool
ignore_sitemap: bool
google_analytics_view_id: str

class AuditResult(BaseModel):
base_url: str
run_time: float
website_404: dict
website_302: dict
website_h1_tags: dict
website_duplicate_h1: dict
website_h2_tags: dict
website_page_duplications: dict
website_page_similarities: dict
website_page_desc_duplications: dict
website_page_title_duplications: dict
pages: list
pages_out_links_404: dict = None
pages_canonicals: dict
seo_phrases: dict
social: dict
google_analytics_report: dict
google_psi_desktop: dict
google_psi_mobile: dict
google_algo_updates: dict
google_sb: list
robots_txt: list

This line throws the error in the logs:

2020-09-10 10:02:31.483 | ERROR | uvicorn.protocols.http.h11_impl:run_asgi:391 - Exception in ASGI application

I've included the full stack trace as I'm not sure which bit is most relevant, but I believe this has something to do with it:

File "pydantic\main.py", line 623, in pydantic.main.BaseModel._get_value
[Previous line repeated 722 more times]

Full traceback:

File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\pydevconsole.py", line 483, in <module>
pydevconsole.start_client(host, port)
│ │ │ └ 50488
│ │ └ '127.0.0.1'
│ └ <function start_client at 0x000001BCEDC19D08>
└ <module 'pydevconsole' from 'C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\pl...
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\pydevconsole.py", line 411, in start_client
process_exec_queue(interpreter)
│ └ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>
└ <function process_exec_queue at 0x000001BCEDC19A60>
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\pydevconsole.py", line 258, in process_exec_queue
more = interpreter.add_exec(code_fragment)
│ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>
│ └ <function BaseCodeExecutor.add_exec at 0x000001BCECF38488>
└ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\_pydev_bundle\pydev_code_executor.py", line 106, in add_exec
more = self.do_add_exec(code_fragment)
│ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>
│ └ <function InterpreterInterface.do_add_exec at 0x000001BCEDC15D90>
└ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\_pydev_bundle\pydev_ipython_console.py", line 36, in do_add_exec
res = bool(self.interpreter.add_exec(code_fragment.text))
│ │ │ │ └ "runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...
│ │ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>
│ │ └ <function _PyDevFrontEnd.add_exec at 0x000001BCEDC15A60>
│ └ <_pydev_bundle.pydev_ipython_console_011._PyDevFrontEnd object at 0x000001BCEDC350B8>
└ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\_pydev_bundle\pydev_ipython_console_011.py", line 483, in add_exec
self.ipython.run_cell(line, store_history=True)
│ │ │ └ "runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...
│ │ └ <function InteractiveShell.run_cell at 0x000001BCED5E7268>
│ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>
└ <_pydev_bundle.pydev_ipython_console_011._PyDevFrontEnd object at 0x000001BCEDC350B8>
File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 2843, in run_cell
raw_cell, store_history, silent, shell_futures)
│ │ │ └ True
│ │ └ False
│ └ True
└ "runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...
File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 2869, in _run_cell
return runner(coro)
│ └ <generator object InteractiveShell.run_cell_async at 0x000001BCEDC49C78>
└ <function _pseudo_sync_runner at 0x000001BCED5D0C80>
File "C:\Program Files\Python37\lib\site-packages\IPython\core\async_helpers.py", line 67, in _pseudo_sync_runner
coro.send(None)
│ └ <method 'send' of 'generator' objects>
└ <generator object InteractiveShell.run_cell_async at 0x000001BCEDC49C78>
File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3044, in run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
│ │ └ <ExecutionResult object at 1bcedcd3470, execution_count=2 error_before_exec=None error_in_exec=None info=<ExecutionInfo objec...
│ └ <IPython.core.compilerop.CachingCompiler object at 0x000001BCEDC356D8>
└ 'last_expr'
File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3215, in run_ast_nodes
if (yield from self.run_code(code, result)):
│ │ │ └ <ExecutionResult object at 1bcedcd3470, execution_count=2 error_before_exec=None error_in_exec=None info=<ExecutionInfo objec...
│ │ └ <code object <module> at 0x000001BCEDCDADB0, file "<ipython-input-2-086756a0f1dd>", line 1>
│ └ <function InteractiveShell.run_code at 0x000001BCED5E76A8>
└ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>
File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3291, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
│ │ │ │ └ {'__name__': 'pydev_umd', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None,...
│ │ │ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>
│ │ └ <property object at 0x000001BCED5D8958>
│ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>
└ <code object <module> at 0x000001BCEDCDADB0, file "<ipython-input-2-086756a0f1dd>", line 1>
File "<ipython-input-2-086756a0f1dd>", line 1, in <module>
runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app')
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
│ │ │ │ └ {'__name__': '__main__', '__doc__': "\nMain entry point into API for endpoints related to HawkSense's main functionality.\nto...
│ │ │ └ {'__name__': '__main__', '__doc__': "\nMain entry point into API for endpoints related to HawkSense's main functionality.\nto...
│ │ └ 'E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py'
│ └ <function execfile at 0x000001BCECC521E0>
└ <module '_pydev_bundle.pydev_imports' from 'C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\...
File "C:\Users\<user>\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\202.6948.78\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
│ │ │ └ {'__name__': '__main__', '__doc__': "\nMain entry point into API for endpoints related to HawkSense's main functionality.\nto...
│ │ └ {'__name__': '__main__', '__doc__': "\nMain entry point into API for endpoints related to HawkSense's main functionality.\nto...
│ └ 'E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py'
└ '#!/usr/bin/env python\n\n"""\nMain entry point into API for endpoints related to HawkSense\'s main functionality.\ntodo: htt...
File "E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app\main.py", line 47, in <module>
uvicorn.run("main:app", host="127.0.0.1", port=80) # for debug only
│ └ <function run at 0x000001BCEDE041E0>
└ <module 'uvicorn' from 'C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\__init__.py'>
File "C:\Program Files\Python37\lib\site-packages\uvicorn\main.py", line 362, in run
server.run()
│ └ <function Server.run at 0x000001BCEDE4B510>
└ <uvicorn.main.Server object at 0x000001BCFC722198>
File "C:\Program Files\Python37\lib\site-packages\uvicorn\main.py", line 390, in run
loop.run_until_complete(self.serve(sockets=sockets))
│ │ │ │ └ None
│ │ │ └ <function Server.serve at 0x000001BCEDE4B598>
│ │ └ <uvicorn.main.Server object at 0x000001BCFC722198>
│ └ <function BaseEventLoop.run_until_complete at 0x000001BCED49FE18>
└ <_WindowsSelectorEventLoop running=True closed=False debug=False>
File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 560, in run_until_complete
self.run_forever()
│ └ <function BaseEventLoop.run_forever at 0x000001BCED49FD90>
└ <_WindowsSelectorEventLoop running=True closed=False debug=False>
File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 528, in run_forever
self._run_once()
│ └ <function BaseEventLoop._run_once at 0x000001BCED4A27B8>
└ <_WindowsSelectorEventLoop running=True closed=False debug=False>
File "C:\Program Files\Python37\lib\asyncio\base_events.py", line 1764, in _run_once
handle._run()
│ └ <function Handle._run at 0x000001BCED43AB70>
└ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>
File "C:\Program Files\Python37\lib\asyncio\events.py", line 88, in _run
self._context.run(self._callback, *self._args)
│ │ │ │ │ └ <member '_args' of 'Handle' objects>
│ │ │ │ └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>
│ │ │ └ <member '_callback' of 'Handle' objects>
│ │ └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>
│ └ <member '_context' of 'Handle' objects>
└ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>
> File "C:\Program Files\Python37\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 388, in run_asgi
result = await app(self.scope, self.receive, self.send)
│ │ │ │ │ │ └ <function RequestResponseCycle.send at 0x000001BCFC757840>
│ │ │ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>
│ │ │ │ └ <function RequestResponseCycle.receive at 0x000001BCFC7578C8>
│ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x000001BCFC722BA8>
File "C:\Program Files\Python37\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <fastapi.applications.FastAPI object at 0x000001BCFC722710>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x000001BCFC722BA8>
File "C:\Program Files\Python37\lib\site-packages\fastapi\applications.py", line 149, in __call__
await super().__call__(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
File "C:\Program Files\Python37\lib\site-packages\starlette\applications.py", line 102, in __call__
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x000001BCFC7B8FD0>
└ <fastapi.applications.FastAPI object at 0x000001BCFC722710>
File "C:\Program Files\Python37\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Program Files\Python37\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x000001BCFC72AE18>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x000001BCFC7B8FD0>
File "C:\Program Files\Python37\lib\site-packages\starlette\middleware\cors.py", line 84, in __call__
await self.simple_response(scope, receive, send, request_headers=headers)
│ │ │ │ │ └ Headers({'host': '127.0.0.1', 'connection': 'keep-alive', 'content-length': '295', 'accept': 'application/json', 'user-agent'...
│ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x000001BCFC72AE18>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <function CORSMiddleware.simple_response at 0x000001BCEE53DC80>
└ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>
File "C:\Program Files\Python37\lib\site-packages\starlette\middleware\cors.py", line 140, in simple_response
await self.app(scope, receive, send)
│ │ │ │ └ functools.partial(<bound method CORSMiddleware.send of <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <starlette.exceptions.ExceptionMiddleware object at 0x000001BCFC7B8E48>
└ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>
File "C:\Program Files\Python37\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Program Files\Python37\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <fastapi.routing.APIRouter object at 0x000001BCFC7220F0>
└ <starlette.exceptions.ExceptionMiddleware object at 0x000001BCFC7B8E48>
File "C:\Program Files\Python37\lib\site-packages\starlette\routing.py", line 550, in __call__
await route.handle(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <function Route.handle at 0x000001BCEE4FF6A8>
└ <fastapi.routing.APIRoute object at 0x000001BCFC7B8E80>
File "C:\Program Files\Python37\lib\site-packages\starlette\routing.py", line 227, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...
│ └ <function request_response.<locals>.app at 0x000001BCFC7C1A60>
└ <fastapi.routing.APIRoute object at 0x000001BCFC7B8E80>
File "C:\Program Files\Python37\lib\site-packages\starlette\routing.py", line 41, in app
response = await func(request)
│ └ <starlette.requests.Request object at 0x000001BCFC7D4588>
└ <function get_request_handler.<locals>.app at 0x000001BCFC7C19D8>
File "C:\Program Files\Python37\lib\site-packages\fastapi\routing.py", line 213, in app
is_coroutine=is_coroutine,
└ True
File "C:\Program Files\Python37\lib\site-packages\fastapi\routing.py", line 113, in serialize_response
exclude_none=exclude_none,
└ False
File "C:\Program Files\Python37\lib\site-packages\fastapi\routing.py", line 65, in _prepare_response_content
exclude_none=exclude_none,
└ False
File "pydantic\main.py", line 386, in pydantic.main.BaseModel.dict
File "pydantic\main.py", line 706, in _iter
File "pydantic\main.py", line 623, in pydantic.main.BaseModel._get_value
File "pydantic\main.py", line 623, in pydantic.main.BaseModel._get_value
File "pydantic\main.py", line 623, in pydantic.main.BaseModel._get_value
[Previous line repeated 722 more times]
File "pydantic\main.py", line 605, in pydantic.main.BaseModel._get_value
File "C:\Program Files\Python37\lib\abc.py", line 139, in __instancecheck__
return _abc_instancecheck(cls, instance)
│ │ └ 8
│ └ <class 'pydantic.main.BaseModel'>
└ <built-in function _abc_instancecheck>
RecursionError: maximum recursion depth exceeded in comparison```

Issue 2:
First Check

I added a very descriptive title to this issue.

I used the GitHub search to find a similar issue and didn't find it.

I searched the FastAPI documentation, with the integrated search.

I already searched in Google "How to X in FastAPI" and didn't find any information.

I already read and followed all the tutorial in the docs and didn't find an answer.

I already checked if it is not related to FastAPI but to Pydantic.

I already checked if it is not related to FastAPI but to Swagger UI.

I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

I commit to help with one of those options 👆

Example Code

Here's conftest.py where I attempt to define a fixture that takes care of creating a test PostgreSQL database in the beginning of the test session, and dropping it after the test suite is done running:

Base = declarative_base()

@pytest.fixture(scope="session")
def db_engine():
default_db = (
"postgresql+asyncpg://postgres:postgres@postgres:5432/postgres"
)
test_db = "postgresql+asyncpg://postgres:postgres@postgres:5432/test"
engine = create_async_engine(default_db)
if not database_exists(test_db): # <- Getting error on this line
create_database(test_db)

Base.metadata.create_all(bind=engine)
yield engine

@pytest.fixture(scope="function")
def db(db_engine):
connection = db_engine.connect()

# begin a non-ORM transaction
connection.begin()

# bind an individual Session to the connection
Session = sessionmaker(bind=connection)
db = Session()
# db = Session(db_engine)

yield db

db.rollback()
connection.close()

@pytest.fixture(scope="function")
def client(db):
app.dependency_overrides[get_session] = lambda: db

PREFIX = "/api/v1/my-endpoint"
with TestClient(PREFIX, app) as c:
yield c

Here's the error I get:

E sqlalchemy.exc.PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: Task <Task pending name='anyio.from_thread.BlockingPortal._call_func' coro=<BlockingPortal._call_func() running at /usr/local/lib/python3.9/site-packages/anyio/from_thread.py:187> cb=[TaskGroup._spawn.<locals>.task_done() at /usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py:629]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop (Background on this error at: https://sqlalche.me/e/14/7s2a)

/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py:601: PendingRollbackError

Description

I'm trying to create and drop test database during tests but I couldn't find any resources helping me do that. I posted to questions on StackOverflow (this and this) but got no answer. I believe this is a common use-case, so I figure I'd ask here. If this is possible, I believe an example of how to do it should be added to the documentation.

Operating System

macOS

Operating System Details

No response

FastAPI Version

0.70.1

Python Version

3.9.9

Additional Context

No response