Skip to main content

Fast and easy Redis integration for FastAPI applications.

Project description

FastAPI Redis Utils

Publish codecov PyPI GitHub release (latest by date) License: MIT Python Versions Code style: ruff Type checked with mypy Security: bandit

Fast and easy Redis integration for FastAPI applications.

This library provides everything you need to quickly integrate Redis with FastAPI:

  • RedisManager - Async Redis manager with connection pooling
  • FastAPI Dependencies - Ready-to-use dependencies for Redis injection into your endpoints
  • BaseRepository - CRUD operations with Pydantic models for rapid development

Perfect for caching, session storage, and data persistence in FastAPI applications.

Features

  • FastAPI Integration - Ready-to-use dependencies for Redis injection
  • Async Support - Full async/await capabilities
  • Connection Management - Efficient connection pooling
  • Monitoring - Built-in connection health checks
  • Type Hints - Complete typing support
  • Pydantic Models - Base repository with Pydantic support

Documentation

Installation

From PyPI

uv add fastapi-redis-utils

From Git repository

uv add git+https://github.com/serafinovsky/fastapi-redis-utils.git

Quick Start

FastAPI Integration

from contextlib import asynccontextmanager

from fastapi import FastAPI, Depends
from fastapi_redis_utils import RedisManager, create_redis_client_dependencies
import redis.asyncio as redis

# Create Redis manager
redis_manager = RedisManager(
    dsn="redis://localhost:6379"
)

# Create FastAPI dependency
get_redis_client = create_redis_client_dependencies(redis_manager)

@asynccontextmanager
async def lifespan(app: FastAPI):
    await redis_manager.connect()
    try:
        yield
    finally:
        await redis_manager.close()

app = FastAPI(lifespan=lifespan)

@app.get("/cache/{key}")
async def get_cached_data(key: str, redis_client: redis.Redis = Depends(get_redis_client)):
    """Get data from cache"""
    value = await redis_client.get(key)
    return {"key": key, "value": value}


@app.post("/cache/{key}")
async def set_cached_data(
    key: str,
    value: str,
    redis_client: redis.Redis = Depends(get_redis_client)
):
    """Save data to cache"""
    await redis_client.set(key, value)
    return {"key": key, "value": value, "status": "saved"}


@app.get("/health")
async def health_check():
    """Check Redis connection status"""
    is_healthy = await redis_manager.health_check()
    return {"redis_healthy": is_healthy}

Using BaseRepository with Separate Create and Update Schemas

import uuid

from contextlib import asynccontextmanager
from uuid import UUID

from fastapi import HTTPException, status
from fastapi_redis_utils import BaseRepository, BaseResultModel
from fastapi import FastAPI
from fastapi_redis_utils import RedisManager
from pydantic import BaseModel

# Create Redis manager
redis_manager = RedisManager(
    dsn="redis://localhost:6379"
)

@asynccontextmanager
async def lifespan(app: FastAPI):
    await redis_manager.connect()
    try:
        yield
    finally:
        await redis_manager.close()

app = FastAPI(lifespan=lifespan)

class CreateDemoSchema(BaseModel):
    field1: str
    field2: str


class UpdateDemoSchema(BaseModel):
    field1: str | None = None
    field2: str | None = None


class DemoSchema(BaseResultModel):
    key: str | None = None
    field1: str
    field2: str

    def set_key(self, key: str) -> None:
        self.key = key


class DemoRepository(BaseRepository[CreateDemoSchema, UpdateDemoSchema, DemoSchema]):
    pass


demo_crud = DemoRepository(redis_manager, CreateDemoSchema, UpdateDemoSchema, DemoSchema)


@app.post("/repo/", response_model=DemoSchema, status_code=status.HTTP_201_CREATED)
async def create_demo(demo_model: CreateDemoSchema) -> DemoSchema:
    """Create a new demo record."""
    demo_id = str(uuid.uuid4())
    return await demo_crud.create(demo_id, demo_model)


@app.get("/repo/{demo_id}", response_model=DemoSchema)
async def get_demo(demo_id: UUID) -> DemoSchema:
    """Get a demo record by ID."""
    demo = await demo_crud.get(str(demo_id))
    if demo is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Demo record with ID '{demo_id}' not found",
        )
    return demo


@app.get("/repo/", response_model=list[DemoSchema])
async def list_demos(limit: int = 100) -> list[DemoSchema]:
    """List all demo records"""
    return await demo_crud.list(limit=limit)


@app.put("/repo/{demo_id}", response_model=DemoSchema)
async def update_demo(demo_id: UUID, demo_update: UpdateDemoSchema) -> DemoSchema:
    """Update a demo record."""
    updated_demo = await demo_crud.update(str(demo_id), demo_update)
    if updated_demo is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Demo record with ID '{demo_id}' not found",
        )
    return updated_demo


@app.delete("/repo/{demo_id}")
async def delete_demo(demo_id: UUID) -> dict[str, UUID]:
    """Delete a demo record."""
    deleted = await demo_crud.delete(str(demo_id))
    if not deleted:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Demo record with ID '{demo_id}' not found",
        )
    return {"id": demo_id}


@app.get("/repo/{demo_id}/exists")
async def check_demo_exists(demo_id: UUID) -> dict[str, UUID | bool]:
    """Check if a demo record exists."""
    exists = await demo_crud.exists(str(demo_id))
    return {"id": demo_id, "exists": exists}

Configuration

RedisManager Parameters

Parameter Type Default Description
dsn str - DSN for Redis connection
max_connections int 20 Maximum number of connections in pool
socket_connect_timeout int 5 Socket connection timeout (seconds)
socket_timeout int 5 Socket operation timeout (seconds)

API Reference

RedisManager

Main class for managing Redis connections.

Methods

  • connect() - Connect to Redis
  • close() - Close connection and cleanup resources
  • health_check() - Check connection status
  • get_client() - Get Redis client

create_redis_client_dependencies

Creates FastAPI dependency for getting Redis client.

BaseRepository

Base repository class for working with Pydantic models in Redis. Supports separate schemas for create, update, and result operations with partial updates.

Generic Parameters

  • CreateSchemaType - Pydantic model for create operations
  • UpdateSchemaType - Pydantic model for update operations (all fields optional)
  • ResultSchemaType - Pydantic model for result operations (must inherit from BaseResultModel)

Core Methods

  • create(key, data: CreateSchemaType, ttl=None) - Create record
  • get(key) - Get record (returns ResultSchemaType)
  • update(key, data: UpdateSchemaType, ttl=None) - Update record with partial update (only set fields)
  • delete(key) - Delete record
  • exists(key) - Check record existence
  • list(pattern="*", limit=None) - Get list of records
  • count(pattern="*") - Count records
  • set_ttl(key, ttl) - Set TTL
  • get_ttl(key) - Get TTL
  • clear(pattern="*") - Clear records

Partial Update Feature

The update method performs partial updates - only fields that are set in the update schema will be modified. Fields with None values are ignored.


Repository initiated with serafinovsky/cookiecutter-python-package

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_redis_utils-2.0.2.tar.gz (89.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_redis_utils-2.0.2-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_redis_utils-2.0.2.tar.gz.

File metadata

  • Download URL: fastapi_redis_utils-2.0.2.tar.gz
  • Upload date:
  • Size: 89.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_redis_utils-2.0.2.tar.gz
Algorithm Hash digest
SHA256 b97f33609565b70eccd78eba16115bcc6c0a2bb6262b33dc3796cdd201e3aa2f
MD5 0c74376240e23f56f299d691dd548b6b
BLAKE2b-256 fc7f3a475eabfae8030fc6b816297f0a46574b9f0f0a40aa917dd6fb1cdcab82

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_redis_utils-2.0.2.tar.gz:

Publisher: publish.yml on serafinovsky/fastapi-redis-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastapi_redis_utils-2.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_redis_utils-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fc8f947c8ffb49c1501452c0f183916c03f58573b98f1e040fcd3e246f167e60
MD5 919419aab51133307369b57f2d0bc92b
BLAKE2b-256 77a2110bc9621277ad2f938cc3abf74a3a59c35182ec70e6f0c322ec53165350

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_redis_utils-2.0.2-py3-none-any.whl:

Publisher: publish.yml on serafinovsky/fastapi-redis-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page