DEV Community

Cover image for Building 10 Python Packages for Enterprise FastAPI Apps: What I Learned
Daniel Garza
Daniel Garza

Posted on

Building 10 Python Packages for Enterprise FastAPI Apps: What I Learned

After a year of building enterprise platforms, I kept solving the same problems:

  • How do I handle JWT auth with RBAC that actually scales?
  • Why does every project need its own logging configuration?
  • How do I manage secrets across Azure Key Vault and local dev?
  • What's the cleanest way to handle database connection pooling?

So I extracted the patterns into 10 reusable packages and open sourced them.

The Netrun Service Library

All packages are MIT licensed and available on PyPI:

pip install netrun-auth netrun-logging netrun-config
Enter fullscreen mode Exit fullscreen mode

The Foundation Layer

netrun-logging - Structured logging that doesn't suck

Built on Structlog for ~2.9x performance improvement over stdlib. The killer feature? Automatic redaction of sensitive fields:

from netrun_logging import get_logger

logger = get_logger(__name__)

# This automatically redacts the password field
logger.info("user_login",
    username="daniel",
    password="secret123",  # Logged as "password": "[REDACTED]"
    ip_address="192.168.1.1"
)
Enter fullscreen mode Exit fullscreen mode

netrun-errors - Exception hierarchy that maps to HTTP

Instead of catching generic exceptions, use typed errors:

from netrun_errors import NotFoundError, ValidationError

@app.get("/users/{user_id}")
async def get_user(user_id: str):
    user = await db.get_user(user_id)
    if not user:
        raise NotFoundError("User", user_id)  # Returns 404
    return user
Enter fullscreen mode Exit fullscreen mode

The Auth Layer

netrun-auth - JWT + RBAC + Multi-tenant isolation

This was the hardest one to get right. Uses Casbin for policy-based access control:

from netrun_auth import JWTAuthenticator, require_permission

auth = JWTAuthenticator(
    secret_key="your-secret",
    algorithm="HS256"
)

@app.get("/admin/users")
@require_permission("users:read")
async def list_users(user = Depends(auth.get_current_user)):
    # Only users with users:read permission can access
    return await get_users()
Enter fullscreen mode Exit fullscreen mode

The multi-tenant isolation ensures users can only access their own tenant's data:

@require_tenant_access
async def get_tenant_data(tenant_id: str, user = Depends(auth.get_current_user)):
    # Automatically validates user.tenant_id == tenant_id
    return await db.get_tenant_data(tenant_id)
Enter fullscreen mode Exit fullscreen mode

The Config Layer

netrun-config - Azure Key Vault with local fallback

Works in production with Key Vault and locally with .env files:

from netrun_config import AzureKeyVaultConfig

config = AzureKeyVaultConfig(
    vault_url="https://my-vault.vault.azure.net",
    cache_ttl=300  # Cache secrets for 5 minutes
)

# In production: fetches from Key Vault
# Locally: falls back to environment variables
db_password = await config.get_secret("database-password")
Enter fullscreen mode Exit fullscreen mode

The LLM Layer

netrun-llm - Multi-provider orchestration

This one was fun. Abstracts away the differences between LLM providers:

from netrun_llm import LLMOrchestrator

llm = LLMOrchestrator(
    providers=["azure-openai", "ollama", "claude"],
    fallback_enabled=True
)

# Automatically fails over if primary provider is down
response = await llm.complete(
    prompt="Summarize this document",
    model="gpt-4",
    fallback_model="llama2"  # Use Ollama if Azure is down
)
Enter fullscreen mode Exit fullscreen mode

The Data Layer

netrun-db-pool - Async SQLAlchemy that handles connection storms

Connection pooling with automatic health checks:

from netrun_db_pool import DatabasePool

pool = DatabasePool(
    url="postgresql+asyncpg://...",
    pool_size=20,
    max_overflow=10,
    health_check_interval=30
)

async with pool.session() as session:
    result = await session.execute(query)
Enter fullscreen mode Exit fullscreen mode

The Design Philosophy

Soft Dependencies

Every package works standalone. But when you install multiple packages, they
automatically integrate:

netrun-auth + netrun-logging = Auth events automatically logged
netrun-config + netrun-logging = Secret access audited
netrun-db-pool + netrun-errors = Connection errors typed
Enter fullscreen mode Exit fullscreen mode

This is achieved through runtime detection:

try:
    from netrun_logging import get_logger
    logger = get_logger(__name__)
except ImportError:
    import logging
    logger = logging.getLogger(__name__)
Enter fullscreen mode Exit fullscreen mode

Zero Config Defaults

Every package has sensible defaults. You don't need to configure anything to
get started:

from netrun_auth import JWTAuthenticator

# Works with defaults
auth = JWTAuthenticator()

# Or customize everything
auth = JWTAuthenticator(
    secret_key="...",
    algorithm="RS256",
    issuer="my-app",
    audience=["api", "web"]
)
Enter fullscreen mode Exit fullscreen mode

Testing First

netrun-pytest-fixtures provides unified test fixtures:

# conftest.py
pytest_plugins = ["netrun_pytest_fixtures"]

# Your tests automatically get:
# - mock_auth: Pre-configured auth bypass
# - mock_db: In-memory SQLite
# - mock_config: Environment-based config
# - mock_llm: Deterministic LLM responses
Enter fullscreen mode Exit fullscreen mode

What's Next

I'm actively maintaining these packages. Current priorities:

  1. Better documentation (it's in the READMEs but needs a proper docs site)
  2. More LLM providers (Anthropic Claude API, Google Gemini)
  3. OpenTelemetry tracing across all packages

Try It Out

pip install netrun-auth netrun-logging netrun-config
Enter fullscreen mode Exit fullscreen mode

MIT licensed. Issues and PRs welcome.


What patterns do you use for cross-cutting concerns in your FastAPI apps? I'd love to hear what I'm missing.

Top comments (0)