0
# Utilities
1
2
Helper functions for package management, compatibility checking, and error handling. These utilities support the core functionality of python-json-logger.
3
4
## Core Imports
5
6
```python
7
from pythonjsonlogger.utils import package_is_available
8
from pythonjsonlogger.exception import PythonJsonLoggerError, MissingPackageError
9
```
10
11
For checking availability constants:
12
13
```python
14
import pythonjsonlogger
15
# pythonjsonlogger.ORJSON_AVAILABLE
16
# pythonjsonlogger.MSGSPEC_AVAILABLE
17
```
18
19
## Capabilities
20
21
### Package Availability Checking
22
23
Function to check if optional dependencies are available for import.
24
25
```python { .api }
26
def package_is_available(
27
name: str,
28
*,
29
throw_error: bool = False,
30
extras_name: str | None = None
31
) -> bool:
32
"""
33
Determine if the given package is available for import.
34
35
Used internally to check for optional dependencies like orjson
36
and msgspec before attempting to import them.
37
38
Parameters:
39
- name: import name of the package to check
40
- throw_error: raise MissingPackageError if package is unavailable
41
- extras_name: extra dependency name for error message
42
43
Returns:
44
True if package is available for import, False otherwise
45
46
Raises:
47
MissingPackageError: when throw_error is True and package is unavailable
48
"""
49
```
50
51
### Exception Classes
52
53
Custom exception classes for python-json-logger specific errors.
54
55
```python { .api }
56
class PythonJsonLoggerError(Exception):
57
"""
58
Generic base class for all Python JSON Logger exceptions.
59
60
Serves as the parent class for all custom exceptions
61
raised by the python-json-logger package.
62
"""
63
64
class MissingPackageError(ImportError, PythonJsonLoggerError):
65
"""
66
Exception raised when a required package is missing.
67
68
Inherits from both ImportError and PythonJsonLoggerError
69
to provide appropriate exception hierarchy.
70
"""
71
72
def __init__(self, name: str, extras_name: str | None = None) -> None:
73
"""
74
Initialize MissingPackageError with package information.
75
76
Parameters:
77
- name: name of the missing package
78
- extras_name: optional extras name for installation instructions
79
"""
80
```
81
82
### Package Constants
83
84
Module-level constants indicating availability of optional dependencies.
85
86
```python { .api }
87
ORJSON_AVAILABLE: bool
88
"""
89
Boolean indicating whether the orjson package is available.
90
91
Set automatically at import time by checking if orjson can be imported.
92
Used to conditionally enable high-performance JSON formatting features.
93
"""
94
95
MSGSPEC_AVAILABLE: bool
96
"""
97
Boolean indicating whether the msgspec package is available.
98
99
Set automatically at import time by checking if msgspec can be imported.
100
Used to conditionally enable msgspec-based JSON formatting features.
101
"""
102
```
103
104
## Usage Examples
105
106
### Checking Package Availability
107
108
```python
109
from pythonjsonlogger.utils import package_is_available
110
111
# Simple availability check
112
if package_is_available("orjson"):
113
from pythonjsonlogger.orjson import OrjsonFormatter
114
formatter = OrjsonFormatter()
115
else:
116
from pythonjsonlogger.json import JsonFormatter
117
formatter = JsonFormatter()
118
119
# Check with error raising
120
try:
121
package_is_available("orjson", throw_error=True)
122
from pythonjsonlogger.orjson import OrjsonFormatter
123
formatter = OrjsonFormatter()
124
except MissingPackageError as e:
125
print(f"Cannot use orjson: {e}")
126
from pythonjsonlogger.json import JsonFormatter
127
formatter = JsonFormatter()
128
```
129
130
### Using Package Constants
131
132
```python
133
import pythonjsonlogger
134
135
def get_optimal_formatter():
136
"""Select the best available JSON formatter."""
137
if pythonjsonlogger.ORJSON_AVAILABLE:
138
from pythonjsonlogger.orjson import OrjsonFormatter
139
return OrjsonFormatter('%(levelname)s %(name)s %(message)s')
140
elif pythonjsonlogger.MSGSPEC_AVAILABLE:
141
from pythonjsonlogger.msgspec import MsgspecFormatter
142
return MsgspecFormatter('%(levelname)s %(name)s %(message)s')
143
else:
144
from pythonjsonlogger.json import JsonFormatter
145
return JsonFormatter('%(levelname)s %(name)s %(message)s')
146
147
# Use the optimal formatter
148
formatter = get_optimal_formatter()
149
```
150
151
### Exception Handling
152
153
```python
154
from pythonjsonlogger.utils import package_is_available, MissingPackageError
155
from pythonjsonlogger.exception import PythonJsonLoggerError
156
157
def setup_high_performance_logging():
158
"""Set up logging with high-performance formatter or fallback."""
159
try:
160
# Try to use orjson with error on failure
161
package_is_available("orjson", throw_error=True, extras_name="orjson")
162
from pythonjsonlogger.orjson import OrjsonFormatter
163
return OrjsonFormatter('%(levelname)s %(message)s')
164
165
except MissingPackageError as e:
166
print(f"orjson not available: {e}")
167
168
try:
169
# Try msgspec as fallback
170
package_is_available("msgspec", throw_error=True, extras_name="msgspec")
171
from pythonjsonlogger.msgspec import MsgspecFormatter
172
return MsgspecFormatter('%(levelname)s %(message)s')
173
174
except MissingPackageError as e:
175
print(f"msgspec not available: {e}")
176
print("Using standard JSON formatter")
177
from pythonjsonlogger.json import JsonFormatter
178
return JsonFormatter('%(levelname)s %(message)s')
179
```
180
181
### Custom Package Checking
182
183
```python
184
from pythonjsonlogger.utils import package_is_available
185
186
def check_json_libraries():
187
"""Check availability of various JSON libraries."""
188
libraries = ['orjson', 'msgspec', 'ujson', 'rapidjson']
189
available = {}
190
191
for lib in libraries:
192
available[lib] = package_is_available(lib)
193
194
return available
195
196
# Check what's available
197
json_libs = check_json_libraries()
198
print("Available JSON libraries:", [k for k, v in json_libs.items() if v])
199
```
200
201
### Installation Instructions Generation
202
203
```python
204
from pythonjsonlogger.utils import MissingPackageError
205
206
def generate_install_command(package_name, extras_name=None):
207
"""Generate installation command for missing packages."""
208
if extras_name:
209
return f"pip install python-json-logger[{extras_name}]"
210
else:
211
return f"pip install {package_name}"
212
213
def safe_import_formatter(formatter_type):
214
"""Safely import a formatter with helpful error messages."""
215
try:
216
if formatter_type == "orjson":
217
from pythonjsonlogger.orjson import OrjsonFormatter
218
return OrjsonFormatter
219
elif formatter_type == "msgspec":
220
from pythonjsonlogger.msgspec import MsgspecFormatter
221
return MsgspecFormatter
222
else:
223
from pythonjsonlogger.json import JsonFormatter
224
return JsonFormatter
225
226
except MissingPackageError as e:
227
if "orjson" in str(e):
228
cmd = generate_install_command("orjson", "orjson")
229
print(f"To use orjson formatter: {cmd}")
230
elif "msgspec" in str(e):
231
cmd = generate_install_command("msgspec", "msgspec")
232
print(f"To use msgspec formatter: {cmd}")
233
234
# Fallback to standard formatter
235
from pythonjsonlogger.json import JsonFormatter
236
return JsonFormatter
237
```
238
239
## Error Messages
240
241
### MissingPackageError Messages
242
243
The MissingPackageError provides helpful error messages:
244
245
```python
246
# Without extras_name
247
MissingPackageError("orjson")
248
# Message: "The 'orjson' package is required but could not be found."
249
250
# With extras_name
251
MissingPackageError("orjson", "orjson")
252
# Message: "The 'orjson' package is required but could not be found. It can be installed using 'python-json-logger[orjson]'."
253
```
254
255
## Installation Commands
256
257
For optional high-performance dependencies:
258
259
```bash
260
# Install with orjson support
261
pip install python-json-logger[orjson]
262
263
# Install with msgspec support
264
pip install python-json-logger[msgspec]
265
266
# Install with all optional dependencies
267
pip install python-json-logger[dev]
268
```
269
270
Note: orjson and msgspec are not available on PyPy implementations.