feat: migrate database access to async with aiosqlite#10
Conversation
- replace synchronous SQLite connection with asynchronous aiosqlite - update database access methods to be async - add aiosqlite dependency to pyproject.toml
There was a problem hiding this comment.
Pull Request Overview
This PR converts the OPDS server from synchronous to asynchronous operations by replacing sqlite3 with aiosqlite and making all database-related functions async. The migration enables better concurrent handling of multiple requests and improved performance.
Key changes:
- Migrated from sqlite3 to aiosqlite for async database operations
- Converted all database access functions to async/await pattern
- Updated API endpoints to use async handlers
Reviewed Changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/opds_server/db/access.py | Complete migration from sqlite3 to aiosqlite with async context managers and cursor handling |
| src/opds_server/services/opds.py | Converted feed generation functions to async and added await calls to database operations |
| src/opds_server/api/catalog.py | Updated API endpoint handlers to async and added await calls to service functions |
| src/opds_server/main.py | Updated health check endpoint to use async database connection |
| pyproject.toml | Added aiosqlite dependency |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| ) as cursor: | ||
| async for book_id, author_id, name in cursor: |
There was a problem hiding this comment.
Using async for to iterate over cursor results may not be supported by aiosqlite. Consider using await cursor.fetchall() and then iterating over the results with a regular for loop.
| ) as cursor: | |
| async for book_id, author_id, name in cursor: | |
| rows = await cursor.fetchall() | |
| for book_id, author_id, name in rows: |
| ) as cursor: | ||
| async for book_id, file_format, filename in cursor: |
There was a problem hiding this comment.
Using async for to iterate over cursor results may not be supported by aiosqlite. Consider using await cursor.fetchall() and then iterating over the results with a regular for loop.
| ) as cursor: | |
| async for book_id, file_format, filename in cursor: | |
| rows = await cursor.fetchall() | |
| for book_id, file_format, filename in rows: |
What
Added async database support using
aiosqliteand converted the API, services, and DB access layer to fully asynchronous.Why
Synchronous SQLite access was blocking the FastAPI event loop and limiting concurrency. Async queries allow the server to handle more requests efficiently without blocking I/O.
How
aiosqlitedependency inpyproject.tomlandpoetry.lock.sqlite3withaiosqliteand introduced anasynccontextmanagerfor DB connections.get_book_title,get_book_file_path,get_cover_path,get_authors, etc.) toasync.generate_*_feed,search_books, etc.) to async and awaited DB calls.download_book,get_cover,search,root_by_*, etc.) async./readyprobe to use async DB check.