skills/awais68/env-config/SKILL.md
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.
npx skillsauth add aiskillstore/marketplace env-configInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert environment configuration management for Python/FastAPI projects with secure secrets handling and multi-environment support.
| Pattern | Usage |
|---------|-------|
| Load .env | load_dotenv() at application start |
| Access var | settings.DB_URL, settings.JWT_SECRET |
| Required var | Field(..., description="Database URL") |
| Optional var | DB_HOST: str = "localhost" |
| Secret type | SecretStr for sensitive values |
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
# 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 - 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 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"
# 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.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
# 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
# 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 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"
# Generate secure random secret
openssl rand -hex 32 # For JWT_SECRET_KEY
# Generate database password
openssl rand -base64 32
# 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])
Field(..., ...) validationSecretStr for sensitive values, never print settingsopenssl rand -hex 32| Skill | Integration Point |
|-------|-------------------|
| @jwt-auth | JWT_SECRET_KEY from settings |
| @sqlmodel-crud | DB_URL from settings |
| @fastapi-app | All app settings from settings |
| @db-migration | Database URL for migrations |
| @api-route-design | API prefix, CORS origins |
SecretStr for passwords, API keys, tokens.env files to version control# 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)
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.