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¶
- Python 3.14 or later
uvpackage manager (installation guide)
Tip: Check your Python version:
Step 1 — Create the Project¶
Step 2 — Install ArchiPy¶
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()
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:
- Concepts — understand the four-layer architecture and import rules
- Project Structure — recommended folder layout for a full service
- Configuration Management — environment variables,
.envfiles, nested config - Dependency Injection — wire adapters and logic with a DI container
- Tutorials — guides for every adapter (PostgreSQL, Kafka, Keycloak, …)