Install
$ agentstack add skill-robhowley-py-pit-skills-settings-config ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Skill: settings-config
Core position
This skill creates clean, production-ready application configuration management using pydantic-settings.
It enforces disciplined configuration patterns that prevent common problems such as:
- configuration drift
- unclear env var naming
- environment-specific branching
- accidental secrets in code
The skill favors minimal, explicit configuration surfaces and ensures configuration is:
- typed
- validated
- environment-driven
- testable
------------------------------------------------------------------------
Goals
Produce a configuration system that:
- Centralizes configuration in a single settings module
- Uses typed settings via pydantic
- Reads configuration from environment variables
- Allows
.envusage in local development - Avoids configuration logic scattered across the codebase
------------------------------------------------------------------------
Step 0 — Inspect the existing project first
Before generating anything:
- Check whether a
config.pyorsettings.pyalready exists. If it
does, extend it rather than creating a parallel one.
- Note the existing package layout. If the project was scaffolded with
fastapi-init, config lives at {pkg_name}/core/config.py — use that path, not app/config.py.
- Check whether an
env_prefixis already in use anywhere
(env_prefix=, os.getenv("XYZ_, existing .env keys). If one exists, adopt it.
- Check whether
.envloading is already part of the project
convention (for example a real .env file used locally, documented setup instructions, or an explicit user request). If so, adopt env_file=".env" in the config.
Do not assume that the presence of .env.example alone means .env should be automatically loaded at runtime.
- Only create new files if no config module is present.
------------------------------------------------------------------------
Standard structure
Create a dedicated settings module.
Typical layout (adapt to the actual package structure found in Step 0):
project/ {pkg_name}/ core/ config.py ← preferred location for fastapi-init projects .env .env.example
Example implementation:
``` python from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings): appname: str = "service" debug: bool = False databaseurl: str
modelconfig = SettingsConfigDict( envprefix="APP_", extra="ignore", )
settings = Settings()
Usage:
``` python
from {pkg_name}.core.config import settings
print(settings.database_url)
------------------------------------------------------------------------
Environment variable pattern
Environment variables should follow a consistent prefix convention.
Example:
APPDATABASEURL=postgresql+asyncpg://... APP_DEBUG=true
The prefix prevents collisions with other services or system variables. Database URLs must use an async-compatible driver scheme (e.g. sqlite+aiosqlite://, postgresql+asyncpg://).
------------------------------------------------------------------------
.env files (optional, local dev)
Environment variables are the canonical configuration source. .env support is an optional local-development convenience layer.
To enable it, add env_file to the config:
``` python modelconfig = SettingsConfigDict( envprefix="APP", envfile=".env", extra="ignore", )
Example `.env`:
APP_DATABASE_URL=postgresql://localhost/service
APP_DEBUG=true
When `.env` is in use, commit a `.env.example` to the repo showing
required variables. The `.env` file itself must be in `.gitignore` — it
may contain secrets and should never be committed.
`extra="ignore"` is intentional here (unlike `extra="forbid"` in
request schemas). Environment variables from the shell, Docker, or CI
will be present alongside app config — rejecting unknown keys would
break deployment.
------------------------------------------------------------------------
## Anti-patterns to remove
Replace patterns like:
``` python
import os
DATABASE_URL = os.getenv("DATABASE_URL")
or scattered config usage across modules.
All configuration should flow through the settings object.
------------------------------------------------------------------------
Three subtle rules (important)
These rules are what distinguish this skill from generic AI configuration scaffolding.
Rule 1 --- No runtime environment branching
Avoid code such as:
``` python if ENV == "production": ...
Configuration differences should come from **environment variables**,
not logic in the settings module.
The settings layer should remain **purely declarative**.
### Rule 2 --- Canonical environment prefix
If the repository already uses a prefix pattern (for example
`MY_SERVICE_`), the settings model must adopt it.
If no prefix exists, create one derived from the package name.
Consistency is more important than any specific prefix choice.
### Rule 3 --- Single settings instantiation
Instantiate settings **once** and import the instance everywhere.
Correct:
``` python
settings = Settings()
Incorrect:
``` python Settings() Settings() Settings()
Multiple instantiations can lead to:
- inconsistent configuration reads
- test instability
- hidden environment reloads
------------------------------------------------------------------------
## Output checklist
The skill should produce:
- `config.py` with `BaseSettings`
- a `Settings` class
- a single `settings` instance
- consistent env var prefix
- removal of `os.getenv` usage
- documentation comment describing required variables
- `.env.example` committed *(if using .env)*
- `.env` in `.gitignore` *(if using .env)*
------------------------------------------------------------------------
## Summary
A good configuration system is:
- **typed**
- **centralized**
- **environment-driven**
- **boring and predictable**
This skill enforces those properties so configuration never becomes a
source of production bugs.
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [robhowley](https://github.com/robhowley)
- **Source:** [robhowley/py-pit-skills](https://github.com/robhowley/py-pit-skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.