🌟 envdot
Enhanced environment variable management for Python with multi-format support and automatic type detection.
📋 Features
- 🔧 Multiple Format Support:
.env,.json,.yaml,.yml, and.inifiles - 🎯 Automatic Type Detection: Automatically converts strings to
bool,int,float, or keeps asstring - 💾 Read and Write: Load from and save to configuration files
- 🔄 Method Chaining: Fluent API for cleaner code
- 🌍 OS Environment Integration: Seamlessly works with
os.environ(os.getenv, os.setenv) - 📦 Zero Dependencies: Core functionality works without external packages (YAML support requires PyYAML)
- ✅ Nested structure flattening: Deep hierarchies → flat env vars
- ✅ Format conversion: Convert between any supported formats
- ✅ Auto-typed
os.getenv(): Get typed values instead of strings - ✅ Attribute-style access:
config.DATABASE_HOST - ✅ Dictionary-style access:
config['DATABASE_HOST']
Installation
pip install envdot
# Full installation (all formats)
pip install envdot[full]
# Specific format support
pip install envdot[yaml] # YAML support
pip install envdot[toml] # TOML support
pip install envdot[json5] # JSON5 support
Documentation
🚀 Quick Start
Basic Usage
from envdot import load_env, get_env
# Load configuration (auto-detects format)
load_env() # Searches for .env, config.json, config.yaml, etc.
# Or load specific file
load_env('config.toml')
# Get values (automatically typed!)
db_host = get_env('DATABASE_HOST') # Returns: "localhost" (str)
db_port = get_env('DATABASE_PORT') # Returns: 5432 (int)
debug = get_env('DEBUG') # Returns: True (bool)
timeout = get_env('TIMEOUT') # Returns: 30.5 (float)
# With defaults
redis_host = get_env('REDIS_HOST', default='127.0.0.1')
# Explicit type casting
max_connections = get_env('MAX_CONNECTIONS', cast_type=int)
allowed_hosts = get_env('ALLOWED_HOSTS', cast_type=list)
$ cat .env
CELERY_BACKEND=redis://redis:6379/0
CELERY_BROKER=redis://redis:6379/0
DEBUG=true
DEBUGGER_SERVER=5.5
DEBUG_SERVER=false
DJANGO_ALLOWED_HOSTS="localhost 127.0.0.1 [::1] 192.168.100.2 192.168.100.2"
POSTGRES_DB=django_celery
POSTGRES_PASSWORD=password1234-8
POSTGRES_USER=celery_admin
PYTHONDONTWRITEBYTECODE=true
PYTHONUNBUFFERED=true
RABBITMQ_DEFAULT_PASS=hackmeplease
RABBITMQ_DEFAULT_USER=syslog
RABBITMQ_HOST_DJANGO=rabbitmq
RABBITMQ_MANAGEMENT=true
RABBITMQ_PASSWORD_DJANGO=123-8
RABBITMQ_USERNAME_DJANGO=syslog
SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m
In [1]: from envdot import load_env, show
In [2]: load_env()
Out[2]: DotEnv(filepath=.env, vars=18)
In [3]: show()
Out[3]:
{'CELERY_BACKEND': 'redis://redis:6379/0',
'CELERY_BROKER': 'redis://redis:6379/0',
'DEBUG': True,
'DEBUGGER_SERVER': 5.5,
'DEBUG_SERVER': False,
'DJANGO_ALLOWED_HOSTS': 'localhost 127.0.0.1 [::1] 192.168.100.2 192.168.100.2',
'POSTGRES_DB': 'django_celery',
'POSTGRES_PASSWORD': 'password1234-8',
'POSTGRES_USER': 'celery_admin',
'PYTHONDONTWRITEBYTECODE': True,
'PYTHONUNBUFFERED': True,
'RABBITMQ_DEFAULT_PASS': 'hackmeplease',
'RABBITMQ_DEFAULT_USER': 'syslog',
'RABBITMQ_HOST_DJANGO': 'rabbitmq',
'RABBITMQ_MANAGEMENT': True,
'RABBITMQ_PASSWORD_DJANGO': '123-8',
'RABBITMQ_USERNAME_DJANGO': 'syslog',
'SECRET_KEY': 'dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m'}
In [4]: config = load_env()
In [5]: config.show()
Out[5]:
{'CELERY_BACKEND': 'redis://redis:6379/0',
'CELERY_BROKER': 'redis://redis:6379/0',
'DEBUG': True,
'DEBUGGER_SERVER': 5.5,
'DEBUG_SERVER': False,
'DJANGO_ALLOWED_HOSTS': 'localhost 127.0.0.1 [::1] 192.168.100.2 192.168.100.2',
'POSTGRES_DB': 'django_celery',
'POSTGRES_PASSWORD': 'password1234-8',
'POSTGRES_USER': 'celery_admin',
'PYTHONDONTWRITEBYTECODE': True,
'PYTHONUNBUFFERED': True,
'RABBITMQ_DEFAULT_PASS': 'hackmeplease',
'RABBITMQ_DEFAULT_USER': 'syslog',
'RABBITMQ_HOST_DJANGO': 'rabbitmq',
'RABBITMQ_MANAGEMENT': True,
'RABBITMQ_PASSWORD_DJANGO': '123-8',
'RABBITMQ_USERNAME_DJANGO': 'syslog',
'SECRET_KEY': 'dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m'}
In [6]: config.DEBUG_SERVER
Out[6]: False
In [7]: config.DEBUG_SERVER = True
In [8]: show()
Out[8]:
{'CELERY_BACKEND': 'redis://redis:6379/0',
'CELERY_BROKER': 'redis://redis:6379/0',
'DEBUG': True,
'DEBUGGER_SERVER': 5.5,
'DEBUG_SERVER': True,
'DJANGO_ALLOWED_HOSTS': 'localhost 127.0.0.1 [::1] 192.168.100.2 192.168.100.2',
'POSTGRES_DB': 'django_celery',
'POSTGRES_PASSWORD': 'password1234-8',
'POSTGRES_USER': 'celery_admin',
'PYTHONDONTWRITEBYTECODE': True,
'PYTHONUNBUFFERED': True,
'RABBITMQ_DEFAULT_PASS': 'hackmeplease',
'RABBITMQ_DEFAULT_USER': 'syslog',
'RABBITMQ_HOST_DJANGO': 'rabbitmq',
'RABBITMQ_MANAGEMENT': True,
'RABBITMQ_PASSWORD_DJANGO': '123-8',
'RABBITMQ_USERNAME_DJANGO': 'syslog',
'SECRET_KEY': 'dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m'}
In [9]: config.show()
Out[9]:
{'CELERY_BACKEND': 'redis://redis:6379/0',
'CELERY_BROKER': 'redis://redis:6379/0',
'DEBUG': True,
'DEBUGGER_SERVER': 5.5,
'DEBUG_SERVER': True,
'DJANGO_ALLOWED_HOSTS': 'localhost 127.0.0.1 [::1] 192.168.100.2 192.168.100.2',
'POSTGRES_DB': 'django_celery',
'POSTGRES_PASSWORD': 'password1234-8',
'POSTGRES_USER': 'celery_admin',
'PYTHONDONTWRITEBYTECODE': True,
'PYTHONUNBUFFERED': True,
'RABBITMQ_DEFAULT_PASS': 'hackmeplease',
'RABBITMQ_DEFAULT_USER': 'syslog',
'RABBITMQ_HOST_DJANGO': 'rabbitmq',
'RABBITMQ_MANAGEMENT': True,
'RABBITMQ_PASSWORD_DJANGO': '123-8',
'RABBITMQ_USERNAME_DJANGO': 'syslog',
'SECRET_KEY': 'dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m'}
In [10]: os.getenv('DEBUG_SERVER')
Out[10]: True
In [11]: config.DEBUG_SERVER = False
In [12]: os.getenv('DEBUG_SERVER')
Out[12]: False
from envdot import DotEnv
# Auto-detect and load from common config files (.env, config.json, etc.)
env = DotEnv()
# Or specify a file
env = DotEnv('.env')
# Get values with automatic type detection
db_host = env.get('DB_HOST') # Returns string
# or
db_host = os.getenv('DB_HOST') # Returns string
db_port = env.get('DB_PORT') # Returns int (auto-detected)
# or
db_port = os.getenv('DB_PORT') # Returns int (auto-detected)
debug_mode = env.get('DEBUG') # Returns bool (auto-detected)
# or
debug_mode = os.getenv('DEBUG') # Returns bool (auto-detected)
api_timeout = env.get('API_TIMEOUT') # Returns float (auto-detected)
# or
api_timeout = os.getenv('API_TIMEOUT') # Returns float (auto-detected)
# Set values
env.set('NEW_KEY', 'value')
# or
env.setenv('NEW_KEY', 'value')
env.set('FEATURE_ENABLED', True)
# or
env.setenv('FEATURE_ENABLED', True)
# Save to file
env.save('.env')
# or
env.save()
# or
os.save_env()
Convenience Functions
from envdot import load_env, get_env, set_env, save_env
# Load configuration
load_env('.env')
# or just
load_env()
# Get values
database_url = get_env('DATABASE_URL')
max_connections = get_env('MAX_CONNECTIONS', default=100)
# Set values
set_env('NEW_FEATURE', True)
# Save changes
save_env('.env') # or just save_env()
Working with Different File Formats
.env File
env = DotEnv('.env')
env.load()
JSON File
env = DotEnv('config.json')
env.load()
YAML File
env = DotEnv('config.yaml')
env.load() # Requires PyYAML
INI File
env = DotEnv('config.ini')
env.load()
Type Detection Examples
The package automatically detects and converts types:
# Given this .env file:
# DEBUG=true
# PORT=8080
# TIMEOUT=30.5
# APP_NAME=MyApp
# EMPTY_VALUE=
env = DotEnv('.env') # or load_env() or load_env('.env')
env.get('DEBUG') # Returns: True (bool)
env.get('PORT') # Returns: 8080 (int)
env.get('TIMEOUT') # Returns: 30.5 (float)
env.get('APP_NAME') # Returns: 'MyApp' (str)
env.get('EMPTY_VALUE') # Returns: None
# env.get same as os.getenv
Explicit Type Casting
# Force a specific type
version = env.get('VERSION', cast_type=str)
port = env.get('PORT', cast_type=int)
enabled = env.get('ENABLED', cast_type=bool)
Method Chaining
env = DotEnv('.env') \
.load() \
.set('NEW_KEY', 'value') \
.set('ANOTHER_KEY', 123) \
.save()
Dictionary-Style Access
env = DotEnv('.env')
# Get values
value = env['KEY_NAME']
# Set values
env['NEW_KEY'] = 'new value'
# Check existence
if 'API_KEY' in env:
print("API key is configured")
# Get all variables
all_vars = env.all()
Advanced Features
Load Without Overriding
env.load(override=False) # Keep existing values
Load Without Applying to OS Environment
env.load(apply_to_os=False) # Don't set in os.environ
Save to Different Format
env = DotEnv('.env')
env.load()
env.save('config.json') # Convert .env to JSON
Clear Variables
env.clear() # Clear internal storage only
env.clear(clear_os=True) # Also clear from os.environ
Delete Specific Keys
env.delete('OLD_KEY')
env.delete('TEMP_KEY', remove_from_os=True)
Type Detection Rules
The package uses the following rules for automatic type detection:
- Boolean:
true,yes,on,1→True|false,no,off,0→False - None:
none,null, empty string →None - Integer: Numbers without decimal point →
int - Float: Numbers with decimal point →
float - String: Everything else →
str
📝 Supported Formats
1. .env File (Most Common)
DEBUG=true
PORT=8080
DATABASE_URL=postgresql://localhost/mydb
# .env
DATABASE_HOST=localhost
DATABASE_PORT=5432
DEBUG=true
TIMEOUT=30.5
APP_NAME="My Application"
from envdot import load_env, get_env
load_env('.env')
print(get_env('DATABASE_PORT')) # 5432 (int, not string!)
print(get_env('DEBUG')) # True (bool, not string!)
2. JSON File
{
"DEBUG": true,
"PORT": 8080,
"DATABASE_URL": "postgresql://localhost/mydb"
}
{
"database": {
"host": "localhost",
"port": 5432,
"credentials": {
"username": "admin",
"password": "secret"
}
},
"features": ["auth", "cache"]
}
load_env('config.json')
# Nested keys are flattened with underscores
print(get_env('DATABASE_HOST')) # localhost
print(get_env('DATABASE_CREDENTIALS_USERNAME')) # admin
print(get_env('FEATURES_0')) # auth
Flattening Rules:
database.host→DATABASE_HOSTdatabase.credentials.username→DATABASE_CREDENTIALS_USERNAMEfeatures[0]→FEATURES_0
3. YAML File
DEBUG: true
PORT: 8080
DATABASE_URL: postgresql://localhost/mydb
# config.yaml
database:
host: localhost
port: 5432
credentials:
username: admin
password: secret
server:
primary:
host: server1.example.com
port: 8080
secondary:
host: server2.example.com
port: 8081
load_env('config.yaml')
print(get_env('DATABASE_HOST')) # localhost
print(get_env('DATABASE_CREDENTIALS_USERNAME')) # admin
print(get_env('SERVER_PRIMARY_HOST')) # server1.example.com
Installation: pip install pyyaml
4. INI File
[DEFAULT]
DEBUG = true
PORT = 8080
DATABASE_URL = postgresql://localhost/mydb
# config.ini
[DEFAULT]
app_name = My Application
version = 1.0.0
[database]
host = localhost
port = 5432
username = admin
[server]
host = 0.0.0.0
port = 8080
load_env('config.ini')
# DEFAULT section items have no prefix
print(get_env('APP_NAME')) # My Application
# Other sections use section name as prefix
print(get_env('DATABASE_HOST')) # localhost
print(get_env('SERVER_PORT')) # 8080
5. TOML File (⭐ Recommended for Python Projects)
# config.toml
title = "My Application"
version = "1.0.0"
[database]
host = "localhost"
port = 5432
[database.credentials]
username = "admin"
password = "secret"
[[features]]
name = "authentication"
enabled = true
[[features]]
name = "caching"
enabled = false
load_env('config.toml')
print(get_env('TITLE')) # My Application
print(get_env('DATABASE_HOST')) # localhost
print(get_env('DATABASE_CREDENTIALS_USERNAME')) # admin
print(get_env('FEATURES_0_NAME')) # authentication
print(get_env('FEATURES_0_ENABLED')) # True
Installation:
- Python 3.11+: Built-in support for reading
- Python < 3.11:
pip install tomli - Writing TOML:
pip install tomli-w(all Python versions)
🔄 Format Conversion
Convert between any supported formats:
from envdot import load_env, save_env
# Load from JSON
load_env('config.json')
# Save as different formats
save_env('config.env', format='env') # Convert to .env
save_env('config.yaml', format='yaml') # Convert to YAML
save_env('config.toml', format='toml') # Convert to TOML
save_env('config.ini', format='ini') # Convert to INI
🎯 Advanced Usage
1. Auto-typed os.getenv()
Make os.getenv() return typed values automatically:
from envdot import load_env
import os
# Enable auto-typed os.getenv()
load_env(auto_replace_getenv=True) # Default is True
# Now os.getenv() returns typed values!
port = os.getenv('DATABASE_PORT') # Returns: 5432 (int), not "5432" (str)
debug = os.getenv('DEBUG') # Returns: True (bool), not "true" (str)
timeout = os.getenv('TIMEOUT') # Returns: 30.5 (float), not "30.5" (str)
2. OS Module Patching
Add helpful methods to os module:
from envdot import load_env
import os
# Enable os module patching
load_env(patch_os=True) # Default is True
# Now you can use:
os.getenv_typed('PORT') # Auto-typed getenv
os.getenv_int('PORT', default=8080)
os.getenv_bool('DEBUG', default=False)
os.getenv_float('RATIO', default=1.0)
os.setenv('KEY', 'value') # Set and save
os.save_env() # Save to file
3. Attribute-Style Access
from envdot import DotEnv
env = DotEnv('config.toml')
# Access like attributes
print(env.DATABASE_HOST)
print(env.DATABASE_PORT)
# Set like attributes (auto-saves!)
env.NEW_KEY = 'new_value'
env.MAX_WORKERS = 10
4. Dictionary-Style Access
from envdot import DotEnv
env = DotEnv('config.json')
# Dictionary-like access
print(env['DATABASE_HOST'])
env['NEW_KEY'] = 'value'
# Check existence
if 'DEBUG' in env:
print("Debug mode is set")
5. Explicit Type Casting
from envdot import get_env
# Force specific types
port = get_env('PORT', cast_type=int)
enabled = get_env('ENABLED', cast_type=bool)
ratio = get_env('RATIO', cast_type=float)
# Cast to list
hosts = get_env('ALLOWED_HOSTS', cast_type=list)
# "localhost, 127.0.0.1, example.com" → ['localhost', '127.0.0.1', 'example.com']
# Cast to tuple
coords = get_env('COORDINATES', cast_type=tuple)
6. Production Environment Setup
from envdot import load_env, get_env
import os
# Load base configuration
load_env('config.base.toml')
# Override with environment-specific settings
environment = os.getenv('ENVIRONMENT', 'development')
if environment == 'production':
load_env('config.prod.env', override=True)
elif environment == 'staging':
load_env('config.staging.env', override=True)
# Now get_env() returns environment-specific values
db_host = get_env('DATABASE_HOST')
7. Recursive File Search
from envdot import DotEnv
# Automatically search current directory and subdirectories
env = DotEnv()
env.load(recursive=True)
# Or specify search parameters
env.find_settings_recursive(
start_path='/path/to/project',
max_depth=5,
filename=['.env', 'config.toml'],
exceptions=['node_modules', 'venv']
)
🔧 API Reference
DotEnv Class
__init__(filepath=None, auto_load=True)
Initialize DotEnv instance.
load(filepath=None, override=True, apply_to_os=True)
Load environment variables from file.
get(key, default=None, cast_type=None)
Get environment variable with automatic type detection.
set(key, value, apply_to_os=True)
Set environment variable.
os.getenv(key, default=None, cast_type=None)
Get environment variable with automatic type detection.
os.setenv(key, value, apply_to_os=True)
Set environment variable.
save(filepath=None, format=None)
Save environment variables to file.
delete(key, remove_from_os=True)
Delete environment variable.
all()
Get all environment variables as dictionary.
keys()
Get all variable names.
clear(clear_os=False)
Clear all stored variables.
Main Functions
# Load configuration
load_env(
filepath=None, # Path to config file (auto-detects if None)
auto_replace_getenv=True, # Replace os.getenv() with typed version
patch_os=True, # Add helpers to os module
override=True, # Override existing values
apply_to_os=True, # Set values in os.environ
store_typed=True, # Store typed values internally
recursive=True, # Search recursively for config files
newone=False # Create new file if not found
)
# Get environment variable
get_env(
key, # Variable name
default=None, # Default value if not found
cast_type=None # Force type conversion
)
# Set environment variable
set_env(
key, # Variable name
value, # Variable value
apply_to_os=True # Also set in os.environ
)
# Save configuration
save_env(
filepath=None, # Path to save (uses loaded path if None)
format=None # Format: 'env', 'json', 'yaml', 'ini', 'toml'
)
DotEnv Class
from envdot import DotEnv
env = DotEnv(
filepath='config.toml', # Config file path
auto_load=True, # Auto-load on init
newone=False # Create new if not exists
)
# Methods
env.load(filepath=None, **kwargs)
env.get(key, default=None, cast_type=None)
env.set(key, value, apply_to_os=True)
env.save(filepath=None, format=None)
env.delete(key, remove_from_os=True)
env.all() # Get all as dict
env.keys() # Get all keys
env.clear(clear_os=False) # Clear all variables
# Access styles
value = env.KEY # Attribute
value = env['KEY'] # Dictionary
value = env.get('KEY') # Method
value = env('KEY') # Callable
Convenience Functions
load_env(filepath=None, **kwargs)- Load environment variablesget_env(key, default=None, cast_type=None)- Get environment variable same as os.getenvset_env(key, value, **kwargs)- Set environment variable same as os.setenvsave_env(filepath=None, **kwargs)- Save environment variables
📊 Format Comparison
| Feature | .env | JSON | YAML | INI | TOML |
|---|---|---|---|---|---|
| Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Nesting | ❌ | ✅ Deep | ✅ Deep | ⚠️ 1 level | ✅ Deep |
| Comments | ✅ | ❌* | ✅ | ✅ | ✅ |
| Type Safety | ⚠️ Auto | ✅ Native | ✅ Native | ⚠️ Auto | ✅ Strong |
| Arrays | ❌ | ✅ | ✅ | ❌ | ✅ |
| Portability | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Python Std | ❌ | ✅ | ❌ | ✅ | ✅ (3.11+) |
| Best For | Secrets | Web apps | Complex config | Legacy | Python projects |
* JSON5 supports comments
🎓 Best Practices
1. Choose the Right Format
- Use .env for: Secrets, simple configs, CI/CD, maximum portability
- Use JSON for: API configs, web apps, cross-language projects
- Use YAML for: Complex configs, Kubernetes/Docker, human-readable
- Use INI for: Legacy systems, section-based configs
- Use TOML for: Python projects (recommended), strong typing needs
2. Type Safety
# ✅ Good: Use explicit types for critical values
db_port = get_env('DATABASE_PORT', cast_type=int)
max_retries = get_env('MAX_RETRIES', cast_type=int)
# ✅ Good: Use defaults
timeout = get_env('TIMEOUT', default=30, cast_type=int)
# ⚠️ Careful: Auto-detection might surprise you
value = get_env('SOME_VALUE') # Could be str, int, float, bool, or None
3. Environment-Specific Configs
# config.base.toml - shared settings
# config.dev.env - development overrides
# config.prod.env - production overrides
load_env('config.base.toml')
import os
env = os.getenv('ENVIRONMENT', 'development')
if env == 'production':
load_env('config.prod.env', override=True)
4. Secure Secrets
# ✅ Good: Keep secrets in .env, never in version control
# .env (in .gitignore)
DATABASE_PASSWORD=secret123
API_KEY=xyz789
# config.toml (in git)
[database]
host = "localhost"
port = 5432
# password loaded from .env
# Load both
load_env('config.toml')
load_env('.env', override=True) # Secrets override config
🧪 Testing
# Run tests
pytest
# With coverage
pytest --cov=envdot --cov-report=html
# Specific test file
pytest tests/test_all_formats.py -v
📦 Dependencies
Core (always installed)
version-get- Version management
Optional
pyyaml>=6.0.1- YAML supporttomli>=2.0.1- TOML reading (Python < 3.11)tomli-w>=1.0.0- TOML writingjson5>=0.9.14- JSON5 supportrichcolorlog>=0.1.0- Rich logging
🔒 Security
- Never commit
.envfiles to version control - Use environment variables for secrets
- Use config files for non-sensitive settings
- Consider using secret management services for production
Example .gitignore
# Environment files
.env
.env.local
.env.*.local
config.local.*
*.env.local
# But keep examples
!.env.example
!config.example.*
📖 Examples
See the examples/ directory for complete examples:
example_basic.py- Basic usageexample_all_formats.py- All format examplesexample_production.py- Production setupexample_conversion.py- Format conversion
📄 Debug envs
DOTENV_DEBUGLOG_LEVEL_ENVDOT|ENVDOT_LOG_LEVEL- default:CRITICALNO_LOGGING- use by richcolorlogPYDEBUGGER- use by pydebuggerDEBUG- global debug env for any modules
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Inspired by
python-dotenv - TOML support via
tomli/tomllib - YAML support via
PyYAML
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Author
📞 Support
- Issues: GitHub Issues
- Email: cumulus13@gmail.com
- Documentation: See this README and inline documentation
Made with ❤️ by Hadi Cahyadi
⭐ Star this repo if you find it helpful!
Metadata
Release files for envdot 1.0.38
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| envdot-1.0.38.tar.gz | 43.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| envdot-1.0.38-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.2 kB
Release files / envdot-1.0.38.tar.gz
| Download URL | envdot-1.0.38.tar.gz |
|---|---|
| Size | 43.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aa5f5b1ca185307cb42a4d9b97270c2f61648eec47d7b7785b96dd1fea307617
|
|
BLAKE2b-256 checksum How to use checksums |
3340a18992bac5547bfc34f3c2784a36228bdcacfb9e451abd49bdfbf399fc2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.4
|
Release files / envdot-1.0.38-py3-none-any.whl
| Download URL | envdot-1.0.38-py3-none-any.whl |
|---|---|
| Size | 31.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b33eefbd7485f60dbe862a589c79c9a4f081f175e03f75fb4f8b794286db04eb
|
|
BLAKE2b-256 checksum How to use checksums |
9886c2a2fa985490813e65bd67ff6e8fe5479cedeecf7d2641722030a4fbac8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.4
|