0
# Advanced Data Structures
1
2
Complex data structure parsing including lists, dictionaries, and JSON with support for nested type casting, custom delimiters, and flexible serialization formats.
3
4
## Capabilities
5
6
### List Parsing
7
8
Parse delimited strings into Python lists with optional element type casting and custom delimiter support.
9
10
```python { .api }
11
def list(self, name: str, default=..., subcast=None, *, delimiter=",", validate=None, **kwargs):
12
"""
13
Parse environment variable as list.
14
15
Parameters:
16
- name: str, environment variable name
17
- default: list, default value if variable not set (optional)
18
- subcast: type or callable for element type conversion (optional)
19
- delimiter: str, character(s) used to split the string (default: ",")
20
- validate: callable or list of callables for validation (optional)
21
- **kwargs: additional marshmallow field arguments
22
23
Returns:
24
list: List of elements, optionally type-cast
25
26
Notes:
27
Empty string returns empty list. Subcast applies to each list element.
28
"""
29
```
30
31
Usage examples:
32
33
```python
34
import os
35
from environs import env
36
37
# Basic list parsing
38
os.environ["TAGS"] = "web,api,python"
39
tags = env.list("TAGS") # => ["web", "api", "python"]
40
41
# List with type casting
42
os.environ["PORTS"] = "8080,8081,8082"
43
ports = env.list("PORTS", subcast=int) # => [8080, 8081, 8082]
44
45
# List with custom delimiter
46
os.environ["COORDINATES"] = "23.3 50.0 -1.2"
47
coords = env.list("COORDINATES", subcast=float, delimiter=" ") # => [23.3, 50.0, -1.2]
48
49
# Empty list handling
50
os.environ["EMPTY_LIST"] = ""
51
empty = env.list("EMPTY_LIST") # => []
52
53
# Default value
54
default_tags = env.list("MISSING_TAGS", ["default"]) # => ["default"]
55
```
56
57
### Dictionary Parsing
58
59
Parse key-value string representations into Python dictionaries with support for nested type casting and custom delimiters.
60
61
```python { .api }
62
def dict(self, name: str, default=..., *, subcast_keys=None, subcast_values=None,
63
delimiter=",", key_value_delimiter="=", validate=None, **kwargs):
64
"""
65
Parse environment variable as dictionary.
66
67
Parameters:
68
- name: str, environment variable name
69
- default: dict, default value if variable not set (optional)
70
- subcast_keys: type or callable for key type conversion (optional)
71
- subcast_values: type or callable for value type conversion (optional)
72
- delimiter: str, character(s) separating key-value pairs (default: ",")
73
- key_value_delimiter: str, character(s) separating keys from values (default: "=")
74
- validate: callable or list of callables for validation (optional)
75
- **kwargs: additional marshmallow field arguments
76
77
Returns:
78
dict: Dictionary with optionally type-cast keys and values
79
"""
80
```
81
82
Usage examples:
83
84
```python
85
import os
86
from environs import env
87
88
# Basic dictionary parsing
89
os.environ["CONFIG"] = "host=localhost,port=8080,debug=true"
90
config = env.dict("CONFIG") # => {"host": "localhost", "port": "8080", "debug": "true"}
91
92
# Dictionary with value type casting
93
os.environ["LIMITS"] = "max_connections=100,timeout=30,retries=3"
94
limits = env.dict("LIMITS", subcast_values=int) # => {"max_connections": 100, "timeout": 30, "retries": 3}
95
96
# Dictionary with both key and value casting
97
os.environ["WEIGHTS"] = "1=0.5,2=0.3,3=0.2"
98
weights = env.dict("WEIGHTS", subcast_keys=int, subcast_values=float) # => {1: 0.5, 2: 0.3, 3: 0.2}
99
100
# Custom delimiters
101
os.environ["LOCATIONS"] = "x:234 y:123 z:456"
102
locations = env.dict("LOCATIONS", subcast_values=int, delimiter=" ", key_value_delimiter=":")
103
# => {"x": 234, "y": 123, "z": 456}
104
```
105
106
### JSON Parsing
107
108
Parse JSON-formatted strings into Python objects with full JSON specification support.
109
110
```python { .api }
111
def json(self, name: str, default=..., *, validate=None, **kwargs):
112
"""
113
Parse environment variable as JSON.
114
115
Parameters:
116
- name: str, environment variable name
117
- default: any JSON-serializable type, default value if variable not set (optional)
118
- validate: callable or list of callables for validation (optional)
119
- **kwargs: additional marshmallow field arguments
120
121
Returns:
122
any: Parsed JSON object (dict, list, str, int, float, bool, None)
123
124
Raises:
125
EnvValidationError: If value is not valid JSON
126
"""
127
```
128
129
Usage examples:
130
131
```python
132
import os
133
from environs import env
134
135
# Simple JSON object
136
os.environ["API_CONFIG"] = '{"endpoint": "https://api.example.com", "timeout": 30, "retries": 3}'
137
api_config = env.json("API_CONFIG")
138
# => {"endpoint": "https://api.example.com", "timeout": 30, "retries": 3}
139
140
# JSON array
141
os.environ["ALLOWED_HOSTS"] = '["localhost", "127.0.0.1", "example.com"]'
142
hosts = env.json("ALLOWED_HOSTS") # => ["localhost", "127.0.0.1", "example.com"]
143
144
# Complex nested JSON
145
os.environ["DATABASE_CONFIG"] = '''
146
{
147
"default": {
148
"engine": "postgresql",
149
"host": "localhost",
150
"port": 5432,
151
"credentials": {
152
"username": "user",
153
"password": "secret"
154
}
155
}
156
}
157
'''
158
db_config = env.json("DATABASE_CONFIG")
159
# => Complex nested dictionary structure
160
161
# Default JSON value
162
default_config = env.json("MISSING_CONFIG", {"enabled": False}) # => {"enabled": False}
163
```
164
165
## Advanced Usage Patterns
166
167
### Combining Lists and Type Casting
168
169
```python
170
import os
171
from environs import env
172
from decimal import Decimal
173
174
# List of decimals for financial calculations
175
os.environ["PRICES"] = "19.99,29.99,49.99"
176
prices = env.list("PRICES", subcast=Decimal) # => [Decimal('19.99'), Decimal('29.99'), Decimal('49.99')]
177
178
# List of booleans
179
os.environ["FEATURE_FLAGS"] = "true,false,true"
180
flags = env.list("FEATURE_FLAGS", subcast=env.bool) # Custom subcast using env methods
181
```
182
183
### Complex Dictionary Configurations
184
185
```python
186
import os
187
from environs import env
188
189
# Multi-level configuration parsing
190
os.environ["CACHE_SETTINGS"] = "redis_host=localhost,redis_port=6379,redis_db=0,timeout=300"
191
cache_config = env.dict("CACHE_SETTINGS")
192
193
# Extract and cast specific values
194
redis_port = int(cache_config["redis_port"]) # Manual casting after parsing
195
timeout = int(cache_config["timeout"])
196
```
197
198
### Error Handling
199
200
```python
201
from environs import env, EnvValidationError
202
import os
203
204
# Invalid JSON handling
205
os.environ["INVALID_JSON"] = '{"missing": "quote}'
206
207
try:
208
config = env.json("INVALID_JSON")
209
except EnvValidationError as e:
210
print(f"JSON parsing failed: {e}")
211
print(f"Error details: {e.error_messages}")
212
213
# Invalid list subcast handling
214
os.environ["INVALID_NUMBERS"] = "1,2,not_a_number,4"
215
216
try:
217
numbers = env.list("INVALID_NUMBERS", subcast=int)
218
except EnvValidationError as e:
219
print(f"List subcast failed: {e}")
220
```
221
222
## Types
223
224
```python { .api }
225
from typing import Any, Callable, Dict, List, Union
226
227
SubcastFunction = Union[type, Callable[[Any], Any]]
228
JSONValue = Union[Dict, List, str, int, float, bool, None]
229
```