irongit

Enhanced time synchronization for drf views.

123 lines5.0 KBMarkdown
1# TimeCheck
2
3**TimeCheck** is a Django REST Framework (DRF) extension that wraps the standard `Request` with first-class support for timestamp-based synchronization.
4
5It adds a structured way to compare client and server timestamps, detect when updates are needed, and manage API headers in a consistent, testable manner.
6
7---
8
9## Features
10
11- 🧠 `TimeCheck`: context-aware timestamp diff logic (`raise_get`, etc.)
12- ⚙️ Configurable via `TimeCheckConf` (env vars or `settings.TIMECHECK_CONF`)
13- 🔒 Built-in error handling for missing or invalid timestamps
14
15---
16
17## Installation
18
19```bash
20pip install git+https://github.com/huncholane/django-timecheck
21````
22
23---
24
25## Usage
26
27### Example View
28
29```python
30from timecheck import TimeCheck
31from rest_framework.request import Request
32from rest_framework.response import Response
33from rest_framework.views import APIView
34from .models import MyModel
35
36class MyView(APIView):
37 def get(request: Request, pk:int):
38 instance = MyModel.objects.get(pk=pk)
39 TimeCheck(request,instance).should_get() # throws rest framework exception
40 ...
41 return Response(data)
42
43 def put(request: Request, pk:int):
44 instance = MyModel.objects.get(pk=pk)
45 TimeCheck(request,instance).should_update() # throws rest framework exception
46 ...
47 return Response(data)
48```
49
50---
51
52### Parameters
53
54TimeCheck(request, ...) has the following arguments:
55
56- **request** `rest_framework.request.Request`: A request to extract the client timestamp from. (required)
57- **instance** `models.Model`: The database instance to extract the server timestamp from using the instance field. (optional)
58- **server_timestamp** `dt.datetime`: A manual server timestamp to override TimeCheck parsing.(optional)
59- **client_timestamp** `dt.datetime`: A manual client timestamp to override TimeCheck parsing. (optional)
60- **header_field** `str`: Field to find client timestamp in the header (defaults to config)
61- **body_field** `str`: Field to find client timestamp in request body (defaults to config)
62- **instance_field** `str`: Field to find server timestamp in database model (defaults to config)
63- **missing_action**: `"noupdate" | "continue"` (defaults to config)
64 - `noupdate` will raise a drf exception to indicate the view should stop early if the client does not provide a timestamp
65 - `continue` allows the view to continue processing data when the client does not provide a timestamp
66- **noupdate_code** `int` The response code for exceptions raised to indicate the view should stop processing
67- **dt_fmt** `str` The datetime format used to normalize timestamps. Useful when the client and server use mismatched time depths (defaults to config)
68- **raise_exception** `bool` Raises and exception if the process should stop (defaults to config)
69
70### TimeCheck Methods
71
72- `should_get` Raises a `NoUpdate` exception when the client timestamp is newer than or equal to the server timestamp. Returns a True if the client should receive data.
73- `should_update` Raises a `NoUpdate` exception when the client timestamp is older than or equal to the server timestamp. Returns a True if the update should continue.
74
75---
76
77## Configuration
78
79TimeCheck is customizable through the django settings, env, and on a per usage basis.
80
81### Django Settings Dictionairy (Defaults)
82
83```python
84TIMECHECK_CONF = {
85 "body_field": "lastUpdated",
86 "dt_fmt": "%Y-%m-%dT%H:%M:%S%z",
87 "header_field": "lastUpdated",
88 "instance_field": "lastUpdated",
89 "missing_action": "noupdate",
90 "noupdate_code": 418,
91 "raise_exception": True,
92}
93```
94
95###
96
97Set via environment variables or in `settings.TIMECHECK_CONF`:
98
99| Key | Default | Description |
100| -------------------------------------- | --------------------- | ------------------------------------------------------------- |
101| `TIMECHECK_HEADER_FIELD` | `lastUpdated` | Header field used for client timestamp (str) |
102| `TIMECHECK_BODY_FIELD` | `lastUpdated` | Body field used for client timestamp (str) |
103| `TIMECHECK_INSTANCE_FIELD` | `lastUpdated` | Model field used for server timestamp (str) |
104| `TIMECHECK_NOUPDATE_CODE` | `418` | Error code raised when update is unnecessary (int) |
105| `TIMECHECK_MISSING_ACTION` | `noupdate` | Action if timestamp is missing (`continue`, `noupdate`) |
106| `TIMECHECK_DT_FMT` | `%Y-%m-%dT%H:%M:%S%z` | Timestamp parsing format (str) |
107| RAISE_EXCEPTION | True | Raises exceptions by default (bool) |
108
109---
110
111## Exceptions
112
113- `InvalidClientDatetimeField (400)` When the client timestamp is found but cannot be parsed.
114- `InvalidServerDatetimeField (500)` When the server cannot make up a timestamp.
115- `NoUpdate (Custom)` Custom status code used to represent no update.
116
117Raised when timestamps are missing, malformatted, or update should be skipped.
118
119---
120
121## License
122
123This project is licensed under the [MIT License]LICENSE.