environment-guard 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,103 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .coverage
42
+ .coverage.*
43
+ .cache
44
+ nosetests.xml
45
+ coverage.xml
46
+ *.cover
47
+ *.py,cover
48
+ .hypothesis/
49
+ .pytest_cache/
50
+
51
+ # Translations
52
+ *.mo
53
+ *.pot
54
+
55
+ # Environments
56
+ .env
57
+ .env.local
58
+ .env.*.local
59
+ .venv
60
+ env/
61
+ venv/
62
+ ENV/
63
+ env.bak/
64
+ venv.bak/
65
+
66
+ # Spyder project settings
67
+ .spyderproject
68
+ .spyproject
69
+
70
+ # Rope project settings
71
+ .ropeproject
72
+
73
+ # mkdocs documentation
74
+ /site
75
+
76
+ # mypy
77
+ .mypy_cache/
78
+ .dmypy.json
79
+ dmypy.json
80
+
81
+ # Pyre type checker
82
+ .pyre/
83
+
84
+ # pytype static type analyzer
85
+ .pytype/
86
+
87
+ # Cython debug symbols
88
+ cython_debug/
89
+
90
+ # IDE
91
+ .idea/
92
+ .vscode/
93
+ *.swp
94
+ *.swo
95
+ *~
96
+
97
+ # OS
98
+ .DS_Store
99
+ Thumbs.db
100
+
101
+ # Project specific
102
+ .env.local
103
+ .env.production
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,352 @@
1
+ Metadata-Version: 2.4
2
+ Name: environment-guard
3
+ Version: 0.1.0
4
+ Summary: Zero-config environment variable validation - infer types from .env.example, validate at runtime
5
+ Project-URL: Homepage, https://github.com/ljo3/env-guard
6
+ Project-URL: Documentation, https://github.com/ljo3/env-guard#readme
7
+ Project-URL: Repository, https://github.com/ljo3/env-guard
8
+ Project-URL: Issues, https://github.com/ljo3/env-guard/issues
9
+ Author-email: Your Name <your.email@example.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: config,configuration,dotenv,env,environment,type-checking,validation
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: System :: Systems Administration
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.9
27
+ Requires-Dist: python-dotenv>=1.0.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.0.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
31
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
32
+ Requires-Dist: rich>=13.0.0; extra == 'dev'
33
+ Requires-Dist: twine>=4.0.0; extra == 'dev'
34
+ Provides-Extra: rich
35
+ Requires-Dist: rich>=13.0.0; extra == 'rich'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # env-guard
39
+
40
+ **Zero-config environment variable validation for Python.**
41
+
42
+ Stop writing boilerplate. Your `.env.example` already documents your config — let it validate too.
43
+
44
+ ## Why env-guard?
45
+
46
+ Most environment validation libraries require you to define your schema twice:
47
+
48
+ ```python
49
+ # With Pydantic Settings (the old way)
50
+ class Settings(BaseSettings):
51
+ PORT: int
52
+ DEBUG: bool = False
53
+ DATABASE_URL: str
54
+ API_KEY: str
55
+ REDIS_HOST: str = "localhost"
56
+ REDIS_PORT: int = 6379
57
+ ```
58
+
59
+ But you already have this information in `.env.example`:
60
+
61
+ ```bash
62
+ PORT=8000
63
+ DEBUG=false
64
+ DATABASE_URL=postgresql://localhost/myapp
65
+ API_KEY=your-api-key-here
66
+ REDIS_HOST=localhost
67
+ REDIS_PORT=6379
68
+ ```
69
+
70
+ **Why write it twice?**
71
+
72
+ With env-guard, you don't. One line validates everything:
73
+
74
+ ```python
75
+ from env_guard import validate_env
76
+
77
+ validate_env() # That's it. Zero config.
78
+ ```
79
+
80
+ ## Features
81
+
82
+ - **Zero configuration** — Types are inferred from `.env.example` values
83
+ - **Fail fast** — All errors reported at once with beautiful output
84
+ - **Type coercion** — Get typed values (`int`, `bool`, `float`, `str`)
85
+ - **Optional variables** — Mark with `# optional` comment
86
+ - **Rich output** — Colorized error reports (with fallback for minimal installs)
87
+ - **CI-friendly** — Exit code 1 on failure, works in any pipeline
88
+
89
+ ## Installation
90
+
91
+ ```bash
92
+ pip install environment-guard
93
+ ```
94
+
95
+ For colorized output with Rich:
96
+
97
+ ```bash
98
+ pip install environment-guard[rich]
99
+ ```
100
+
101
+ ## Quick Start
102
+
103
+ ### 1. Create your `.env.example`
104
+
105
+ ```bash
106
+ # .env.example
107
+ PORT=8000
108
+ DEBUG=false
109
+ DATABASE_URL=postgresql://localhost/myapp
110
+ API_KEY=your-secret-key
111
+ WEBHOOK_URL=https://example.com/hook # optional
112
+ ```
113
+
114
+ ### 2. Validate on startup
115
+
116
+ ```python
117
+ # app.py
118
+ from env_guard import validate_env
119
+
120
+ # Validates against .env.example, exits with code 1 on failure
121
+ validate_env()
122
+
123
+ # Your app starts here...
124
+ ```
125
+
126
+ ### 3. Get typed values (optional)
127
+
128
+ ```python
129
+ from env_guard import validate
130
+
131
+ env = validate()
132
+
133
+ print(env["PORT"]) # 8000 (int, not str!)
134
+ print(env["DEBUG"]) # False (bool)
135
+ print(env["DATABASE_URL"]) # "postgresql://..." (str)
136
+ ```
137
+
138
+ ## Type Inference Rules
139
+
140
+ env-guard infers types from your example values:
141
+
142
+ | Example Value | Inferred Type |
143
+ |---------------|---------------|
144
+ | `8000` | `int` |
145
+ | `3.14` | `float` |
146
+ | `true`, `false`, `yes`, `no` | `bool` |
147
+ | Everything else | `str` |
148
+
149
+ ## Optional Variables
150
+
151
+ Mark variables as optional with a comment:
152
+
153
+ ```bash
154
+ REQUIRED_VAR=value
155
+ OPTIONAL_VAR=default # optional
156
+ ALSO_OPTIONAL=123 # ?
157
+ NOT_REQUIRED=true # not required
158
+ ```
159
+
160
+ Optional variables won't cause validation failures if missing.
161
+
162
+ ## API Reference
163
+
164
+ ### `validate_env()`
165
+
166
+ Main validation function. Prints results and exits on failure.
167
+
168
+ ```python
169
+ from env_guard import validate_env
170
+
171
+ result = validate_env(
172
+ example_path=".env.example", # Path to example file
173
+ exit_on_error=True, # Exit with code 1 on failure
174
+ quiet=False, # Suppress output
175
+ )
176
+ ```
177
+
178
+ ### `validate()`
179
+
180
+ Returns typed values or raises `EnvValidationError`.
181
+
182
+ ```python
183
+ from env_guard import validate, EnvValidationError
184
+
185
+ try:
186
+ env = validate()
187
+ port = env["PORT"] # Already an int!
188
+ except EnvValidationError as e:
189
+ print(f"Missing: {[err.var_name for err in e.result.errors]}")
190
+ ```
191
+
192
+ ### CLI
193
+
194
+ ```bash
195
+ # Validate using .env.example in current directory
196
+ env-guard
197
+
198
+ # Specify a different file
199
+ env-guard -e config/.env.example
200
+
201
+ # Quiet mode (only show errors)
202
+ env-guard -q
203
+
204
+ # Don't exit with error code (useful for scripts)
205
+ env-guard --no-exit
206
+ ```
207
+
208
+ ## Error Output
209
+
210
+ When validation fails, you get a clear, grouped error report:
211
+
212
+ ```
213
+ ╭─────────────────────────────────────────────────────────────╮
214
+ │ Environment validation failed with 3 error(s) │
215
+ ╰─────────────────────────────────────────────────────────────╯
216
+
217
+ ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
218
+ ┃ Missing Variables ┃
219
+ ┣━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━┫
220
+ ┃ Variable ┃ Expected Type┃
221
+ ┣━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━┫
222
+ ┃ API_KEY ┃ string ┃
223
+ ┃ DATABASE_URL ┃ string ┃
224
+ ┗━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
225
+
226
+ ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
227
+ ┃ Type Mismatches ┃
228
+ ┣━━━━━━━━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
229
+ ┃ Variable ┃ Expected ┃ Got ┃
230
+ ┣━━━━━━━━━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━━━━━━┫
231
+ ┃ PORT ┃ integer ┃ 'not-a-port' ┃
232
+ ┗━━━━━━━━━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━━━━━━┛
233
+
234
+ Hint: Set missing variables or fix type mismatches in your environment.
235
+ ```
236
+
237
+ ## Integration Examples
238
+
239
+ ### FastAPI
240
+
241
+ ```python
242
+ # main.py
243
+ from fastapi import FastAPI
244
+ from env_guard import validate
245
+
246
+ # Validate before app creation
247
+ env = validate()
248
+
249
+ app = FastAPI()
250
+
251
+ @app.get("/")
252
+ def root():
253
+ return {"port": env["PORT"], "debug": env["DEBUG"]}
254
+ ```
255
+
256
+ ### Flask
257
+
258
+ ```python
259
+ # app.py
260
+ from flask import Flask
261
+ from env_guard import validate_env
262
+
263
+ validate_env() # Fails fast if env is misconfigured
264
+
265
+ app = Flask(__name__)
266
+ ```
267
+
268
+ ### Django
269
+
270
+ ```python
271
+ # settings.py
272
+ from env_guard import validate
273
+
274
+ env = validate()
275
+
276
+ DEBUG = env["DEBUG"]
277
+ DATABASES = {
278
+ "default": {
279
+ "ENGINE": "django.db.backends.postgresql",
280
+ "NAME": env["DATABASE_NAME"],
281
+ }
282
+ }
283
+ ```
284
+
285
+ ### Docker / CI
286
+
287
+ ```dockerfile
288
+ # Dockerfile
289
+ FROM python:3.12-slim
290
+ COPY . /app
291
+ WORKDIR /app
292
+ RUN pip install .
293
+ # Validate env before starting
294
+ CMD ["sh", "-c", "env-guard && python main.py"]
295
+ ```
296
+
297
+ ```yaml
298
+ # GitHub Actions
299
+ - name: Validate environment
300
+ run: env-guard
301
+ env:
302
+ PORT: 8000
303
+ DEBUG: false
304
+ API_KEY: ${{ secrets.API_KEY }}
305
+ ```
306
+
307
+ ## Comparison
308
+
309
+ | Feature | env-guard | pydantic-settings | environs |
310
+ |---------|-----------|-------------------|----------|
311
+ | Zero config | ✅ | ❌ | ❌ |
312
+ | Type inference | ✅ | ❌ | ❌ |
313
+ | Single source of truth | ✅ | ❌ | ❌ |
314
+ | Grouped error output | ✅ | ❌ | ❌ |
315
+ | No dependencies* | ✅ | ❌ | ❌ |
316
+ | Typed return values | ✅ | ✅ | ✅ |
317
+ | Nested config | ❌ | ✅ | ✅ |
318
+ | Complex validation | ❌ | ✅ | ✅ |
319
+
320
+ *Only requires `python-dotenv`. Rich is optional.
321
+
322
+ ## When NOT to Use env-guard
323
+
324
+ env-guard is designed for simplicity. If you need:
325
+
326
+ - **Complex validation rules** (regex, min/max, custom validators)
327
+ - **Nested configuration** (YAML-style hierarchies)
328
+ - **Multiple environment files** (.env.local, .env.production)
329
+ - **Secret management integration** (AWS Secrets Manager, etc.)
330
+
331
+ Consider [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) or [dynaconf](https://www.dynaconf.com/) instead.
332
+
333
+ ## Contributing
334
+
335
+ Contributions welcome! Please read our contributing guidelines first.
336
+
337
+ ```bash
338
+ # Clone and install dev dependencies
339
+ git clone https://github.com/ljo3/env-guard.git
340
+ cd env-guard
341
+ pip install -e ".[dev]"
342
+
343
+ # Run tests
344
+ pytest
345
+
346
+ # Run tests with coverage
347
+ pytest --cov=env_guard
348
+ ```
349
+
350
+ ## License
351
+
352
+ MIT License - see [LICENSE](LICENSE) for details.