python-corekit 0.1.1__py3-none-any.whl → 0.3.0__py3-none-any.whl

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 (109) hide show
  1. corekit/api/__init__.py +18 -3
  2. corekit/api/application.py +275 -0
  3. corekit/api/lifespan.py +233 -0
  4. corekit/api/middleware.py +93 -0
  5. corekit/api/routers.py +109 -1
  6. corekit/concurrency/__init__.py +2 -2
  7. corekit/concurrency/decorators.py +32 -5
  8. corekit/concurrency/thread_local.py +2 -2
  9. corekit/concurrency/worker.py +74 -65
  10. corekit/config/loader.py +42 -5
  11. corekit/config/settings.py +11 -1
  12. corekit/connections/__init__.py +7 -1
  13. corekit/connections/connectable.py +45 -4
  14. corekit/connections/redis/connection.py +53 -10
  15. corekit/connections/sql/__init__.py +33 -4
  16. corekit/connections/sql/connection.py +56 -3
  17. corekit/connections/sql/fields/__init__.py +2 -2
  18. corekit/connections/sql/fields/jsonb.py +13 -6
  19. corekit/connections/sql/migration/__init__.py +9 -5
  20. corekit/connections/sql/migration/base.py +3 -3
  21. corekit/connections/sql/migration/operations.py +135 -44
  22. corekit/connections/sql/migration/registry.py +2 -2
  23. corekit/connections/sql/operations/__init__.py +24 -0
  24. corekit/connections/sql/operations/base.py +111 -0
  25. corekit/connections/sql/operations/statements.py +170 -0
  26. corekit/connections/sql/query.py +4 -62
  27. corekit/connections/sql/table.py +33 -29
  28. corekit/crypto/__init__.py +3 -1
  29. corekit/crypto/constants.py +2 -2
  30. corekit/crypto/hasher.py +9 -4
  31. corekit/data/__init__.py +8 -0
  32. corekit/data/dataset.py +8 -2
  33. corekit/data/expressions/__init__.py +10 -2
  34. corekit/data/expressions/comparison.py +142 -123
  35. corekit/data/expressions/expression.py +71 -98
  36. corekit/data/expressions/operator.py +39 -0
  37. corekit/data/expressions/target.py +21 -0
  38. corekit/data/record.py +147 -147
  39. corekit/data/stats.py +162 -157
  40. corekit/decorators/__init__.py +2 -2
  41. corekit/decorators/exception_handling.py +38 -9
  42. corekit/docker/watchdog.py +50 -31
  43. corekit/etl/__init__.py +2 -1
  44. corekit/etl/connection.py +46 -44
  45. corekit/etl/extract/extractor.py +6 -13
  46. corekit/etl/orchestrator.py +19 -2
  47. corekit/etl/schemas.py +2 -2
  48. corekit/etl/transform/transformer.py +4 -1
  49. corekit/events/publisher.py +1 -1
  50. corekit/events/reader.py +26 -21
  51. corekit/events/sse.py +4 -1
  52. corekit/events/websocket.py +27 -13
  53. corekit/exceptions/__init__.py +33 -0
  54. corekit/exceptions/base.py +139 -10
  55. corekit/exceptions/enum.py +17 -0
  56. corekit/exceptions/types.py +6 -6
  57. corekit/files/__init__.py +2 -4
  58. corekit/files/base.py +15 -2
  59. corekit/files/enum.py +0 -5
  60. corekit/files/json.py +16 -2
  61. corekit/http/__init__.py +51 -0
  62. corekit/http/api.py +24 -0
  63. corekit/http/client.py +100 -73
  64. corekit/http/exceptions.py +140 -0
  65. corekit/http/response.py +50 -1
  66. corekit/http/status.py +89 -0
  67. corekit/jobs/__init__.py +26 -0
  68. corekit/jobs/registry.py +87 -0
  69. corekit/jobs/runner.py +80 -0
  70. corekit/jobs/task.py +173 -0
  71. corekit/log_monitor/models.py +8 -2
  72. corekit/log_monitor/service.py +77 -38
  73. corekit/notifications/base.py +18 -10
  74. corekit/observability/__init__.py +12 -3
  75. corekit/observability/benchmarkable.py +23 -5
  76. corekit/observability/loggable.py +21 -0
  77. corekit/observability/request_context.py +188 -0
  78. corekit/observability/timing/timer.py +4 -2
  79. corekit/registry/__init__.py +12 -7
  80. corekit/registry/ordered.py +86 -0
  81. corekit/registry/registry.py +55 -14
  82. corekit/schemas/__init__.py +10 -0
  83. corekit/schemas/enum.py +70 -49
  84. corekit/schemas/models/arbitrary.py +11 -11
  85. corekit/schemas/pydantic/fields.py +35 -35
  86. corekit/schemas/types.py +45 -40
  87. corekit/serialization/__init__.py +24 -0
  88. corekit/serialization/pickle_file.py +61 -0
  89. corekit/serialization/serializable.py +22 -2
  90. corekit/serialization/serializer.py +10 -3
  91. corekit/utils/__init__.py +59 -5
  92. corekit/utils/coercion.py +118 -0
  93. corekit/utils/collections.py +124 -0
  94. corekit/utils/ids.py +61 -5
  95. corekit/utils/payload.py +112 -0
  96. corekit/utils/raise_exc.py +8 -8
  97. corekit/utils/text.py +56 -0
  98. corekit/utils/time.py +74 -21
  99. corekit/utils/validators.py +15 -15
  100. corekit/utils/void.py +8 -8
  101. {python_corekit-0.1.1.dist-info → python_corekit-0.3.0.dist-info}/METADATA +103 -97
  102. python_corekit-0.3.0.dist-info/RECORD +145 -0
  103. corekit/constants.py +0 -45
  104. corekit/exceptions/http/exceptions.py +0 -37
  105. corekit/files/pickle.py +0 -12
  106. python_corekit-0.1.1.dist-info/RECORD +0 -125
  107. {python_corekit-0.1.1.dist-info → python_corekit-0.3.0.dist-info}/WHEEL +0 -0
  108. {python_corekit-0.1.1.dist-info → python_corekit-0.3.0.dist-info}/licenses/LICENSE +0 -0
  109. {python_corekit-0.1.1.dist-info → python_corekit-0.3.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-corekit
3
- Version: 0.1.1
4
- Summary: Shared foundations for Python projects: logging, benchmarking, registries, FastAPI routers/handlers, data stores, and ETL
3
+ Version: 0.3.0
4
+ Summary: Shared foundations for Python projects: logging, benchmarking, registries, FastAPI application and routers, SQL statements and migrations, background tasks, and ETL
5
5
  Author: Steven Jacobsen
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/stevejaker/corekit
8
8
  Project-URL: Issues, https://github.com/stevejaker/corekit/issues
9
- Keywords: fastapi,etl,homelab,logging,benchmarking
9
+ Keywords: fastapi,etl,logging,benchmarking,sqlmodel,migrations
10
10
  Classifier: Development Status :: 3 - Alpha
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Programming Language :: Python :: 3.11
@@ -36,8 +36,8 @@ Dynamic: license-file
36
36
  # corekit
37
37
 
38
38
  Shared foundations for Python projects: structured logging, benchmarking,
39
- registries, FastAPI routers with built-in handlers, an in-memory record store,
40
- and ETL scaffolding.
39
+ registries, a FastAPI application with routers and handlers, SQL statements and
40
+ migrations, background tasks, an in-memory record store, and ETL scaffolding.
41
41
 
42
42
  Requires Python 3.11+.
43
43
 
@@ -55,7 +55,7 @@ extras to remember, and no import that fails because something was left out.
55
55
  Pin a compatible release rather than tracking whatever is newest:
56
56
 
57
57
  ```
58
- python-corekit~=0.1.0
58
+ python-corekit~=0.3.0
59
59
  ```
60
60
 
61
61
  Before 1.0, the minor version carries breaking changes.
@@ -88,6 +88,57 @@ class Report(Benchmarkable):
88
88
  self.timing("queried") # logs the time since the previous split
89
89
  ```
90
90
 
91
+ ## Assembling an application
92
+
93
+ `Application` is a plain `FastAPI` subclass — every constructor argument,
94
+ including `lifespan`, passes straight through. What it adds is a short set of
95
+ assembly steps, each of which logs what it did.
96
+
97
+ ```python
98
+ from corekit.api import Application, Lifespan
99
+ from app.backend import routers
100
+
101
+ lifespan = Lifespan()
102
+ lifespan.add("cache", startup=cache.connect, shutdown=cache.disconnect)
103
+
104
+ app = Application(lifespan=lifespan)
105
+ app.discover_routers(routers)
106
+ ```
107
+
108
+ `discover_routers` imports every module under the package so each router can
109
+ register itself. It raises if it finds none: passing a package is a statement
110
+ that routers live there, and an app that silently serves nothing is worse than
111
+ one that refuses to start.
112
+
113
+ Lifespan steps start in the order added and shut down in reverse, the way
114
+ nested `with` blocks unwind. If a step fails on the way up, the steps that
115
+ already started are still torn down. A shutdown hook runs only if its own
116
+ startup completed, so it may assume the state that startup builds — and a hook
117
+ that raises cannot stop the unwind.
118
+
119
+ ### Middleware
120
+
121
+ Middleware order is a security property: a host check that reads a client
122
+ address before the proxy-header layer has rewritten it is checking the proxy,
123
+ not the client. So middleware is never auto-discovered, and corekit installs
124
+ none by default. A stack is declared in one place, outermost first — the order
125
+ a request actually meets the layers.
126
+
127
+ ```python
128
+ from corekit.api import MiddlewareStack
129
+
130
+ stack = (
131
+ MiddlewareStack()
132
+ .add(ProxyHeadersMiddleware, trusted_hosts="*")
133
+ .add(TrustedHostMiddleware, allowed_hosts=HOSTS)
134
+ .add(CORSMiddleware, allow_origins=ORIGINS, allow_credentials=True)
135
+ )
136
+ app.add_middleware_stack(stack)
137
+ ```
138
+
139
+ Reading top to bottom gives the order a request travels, which is the property
140
+ you need when reviewing it.
141
+
91
142
  ## Routers and handlers
92
143
 
93
144
  A router and the handler holding its business logic travel together. Declare the
@@ -147,113 +198,67 @@ people.get_record("Ada").age # O(1) lookup by id
147
198
 
148
199
  Stores pickle cleanly, including their dynamically generated record class.
149
200
 
150
- ## Homelab pieces
201
+ ## SQL statements
151
202
 
152
- ### Container control
203
+ Select, insert, update and delete are objects you build and then execute, so a
204
+ statement can be assembled in pieces and passed around before it runs.
153
205
 
154
206
  ```python
155
- from corekit.docker import Watchdog
207
+ from corekit.connections.sql import SQLConnection, Select, Insert, Update, Delete
208
+ from corekit.data import Field
156
209
 
157
- watchdog = Watchdog(enforce_label=True)
158
- watchdog.restart_container_by_name("minecraft")
159
- watchdog.find_and_stop(label="app", value="staging")
160
- ```
210
+ conn = SQLConnection("sqlite:///app.db")
161
211
 
162
- `enforce_label` limits the blast radius: with it on, only containers carrying
163
- the `watchdog=true` label can be started, stopped or paused, so a mistyped name
164
- cannot take down something unrelated. Leave it on unless the watchdog is meant
165
- to control everything on the host.
166
-
167
- ### Reacting to logs
168
-
169
- Describe what to watch for and what to do about it:
170
-
171
- ```yaml
172
- # config.yaml
173
- containers:
174
- - name: "minecraft-.*"
175
- rules:
176
- - name: "out of memory"
177
- pattern: "java.lang.OutOfMemoryError"
178
- severity: critical
179
- send_notification: true
180
- actions:
181
- - type: restart_container
182
- max_restarts: 3
183
- restart_window: 3600
184
- advanced:
185
- ignore_patterns:
186
- - "healthcheck"
187
- rate_limits:
188
- restart_container:
189
- count: 5
190
- period: hour
191
- ```
212
+ conn.execute(Insert(table=User, rows=[{"name": "Ada", "age": 36}]).add(name="Bob", age=17))
192
213
 
193
- ```python
194
- from corekit.log_monitor import LogMonitor
214
+ adults = conn.fetch(Select(table=User).where(User.age >= 18).order_by(User.name).limit(10))
195
215
 
196
- LogMonitor.run("config.yaml")
216
+ conn.execute(Update(table=User).where(User.name == "Bob").set(age=18))
217
+ conn.execute(Delete(table=User).where(User.age < 13))
197
218
  ```
198
219
 
199
- Restarts are capped per container, so a crash loop cannot become a restart loop.
200
-
201
- ### Notifications
220
+ `where` accepts a SQLAlchemy expression or a `corekit.data` one, so the same
221
+ predicate language that filters a `Dataset` also filters a table:
202
222
 
203
223
  ```python
204
- from corekit.notifications import BaseNotificationService, Notification, NotificationType
205
-
206
- class DiscordNotifier(BaseNotificationService):
207
- """
208
- Sends notifications to a Discord channel.
209
- """
210
-
211
- def _send(self, message: str) -> None:
212
- discord.post(message)
213
-
214
- notifier.notify(Notification(message="disk full", type=NotificationType.ERROR))
224
+ Select(table=User).where(Field("age") >= 18)
215
225
  ```
216
226
 
217
- Override `_send`, not `send`. `notify()` formats the message and calls `_send`,
218
- so an override with any other name is silently ignored.
227
+ Update and delete compile to a single statement rather than fetching rows and
228
+ looping, which matters most over a network, where fetch-and-loop pays a round
229
+ trip per row.
219
230
 
220
- ### Real-time updates
231
+ A `Delete` or `Update` with no condition raises rather than running:
221
232
 
222
- Publish from wherever the work happens:
223
-
224
- ```python
225
- from corekit.events import EventPublisher
226
-
227
- publisher = EventPublisher.for_resource("minecraft", "server", "survival")
228
- publisher.publish("backup_finished", {"size": "4.2GB"})
233
+ ```
234
+ Delete on User needs a condition; use truncate to empty a table
229
235
  ```
230
236
 
231
- Stream it to the browser:
237
+ ## Background tasks
232
238
 
233
- ```python
234
- from corekit.api import SSEResponse
235
- from corekit.events import SSEStream
239
+ Tasks describe work and register themselves by name. Nothing here imports a
240
+ queue library, so the same task runs under RQ, Celery, a cron entry, or a test
241
+ with no queue at all.
236
242
 
237
- @router.get("/events")
238
- async def events(channel: str) -> SSEResponse:
239
- return SSEResponse(SSEStream(channel, keepalive_interval=15))
240
- ```
243
+ ```python
244
+ from corekit.jobs import Task, run_task
245
+ from corekit.utils import encode_payload
241
246
 
242
- The browser side is three lines, and reconnects on its own:
247
+ class SendDigest(Task):
248
+ def task_function(self, user: str) -> None:
249
+ ...
243
250
 
244
- ```javascript
245
- const source = new EventSource("/events?channel=minecraft:server:survival");
246
- source.addEventListener("backup_finished", e => console.log(JSON.parse(e.data)));
251
+ # a worker, holding only a name and a JSON string
252
+ run_task("SendDigest", encode_payload(["ada"]))
247
253
  ```
248
254
 
249
- `SSEStream` sends a `connected` frame on subscribe, an optional `initial_state`
250
- so a client arriving late renders immediately, and a comment frame every
251
- `keepalive_interval` seconds so proxies do not close an idle connection. For
252
- WebSockets, `WebSocketBridge` relays the same channel and stops on a terminal
253
- status.
255
+ Arguments cross the queue as JSON, never as a serialized object. `pickle` and
256
+ `dill` execute code while loading, so a queue holding objects turns write
257
+ access to the queue into code execution in a worker. `encode_payload` and
258
+ `decode_payload` live in `corekit.utils`, since crossing a process boundary as
259
+ data is not specific to queues.
254
260
 
255
- Publishing never raises: an event that cannot be delivered should not take down
256
- the operation that produced it. `publish` returns whether it worked.
261
+ `ScheduledTask` adds an `interval` for tasks a scheduler should repeat.
257
262
 
258
263
  ## Parallel work
259
264
 
@@ -279,7 +284,7 @@ instead, which loses results silently and so is opt-in.
279
284
  ## HTTP clients
280
285
 
281
286
  ```python
282
- from corekit.http.client import BaseApiClient
287
+ from corekit.http import BaseApiClient
283
288
 
284
289
  class GithubClient(BaseApiClient):
285
290
  """
@@ -296,7 +301,8 @@ response.data["login"]
296
301
 
297
302
  Retries 429 and 5xx with exponential backoff. Every response is a
298
303
  `BaseApiResponse`, so a non-JSON error page leaves `data` empty rather than
299
- raising. `async_get`, `async_post` and friends do the same without blocking.
304
+ raising. The same methods are awaitable inside a running event loop:
305
+ `await client.get(...)`.
300
306
 
301
307
  ## Serialization
302
308
 
@@ -346,7 +352,7 @@ Settings are grouped by concern, so `get_settings().concurrency.max_threads`
346
352
  says where a value belongs. Environment variables use a double underscore for
347
353
  the section: `COREKIT_CONCURRENCY__MAX_THREADS=16`.
348
354
 
349
- Environment variables use a `COREKIT_` prefix (`COREKIT_CRYPTO_SALT`). Empty
355
+ Environment variables use a `COREKIT_` prefix (`COREKIT_CRYPTO__SALT`). Empty
350
356
  values are treated as unset, because container runtimes routinely pass `FOO=`
351
357
  for a variable that was never set.
352
358
 
@@ -370,23 +376,23 @@ Imports go downward only.
370
376
  ```
371
377
  corekit/
372
378
  config/ settings, sources, loader
373
- constants.py
374
379
 
375
380
  exceptions/ error types
376
381
 
377
382
  observability/ Loggable, Benchmarkable, Timer
378
- registry/ schemas/ utils/ SmartRegistry, enums and fields, helpers
383
+ registry/ schemas/ utils/ registries, enums and fields, helpers
379
384
  data/ Dataset and its filter expressions
385
+ jobs/ queue-independent background tasks
380
386
  crypto/ files/ serialization/
381
387
  concurrency/ ThreadLocalRegistry, ThreadWorker
382
388
  decorators/
383
389
 
384
390
  connections/ the Connectable lifecycle and @connect
385
- sql/ SQLConnection, queries, migrations
391
+ sql/ SQLConnection, statements, migrations
386
392
  redis/ RedisConnection
387
- http/ BaseApiClient, retries, responses
393
+ http/ BaseHttpClient, BaseApiClient, retries, responses
388
394
 
389
- api/ handlers, routers, responses
395
+ api/ Application, lifespan, middleware, routers
390
396
  docker/ notifications/ etl/
391
397
 
392
398
  events/ log_monitor/ built on the capabilities above
@@ -0,0 +1,145 @@
1
+ corekit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ corekit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ corekit/api/__init__.py,sha256=44gtrMRkllhAQdwpfIKrkMuSl3qg61xRxgaTDldzmjg,688
4
+ corekit/api/application.py,sha256=CDdJRHSbXFR6XLufg0idzNm_FFnsYl_0w8B5ArIN-KQ,12001
5
+ corekit/api/handler.py,sha256=vYrao8_B5e6MZGI7GLm1Mr-e8NH8rYt8TNAcnoEuzRQ,2659
6
+ corekit/api/lifespan.py,sha256=OLkiaDfQlhOz3p-gmDXywZgOsO6T-txNjhzeIN44NDk,8848
7
+ corekit/api/middleware.py,sha256=6M5VPjRZTTPEfX5Hm7DHLoDwwWWAgmvWNiTuSykUA98,3168
8
+ corekit/api/responses.py,sha256=bvADoj7snxqCKHIWFiU5rH8Mg5dmvi-ldxVLJbtVEQs,1258
9
+ corekit/api/routers.py,sha256=j2DSkYTTIGd5qFEzYFlY5YM0qhdvhjUu8iFxWc9KM6o,7910
10
+ corekit/concurrency/__init__.py,sha256=ovt0x-VqJhit2ygp0Y7j9gSc67xoQ6mJvQ8fNEF-HHY,348
11
+ corekit/concurrency/decorators.py,sha256=vYnRb2xPTvmX-vmpLk7OL5H6uUYMtvX-pYc3KBV0VDw,3580
12
+ corekit/concurrency/thread_local.py,sha256=8KA0JzX6kV1qjbRv5JZ8X2us8I0tdjS0TAvE-znh77E,3188
13
+ corekit/concurrency/worker.py,sha256=V6wVrcYMTnSWUVTchP7F_ieReQTi6QP9tZDKUspaKSg,2280
14
+ corekit/config/__init__.py,sha256=dw2Y2HvpHw1MXwLSVxdARGPYse9j6IteVN3q70c3Kic,1227
15
+ corekit/config/loader.py,sha256=qjmOEJjO27U2vIgYBfsatNbZB73MkHJHZKbIKY03d2Q,6704
16
+ corekit/config/settings.py,sha256=cmDNMPHkfdHGNmKlxPjFTWzO9fl3pKu7vCMFLP5QHSc,5283
17
+ corekit/config/sources.py,sha256=kdeji29XnEOaDGRctiwEfp7bKuA2jBYGbvAdVEs21KE,3923
18
+ corekit/connections/__init__.py,sha256=LipBfhpCyOG0JiQXqclIB1rUHJ18GMj_9ggpSykH-do,1167
19
+ corekit/connections/connectable.py,sha256=WbNmfGUM9DYmD2daVKqAii_Vx4fs0CUCDDZsd1GOikg,8099
20
+ corekit/connections/decorators.py,sha256=7xfmLuMr3kkceEkkxHxY_Pen2OakJEVukXtiOYAd-6Q,3606
21
+ corekit/connections/registry.py,sha256=BR04dGthcGCtON2MxNsl-TlhRgbRlvGj0RLymDFBkGQ,3119
22
+ corekit/connections/redis/__init__.py,sha256=BsWLZNqpKAqIoreHGLEtftnMqVw-ESK8jbexDAughag,174
23
+ corekit/connections/redis/connection.py,sha256=H6r5WsDfXFgIQlp6vq3rKjp-oBFQoE5h_YaJXZEvHIs,9850
24
+ corekit/connections/sql/__init__.py,sha256=WRBcQ9draDQSooYi4k4peWyuRTgSyEk_WwOYYOAN9K4,882
25
+ corekit/connections/sql/connection.py,sha256=PvLhYXMmq6JneshWhoUb2WD2usGH7uOA9H_ZufybKgQ,12318
26
+ corekit/connections/sql/query.py,sha256=8s5atIssmN2l9FCL2IHnIQqwxOk0fA_mPNh36koLhoE,233
27
+ corekit/connections/sql/table.py,sha256=C7_QCRPd7C1JeH7aIByUBVWsx5qiEOFavWOo6c72djM,3125
28
+ corekit/connections/sql/fields/__init__.py,sha256=2I-TCsvi321yQhesKNZgY1T77FtATZ6o7pw0MNHtbAo,184
29
+ corekit/connections/sql/fields/jsonb.py,sha256=wGjtCP6v3i2bX73X-VVqBNuDNr0-MeWIosc6nvWyO9Q,2313
30
+ corekit/connections/sql/migration/__init__.py,sha256=NBQyKdz84y6Y_QJVTJQVfHz0WrY1CXNoeko113GUoTg,1652
31
+ corekit/connections/sql/migration/base.py,sha256=b-3ISuCRgt_HuLl4lWNPq2QiNC2_3fiNrd1dEgDd7pE,1344
32
+ corekit/connections/sql/migration/operations.py,sha256=UIO0TPJceo0vtGsNQiATn7i7sEnseyli4TttLsSMpUw,15394
33
+ corekit/connections/sql/migration/registry.py,sha256=M1iS7v7aKYfgyf_grvF-6Ogn4KfQ1EEWbA1MO02CiB0,6728
34
+ corekit/connections/sql/migration/table.py,sha256=CpOkJl-4rcG2hTZYq-Yt7OvGTpVhVJ42IrubVO3BUvs,666
35
+ corekit/connections/sql/operations/__init__.py,sha256=f6fnAbD3k8ALXwcwJ31fIHQwkvud_WqmUod_apTErpY,480
36
+ corekit/connections/sql/operations/base.py,sha256=PQSiEz79qd_bp29K7mOh4-qQA-_Wk_r4QfL4oo3hGPY,3286
37
+ corekit/connections/sql/operations/statements.py,sha256=AuJyMM-a3Kiqky_jxi2lH40a6rCeHOaesRPKJuIOGrY,4888
38
+ corekit/crypto/__init__.py,sha256=Qf_FCUoG_jb7Q9tnN4ctX8I6xyaeaJwk74ag_bSchAQ,87
39
+ corekit/crypto/constants.py,sha256=m-uq7_EJ4XfUTSZxFv6h429UkKSrGTj3o_9DfRFGyvU,298
40
+ corekit/crypto/enum.py,sha256=0csj06cATCYDPY_QTNy66j_hB16WCqcHg8tJOO0lMNU,212
41
+ corekit/crypto/hasher.py,sha256=KkxBM8pwaFwdUV31D-LO7Pg8bFULI5Y8rtUDTWti08w,3184
42
+ corekit/data/__init__.py,sha256=COGfw3-OBRp6KKWBSixid5vfaeasFVY5X4Wza0mB_kY,1977
43
+ corekit/data/dataset.py,sha256=TK1yAs7bNCQpV7Z16YqCzYf2Q_Vpu2IbEs1sqMMbikM,12835
44
+ corekit/data/record.py,sha256=EczoOvcxl-lHO1M92AjUh_5E9UQJ2qwBsiu6Yo-34gs,5233
45
+ corekit/data/stats.py,sha256=cRnLGgUHEz66GS1Rs7c_wr2ZVvIJ8WbKq4ifBKR_t0U,4950
46
+ corekit/data/expressions/__init__.py,sha256=_uOPah6QnbnT_W3DROD399b-TtjYQhsmnooD1pr62rE,1301
47
+ corekit/data/expressions/comparison.py,sha256=teLuLEpZ-oohAaE9Oom6tdUSWGTGMDpTxJdWPKv6_7I,9374
48
+ corekit/data/expressions/expression.py,sha256=J8EVyzRjh3VZvqiJyryjHZJfp5c2KwwENVYhZo8S2aw,2126
49
+ corekit/data/expressions/operator.py,sha256=o_QFyiM9v9Ms83k2p2c6fhL3F05TIJ-gplhTk_t1LJk,893
50
+ corekit/data/expressions/target.py,sha256=QSl7sH1qFVUc-mL7gsasTsCahWKhHqdo0bMHt--t2m8,470
51
+ corekit/decorators/__init__.py,sha256=YrBcc_4wkSs7nEb3OjC7C7a8fNEvBk3RzOpD8QccHKM,83
52
+ corekit/decorators/exception_handling.py,sha256=p86gfvdmsmC7_va042NSoGkWrJrbLLuw0ncE131wLWU,2326
53
+ corekit/decorators/warnings.py,sha256=RS7AS6OS05VxiWaMjkj6kYky9FbpT4Z-Cb7TQoPOObk,1109
54
+ corekit/docker/__init__.py,sha256=LtrmEvqorme1-YwL0jGNFLEASdgn69s0eYuh490anmg,104
55
+ corekit/docker/watchdog.py,sha256=kAOF9x-h_oQmyKrkcc4eQ1_HIofRDyYyrfeAULyyBtQ,8855
56
+ corekit/etl/__init__.py,sha256=KFuGv6xstJbEJHHYo_X5akEq_b7muDyKXCGdFeZ3_0M,1369
57
+ corekit/etl/connection.py,sha256=_gWqR36x5f7qb5IYJjrc_7d_6oU2CXm1QeSNCCh0coo,1270
58
+ corekit/etl/orchestrator.py,sha256=GkecTu8gKt17ePDM9PJBUuZTPYoPMdK1yYzBHjMdw3A,7959
59
+ corekit/etl/schemas.py,sha256=3z0qZBintCO45BcxT6TY0Boi_ibrRa0z85wBJvLXNd4,385
60
+ corekit/etl/extract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ corekit/etl/extract/extractor.py,sha256=D_MmEVGUimPlFmNR1CIFOKii8d6y0XIr3MdXo8M0FU4,1434
62
+ corekit/etl/extract/schemas.py,sha256=Hqse-GUwaCuN7eAW7Cacuj4k7Vy1dEu-NagruabiYWU,386
63
+ corekit/etl/load/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ corekit/etl/load/loader.py,sha256=Oh8UZq1gRXFaO1a0poDxMNtdcnIayPsh06XuBQM9KjI,1579
65
+ corekit/etl/load/schemas.py,sha256=c4hZrbjgN_zFKMBhDeNwaPARTiJdgnVFSIW8Lah4c3U,860
66
+ corekit/etl/transform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ corekit/etl/transform/schemas.py,sha256=_Kr8DAXQKZH6nIqYjXVpaeeA0shAsk1vjWOcEcAXly8,319
68
+ corekit/etl/transform/transformer.py,sha256=foNmqhFq1dwWKfMN7hN9l8gMQaV1GBjhDcqu9MEkrY8,1040
69
+ corekit/events/__init__.py,sha256=BrNQKcLnSs5zT1vjDJZ4UX_CD0g87dA5resmzKs0nQQ,1065
70
+ corekit/events/enum.py,sha256=K7ziTjKDjZEZlDO8whjDph8X-bTT_ze2guTrYDGozYc,1342
71
+ corekit/events/frames.py,sha256=ICuF9EKWQ1NqcSfkL0JFHvMB6zrikzkwoujP-292Q8k,1480
72
+ corekit/events/models.py,sha256=faE-Z2qwggOaSBrzte-mBWXuomrzWMIl0gOEkjvPqLo,470
73
+ corekit/events/publisher.py,sha256=70lHyEIEg0eXUWJ9k9eUNVBBmckm4rYBgvTZgRfbcl8,2598
74
+ corekit/events/reader.py,sha256=HoJs6zb9N3VDD-nJV2fpks7ny2OI8UaAKQMBaXcK7_k,4994
75
+ corekit/events/sse.py,sha256=lhF4KUQ_XrdExGLWbKYJghti2t6ExNzXYoA6dOZi9mA,4090
76
+ corekit/events/websocket.py,sha256=S6CUh9duI5xHVrKqbHpss8FrnKKqnFHBFJpSkmgInN4,3858
77
+ corekit/exceptions/__init__.py,sha256=8q9EX-0bzOiJI1FOzCbViQFwx53Ugs8NH482Cvpci6k,995
78
+ corekit/exceptions/base.py,sha256=k0AfTfPrLWR6x-l2qvvjqD_sup0fiWhqu1OoNaNM-Lk,5596
79
+ corekit/exceptions/enum.py,sha256=D-YL-cZXs-F2jS1GgRBhPWmuqBfX33B1QP61vAXdAes,324
80
+ corekit/exceptions/types.py,sha256=rxhQ8sghV2TCHh_vB7tX6Yb6Vkyv1PF_0PLtalyFVxY,665
81
+ corekit/exceptions/custom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ corekit/exceptions/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ corekit/files/__init__.py,sha256=IllQEAWtcT72vVUdRaMwfF5VlhzMJ16VIKDhqvWG9Cw,612
84
+ corekit/files/base.py,sha256=Ca2bhdlwntHh425PedaUG-UW2fEFZsPCss_3f7REsAE,4022
85
+ corekit/files/enum.py,sha256=mcrQXcp-AizTAp4VoaVMLj9zu5D81XXMsnZwZqe6fz0,597
86
+ corekit/files/json.py,sha256=pRYLKNjeVmkDQsgtjBboFFY5Ljx1Pwa3MFEeQBc4o-g,909
87
+ corekit/files/toml.py,sha256=YFRwghMapbCRSl7srqcI7IhqaTQDyO56XRasGMu_Aug,1273
88
+ corekit/http/__init__.py,sha256=cOZum0wNWuVGDB4PfX2OpWq01BurhV2dir3V0AcStfQ,1508
89
+ corekit/http/api.py,sha256=L4iZ9TdCQH3klKWxIxFE3bEQzqMTDOwy-HKrvHXwsbI,784
90
+ corekit/http/client.py,sha256=O7DSDQaiz1_NvBtT00LWsDqICEEIWGrUWKwgYA84AgQ,6603
91
+ corekit/http/exceptions.py,sha256=etkKN6rgnhENctO7YNvaRAKsctK0PXKCxAe15l6mNwY,4252
92
+ corekit/http/exponential_backoff.py,sha256=5jjGTspX_BC9aBKPr5Y5dNhJqXesmljsjJoQ6i2d4_I,3180
93
+ corekit/http/response.py,sha256=rOcUEgPYxfmKXfGO5fQsMA8q4YJof8dNNGBf-nb7l8k,2375
94
+ corekit/http/status.py,sha256=rZ-cdliG9EAvWMTzvxjqjipRkZRc6RgSzcBY4Kewdg0,2377
95
+ corekit/jobs/__init__.py,sha256=vsv8o23ApT6MlOwOq-AFYeQW2NT1kjyvu89A5CL2PsY,880
96
+ corekit/jobs/registry.py,sha256=cco6884eVuIYHEtSv6P62MICFjX-QhuSZIFkEJcQi_M,2557
97
+ corekit/jobs/runner.py,sha256=KRzUIaeXVqLFekoIi2C5cnZ8F-5V5Oy_91xOPHjhjmY,2650
98
+ corekit/jobs/task.py,sha256=tqr-QaQSHyfPjbyZscM5i-YgT-fl58cpd2FVxevtG_E,6112
99
+ corekit/log_monitor/__init__.py,sha256=uuXTQdI8EMeFbdt69G-2K8dKh5Nt-h9SzBEsOGcu0lo,371
100
+ corekit/log_monitor/constants.py,sha256=8nzIzU3Qit9h7_stZLWW1Q_0DTnYglw_j5bQUsF586g,230
101
+ corekit/log_monitor/models.py,sha256=EiXVzPMdupbVOHoSFbagAyNhtdBf5jx_LlJqgQpoKqI,4999
102
+ corekit/log_monitor/service.py,sha256=xGIaNYDfs8DZrJoKMMb5ZsUbdcmbHvn5OXvhFyZJl10,18606
103
+ corekit/notifications/__init__.py,sha256=dLSyNnW7pOCgUNFsHRqTNzMRGYTItpwTWR3-wL7WxAI,255
104
+ corekit/notifications/base.py,sha256=cAgENDk6EEeQNzaDPAitm9OybkC0i8gFjcrDh8TfCtg,1889
105
+ corekit/notifications/models.py,sha256=cCAxNFCYCgzSclkUWHQL9O-uWdE058KUUaMewY5PL6M,646
106
+ corekit/observability/__init__.py,sha256=DTUg9SQvUDRSG_3qOVaTXEk0jlqZzWXXMQdP8CH2Lzs,968
107
+ corekit/observability/benchmarkable.py,sha256=VBO70x-UeBareVIBXRZRQX3TqAHhVYCjZWNyX19kcdo,993
108
+ corekit/observability/loggable.py,sha256=VajvdhPB09QERyq585yItHMYTngvW-DWBv1sxkySlbc,1769
109
+ corekit/observability/request_context.py,sha256=X2WDmp2fV-PJVILkWU2S0WksxW0BYD2nG4mDhEjPYNM,6698
110
+ corekit/observability/timing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
+ corekit/observability/timing/constants.py,sha256=Cv6h98NHzJiTJJufVQBVMBpdI0_fNMTnxAZF0j0vrsg,22
112
+ corekit/observability/timing/split.py,sha256=qoITQnLLKfXe6NdCRvpL4ch8C9f_9G6a-P4bSQFYGYw,528
113
+ corekit/observability/timing/timer.py,sha256=IPHCkoIWK-eBRlEOJSx92AU1YxbgLiww3_EKyFgONGY,1080
114
+ corekit/registry/__init__.py,sha256=R67Jssr06Eyx2u5AbX1omm2LziWvwS_Sd7fExnNv9CM,681
115
+ corekit/registry/ordered.py,sha256=_KS4mWzmLgFvODW2M0_ugxZIBW_dKhwwxrVrtNqLMfs,2506
116
+ corekit/registry/registry.py,sha256=t1iwzxgvd-iyLIf_5wahg_P7eN9V1oumpupkAqi2GdQ,5601
117
+ corekit/schemas/__init__.py,sha256=lpGVfqzXLpxpdP5ijS9uye_XfF1yNgjJ0Rt4m2EkwPE,298
118
+ corekit/schemas/enum.py,sha256=gLc44kIXRfpDFkV51JoN4KT1CU92hnb529rd1b88fBM,2033
119
+ corekit/schemas/types.py,sha256=AWIxZHXUiUjJRZjmOhAdCq3RIsRzL-Fy7RvYy4i5Ozo,1347
120
+ corekit/schemas/dataclasses/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
+ corekit/schemas/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
+ corekit/schemas/models/arbitrary.py,sha256=L2Uqxo_twPAmzoly3Lyo5rzYhDzReSB_U-oAuRgWubg,396
123
+ corekit/schemas/models/date_models.py,sha256=UOlSLVsWqgr_jnHfxVRgSl4nVVdfbe6zPBYveOgRcIg,399
124
+ corekit/schemas/pydantic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
+ corekit/schemas/pydantic/fields.py,sha256=ScP2ZQCR2qTWaqwjKl7lGvkTGSIeQBJ0yeNs79E47AA,1175
126
+ corekit/serialization/__init__.py,sha256=RuS_bQmN1gz2-wg9HcyM03d_CU9MZO0QliIcnZGEq8I,830
127
+ corekit/serialization/enum.py,sha256=pzHuAIXeonEF7-jyN1uYddJk-xvmQGuymDf1U6RWR5w,566
128
+ corekit/serialization/pickle_file.py,sha256=dudKIxR8ueT3wx_IBxHJeoqnFeP1rT7dlTb_PXlSkd8,2251
129
+ corekit/serialization/serializable.py,sha256=viF3ZCKRJ90hk6m4lbqIfo6ifsY2c4sXr4xZrn1Yz-Q,1999
130
+ corekit/serialization/serializer.py,sha256=XlGE1Rq8M55Jl2a4F5MkvDcba2VI7lrh0v9kwL0DWG8,6617
131
+ corekit/utils/__init__.py,sha256=n3feLbH1WrGqWZACyg-hChxkTrqfADFlFkxm5ie2JGo,1769
132
+ corekit/utils/coercion.py,sha256=Aq63jrxQYg1ooWUFXHff2uepB_LoHm1izao8_3xkzEU,3650
133
+ corekit/utils/collections.py,sha256=Kxjlw4ybNo3ClaJQamsZ1ZGRc_KpU2v1HXnR2me2zl8,4013
134
+ corekit/utils/ids.py,sha256=BVniaYqewM-EosDxcJAT_S_7T9C1c5X8nsaVGs5up34,1731
135
+ corekit/utils/payload.py,sha256=T7EgdVU0S5h8MAzvQsmkfRPMatWqUbxjHL9hmZdM9ho,3882
136
+ corekit/utils/raise_exc.py,sha256=cz7ljc6ZW90AGQussKuANN8PLsDLUhl-E8FZ0Ipsw-0,175
137
+ corekit/utils/text.py,sha256=54maLM4jsS8cjVXRQCNVFzVszGimuzgaNzudhZzZeio,1694
138
+ corekit/utils/time.py,sha256=-iPaETXcgDu7J39Kwe938JyZKhPVjl6a572BBqsqcDQ,2215
139
+ corekit/utils/validators.py,sha256=_HVKo3y264KGNaZ-1RyM1x46VPvu7XKcQkrHWDC9uxs,340
140
+ corekit/utils/void.py,sha256=eXDb2QynuguiSgHGJLdgE08MuRnxBdYebRdMD7s1m9o,178
141
+ python_corekit-0.3.0.dist-info/licenses/LICENSE,sha256=357LYxbxAQZ95q5cV-8JK6j-KNgiE6AteRodjEsm-kE,1072
142
+ python_corekit-0.3.0.dist-info/METADATA,sha256=59HC-Dee9ORoSCa6YSxqd41jf4euLDkF9d6sE2ZzZZk,13167
143
+ python_corekit-0.3.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
144
+ python_corekit-0.3.0.dist-info/top_level.txt,sha256=SDK4o8BoaI47E9tPbiNCbbWoc2y6N_wCjwnIEfr-GWI,8
145
+ python_corekit-0.3.0.dist-info/RECORD,,
corekit/constants.py DELETED
@@ -1,45 +0,0 @@
1
- # Minutes
2
- ONE_MINUTE = 60
3
- TWO_MINUTES = ONE_MINUTE * 2
4
- THREE_MINUTES = ONE_MINUTE * 3
5
- FIVE_MINUTES = ONE_MINUTE * 5
6
- TEN_MINUTES = ONE_MINUTE * 10
7
- FIFTEEN_MINUTES = ONE_MINUTE * 15
8
- THIRTY_MINUTES = ONE_MINUTE * 30
9
- FORTY_FIVE_MINUTES = ONE_MINUTE * 45
10
-
11
- # Hours
12
- ONE_HOUR = ONE_MINUTE * 60
13
- TWO_HOURS = ONE_HOUR * 2
14
- THREE_HOURS = ONE_HOUR * 3
15
- FIVE_HOURS = ONE_HOUR * 5
16
- SIX_HOURS = ONE_HOUR * 6
17
- NINE_HOURS = ONE_HOUR * 9
18
- TWELVE_HOURS = ONE_HOUR * 12
19
- FIFTEEN_HOURS = ONE_HOUR * 15
20
- EIGHTEEN_HOURS = ONE_HOUR * 18
21
-
22
- # Days
23
- ONE_DAY = ONE_HOUR * 24
24
- TWO_DAYS = ONE_DAY * 2
25
- THREE_DAYS = ONE_DAY * 3
26
- FOUR_DAYS = ONE_DAY * 4
27
- FIVE_DAYS = ONE_DAY * 5
28
- SIX_DAYS = ONE_DAY * 6
29
- TEN_DAYS = ONE_DAY * 10
30
- FIFTEEN_DAYS = ONE_DAY * 15
31
- THIRTY_DAYS = ONE_DAY * 30
32
- FORTY_FIVE_DAYS = ONE_DAY * 45
33
- SIXTY_FIVE_DAYS = ONE_DAY * 60
34
- NINETY_FIVE_DAYS = ONE_DAY * 90
35
- ONE_HUNDRED_TWENTY_DAYS = ONE_DAY * 120
36
- ONE_HUNDRED_EIGHTY_DAYS = ONE_DAY * 180
37
-
38
- # Weeks
39
- ONE_WEEK = ONE_DAY * 7
40
- TWO_WEEKS = ONE_WEEK * 2
41
- THREE_WEEKS = ONE_WEEK * 3
42
- FOUR_WEEKS = ONE_WEEK * 4
43
-
44
- # Years
45
- ONE_YEAR = ONE_DAY * 365
@@ -1,37 +0,0 @@
1
- from typing import Any
2
-
3
- from fastapi import status
4
-
5
- from corekit.exceptions.base import CustomHTTPException
6
-
7
-
8
- # 400 Errors
9
- class UnauthorizedException(CustomHTTPException):
10
- def __init__(self, **kwargs: Any) -> None:
11
- super().__init__(status_code=status.HTTP_401_UNAUTHORIZED, **kwargs)
12
-
13
-
14
- class ForbiddenException(CustomHTTPException):
15
- def __init__(self, **kwargs: Any) -> None:
16
- super().__init__(status_code=status.HTTP_403_FORBIDDEN, **kwargs)
17
-
18
-
19
- class NotFoundException(CustomHTTPException):
20
- def __init__(self, **kwargs: Any) -> None:
21
- super().__init__(status_code=status.HTTP_404_NOT_FOUND, **kwargs)
22
-
23
-
24
- class ConflictErrorException(CustomHTTPException):
25
- def __init__(self, **kwargs: Any) -> None:
26
- super().__init__(status_code=status.HTTP_409_CONFLICT, **kwargs)
27
-
28
-
29
- class UnprocessableEntityException(CustomHTTPException):
30
- def __init__(self, **kwargs: Any) -> None:
31
- super().__init__(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, **kwargs)
32
-
33
-
34
- # 500 Errors
35
- class InternalServerErrorException(CustomHTTPException):
36
- def __init__(self, **kwargs: Any) -> None:
37
- super().__init__(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, **kwargs)
corekit/files/pickle.py DELETED
@@ -1,12 +0,0 @@
1
- import pickle
2
- from typing import Any
3
-
4
- from corekit.files.base import FileContent, FileManager
5
-
6
-
7
- class PickleFileManager(FileManager):
8
- def _serialize(self, content: Any) -> FileContent:
9
- return pickle.dumps(content)
10
-
11
- def _deserialize(self, content: FileContent) -> Any:
12
- return pickle.loads(content)