pythonmongodbfastapievent-looppytest-asyncio

Add index to AsyncIOMotorClient while having Async tests


I have a mongo class for my fastAPI application: ` from motor.motor_asyncio import AsyncIOMotorClient from config import settings import asyncio

 class Mongo:
   def __init__(self):
    client = AsyncIOMotorClient(
        host=settings.MONGO_HOST,
        port=settings.MONGO_PORT,
        username=settings.MONGO_USER,
        password=settings.MONGO_PASS,
        authSource=settings.MONGO_DB,
        retryWrites=False
    )
    
    db = client[settings.MONGO_DB]
    
    self.services_col = db["services"]
    self.access_keys_col = db["access-keys"]
    self.categories_col = db["categories"]
    self.roles_col = db['roles']

    self.collections = {
        "services": self.services_col,
        "access-keys": self.access_keys_col,
        "categories": self.categories_col,
        "roles": self.roles_col
    }

async def create_indexes(self):
    # Create indexes on the services collection
    await self.services_col.create_index("name")
    await self.services_col.create_index("dashboardPath")
    
    # Create indexes on the categories collection
    await self.categories_col.create_index("name")
    await self.categories_col.create_index("dashboardPath")

mongo_instance = Mongo()`

I Also have some async tests to test my APIs:

This is the conftest.py:

 @pytest.yield_fixture(scope="session")
 def event_loop(request):
    """Create an instance of the default event loop for each test 
    case."""
    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()

And these are some tests for example:

 import pytest
 from httpx import AsyncClient
 import pytest_asyncio
 import asyncio
 from tests.utils import *


 @pytest.mark.asyncio
 async def test_add_service(async_client):
     await remove_entity('test_category', 'categories')
     await remove_entity('test_service', 'services')

     current_services = await count_entities('services')

`

The problem is I don't know how to add indices to the Mongo instance since add index needs await, and if I do await on that on my application, I will get event loop closed on my tests as well and even without tests my API does not work in Swagger.

Thanks

I tried adding await to create index function or changing conftest but did not work


Solution

  • It's not a good idea to create indexes at startup. The next time you starting the app will raise an error about creating existing indexes.

    You can use curl to create indexes before starting or testing your app.

    If you insist on creating at startup, you can use lifespan:

    @asynccontextmanager
    async def lifespan(app: FastAPI):
        await create_indexes()
        yield
    
    
    app = FastAPI(
        lifespan=lifespan,
    )