ghosttrap-sdk 0.4.2__tar.gz → 0.4.4__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.
- ghosttrap_sdk-0.4.4/PKG-INFO +90 -0
- ghosttrap_sdk-0.4.4/README.md +82 -0
- ghosttrap_sdk-0.4.4/ghosttrap/__init__.py +3 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/ghosttrap/client.py +38 -3
- ghosttrap_sdk-0.4.4/ghosttrap_sdk.egg-info/PKG-INFO +90 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/pyproject.toml +1 -1
- ghosttrap_sdk-0.4.2/PKG-INFO +0 -50
- ghosttrap_sdk-0.4.2/README.md +0 -42
- ghosttrap_sdk-0.4.2/ghosttrap/__init__.py +0 -3
- ghosttrap_sdk-0.4.2/ghosttrap_sdk.egg-info/PKG-INFO +0 -50
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/ghosttrap/django.py +0 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/ghosttrap_sdk.egg-info/SOURCES.txt +0 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/ghosttrap_sdk.egg-info/dependency_links.txt +0 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/ghosttrap_sdk.egg-info/top_level.txt +0 -0
- {ghosttrap_sdk-0.4.2 → ghosttrap_sdk-0.4.4}/setup.cfg +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ghosttrap-sdk
|
|
3
|
+
Version: 0.4.4
|
|
4
|
+
Summary: Drop-in error reporter for ghosttrap.io
|
|
5
|
+
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-sdk
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# ghosttrap-sdk
|
|
10
|
+
|
|
11
|
+
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
pip install ghosttrap-sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Use
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
import ghosttrap
|
|
23
|
+
ghosttrap.init("t_your_token_here")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
27
|
+
|
|
28
|
+
### Optional kwargs
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
ghosttrap.init(
|
|
32
|
+
"t_your_token_here",
|
|
33
|
+
server="https://ghosttrap.io", # override only if self-hosting
|
|
34
|
+
send_user=False, # see "User context" below
|
|
35
|
+
)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## What it hooks into
|
|
39
|
+
|
|
40
|
+
- **`sys.excepthook`** — unhandled exceptions
|
|
41
|
+
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
42
|
+
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
43
|
+
|
|
44
|
+
## What it sends
|
|
45
|
+
|
|
46
|
+
Every report includes the exception type, message, traceback, frames (file/line/function/code), and the server's hostname (`socket.gethostname()`).
|
|
47
|
+
|
|
48
|
+
## Django
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
INSTALLED_APPS = [
|
|
52
|
+
...
|
|
53
|
+
"ghosttrap.django.GhostTrapApp",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
MIDDLEWARE = [
|
|
57
|
+
"ghosttrap.django.GhostTrapMiddleware",
|
|
58
|
+
...
|
|
59
|
+
]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Manually trap an event
|
|
63
|
+
|
|
64
|
+
For errors you catch and handle but still want logged, or for non-exception conditions worth flagging:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import ghosttrap
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
do_thing()
|
|
71
|
+
except ValueError as e:
|
|
72
|
+
ghosttrap.trap(e) # caught exception — sent with type, message, traceback
|
|
73
|
+
fallback()
|
|
74
|
+
|
|
75
|
+
ghosttrap.trap("payment gateway returned 503") # synthetic event labelled "TrappedEvent"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`trap()` accepts an exception instance or a string. Strings get the caller's stack attached and a `TrappedEvent` type so they're distinct from real exceptions in the CLI. Both go through the same 5-minute dedup window as the auto-hook.
|
|
79
|
+
|
|
80
|
+
## User context
|
|
81
|
+
|
|
82
|
+
Off by default. Pass `send_user=True` to `init()` and the Django middleware will attach the authenticated user's `id` and `username` to each report. Has no effect outside Django.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
ghosttrap.init("t_your_token_here", send_user=True)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Zero dependencies
|
|
89
|
+
|
|
90
|
+
Pure Python stdlib. No transitive dependencies in your production image.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# ghosttrap-sdk
|
|
2
|
+
|
|
3
|
+
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pip install ghosttrap-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Use
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import ghosttrap
|
|
15
|
+
ghosttrap.init("t_your_token_here")
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
19
|
+
|
|
20
|
+
### Optional kwargs
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
ghosttrap.init(
|
|
24
|
+
"t_your_token_here",
|
|
25
|
+
server="https://ghosttrap.io", # override only if self-hosting
|
|
26
|
+
send_user=False, # see "User context" below
|
|
27
|
+
)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## What it hooks into
|
|
31
|
+
|
|
32
|
+
- **`sys.excepthook`** — unhandled exceptions
|
|
33
|
+
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
34
|
+
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
35
|
+
|
|
36
|
+
## What it sends
|
|
37
|
+
|
|
38
|
+
Every report includes the exception type, message, traceback, frames (file/line/function/code), and the server's hostname (`socket.gethostname()`).
|
|
39
|
+
|
|
40
|
+
## Django
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
INSTALLED_APPS = [
|
|
44
|
+
...
|
|
45
|
+
"ghosttrap.django.GhostTrapApp",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
MIDDLEWARE = [
|
|
49
|
+
"ghosttrap.django.GhostTrapMiddleware",
|
|
50
|
+
...
|
|
51
|
+
]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Manually trap an event
|
|
55
|
+
|
|
56
|
+
For errors you catch and handle but still want logged, or for non-exception conditions worth flagging:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import ghosttrap
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
do_thing()
|
|
63
|
+
except ValueError as e:
|
|
64
|
+
ghosttrap.trap(e) # caught exception — sent with type, message, traceback
|
|
65
|
+
fallback()
|
|
66
|
+
|
|
67
|
+
ghosttrap.trap("payment gateway returned 503") # synthetic event labelled "TrappedEvent"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`trap()` accepts an exception instance or a string. Strings get the caller's stack attached and a `TrappedEvent` type so they're distinct from real exceptions in the CLI. Both go through the same 5-minute dedup window as the auto-hook.
|
|
71
|
+
|
|
72
|
+
## User context
|
|
73
|
+
|
|
74
|
+
Off by default. Pass `send_user=True` to `init()` and the Django middleware will attach the authenticated user's `id` and `username` to each report. Has no effect outside Django.
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
ghosttrap.init("t_your_token_here", send_user=True)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Zero dependencies
|
|
81
|
+
|
|
82
|
+
Pure Python stdlib. No transitive dependencies in your production image.
|
|
@@ -61,16 +61,30 @@ def init(dsn, server=None, send_user=False):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def report(exc, user=None):
|
|
64
|
-
"""Report a caught exception
|
|
64
|
+
"""Report a caught exception. Kept for backward compatibility; prefer `trap`."""
|
|
65
|
+
trap(exc, user=user)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def trap(exc_or_message, user=None):
|
|
69
|
+
"""Manually trap an event.
|
|
70
|
+
|
|
71
|
+
Pass an exception instance to report a caught error (its type, message,
|
|
72
|
+
and traceback are sent). Pass a string to report a synthetic event with
|
|
73
|
+
the caller's current stack — labelled `TrappedEvent` so it's distinct
|
|
74
|
+
from real exceptions.
|
|
65
75
|
|
|
66
76
|
Args:
|
|
67
|
-
|
|
77
|
+
exc_or_message: exception instance or string
|
|
68
78
|
user: optional dict with user context (id, username). Only sent
|
|
69
79
|
if init() was called with send_user=True.
|
|
70
80
|
"""
|
|
71
81
|
if _endpoint is None:
|
|
72
82
|
return
|
|
73
|
-
|
|
83
|
+
if isinstance(exc_or_message, BaseException):
|
|
84
|
+
exc = exc_or_message
|
|
85
|
+
_post(_build_payload(type(exc), exc, exc.__traceback__, user=user))
|
|
86
|
+
else:
|
|
87
|
+
_post(_build_synthetic_payload(str(exc_or_message), user=user))
|
|
74
88
|
|
|
75
89
|
|
|
76
90
|
def _error_hook(exc_type, exc_value, exc_tb):
|
|
@@ -102,6 +116,27 @@ class _GhostTrapLogHandler(logging.Handler):
|
|
|
102
116
|
report(record.exc_info[1])
|
|
103
117
|
|
|
104
118
|
|
|
119
|
+
def _build_synthetic_payload(message, user=None):
|
|
120
|
+
frames_obj = traceback.extract_stack()[:-2] # drop trap() and this builder
|
|
121
|
+
formatted = ["Traceback (most recent call last):\n"]
|
|
122
|
+
formatted += traceback.format_list(frames_obj)
|
|
123
|
+
formatted.append(f"TrappedEvent: {message}\n")
|
|
124
|
+
payload = {
|
|
125
|
+
"type": "TrappedEvent",
|
|
126
|
+
"message": message,
|
|
127
|
+
"traceback": formatted,
|
|
128
|
+
"frames": [
|
|
129
|
+
{"file": f.filename, "line": f.lineno, "function": f.name, "code": f.line}
|
|
130
|
+
for f in frames_obj
|
|
131
|
+
],
|
|
132
|
+
}
|
|
133
|
+
if _server_name:
|
|
134
|
+
payload["server_name"] = _server_name
|
|
135
|
+
if user and _send_user:
|
|
136
|
+
payload["user"] = user
|
|
137
|
+
return payload
|
|
138
|
+
|
|
139
|
+
|
|
105
140
|
def _build_payload(exc_type, exc_value, exc_tb, user=None):
|
|
106
141
|
frames = traceback.extract_tb(exc_tb) if exc_tb else []
|
|
107
142
|
payload = {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ghosttrap-sdk
|
|
3
|
+
Version: 0.4.4
|
|
4
|
+
Summary: Drop-in error reporter for ghosttrap.io
|
|
5
|
+
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-sdk
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# ghosttrap-sdk
|
|
10
|
+
|
|
11
|
+
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
pip install ghosttrap-sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Use
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
import ghosttrap
|
|
23
|
+
ghosttrap.init("t_your_token_here")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
27
|
+
|
|
28
|
+
### Optional kwargs
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
ghosttrap.init(
|
|
32
|
+
"t_your_token_here",
|
|
33
|
+
server="https://ghosttrap.io", # override only if self-hosting
|
|
34
|
+
send_user=False, # see "User context" below
|
|
35
|
+
)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## What it hooks into
|
|
39
|
+
|
|
40
|
+
- **`sys.excepthook`** — unhandled exceptions
|
|
41
|
+
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
42
|
+
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
43
|
+
|
|
44
|
+
## What it sends
|
|
45
|
+
|
|
46
|
+
Every report includes the exception type, message, traceback, frames (file/line/function/code), and the server's hostname (`socket.gethostname()`).
|
|
47
|
+
|
|
48
|
+
## Django
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
INSTALLED_APPS = [
|
|
52
|
+
...
|
|
53
|
+
"ghosttrap.django.GhostTrapApp",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
MIDDLEWARE = [
|
|
57
|
+
"ghosttrap.django.GhostTrapMiddleware",
|
|
58
|
+
...
|
|
59
|
+
]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Manually trap an event
|
|
63
|
+
|
|
64
|
+
For errors you catch and handle but still want logged, or for non-exception conditions worth flagging:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
import ghosttrap
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
do_thing()
|
|
71
|
+
except ValueError as e:
|
|
72
|
+
ghosttrap.trap(e) # caught exception — sent with type, message, traceback
|
|
73
|
+
fallback()
|
|
74
|
+
|
|
75
|
+
ghosttrap.trap("payment gateway returned 503") # synthetic event labelled "TrappedEvent"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`trap()` accepts an exception instance or a string. Strings get the caller's stack attached and a `TrappedEvent` type so they're distinct from real exceptions in the CLI. Both go through the same 5-minute dedup window as the auto-hook.
|
|
79
|
+
|
|
80
|
+
## User context
|
|
81
|
+
|
|
82
|
+
Off by default. Pass `send_user=True` to `init()` and the Django middleware will attach the authenticated user's `id` and `username` to each report. Has no effect outside Django.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
ghosttrap.init("t_your_token_here", send_user=True)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Zero dependencies
|
|
89
|
+
|
|
90
|
+
Pure Python stdlib. No transitive dependencies in your production image.
|
ghosttrap_sdk-0.4.2/PKG-INFO
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ghosttrap-sdk
|
|
3
|
-
Version: 0.4.2
|
|
4
|
-
Summary: Drop-in error reporter for ghosttrap.io
|
|
5
|
-
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-sdk
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
|
|
9
|
-
# ghosttrap-sdk
|
|
10
|
-
|
|
11
|
-
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
12
|
-
|
|
13
|
-
## Install
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
pip install ghosttrap-sdk
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Use
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
import ghosttrap
|
|
23
|
-
ghosttrap.init("t_your_token_here")
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
27
|
-
|
|
28
|
-
## What it hooks into
|
|
29
|
-
|
|
30
|
-
- **`sys.excepthook`** — unhandled exceptions
|
|
31
|
-
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
32
|
-
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
33
|
-
|
|
34
|
-
## Django
|
|
35
|
-
|
|
36
|
-
```python
|
|
37
|
-
INSTALLED_APPS = [
|
|
38
|
-
...
|
|
39
|
-
"ghosttrap.django.GhostTrapApp",
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
MIDDLEWARE = [
|
|
43
|
-
"ghosttrap.django.GhostTrapMiddleware",
|
|
44
|
-
...
|
|
45
|
-
]
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Zero dependencies
|
|
49
|
-
|
|
50
|
-
Pure Python stdlib. No transitive dependencies in your production image.
|
ghosttrap_sdk-0.4.2/README.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# ghosttrap-sdk
|
|
2
|
-
|
|
3
|
-
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
pip install ghosttrap-sdk
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Use
|
|
12
|
-
|
|
13
|
-
```python
|
|
14
|
-
import ghosttrap
|
|
15
|
-
ghosttrap.init("t_your_token_here")
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
19
|
-
|
|
20
|
-
## What it hooks into
|
|
21
|
-
|
|
22
|
-
- **`sys.excepthook`** — unhandled exceptions
|
|
23
|
-
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
24
|
-
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
25
|
-
|
|
26
|
-
## Django
|
|
27
|
-
|
|
28
|
-
```python
|
|
29
|
-
INSTALLED_APPS = [
|
|
30
|
-
...
|
|
31
|
-
"ghosttrap.django.GhostTrapApp",
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
MIDDLEWARE = [
|
|
35
|
-
"ghosttrap.django.GhostTrapMiddleware",
|
|
36
|
-
...
|
|
37
|
-
]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Zero dependencies
|
|
41
|
-
|
|
42
|
-
Pure Python stdlib. No transitive dependencies in your production image.
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: ghosttrap-sdk
|
|
3
|
-
Version: 0.4.2
|
|
4
|
-
Summary: Drop-in error reporter for ghosttrap.io
|
|
5
|
-
Project-URL: Homepage, https://github.com/alex-rowley/ghosttrap-sdk
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
|
|
9
|
-
# ghosttrap-sdk
|
|
10
|
-
|
|
11
|
-
Error reporting for Python apps, built for AI agents. Part of [ghosttrap](https://github.com/alex-rowley/ghosttrap-cli).
|
|
12
|
-
|
|
13
|
-
## Install
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
pip install ghosttrap-sdk
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Use
|
|
20
|
-
|
|
21
|
-
```python
|
|
22
|
-
import ghosttrap
|
|
23
|
-
ghosttrap.init("t_your_token_here")
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Get your token by running `ghosttrap setup` from [ghosttrap-cli](https://github.com/alex-rowley/ghosttrap-cli).
|
|
27
|
-
|
|
28
|
-
## What it hooks into
|
|
29
|
-
|
|
30
|
-
- **`sys.excepthook`** — unhandled exceptions
|
|
31
|
-
- **Python logging** — `logger.exception()` and `logger.error(..., exc_info=True)`
|
|
32
|
-
- **Celery** — task failures via `celery.signals.task_failure` (auto-detected)
|
|
33
|
-
|
|
34
|
-
## Django
|
|
35
|
-
|
|
36
|
-
```python
|
|
37
|
-
INSTALLED_APPS = [
|
|
38
|
-
...
|
|
39
|
-
"ghosttrap.django.GhostTrapApp",
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
MIDDLEWARE = [
|
|
43
|
-
"ghosttrap.django.GhostTrapMiddleware",
|
|
44
|
-
...
|
|
45
|
-
]
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Zero dependencies
|
|
49
|
-
|
|
50
|
-
Pure Python stdlib. No transitive dependencies in your production image.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|