More in Backend Dev — page 20

Why synchronous DB libraries block async FastAPI endpoints and correct SQLAlchemy usage
This tests event loop blocking: sync DB calls in async def halt all requests. Answer: sync drivers block the loop despite releasing the GIL; use asyncpg with SQLAlchemy create_async_engine and AsyncSession. Red flag: recommending run_in_executor as default.

How do you use FastAPI dependency injection for database sessions?
WHAT IT TESTS: FastAPI Depends() for session lifecycle and testability. ANSWER OUTLINE: Build a generator dependency that yields a session and closes it after; inject via Depends(get_db).

Explain SQLAlchemy ORM vs Pydantic models in FastAPI
This tests separation of database schema from API contracts. A strong answer distinguishes SQLAlchemy table rows from Pydantic validation and OpenAPI generation, and notes that create schemas exclude auto-generated IDs.

Describe SQLAlchemy setup in FastAPI from database config to endpoint
Tests FastAPI dependency injection and SQLAlchemy session lifecycle. Good answers cover: engine with pooling, declarative models, a yield-based session dependency, and endpoint queries. Red flag: engine per request or global session shared everywhere.

Why are contextvars better than threading.local in async Python?
This tests whether you know async tasks share OS threads, making thread-local storage unsafe for request state. A great answer notes ContextVar is task-local and resets automatically, while threading.local bleeds across concurrent coroutines.

How do you gracefully cancel and clean up an asyncio task?
This tests asyncio cooperative cancellation and cleanup. A strong answer covers catching CancelledError at await points, using try/finally or async context managers for cleanup, and re-raising.

Unhandled exception in asyncio.create_task(): consequence and detection
Tests Task exception capture vs propagation. Good answer: exceptions are stored in the Task object, the loop keeps running, and the creator must await the task or call task.exception() to retrieve it; unretrieved ones may be logged.

When should you use asyncio.Lock over threading.Lock?
This tests cooperative multitasking knowledge: asyncio.Lock yields to the event loop via await, while threading.Lock blocks the OS thread and freezes the loop. A red flag is claiming threading.Lock works because locks are universal.

Explain the asyncio event loop and cooperative multitasking
Tests if you view the event loop as a single-threaded orchestrator, not magic parallelism. Strong answers note it runs tasks and callbacks, manages a ready queue, and yields control at await. Red flag: calling it multithreading or parallel execution.

How do you safely execute blocking code from an async function
Tests whether you know how to prevent event loop blocking by offloading sync work. Name asyncio.to_thread or run_in_executor, explain ThreadPoolExecutor scheduling, and note when processes beat threads.

Explain await's purpose, awaitable types, and event loop signaling
This tests whether you understand await as a yield point. A strong answer lists three awaitables (coroutines, Tasks, Futures), explains await yields control to the event loop until completion, and warns that a bare coroutine call does not run it.

What is the difference between async def and regular functions?
This tests async def call semantics. A strong answer contrasts regular functions, which execute immediately, with async def, which returns a coroutine object that does nothing until awaited or wrapped in create_task.
Override a FastAPI dependency at the APIRouter level
Tests FastAPI DI scoping limits. Answer: APIRouter has no dependency_overrides; create a sub-app, apply overrides, mount it. Red flag: Claiming router-level overrides exist or mutating global app state.
How do you manage service lifecycle with FastAPI Depends versus formal DI?
Tests scaling FastAPI DI beyond routes. Answer: use Depends(yield) for request-scoped DB sessions; use a formal container for deep singleton service graphs and lifespan wiring; hybrid is best. Red flag: using Depends for everything and ignoring testability.
How do you dynamically discover and register FastAPI routers from a directory?
WHAT IT TESTS: You can safely register FastAPI routers via dynamic imports. ANSWER OUTLINE: Scan app/routers/ with importlib, validate APIRouter objects, include_router with prefixes, and isolate failures.

How do you apply a common path prefix across FastAPI routers?
Tests whether you know APIRouter decouples routes from path prefixes. Use relative paths in APIRouter, then mount with app.include_router(router, prefix="/api/v1"). This keeps modules reusable. Red flag: hardcoding the full absolute path in every decorator.
Manage dev, staging, and prod configs in a large FastAPI app
This tests separating environment config from code with pydantic-settings and env vars. A strong answer covers .env files for local dev, per-environment validation, and secret injection for prod. Red flags are hardcoded values or scattered conditionals.
How to apply a dependency to only one FastAPI router?
TESTS: router-level dependency injection in FastAPI. OUTLINE: pass dependencies=[Depends(auth)] to APIRouter for /users, omit it for /items, include both. RED FLAG: repeating Depends() on every route or using middleware.

How do you include a router in your main FastAPI app?
WHAT IT TESTS: knowledge of the APIRouter wiring pattern. ANSWER OUTLINE: create APIRouter in another file, import it into main.py, then call app.include_router(router). RED FLAG: rewriting endpoints manually in main.py rather than using include_router.

Describe a common FastAPI project structure and key directories
WHAT IT TESTS: Scaling past one file with APIRouter and domain separation. ANSWER OUTLINE: Main module holds the FastAPI app; domain files (users, items) expose APIRouters; dependencies in their own module; pyproject.toml as entrypoint.