-
Notifications
You must be signed in to change notification settings - Fork 159
RuntimeError(“Task … running at … got Future … attached to a different loop” #207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@david-shiko I'm going to need |
@Tinche Added to question |
@Tinche Do you will fix it or any solution? I jsut waiting to apply this in my work :) |
must be |
and 'if name == "main" or 1:' mean code below will be always executed, that mean that you run uvicorn server during tests (when main imported in tests), this is why you get second event loop and this error |
Solution:
|
@david-shiko I see someone got to this before me, did it solve your issue? |
I am getting the same error message, so hopefully it's okay to continue this thread and add my example (let me know if I should create a new issue instead). Below is the minimum example I've been able to reproduce it with. The interesting thing is that if I only have one test (e.g. comment out
from functools import lru_cache
from fastapi import FastAPI, Depends
from sqlalchemy import Column, Integer, String, select
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import declarative_base, sessionmaker
app = FastAPI()
Base = declarative_base()
class Foo(Base):
__tablename__ = "foo"
id = Column(Integer, primary_key=True)
data = Column(String)
@lru_cache()
def get_engine():
engine = create_async_engine(
"postgresql+asyncpg://postgres:postgres@localhost/postgres", echo=True, future=True
)
return engine
@lru_cache
def get_session_maker():
async_session = sessionmaker(
get_engine(), expire_on_commit=False, class_=AsyncSession
)
return async_session
@app.get("/hello")
async def hello_world():
return "Hello, world!"
@app.get("/foo")
async def get_foo(async_session=Depends(get_session_maker)):
async with async_session() as session:
session.add(Foo(data="test"))
await session.commit()
result = await session.execute(select(Foo).where(Foo.data == "test"))
foo = result.scalar_one()
return foo.id
import pytest
from httpx import AsyncClient
from main import app, Base, get_engine
@pytest.fixture()
async def client() -> AsyncClient:
engine = get_engine()
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)
async with AsyncClient(app=app, base_url="http://test") as c:
yield c
pytestmark = pytest.mark.asyncio
async def test_hello_world(client):
r = await client.get("/hello")
assert r.status_code == 200
assert r.json() == "Hello, world!"
async def test_foo(client):
r = await client.get("/foo")
assert r.status_code == 200
assert r.json() == 1 EditFixed by adding a fixture to create an event loop: @pytest.fixture(scope="session")
def event_loop() -> Generator:
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close() Thanks to this blog post! |
Congratulations! |
How to fix an error?
Test file var 1
test result var 1
test file var 2 (conftest.event_loop userd)
test result var 2
Main.py file
The text was updated successfully, but these errors were encountered: