agentsclimarketplace

Env config

Skill ComeOnOliver/skillshub/skills/aiskillstore/marketplace/awais68/env-config

🧠 The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.

Install
npx -y skills add ComeOnOliver/skillshub --skill env-config

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Use when setting up environment configuration, loading .env files, or managing application settings across environments. Triggers for: .env setup, loading environment variables, Pydantic BaseSettings, configuration validation, or secret management. NOT for: code-specific logic, feature flags, or runtime feature toggles.

SKILL.md

9.0 KB, as published. Nobody here has run it

Environment Configuration Skill

Expert environment configuration management for Python/FastAPI projects with secure secrets handling and multi-environment support.

Quick Reference

PatternUsage
Load .envload_dotenv() at application start
Access varsettings.DB_URL, settings.JWT_SECRET
Required varField(..., description="Database URL")
Optional varDB_HOST: str = "localhost"
Secret typeSecretStr for sensitive values

Project Structure

project/
β”œβ”€β”€ .env                  # Local development (NOT committed)
β”œβ”€β”€ .env.example          # Template with all required vars (committed)
β”œβ”€β”€ .env.staging          # Staging environment
β”œβ”€β”€ .env.production       # Production environment (managed by infra)
└── config/
    β”œβ”€β”€ __init__.py
    └── settings.py       # Pydantic BaseSettings

settings.py - Base Configuration

# config/settings.py
from functools import lru_cache
from pydantic import Field, SecretStr
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    # Application
    APP_NAME: str = "ERP System"
    DEBUG: bool = False
    API_V1_PREFIX: str = "/v1"

    # Database
    DB_URL: str = Field(
        ...,
        description="PostgreSQL connection URL",
        examples=["postgresql://user:pass@localhost:5432/dbname"],
    )
    DB_POOL_SIZE: int = Field(default=5, ge=1, le=100)

    # JWT Authentication
    JWT_SECRET_KEY: SecretStr = Field(
        ...,
        description="Secret key for JWT signing",
    )
    JWT_ALGORITHM: str = "HS256"
    JWT_EXPIRATION_MINUTES: int = Field(default=15, ge=1)

    # Redis (Optional)
    REDIS_URL: str | None = None

    # Logging
    LOG_LEVEL: str = Field(default="INFO", pattern="^(DEBUG|INFO|WARNING|ERROR)$")

    # CORS
    CORS_ORIGINS: list[str] = ["http://localhost:3000"]

    @property
    def is_production(self) -> bool:
        return not self.DEBUG


@lru_cache
def get_settings() -> Settings:
    """Cached settings instance for application lifecycle."""
    return Settings()

.env.example - Template File

# .env.example - Copy to .env and fill in values
# DO NOT commit actual secrets!

# Application
APP_NAME="ERP System"
DEBUG=false
API_V1_PREFIX="/v1"

# Database (required)
DB_URL="postgresql://user:password@localhost:5432/erp_db"

# JWT Authentication (required - generate with: openssl rand -hex 32)
JWT_SECRET_KEY="your-secret-key-here-generate-with-openssl-rand-hex-32"
JWT_ALGORITHM="HS256"
JWT_EXPIRATION_MINUTES=15

# Redis (optional)
# REDIS_URL="redis://localhost:6379/0"

# Logging
LOG_LEVEL="INFO"

# CORS
CORS_ORIGINS="http://localhost:3000"

.env - Local Development

# .env - Local development only
# NEVER commit this file to version control

APP_NAME="ERP System"
DEBUG=true
API_V1_PREFIX="/v1"

# Local PostgreSQL
DB_URL="postgresql://postgres:postgres@localhost:5432/erp_dev"

# Generate with: openssl rand -hex 32
JWT_SECRET_KEY="local-dev-secret-key-change-in-production"
JWT_ALGORITHM="HS256"
JWT_EXPIRATION_MINUTES=15

# Local Redis (if using)
REDIS_URL="redis://localhost:6379/0"

LOG_LEVEL="DEBUG"

CORS_ORIGINS="http://localhost:3000,http://localhost:5173"

Usage in Application

FastAPI Application

# main.py
from contextlib import asynccontextmanager
from dotenv import load_dotenv

load_dotenv()  # Load .env file

from config.settings import get_settings


@asynccontextmanager
async def lifespan(app):
    settings = get_settings()
    print(f"Starting {settings.APP_NAME} in {'DEBUG' if settings.DEBUG else 'PROD'} mode")
    yield
    print("Shutting down...")


app = FastAPI(
    title=get_settings().APP_NAME,
    lifespan=lifespan,
)


# Include routers
from app.routers import fees, students
app.include_router(fees.router, prefix=get_settings().API_V1_PREFIX)
app.include_router(students.router, prefix=get_settings().API_V1_PREFIX)

Database Connection

# database.py
from sqlmodel import create_engine, Session
from config.settings import get_settings

settings = get_settings()

engine = create_engine(
    settings.DB_URL.get_secret_value() if hasattr(settings.DB_URL, 'get_secret_value') else settings.DB_URL,
    pool_size=settings.DB_POOL_SIZE,
    max_overflow=10,
)


def get_session():
    with Session(engine) as session:
        yield session

JWT Configuration

# auth/jwt.py
from datetime import timedelta
from config.settings import get_settings

settings = get_settings()

JWT_SECRET = settings.JWT_SECRET_KEY.get_secret_value()
JWT_ALGORITHM = settings.JWT_ALGORITHM
ACCESS_TOKEN_EXPIRE_MINUTES = settings.JWT_EXPIRATION_MINUTES


def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
    # ... token creation logic
    pass

Multi-Environment Support

Environment-Specific Configs

# config/settings.py

class Settings(BaseSettings):
    # ... shared settings

    @classmethod
    def from_env(cls, env: str = "development") -> "Settings":
        """Load settings for specific environment."""
        env_file = {
            "development": ".env",
            "staging": ".env.staging",
            "production": ".env.production",
        }.get(env, ".env")

        return cls(_env_file=env_file)

Production Override

# Production should use environment variables, not .env files
# Set these in your deployment platform (Docker, K8s, Cloud Run, etc.)

export DB_URL="postgresql://prod_user:[email protected]:5432/erp_prod"
export JWT_SECRET_KEY="production-secret-key-from-secrets-manager"
export DEBUG=false
export LOG_LEVEL="WARNING"

Secret Management

Generate Secrets

# Generate secure random secret
openssl rand -hex 32  # For JWT_SECRET_KEY

# Generate database password
openssl rand -base64 32

Secret Rotation Script

# scripts/rotate_secret.py
"""Rotate a secret in all environments."""
import os
import re

def rotate_secret(env_file: str, key: str, new_value: str):
    """Replace secret value in .env file."""
    with open(env_file, "r") as f:
        content = f.read()

    # Pattern to match KEY=value
    pattern = f"^{key}=.*$"
    replacement = f"{key}={new_value}"

    new_content = re.sub(pattern, replacement, content, flags=re.MULTILINE)

    with open(env_file, "w") as f:
        f.write(new_content)

    print(f"Rotated {key} in {env_file}")


if __name__ == "__main__":
    import sys
    if len(sys.argv) != 4:
        print("Usage: rotate_secret.py <env_file> <key> <new_value>")
        sys.exit(1)

    rotate_secret(sys.argv[1], sys.argv[2], sys.argv[3])

Quality Checklist

  • Validation on load: All required fields have Field(..., ...) validation
  • No leaks in logs: Use SecretStr for sensitive values, never print settings
  • .env.example committed: Template shows all required variables
  • .env.gitignored: Local development file excluded from version control
  • Secrets generated: JWT secrets use openssl rand -hex 32
  • Environment isolation: Different configs for dev/staging/production
  • Type safety: All settings have proper type annotations

Integration with Other Skills

SkillIntegration Point
@jwt-authJWT_SECRET_KEY from settings
@sqlmodel-crudDB_URL from settings
@fastapi-appAll app settings from settings
@db-migrationDatabase URL for migrations
@api-route-designAPI prefix, CORS origins

Security Best Practices

DO

  • Use SecretStr for passwords, API keys, tokens
  • Rotate secrets regularly
  • Use different secrets per environment
  • Store production secrets in secrets manager
  • Validate all required settings at startup

DON'T

  • Never commit .env files to version control
  • Never hardcode secrets in source code
  • Never log settings or environment variables
  • Never use default/placeholder secrets in production
  • Never expose configuration details in error messages

Startup Validation

# config/validate.py
"""Validate required configuration at startup."""
from pydantic import ValidationError
from config.settings import Settings


def validate_settings() -> bool:
    """Ensure all required settings are configured."""
    try:
        settings = Settings()
        return True
    except ValidationError as e:
        print("Configuration validation failed:")
        for error in e.errors():
            print(f"  - {error['loc'][0]}: {error['msg']}")
        return False


if __name__ == "__main__":
    if not validate_settings():
        exit(1)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.