wiselibv2 0.4.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.
- wiselibv2-0.4.0/MANIFEST.in +2 -0
- wiselibv2-0.4.0/PKG-INFO +32 -0
- wiselibv2-0.4.0/README.md +534 -0
- wiselibv2-0.4.0/pyproject.toml +3 -0
- wiselibv2-0.4.0/setup.cfg +4 -0
- wiselibv2-0.4.0/setup.py +41 -0
- wiselibv2-0.4.0/wise/__init__.py +1 -0
- wiselibv2-0.4.0/wise/apps.py +6 -0
- wiselibv2-0.4.0/wise/dependencies/__init__.py +1 -0
- wiselibv2-0.4.0/wise/dependencies/delphinus.py +329 -0
- wiselibv2-0.4.0/wise/internal/__init__.py +0 -0
- wiselibv2-0.4.0/wise/internal/health_check.py +98 -0
- wiselibv2-0.4.0/wise/internal/views.py +10 -0
- wiselibv2-0.4.0/wise/management/__init__.py +0 -0
- wiselibv2-0.4.0/wise/management/commands/__init__.py +0 -0
- wiselibv2-0.4.0/wise/management/commands/consume.py +99 -0
- wiselibv2-0.4.0/wise/management/commands/export_periodic_tasks.py +70 -0
- wiselibv2-0.4.0/wise/management/commands/health_check.py +52 -0
- wiselibv2-0.4.0/wise/management/commands/serve_metrics.py +32 -0
- wiselibv2-0.4.0/wise/management/commands/wise_setup.py +17 -0
- wiselibv2-0.4.0/wise/migrations/__init__.py +0 -0
- wiselibv2-0.4.0/wise/models.py +0 -0
- wiselibv2-0.4.0/wise/settings/__init__.py +2 -0
- wiselibv2-0.4.0/wise/settings/dependencies.py +20 -0
- wiselibv2-0.4.0/wise/settings/env.py +71 -0
- wiselibv2-0.4.0/wise/settings/setup.py +120 -0
- wiselibv2-0.4.0/wise/station/__init__.py +0 -0
- wiselibv2-0.4.0/wise/station/consts.py +3 -0
- wiselibv2-0.4.0/wise/station/heap.py +285 -0
- wiselibv2-0.4.0/wise/station/publish.py +194 -0
- wiselibv2-0.4.0/wise/station/registry.py +34 -0
- wiselibv2-0.4.0/wise/station/updater.py +447 -0
- wiselibv2-0.4.0/wise/station/views.py +71 -0
- wiselibv2-0.4.0/wise/tasks.py +76 -0
- wiselibv2-0.4.0/wise/urls.py +14 -0
- wiselibv2-0.4.0/wise/utils/__init__.py +0 -0
- wiselibv2-0.4.0/wise/utils/async_redis.py +74 -0
- wiselibv2-0.4.0/wise/utils/cache.py +113 -0
- wiselibv2-0.4.0/wise/utils/candles.py +98 -0
- wiselibv2-0.4.0/wise/utils/celery.py +22 -0
- wiselibv2-0.4.0/wise/utils/django.py +12 -0
- wiselibv2-0.4.0/wise/utils/exception.py +99 -0
- wiselibv2-0.4.0/wise/utils/formatters/__init__.py +1 -0
- wiselibv2-0.4.0/wise/utils/formatters/number_formatter.py +136 -0
- wiselibv2-0.4.0/wise/utils/http.py +27 -0
- wiselibv2-0.4.0/wise/utils/http_requests.py +65 -0
- wiselibv2-0.4.0/wise/utils/kafka.py +68 -0
- wiselibv2-0.4.0/wise/utils/metrics/__init__.py +1 -0
- wiselibv2-0.4.0/wise/utils/metrics/logs.py +17 -0
- wiselibv2-0.4.0/wise/utils/models.py +65 -0
- wiselibv2-0.4.0/wise/utils/monitoring.py +199 -0
- wiselibv2-0.4.0/wise/utils/numbers.py +130 -0
- wiselibv2-0.4.0/wise/utils/periodic_tasks.py +163 -0
- wiselibv2-0.4.0/wise/utils/python.py +9 -0
- wiselibv2-0.4.0/wise/utils/rate_limit.py +39 -0
- wiselibv2-0.4.0/wise/utils/redis.py +220 -0
- wiselibv2-0.4.0/wise/utils/secrets.py +35 -0
- wiselibv2-0.4.0/wise/utils/sentry.py +27 -0
- wiselibv2-0.4.0/wise/utils/stream_manager.py +47 -0
- wiselibv2-0.4.0/wise/utils/time.py +95 -0
- wiselibv2-0.4.0/wise/utils/tracing.py +285 -0
- wiselibv2-0.4.0/wise_market/__init__.py +0 -0
- wiselibv2-0.4.0/wise_market/admin.py +49 -0
- wiselibv2-0.4.0/wise_market/apps.py +6 -0
- wiselibv2-0.4.0/wise_market/management/__init__.py +0 -0
- wiselibv2-0.4.0/wise_market/management/commands/__init__.py +0 -0
- wiselibv2-0.4.0/wise_market/management/commands/check_intial_models.py +107 -0
- wiselibv2-0.4.0/wise_market/management/commands/remove_old_models.py +65 -0
- wiselibv2-0.4.0/wise_market/management/commands/table_rename_migration.py +83 -0
- wiselibv2-0.4.0/wise_market/management/commands/utils.py +22 -0
- wiselibv2-0.4.0/wise_market/migrations/0001_initial.py +516 -0
- wiselibv2-0.4.0/wise_market/migrations/0002_networksymbolbinding_network_symbol_binding_unique_contract_address_network.py +20 -0
- wiselibv2-0.4.0/wise_market/migrations/__init__.py +0 -0
- wiselibv2-0.4.0/wise_market/models.py +284 -0
- wiselibv2-0.4.0/wise_market/tests.py +3 -0
- wiselibv2-0.4.0/wise_market/updaters.py +241 -0
- wiselibv2-0.4.0/wise_market/utils.py +47 -0
- wiselibv2-0.4.0/wise_market/views.py +3 -0
- wiselibv2-0.4.0/wiselibv2.egg-info/PKG-INFO +32 -0
- wiselibv2-0.4.0/wiselibv2.egg-info/SOURCES.txt +95 -0
- wiselibv2-0.4.0/wiselibv2.egg-info/dependency_links.txt +1 -0
- wiselibv2-0.4.0/wiselibv2.egg-info/requires.txt +20 -0
- wiselibv2-0.4.0/wiselibv2.egg-info/top_level.txt +4 -0
- wiselibv2-0.4.0/wiserpc/__init__.py +41 -0
- wiselibv2-0.4.0/wiserpc/common_pb2.py +37 -0
- wiselibv2-0.4.0/wiserpc/common_pb2.pyi +41 -0
- wiselibv2-0.4.0/wiserpc/common_pb2_grpc.py +107 -0
- wiselibv2-0.4.0/wiserpc/delphinus_pb2.py +84 -0
- wiselibv2-0.4.0/wiserpc/delphinus_pb2.pyi +1514 -0
- wiselibv2-0.4.0/wiserpc/delphinus_pb2_grpc.py +389 -0
- wiselibv2-0.4.0/wiserpc/network_radar_pb2.py +88 -0
- wiselibv2-0.4.0/wiserpc/network_radar_pb2.pyi +1760 -0
- wiselibv2-0.4.0/wiserpc/network_radar_pb2_grpc.py +530 -0
- wiselibv2-0.4.0/wiserpc/py.typed +0 -0
- wiselibv2-0.4.0/wiserpc/wealth_manager_pb2.py +47 -0
- wiselibv2-0.4.0/wiserpc/wealth_manager_pb2.pyi +604 -0
- wiselibv2-0.4.0/wiserpc/wealth_manager_pb2_grpc.py +107 -0
wiselibv2-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: wiselibv2
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: WISE Library
|
|
5
|
+
Home-page: https://github.com/yourusername/wiselib
|
|
6
|
+
Author: Wise Man
|
|
7
|
+
Author-email: your.email@example.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: setuptools>=70.3.0
|
|
14
|
+
Requires-Dist: Django>=4.0.0
|
|
15
|
+
Requires-Dist: django-prometheus==2.3.1
|
|
16
|
+
Requires-Dist: celery==5.4.0
|
|
17
|
+
Requires-Dist: django-celery-results~=2.5.1
|
|
18
|
+
Requires-Dist: django-celery-beat~=2.5.0
|
|
19
|
+
Requires-Dist: requests
|
|
20
|
+
Requires-Dist: redis~=5.0.4
|
|
21
|
+
Requires-Dist: djangorestframework
|
|
22
|
+
Requires-Dist: urllib3~=2.2.2
|
|
23
|
+
Requires-Dist: pydantic>=2.7.4
|
|
24
|
+
Requires-Dist: kafka-python~=2.0.2
|
|
25
|
+
Requires-Dist: opentelemetry-api>=1.24.0
|
|
26
|
+
Requires-Dist: opentelemetry-sdk>=1.24.0
|
|
27
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-common>=1.24.0
|
|
28
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.24.0
|
|
29
|
+
Requires-Dist: boto3>=1.34.133
|
|
30
|
+
Requires-Dist: sentry-sdk>=1.45.1
|
|
31
|
+
Requires-Dist: pydantic-settings
|
|
32
|
+
Requires-Dist: deprecated
|
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
# Wise
|
|
2
|
+
|
|
3
|
+
Wise is meant to be used as a core for Wisdomise Python/Django microservices.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
poetry add wiselib
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Installation and configuration
|
|
14
|
+
|
|
15
|
+
Add to installed apps in your Django settings:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
INSTALLED_APPS = [
|
|
19
|
+
...
|
|
20
|
+
'wise',
|
|
21
|
+
...
|
|
22
|
+
]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
You can remove the following apps from INSTALLED_APPS (wise will add them):
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
INSTALLED_APPS = [
|
|
29
|
+
...
|
|
30
|
+
# "django_prometheus",
|
|
31
|
+
# "django_celery_results",
|
|
32
|
+
# "django_celery_beat",
|
|
33
|
+
...
|
|
34
|
+
]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Add to settings.py:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from wise.settings import setup_settings
|
|
41
|
+
...
|
|
42
|
+
setup_settings(globals())
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Also you don't need to set the following variables in settings.py,
|
|
46
|
+
wise will set them for you:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# CELERY_BROKER_URL = ...
|
|
50
|
+
# CELERY_RESULT_BACKEND = ...
|
|
51
|
+
# CELERY_BEAT_SCHEDULER = ...
|
|
52
|
+
# Prometheus settings...
|
|
53
|
+
# SentryHandler.setup_sentry(ENV.sentry) # Sentry settings...
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Setup env.py:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from functools import lru_cache
|
|
60
|
+
|
|
61
|
+
from dotenv import find_dotenv, load_dotenv
|
|
62
|
+
from pydantic import StrictStr
|
|
63
|
+
from pydantic_settings import SettingsConfigDict
|
|
64
|
+
from wise.settings.env import (
|
|
65
|
+
EnvSettings as BaseEnvSettings,
|
|
66
|
+
SentrySettings,
|
|
67
|
+
PostgresSettings,
|
|
68
|
+
RedisSettings,
|
|
69
|
+
CelerySettings,
|
|
70
|
+
KafkaSettings,
|
|
71
|
+
PrometheusSettings,
|
|
72
|
+
TracingSettings,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
load_dotenv()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class EnvSettings(BaseEnvSettings):
|
|
79
|
+
service_name: StrictStr = "wise"
|
|
80
|
+
|
|
81
|
+
sentry: SentrySettings
|
|
82
|
+
postgres: PostgresSettings
|
|
83
|
+
kafka: KafkaSettings
|
|
84
|
+
redis: RedisSettings
|
|
85
|
+
celery: CelerySettings
|
|
86
|
+
prometheus: PrometheusSettings
|
|
87
|
+
tracing: TracingSettings
|
|
88
|
+
|
|
89
|
+
model_config = SettingsConfigDict(
|
|
90
|
+
env_prefix="WISE_",
|
|
91
|
+
env_nested_delimiter="__",
|
|
92
|
+
env_file=find_dotenv(raise_error_if_not_found=False),
|
|
93
|
+
extra="allow", # Ignore extra fields
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@lru_cache
|
|
98
|
+
def get_env_settings() -> EnvSettings:
|
|
99
|
+
return EnvSettings() # type: ignore
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Utilities
|
|
103
|
+
|
|
104
|
+
#### Models
|
|
105
|
+
|
|
106
|
+
You don't need the `BaseModel` definition in your code. Use this instead:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from wise.utils.models import BaseModel
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Station
|
|
113
|
+
|
|
114
|
+
Create an app in your project named `station` (if it doesn't exist)
|
|
115
|
+
and add it to `INSTALLED_APPS` in your Django settings.
|
|
116
|
+
|
|
117
|
+
Create the following files:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# my_project/station/publishers.py
|
|
121
|
+
from wise.station.publish import Publisher
|
|
122
|
+
|
|
123
|
+
# All publishers
|
|
124
|
+
|
|
125
|
+
publishers: list[Publisher] = [
|
|
126
|
+
...
|
|
127
|
+
] # can be empty
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# my_project/station/updaters.py
|
|
132
|
+
from django.conf import settings
|
|
133
|
+
from wise.station.updater import UpdaterHandler
|
|
134
|
+
|
|
135
|
+
handle_temple_station_message = UpdaterHandler().add("asset", AssetUpdater) # this is an exmple
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
kafka_updater_handlers = {
|
|
139
|
+
settings.ENV.kafka.temple_station_topic_name: handle_temple_station_message,
|
|
140
|
+
} # dict[topic_name, UpdaterHandler]
|
|
141
|
+
|
|
142
|
+
all_updater_handlers = list(kafka_updater_handlers.values()) # list[UpdaterHandler], can be empty
|
|
143
|
+
|
|
144
|
+
periodic_updaters = [
|
|
145
|
+
...
|
|
146
|
+
] # can be empty
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# my_project/station/setup.py (copy this file as a whole)
|
|
151
|
+
from wise.station.registry import station_registry
|
|
152
|
+
|
|
153
|
+
from station.publishers import publishers
|
|
154
|
+
from station.updaters import kafka_updater_handlers, all_updater_handlers, periodic_updaters
|
|
155
|
+
from station.periodic_tasks import periodic_tasks
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def setup():
|
|
159
|
+
station_registry.set_publishers(publishers)
|
|
160
|
+
station_registry.set_kafka_updater_handlers(kafka_updater_handlers)
|
|
161
|
+
station_registry.set_updater_handlers(all_updater_handlers)
|
|
162
|
+
station_registry.set_periodic_updaters(periodic_updaters)
|
|
163
|
+
station_registry.set_periodic_tasks(periodic_tasks)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# my_project/station/apps.py (copy this file as a whole)
|
|
168
|
+
from django.apps import AppConfig
|
|
169
|
+
from django.db.models.signals import post_migrate
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class StationConfig(AppConfig):
|
|
173
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
174
|
+
name = "station"
|
|
175
|
+
|
|
176
|
+
def ready(self):
|
|
177
|
+
from station.setup import setup
|
|
178
|
+
|
|
179
|
+
setup()
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
You should also remove any `Updater, Publisher, ModelUpdater, SkipUpdate, etc.` definitions from your project and import them from `wise.station`.
|
|
183
|
+
|
|
184
|
+
#### Monitoring
|
|
185
|
+
|
|
186
|
+
You don't need the `monitoring.py` in your projects.
|
|
187
|
+
Use this instead:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from wise.utils.monitoring import Observer, observe, REGISTRY, METRICS_NAMESPACE
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
You also don't need the command `serve_metrics` in your projects. Wise will take care of it.
|
|
194
|
+
|
|
195
|
+
#### Celery
|
|
196
|
+
|
|
197
|
+
You don't need the `celery.py` in your projects.
|
|
198
|
+
Use this instead:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from wise.utils.celery import app
|
|
202
|
+
|
|
203
|
+
@app.task
|
|
204
|
+
def my_task():
|
|
205
|
+
...
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
#### Periodic Tasks
|
|
210
|
+
|
|
211
|
+
You can set the celery periodic tasks deterministically from your code instead of using the admin panel.
|
|
212
|
+
You need to do this in `station/setup.py`:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
# my_project/station/setup.py (copy this file as a whole)
|
|
216
|
+
from wise.station.registry import station_registry
|
|
217
|
+
|
|
218
|
+
from station.periodic_tasks import periodic_tasks
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def setup():
|
|
222
|
+
...
|
|
223
|
+
station_registry.set_periodic_tasks(periodic_tasks)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Also add this to your stat up script/entrypoint after `manage.py migrate`:
|
|
227
|
+
```shell
|
|
228
|
+
python3 manage.py wise_setup
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The argument passed to `set_periodic_tasks` should either be a list of tasks (which will be used for all environments),
|
|
232
|
+
or a dictionary with environment names (production/staging) as keys and lists of tasks as values.
|
|
233
|
+
|
|
234
|
+
Each task should be a dictionary. See the examples:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from wise.station.registry import station_registry
|
|
238
|
+
|
|
239
|
+
station_registry.set_periodic_tasks(
|
|
240
|
+
[
|
|
241
|
+
{
|
|
242
|
+
"name": "My Task", # should be unique, and should not be changed later, as it's used as identifier
|
|
243
|
+
"task": "my_project.tasks.my_task", # task function path
|
|
244
|
+
"interval": "10m", # every 10 minutes. Should be a string. Valid examples: '1s', '2m', '3h', '4d', '5ms', '30' (30 seconds), '6us' or '6µs' (microseconds, both are valid)
|
|
245
|
+
"args": "[1, 2, 3]", # optional
|
|
246
|
+
"enabled": False, # optional, will be set to True each time 'set_periodic_tasks' is called, if not provided
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
You can also set the periodic tasks for different environments:
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
from wise.station.registry import station_registry
|
|
256
|
+
|
|
257
|
+
station_registry.set_periodic_tasks(
|
|
258
|
+
{
|
|
259
|
+
"production": [
|
|
260
|
+
{
|
|
261
|
+
"name": "My Task",
|
|
262
|
+
"task": "my_project.tasks.my_task",
|
|
263
|
+
"interval": "1m",
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
"staging": [
|
|
267
|
+
{
|
|
268
|
+
"name": "My Task",
|
|
269
|
+
"task": "my_project.tasks.my_task",
|
|
270
|
+
"interval": "10m",
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
}
|
|
274
|
+
)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
All other intervaled periodic tasks will be disabled each time `set_periodic_tasks` is called. You can avoid this by
|
|
278
|
+
passing `disable_rest=False` to `set_periodic_tasks`.
|
|
279
|
+
|
|
280
|
+
For the sake of simplicity and backward compatibility (in case of future updates), you can use `WiseTasks` to refer to Wise tasks:
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
from wise.station.registry import station_registry
|
|
284
|
+
from wise.utils.periodic_tasks import WiseTasks
|
|
285
|
+
|
|
286
|
+
...
|
|
287
|
+
station_registry.set_periodic_tasks(
|
|
288
|
+
{
|
|
289
|
+
"production": [
|
|
290
|
+
{
|
|
291
|
+
"name": "Wise: Publish Everything",
|
|
292
|
+
"task": WiseTasks.PUBLISH_EVERYTHING,
|
|
293
|
+
"interval": "1m",
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
} # note that since "staging" is omitted, this will not impact the staging environment at all
|
|
297
|
+
)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**You can use `manage.py export_periodic_tasks` to export the currently enabled periodic tasks to avoid manual entry.**
|
|
301
|
+
|
|
302
|
+
All valid periodic task fields that you can use in your task definition are:
|
|
303
|
+
|
|
304
|
+
```python3
|
|
305
|
+
[
|
|
306
|
+
"name",
|
|
307
|
+
"task",
|
|
308
|
+
"interval",
|
|
309
|
+
"crontab",
|
|
310
|
+
"solar",
|
|
311
|
+
"clocked",
|
|
312
|
+
"args",
|
|
313
|
+
"kwargs",
|
|
314
|
+
"queue",
|
|
315
|
+
"exchange",
|
|
316
|
+
"routing_key",
|
|
317
|
+
"headers",
|
|
318
|
+
"priority",
|
|
319
|
+
"expires",
|
|
320
|
+
"expire_seconds",
|
|
321
|
+
"one_off",
|
|
322
|
+
"start_time",
|
|
323
|
+
"enabled",
|
|
324
|
+
"description"
|
|
325
|
+
]
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
See the [Django Celery Beat documentation](https://django-celery-beat.readthedocs.io/en/latest/reference/django-celery-beat.models.html#django_celery_beat.models.PeriodicTask) for more information.
|
|
329
|
+
|
|
330
|
+
#### Tracing
|
|
331
|
+
|
|
332
|
+
You don't need the `tracing.py` in your projects.
|
|
333
|
+
Use this instead:
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
from wise.utils.tracing import with_trace, trader
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### Views & URLs
|
|
340
|
+
|
|
341
|
+
You don't need health check view in your project anymore. Wise will take care of it.
|
|
342
|
+
|
|
343
|
+
Add wise urls to your urls.py:
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
urlpatterns = [
|
|
347
|
+
...,
|
|
348
|
+
path("", include("wise.urls")),
|
|
349
|
+
]
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
#### Redis
|
|
353
|
+
|
|
354
|
+
You don't need the `redis.py` in your projects. Use this instead:
|
|
355
|
+
|
|
356
|
+
```python
|
|
357
|
+
from wise.utils.redis import get_redis_client
|
|
358
|
+
from wise.utils.redis import get_mock_redis # for testing
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### Kafka
|
|
362
|
+
|
|
363
|
+
You don't need to define Kafka Producer in your projects. Use this instead:
|
|
364
|
+
|
|
365
|
+
```python
|
|
366
|
+
# my_project/utils/kafka.py
|
|
367
|
+
from django.conf import settings
|
|
368
|
+
from wise.utils.kafka import KafkaProducer
|
|
369
|
+
|
|
370
|
+
station_kafka_producer = KafkaProducer(settings.ENV.kafka.my_project_station_topic_name)
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
# my_project/some_file.py
|
|
375
|
+
from my_project.utils.kafka import station_kafka_producer
|
|
376
|
+
station_kafka_producer.produce("my message")
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
You also don't need consume.py (`consume` management command) anymore. Wise will take care of it.
|
|
380
|
+
|
|
381
|
+
#### Caching
|
|
382
|
+
|
|
383
|
+
You don't need to implement `cache_for` and `cache_get_key` in your projects. Remove them and import from wise.
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
from wise.utils.cache import cache_for, cache_get_key
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### Time
|
|
390
|
+
|
|
391
|
+
The time module consists of some useful functions for working with time.
|
|
392
|
+
|
|
393
|
+
```python
|
|
394
|
+
from wise.utils.time import ISO_TIME_FORMAT, iso_serialize, iso_deserialize, expire_from_now
|
|
395
|
+
from wise.utils.time import get_datetime_from_timestamp, get_timestamp_from_datetime, parse_timedelta
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### Numbers
|
|
399
|
+
|
|
400
|
+
The numbers module consists of some useful functions for working with numbers.
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
from wise.utils.numbers import is_zero, safe_add, safe_sub, safe_div, safe_mult, safe_sum, safe_abs, safe_prod
|
|
404
|
+
from wise.utils.numbers import safe_abs, safe_eq, safe_gt, safe_gte, safe_lt, safe_lte, safe_max, safe_min
|
|
405
|
+
|
|
406
|
+
is_zero(1e-12) # True
|
|
407
|
+
|
|
408
|
+
safe_add(1.1, 2.2) # uses Decimal to avoid floating point errors. all safe_* functions do.
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
#### Rate Limit
|
|
412
|
+
|
|
413
|
+
There is a `rate_limit_func` decorator you can use to limit the number of calls to a function. (otherwise returns None).
|
|
414
|
+
|
|
415
|
+
It uses the `args` and `kwargs` in your function call (so it's per-parameter, not per-function).
|
|
416
|
+
Your function parameters should be cachable (using `cache_get_key`).
|
|
417
|
+
|
|
418
|
+
Example 1:
|
|
419
|
+
|
|
420
|
+
```python
|
|
421
|
+
from wise.utils.rate_limit import rate_limit_func
|
|
422
|
+
@rate_limit_func(24 * 60 * 60) # once a day
|
|
423
|
+
def foo():
|
|
424
|
+
...
|
|
425
|
+
|
|
426
|
+
foo() # will be called only once a day
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Example 2:
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
from datetime import timedelta
|
|
433
|
+
from wise.utils.rate_limit import rate_limit_func
|
|
434
|
+
|
|
435
|
+
@rate_limit_func(timedelta(milliseconds=10)) # once every 10ms
|
|
436
|
+
def bar():
|
|
437
|
+
...
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Example 3:
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
from datetime import timedelta
|
|
444
|
+
from wise.utils.rate_limit import rate_limit_func
|
|
445
|
+
|
|
446
|
+
@rate_limit_func(None)
|
|
447
|
+
def foobar(x):
|
|
448
|
+
...
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
foobar(x=12345, rate_limit_period=12 * 60 * 60)
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Important notes:
|
|
455
|
+
|
|
456
|
+
#### Management Commands
|
|
457
|
+
Wise adds some management commands to your project, which you should run in your entrypoint/startup script:
|
|
458
|
+
```bash
|
|
459
|
+
manage.py consume
|
|
460
|
+
manage.py serve_metrics
|
|
461
|
+
manage.py wise_setup # (this should be run after 'manage.py migrate')
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Running Celery
|
|
465
|
+
|
|
466
|
+
1. Run celery beat *only one* of your pods (like worker-master).
|
|
467
|
+
|
|
468
|
+
Add this to your worker.ini or worker-master.ini (or other ini file):
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
celery -A wise.utils beat --loglevel=INFO
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
2. Run celery worker in any any of pods you want.
|
|
475
|
+
|
|
476
|
+
Add this to your worker.ini or worker-master.ini (or other ini file):
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
celery -A wise.utils worker --loglevel=INFO --concurrency=CONCURRENCY
|
|
480
|
+
```
|
|
481
|
+
and replace `CONCURRENCY` with the number of workers you want.
|
|
482
|
+
|
|
483
|
+
3. Add celery periodic tasks (in your project's admin panel) (post-deploy):
|
|
484
|
+
|
|
485
|
+
Here are the celery tasks that you should/can add periodic tasks for:
|
|
486
|
+
|
|
487
|
+
1. `wise.tasks.publish_everything` (low frequency)
|
|
488
|
+
2. `wise.tasks.publish_recently_updated_objects` (high frequency)
|
|
489
|
+
3. `wise.tasks.update_everything` (up to you)
|
|
490
|
+
4. `wise.tasks.update_set` (you should provide an argument for this one)
|
|
491
|
+
5. `wise.tasks.rebuild_publisher_heaps` (low frequency)
|
|
492
|
+
6. `wise.tasks.update_publisher_heaps` (high frequency)
|
|
493
|
+
7. `wise.tasks.sync_updater_heaps` (high frequency)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
## Development
|
|
497
|
+
|
|
498
|
+
### Installing Dependencies
|
|
499
|
+
|
|
500
|
+
Use venv:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
python3 -m venv venv
|
|
504
|
+
source venv/bin/activate
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Install the dependencies:
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
make install
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Pre-commit
|
|
514
|
+
|
|
515
|
+
Run pre-commit hooks:
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
make pre-commit
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Publish
|
|
522
|
+
|
|
523
|
+
#### Setup your PyPI credentials:
|
|
524
|
+
|
|
525
|
+
Find the PyPI credentials in safe.wisdomise.com (look for "PyPI credentials"). Copy it to your local `~/.pypirc` file.
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
#### Publish to PyPI
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
make publish
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
This command also runs pre-commit hooks.
|
wiselibv2-0.4.0/setup.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="wiselibv2",
|
|
5
|
+
version="0.4.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
include_package_data=True,
|
|
8
|
+
install_requires=[
|
|
9
|
+
"setuptools>=70.3.0",
|
|
10
|
+
"Django>=4.0.0",
|
|
11
|
+
"django-prometheus==2.3.1",
|
|
12
|
+
"celery==5.4.0",
|
|
13
|
+
"django-celery-results~=2.5.1",
|
|
14
|
+
"django-celery-beat~=2.5.0",
|
|
15
|
+
"requests",
|
|
16
|
+
"redis~=5.0.4",
|
|
17
|
+
"djangorestframework",
|
|
18
|
+
"urllib3~=2.2.2",
|
|
19
|
+
"pydantic>=2.7.4",
|
|
20
|
+
"kafka-python~=2.0.2",
|
|
21
|
+
"opentelemetry-api>=1.24.0",
|
|
22
|
+
"opentelemetry-sdk>=1.24.0",
|
|
23
|
+
"opentelemetry-exporter-otlp-proto-common>=1.24.0",
|
|
24
|
+
"opentelemetry-exporter-otlp-proto-http>=1.24.0",
|
|
25
|
+
"boto3>=1.34.133",
|
|
26
|
+
"sentry-sdk>=1.45.1",
|
|
27
|
+
"pydantic-settings",
|
|
28
|
+
"deprecated",
|
|
29
|
+
],
|
|
30
|
+
author="Wise Man",
|
|
31
|
+
author_email="your.email@example.com",
|
|
32
|
+
description="WISE Library",
|
|
33
|
+
long_description_content_type="text/markdown",
|
|
34
|
+
url="https://github.com/yourusername/wiselib",
|
|
35
|
+
classifiers=[
|
|
36
|
+
"Programming Language :: Python :: 3",
|
|
37
|
+
"License :: OSI Approved :: MIT License",
|
|
38
|
+
"Operating System :: OS Independent",
|
|
39
|
+
],
|
|
40
|
+
python_requires=">=3.6",
|
|
41
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
default_app_config = "wise.apps.WiseConfig"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .delphinus import delphinus_client
|