auditrum 0.2.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.
Files changed (39) hide show
  1. auditrum-0.2.0/LICENSE +21 -0
  2. auditrum-0.2.0/PKG-INFO +266 -0
  3. auditrum-0.2.0/README.md +230 -0
  4. auditrum-0.2.0/auditrum/__init__.py +0 -0
  5. auditrum-0.2.0/auditrum/cli.py +237 -0
  6. auditrum-0.2.0/auditrum/context.py +131 -0
  7. auditrum-0.2.0/auditrum/integrations/__init__.py +0 -0
  8. auditrum-0.2.0/auditrum/integrations/django/__init__.py +0 -0
  9. auditrum-0.2.0/auditrum/integrations/django/admin.py +34 -0
  10. auditrum-0.2.0/auditrum/integrations/django/apps.py +23 -0
  11. auditrum-0.2.0/auditrum/integrations/django/audit.py +27 -0
  12. auditrum-0.2.0/auditrum/integrations/django/hooks.py +29 -0
  13. auditrum-0.2.0/auditrum/integrations/django/management/__init__.py +0 -0
  14. auditrum-0.2.0/auditrum/integrations/django/management/commands/__init__.py +0 -0
  15. auditrum-0.2.0/auditrum/integrations/django/management/commands/audit_add_partitions.py +40 -0
  16. auditrum-0.2.0/auditrum/integrations/django/middleware.py +25 -0
  17. auditrum-0.2.0/auditrum/integrations/django/migrations/0001_initial.py +24 -0
  18. auditrum-0.2.0/auditrum/integrations/django/migrations/__init__.py +0 -0
  19. auditrum-0.2.0/auditrum/integrations/django/mixins.py +46 -0
  20. auditrum-0.2.0/auditrum/integrations/django/models.py +31 -0
  21. auditrum-0.2.0/auditrum/integrations/django/settings.py +14 -0
  22. auditrum-0.2.0/auditrum/integrations/django/shell_context.py +3 -0
  23. auditrum-0.2.0/auditrum/integrations/django/templates/audit/object_history.html +58 -0
  24. auditrum-0.2.0/auditrum/integrations/django/templatetags/__init__.py +0 -0
  25. auditrum-0.2.0/auditrum/integrations/django/templatetags/audit_tags.py +14 -0
  26. auditrum-0.2.0/auditrum/integrations/django/utils.py +172 -0
  27. auditrum-0.2.0/auditrum/revert.py +39 -0
  28. auditrum-0.2.0/auditrum/schema.py +79 -0
  29. auditrum-0.2.0/auditrum/settings.py +20 -0
  30. auditrum-0.2.0/auditrum/triggers.py +118 -0
  31. auditrum-0.2.0/auditrum/utils.py +0 -0
  32. auditrum-0.2.0/auditrum.egg-info/PKG-INFO +266 -0
  33. auditrum-0.2.0/auditrum.egg-info/SOURCES.txt +37 -0
  34. auditrum-0.2.0/auditrum.egg-info/dependency_links.txt +1 -0
  35. auditrum-0.2.0/auditrum.egg-info/entry_points.txt +2 -0
  36. auditrum-0.2.0/auditrum.egg-info/requires.txt +9 -0
  37. auditrum-0.2.0/auditrum.egg-info/top_level.txt +1 -0
  38. auditrum-0.2.0/pyproject.toml +59 -0
  39. auditrum-0.2.0/setup.cfg +4 -0
auditrum-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
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,266 @@
1
+ Metadata-Version: 2.4
2
+ Name: auditrum
3
+ Version: 0.2.0
4
+ Summary: Auditrum — a PostgreSQL audit system with rich contextual logging and Django integration
5
+ Author-email: Andrei Karbanovich <andrey.karbanovich@icloud.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/tauvin/auditrum
8
+ Project-URL: BugTracker, https://github.com/tauvin/auditrum/issues
9
+ Project-URL: Documentation, https://auditrum.readthedocs.io/
10
+ Keywords: postgresql,audit,django,database,triggers,history,track changes
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Framework :: Django
22
+ Classifier: Topic :: Database
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: typer>=0.9
28
+ Requires-Dist: psycopg[binary]>=3.1
29
+ Requires-Dist: pydantic>=2.5
30
+ Requires-Dist: structlog>=23.0
31
+ Requires-Dist: dateutils>=0.6.12
32
+ Requires-Dist: dotenv>=0.9.9
33
+ Provides-Extra: django
34
+ Requires-Dist: Django>=4.2; extra == "django"
35
+ Dynamic: license-file
36
+
37
+ <file name=0 path=README.md>#auditrum
38
+
39
+ A PostgreSQL audit system for tracking database changes with rich contextual information, featuring seamless Django integration.
40
+
41
+ ---
42
+
43
+ ## ✨ Features
44
+
45
+ - **Automatic Change Tracking** – PostgreSQL triggers to log all `INSERT`, `UPDATE`, and `DELETE`
46
+ - **Rich Context** – Who, when, why, and from where
47
+ - **Partitioned Storage** – Time-partitioned audit table
48
+ - **Django Integration** – Models, admin, middleware
49
+ - **Flexible Configuration** – Track/include/exclude fields, add conditions
50
+ - **Performance Optimized** – Minimal database overhead
51
+
52
+ ---
53
+
54
+ ## 📦 Installation
55
+
56
+ ### With `pip`
57
+
58
+ ```bash
59
+ pip install auditrum
60
+ ```
61
+
62
+ To include Django support:
63
+
64
+ ```bash
65
+ pip install auditrum[django]
66
+ ```
67
+
68
+ ---
69
+
70
+ ### With [`uv`](https://github.com/astral-sh/uv)
71
+
72
+ ```bash
73
+ uv add auditrum
74
+ uv add auditrum[django]
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 🚀 Quick Start
80
+
81
+ ### 🔧 With Django
82
+
83
+ 1. **Add to `INSTALLED_APPS`:**
84
+
85
+ ```python
86
+ INSTALLED_APPS = [
87
+ # ...
88
+ 'auditrum.integrations.django',
89
+ ]
90
+ ```
91
+
92
+ 2. **Add middleware:**
93
+
94
+ ```python
95
+ MIDDLEWARE = [
96
+ # ...
97
+ 'auditrum.integrations.django.middleware.RequestIDMiddleware',
98
+ 'auditrum.integrations.django.middleware.AuditrumMiddleware',
99
+ ]
100
+ ```
101
+
102
+ 3. **Register models:**
103
+
104
+ Create a new `audit.py` file inside your Django app (e.g., `yourapp/audit.py`) and register models there:
105
+
106
+ ```python
107
+ # yourapp/audit.py
108
+
109
+ from auditrum.integrations.django.audit import register
110
+ from .models import User
111
+
112
+ register(User, track_only=["name", "email"])
113
+ ```
114
+
115
+ The `auditrum` integration will automatically discover and execute this file (like `admin.py`), so no need to import it manually.
116
+
117
+ 4. **Run migrations:**
118
+
119
+ ```bash
120
+ python manage.py migrate
121
+ ```
122
+
123
+ This will create the audit table and set up triggers automatically.
124
+
125
+ 5. **Set up monthly partitions:**
126
+
127
+ Add a cron job to run the following command on the last day of each month. This will ensure partitions exist for upcoming months:
128
+
129
+ ```bash
130
+ python manage.py audit_add_partitions --months 3
131
+ ```
132
+
133
+ This will create audit table partitions for the next 3 months.
134
+
135
+ #### ⏰ Cron Job Example
136
+
137
+ To automatically run the partition creation every month (e.g. on the 28th at 23:50), add the following cron entry:
138
+
139
+ ```cron
140
+ 50 23 28 * * /path/to/your/venv/bin/python /path/to/your/project/manage.py audit_add_partitions --months 3
141
+ ```
142
+
143
+ - Replace `/path/to/your/venv/bin/python` with the full path to your virtualenv's Python interpreter.
144
+ - Replace `/path/to/your/project/manage.py` with the path to your project's manage.py file.
145
+ - Adjust the `--months 3` argument as needed to define how far ahead partitions should be created.
146
+
147
+ 6. **Enable audit context for management commands (optional)**
148
+
149
+ To track changes made via `manage.py` commands (e.g. `migrate`, `shell`) with proper `source` and `change_reason` in audit logs, you can modify your `manage.py` like this:
150
+
151
+ ```python
152
+ # manage.py
153
+
154
+ from auditrum.utils import audit_tracked
155
+
156
+
157
+ def main():
158
+ """Run administrative tasks."""
159
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_app.settings")
160
+
161
+ AUDIT_COMMAND_SOURCES = {
162
+ "shell": "shell",
163
+ "migrate": "migration",
164
+ "makemigrations": "migration",
165
+ }
166
+
167
+ cmd = sys.argv[1] if len(sys.argv) > 1 else None
168
+ audit_source = AUDIT_COMMAND_SOURCES.get(cmd)
169
+
170
+ if audit_source:
171
+ try:
172
+ audit_tracked(source=audit_source).__enter__()
173
+ except Exception as e:
174
+ print(f"[audit] failed to enable tracking for source='{audit_source}': {e}")
175
+
176
+ if cmd == "shell":
177
+ try:
178
+ import apps.audit.shell_context # noqa
179
+ except ImportError:
180
+ print("[audit] Warning: shell_context not found. Skipping shell audit.")
181
+
182
+ ...
183
+ ```
184
+
185
+ This ensures your migrations and shell activity are properly attributed in the audit log.
186
+
187
+ ---
188
+
189
+ ### 🧩 Without Django
190
+
191
+ ```python
192
+ from auditrum.schema import generate_auditlog_table_sql
193
+ from auditrum.triggers import generate_trigger_sql
194
+ import psycopg
195
+
196
+ with psycopg.connect("your_connection_string") as conn, conn.cursor() as cursor:
197
+ # Create audit table
198
+ cursor.execute(generate_auditlog_table_sql("auditlog"))
199
+
200
+ # Create trigger for a table
201
+ sql = generate_trigger_sql(
202
+ table_name="users",
203
+ track_only=["name", "email"]
204
+ )
205
+ cursor.execute(sql)
206
+ conn.commit()
207
+ ```
208
+
209
+ ---
210
+
211
+ ## ⚙️ Configuration Examples
212
+
213
+ ### ✅ Track only specific fields
214
+
215
+ ```python
216
+ register(User, track_only=["name", "email"])
217
+ ```
218
+
219
+ ### ❌ Exclude specific fields
220
+
221
+ ```python
222
+ register(Product, exclude_fields=["created_at", "updated_at"])
223
+ ```
224
+
225
+ ### 📐 Add conditions
226
+
227
+ ```python
228
+ register(Subscription, log_conditions="NEW.is_active = TRUE")
229
+ ```
230
+
231
+ ---
232
+
233
+ ## 📚 Adding Context to Changes
234
+
235
+ ### Using decorator:
236
+
237
+ ```python
238
+ from auditrum.context import with_change_reason
239
+
240
+
241
+ @with_change_reason("User requested password reset")
242
+ def reset_password(user_id):
243
+ ...
244
+ ```
245
+
246
+ ### Using context manager:
247
+
248
+ ```python
249
+ from auditrum.context import audit_context
250
+
251
+ with audit_context.use_change_reason("Bulk update for compliance"):
252
+ ...
253
+ ```
254
+
255
+ ---
256
+
257
+ ## 📖 Documentation
258
+
259
+ 👉 Full docs at: [https://auditrum.readthedocs.io/](https://auditrum.readthedocs.io/)
260
+
261
+ ---
262
+
263
+ ## 🪪 License
264
+
265
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
266
+ </file>
@@ -0,0 +1,230 @@
1
+ <file name=0 path=README.md>#auditrum
2
+
3
+ A PostgreSQL audit system for tracking database changes with rich contextual information, featuring seamless Django integration.
4
+
5
+ ---
6
+
7
+ ## ✨ Features
8
+
9
+ - **Automatic Change Tracking** – PostgreSQL triggers to log all `INSERT`, `UPDATE`, and `DELETE`
10
+ - **Rich Context** – Who, when, why, and from where
11
+ - **Partitioned Storage** – Time-partitioned audit table
12
+ - **Django Integration** – Models, admin, middleware
13
+ - **Flexible Configuration** – Track/include/exclude fields, add conditions
14
+ - **Performance Optimized** – Minimal database overhead
15
+
16
+ ---
17
+
18
+ ## 📦 Installation
19
+
20
+ ### With `pip`
21
+
22
+ ```bash
23
+ pip install auditrum
24
+ ```
25
+
26
+ To include Django support:
27
+
28
+ ```bash
29
+ pip install auditrum[django]
30
+ ```
31
+
32
+ ---
33
+
34
+ ### With [`uv`](https://github.com/astral-sh/uv)
35
+
36
+ ```bash
37
+ uv add auditrum
38
+ uv add auditrum[django]
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 🚀 Quick Start
44
+
45
+ ### 🔧 With Django
46
+
47
+ 1. **Add to `INSTALLED_APPS`:**
48
+
49
+ ```python
50
+ INSTALLED_APPS = [
51
+ # ...
52
+ 'auditrum.integrations.django',
53
+ ]
54
+ ```
55
+
56
+ 2. **Add middleware:**
57
+
58
+ ```python
59
+ MIDDLEWARE = [
60
+ # ...
61
+ 'auditrum.integrations.django.middleware.RequestIDMiddleware',
62
+ 'auditrum.integrations.django.middleware.AuditrumMiddleware',
63
+ ]
64
+ ```
65
+
66
+ 3. **Register models:**
67
+
68
+ Create a new `audit.py` file inside your Django app (e.g., `yourapp/audit.py`) and register models there:
69
+
70
+ ```python
71
+ # yourapp/audit.py
72
+
73
+ from auditrum.integrations.django.audit import register
74
+ from .models import User
75
+
76
+ register(User, track_only=["name", "email"])
77
+ ```
78
+
79
+ The `auditrum` integration will automatically discover and execute this file (like `admin.py`), so no need to import it manually.
80
+
81
+ 4. **Run migrations:**
82
+
83
+ ```bash
84
+ python manage.py migrate
85
+ ```
86
+
87
+ This will create the audit table and set up triggers automatically.
88
+
89
+ 5. **Set up monthly partitions:**
90
+
91
+ Add a cron job to run the following command on the last day of each month. This will ensure partitions exist for upcoming months:
92
+
93
+ ```bash
94
+ python manage.py audit_add_partitions --months 3
95
+ ```
96
+
97
+ This will create audit table partitions for the next 3 months.
98
+
99
+ #### ⏰ Cron Job Example
100
+
101
+ To automatically run the partition creation every month (e.g. on the 28th at 23:50), add the following cron entry:
102
+
103
+ ```cron
104
+ 50 23 28 * * /path/to/your/venv/bin/python /path/to/your/project/manage.py audit_add_partitions --months 3
105
+ ```
106
+
107
+ - Replace `/path/to/your/venv/bin/python` with the full path to your virtualenv's Python interpreter.
108
+ - Replace `/path/to/your/project/manage.py` with the path to your project's manage.py file.
109
+ - Adjust the `--months 3` argument as needed to define how far ahead partitions should be created.
110
+
111
+ 6. **Enable audit context for management commands (optional)**
112
+
113
+ To track changes made via `manage.py` commands (e.g. `migrate`, `shell`) with proper `source` and `change_reason` in audit logs, you can modify your `manage.py` like this:
114
+
115
+ ```python
116
+ # manage.py
117
+
118
+ from auditrum.utils import audit_tracked
119
+
120
+
121
+ def main():
122
+ """Run administrative tasks."""
123
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_app.settings")
124
+
125
+ AUDIT_COMMAND_SOURCES = {
126
+ "shell": "shell",
127
+ "migrate": "migration",
128
+ "makemigrations": "migration",
129
+ }
130
+
131
+ cmd = sys.argv[1] if len(sys.argv) > 1 else None
132
+ audit_source = AUDIT_COMMAND_SOURCES.get(cmd)
133
+
134
+ if audit_source:
135
+ try:
136
+ audit_tracked(source=audit_source).__enter__()
137
+ except Exception as e:
138
+ print(f"[audit] failed to enable tracking for source='{audit_source}': {e}")
139
+
140
+ if cmd == "shell":
141
+ try:
142
+ import apps.audit.shell_context # noqa
143
+ except ImportError:
144
+ print("[audit] Warning: shell_context not found. Skipping shell audit.")
145
+
146
+ ...
147
+ ```
148
+
149
+ This ensures your migrations and shell activity are properly attributed in the audit log.
150
+
151
+ ---
152
+
153
+ ### 🧩 Without Django
154
+
155
+ ```python
156
+ from auditrum.schema import generate_auditlog_table_sql
157
+ from auditrum.triggers import generate_trigger_sql
158
+ import psycopg
159
+
160
+ with psycopg.connect("your_connection_string") as conn, conn.cursor() as cursor:
161
+ # Create audit table
162
+ cursor.execute(generate_auditlog_table_sql("auditlog"))
163
+
164
+ # Create trigger for a table
165
+ sql = generate_trigger_sql(
166
+ table_name="users",
167
+ track_only=["name", "email"]
168
+ )
169
+ cursor.execute(sql)
170
+ conn.commit()
171
+ ```
172
+
173
+ ---
174
+
175
+ ## ⚙️ Configuration Examples
176
+
177
+ ### ✅ Track only specific fields
178
+
179
+ ```python
180
+ register(User, track_only=["name", "email"])
181
+ ```
182
+
183
+ ### ❌ Exclude specific fields
184
+
185
+ ```python
186
+ register(Product, exclude_fields=["created_at", "updated_at"])
187
+ ```
188
+
189
+ ### 📐 Add conditions
190
+
191
+ ```python
192
+ register(Subscription, log_conditions="NEW.is_active = TRUE")
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 📚 Adding Context to Changes
198
+
199
+ ### Using decorator:
200
+
201
+ ```python
202
+ from auditrum.context import with_change_reason
203
+
204
+
205
+ @with_change_reason("User requested password reset")
206
+ def reset_password(user_id):
207
+ ...
208
+ ```
209
+
210
+ ### Using context manager:
211
+
212
+ ```python
213
+ from auditrum.context import audit_context
214
+
215
+ with audit_context.use_change_reason("Bulk update for compliance"):
216
+ ...
217
+ ```
218
+
219
+ ---
220
+
221
+ ## 📖 Documentation
222
+
223
+ 👉 Full docs at: [https://auditrum.readthedocs.io/](https://auditrum.readthedocs.io/)
224
+
225
+ ---
226
+
227
+ ## 🪪 License
228
+
229
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
230
+ </file>
File without changes