I found out that startup and shutdown events are deprecated and want to switch over to lifespan events but dont understand the docs, can someone explain pls?
#๐ How do i implement lifespan events | Fastapi
58 messages ยท Page 1 of 1 (latest)
@bronze whale
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
Closes after a period of inactivity, or when you send !close.
what part do you not understand?
how would i implement them exactly, i understand the defining
but i have multiple events
do they get clubbed into 1
or how
basically startup and shutdown are now combined into a single lifespan function
with a yield in between them
thats for 1 event sequence
Do you have your current startup and shutdown events top hand?
what if i have multiple
wot? sorry didnt get u
you'd call them all from within the lifespan function
as in the code for them, but it sounds like there's a lot so probably not worth going down that road as an example
app.add_event_handler("startup", open_db)
app.add_event_handler("startup", create_session)
app.add_event_handler("startup", add_new_parties) # called once every 5 seconds
app.add_event_handler("startup", check_for_inactivity) # called once every 5 seconds
app.add_event_handler("startup", update_party_details) # called once every 5 seconds
app.add_event_handler("startup", update_playback) # called once every 5 seconds
app.add_event_handler("shutdown", delete_parties)
app.add_event_handler("shutdown", close_db)
app.add_event_handler("shutdown", close_session)``` i have these
yes the code is ready
just want to switch over
so instead do this ```py
from contextlib import asynccontextmanager
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
await open_db()
await create_session()
...etc...
yield
await delete_parties()
await close_db()
...
app = FastAPI(lifespan=lifespan)
changing the order as needed
im using fastapi_utils.tasks.repeat_every too so im unsure if they will work with context managers
might be better to define a task that gets created on startup and repeats every 5s
so make a new function for that?
so instead do this ```py
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
async def check_for_inactivity():
while True:
... do something
await asyncio.sleep(5)
@asynccontextmanager
async def lifespan(app: FastAPI):
asyncio.create_task(check_for_inactivity())
yield
await close_db()
...
app = FastAPI(lifespan=lifespan)
having a decorator is cleaner tho ๐
@repeat_every(seconds=5, raise_exceptions=True)
async def add_new_parties():
parties = await get_parties()
async for party in parties:
if party["_id"] not in currently_listening.keys():
currently_listening[party["_id"]] = party["party_info"]["users"]
ah right, never used fastapi_utils, so not aware of that syntax
if it's rely on startup events to start the loop, then it needs to update to support the lifespan event
their docs might have more info
oh, all the startup event does is call the task on startup too
so just call the function directly
If you also apply the @app.event("startup") decorator, FastAPI will call the function during server startup, and the function will then be called repeatedly while the server is still running.
ah, lol
in the lifespan handler I mean
then it should be fine to use lifespan
Yea
AttributeError: type object 'Database' has no attribute '__bool__'. Did you mean: '__call__'? it caused something
it was working fine before using lifespans
lemme get the code
Pasting large amounts of code
If your code is too long to fit in a codeblock in Discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the Paste! button in the bottom left, or by pressing CTRL + S. After doing that, you will be navigated to the new paste's page. Copy the URL and post it here so others can see it.
from motor.motor_asyncio import AsyncIOMotorClient
async def open_db():
global client, users_db, parties_db
client = AsyncIOMotorClient(connection_str)
users_db = client.users
parties_db = client.parties
what is Database from that error?
Traceback (most recent call last):
File "d:\Python\SpartyTime\SpartyTime\backend\main.py", line 5, in <module>
from routes import auth, parties
File "d:\Python\SpartyTime\SpartyTime\backend\routes\auth.py", line 10, in <module>
from utils.database_handler import create_user, get_user_by_id
File "d:\Python\SpartyTime\SpartyTime\backend\utils\database_handler.py", line 6, in <module>
from motor.motor_asyncio import AsyncIOMotorClient
File "C:\Users\Sahran\AppData\Local\Programs\Python\Python311\Lib\site-packages\motor\motor_asyncio.py", line 46, in <module>
AsyncIOMotorDatabase = create_asyncio_class(core.AgnosticDatabase)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Sahran\AppData\Local\Programs\Python\Python311\Lib\site-packages\motor\motor_asyncio.py", line 37, in create_asyncio_class
return create_class_with_framework(cls, asyncio_framework, "motor.motor_asyncio")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Sahran\AppData\Local\Programs\Python\Python311\Lib\site-packages\motor\metaprogramming.py", line 293, in create_class_with_framework
new_class_attr = attr.create_attribute(new_class, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Sahran\AppData\Local\Programs\Python\Python311\Lib\site-packages\motor\metaprogramming.py", line 228, in create_attribute
return ReadOnlyProperty.create_attribute(self, cls, attr_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Sahran\AppData\Local\Programs\Python\Python311\Lib\site-packages\motor\metaprogramming.py", line 206, in create_attribute
doc = getattr(cls.__delegate_class__, attr_name).__doc__
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'Database' has no attribute '__bool__'. Did you mean: '__call__'?```
seems to be failing on the import statement, rather than your code
but it was working just fine before lifespans
nvm
its still broken
okay updating the library fixed it
nice
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.