Skip to content

Quickstart

This guide walks you through creating a minimal ArchiPy application from scratch. You will have a running service with a typed config, a Redis adapter, and a TTL cache backed by Redis in under five minutes.

Prerequisites

Tip: Check your Python version:

python --version  # must be 3.14+

Step 1 — Create the Project

mkdir my_service && cd my_service
uv init

Step 2 — Install ArchiPy

uv add "archipy[redis]"

Step 3 — Define the Configuration

Create a configuration class that extends BaseConfig. Override customize() to apply service-specific defaults after all sources are loaded:

# configs/app_config.py
import logging

from archipy.configs.base_config import BaseConfig
from archipy.configs.environment_type import EnvironmentType

logger = logging.getLogger(__name__)


class AppConfig(BaseConfig):
    """Service-level configuration.

    All ArchiPy config sections (REDIS, FASTAPI, etc.) are inherited.
    Override `customize` to set service-specific defaults.
    """

    def customize(self) -> None:
        """Apply service-specific configuration overrides."""
        super().customize()
        self.FASTAPI.PROJECT_NAME = "my-service"
        self.FASTAPI.RELOAD = self.ENVIRONMENT == EnvironmentType.LOCAL


config = AppConfig()
BaseConfig.set_global(config)
logger.info("Config loaded for environment: %s", config.ENVIRONMENT)

Step 4 — Connect to Redis

Create a Redis adapter using the global config:

# adapters/cache_adapter.py
import logging
from archipy.adapters.redis.adapters import RedisAdapter

logger = logging.getLogger(__name__)

redis = RedisAdapter()  # reads config.REDIS automatically
logger.info("Redis adapter ready")

Step 5 — Add a Caching Layer with Redis

Use RedisAdapter to cache function results in Redis with a TTL:

# logics/user_logic.py
import logging

from adapters.cache_adapter import redis

logger = logging.getLogger(__name__)

_CACHE_TTL = 60  # seconds


def get_user_name(user_id: str) -> str:
    """Fetch a user name, served from Redis cache when available.

    Args:
        user_id: Unique user identifier.

    Returns:
        The user's display name.
    """
    cache_key = f"user:name:{user_id}"
    cached = redis.get(cache_key)
    if cached is not None:
        return str(cached)

    logger.info("Cache miss — fetching user %s from database", user_id)
    name = f"User-{user_id}"  # replace with a real DB call
    redis.set(cache_key, name, ex=_CACHE_TTL)
    return name


# First call: cache miss — hits the database and stores in Redis
name = get_user_name("42")

# Second call within 60 seconds: cache hit — returns from Redis instantly
name = get_user_name("42")

Step 6 — Run the App

# manage.py
import logging

import click

import configs.app_config  # noqa: F401 — triggers BaseConfig.set_global
from logics.user_logic import get_user_name

logging.basicConfig(level="INFO")
logger = logging.getLogger(__name__)


@click.group()
def cli():
    """Management commands for my_service."""


@cli.command()
def run() -> None:
    """Run a quick cache demonstration."""
    logger.info(get_user_name("42"))
    logger.info(get_user_name("42"))  # returns from cache


if __name__ == "__main__":
    cli()
python manage.py run

You should see:

INFO:logics.user_logic:Cache miss — fetching user 42 from database
INFO:__main__:User-42
INFO:__main__:User-42

The second call is served from Redis without hitting the database.


What's Next

Now that the basics work, explore the full feature set: