opendataframework 0.3.0__tar.gz → 0.5.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 (25) hide show
  1. {opendataframework-0.3.0 → opendataframework-0.5.0}/PKG-INFO +40 -4
  2. {opendataframework-0.3.0 → opendataframework-0.5.0}/README.md +39 -3
  3. {opendataframework-0.3.0 → opendataframework-0.5.0}/pyproject.toml +1 -1
  4. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/__init__.py +8 -1
  5. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/context.py +219 -87
  6. opendataframework-0.5.0/src/opendataframework/events.py +360 -0
  7. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/function.py +23 -0
  8. opendataframework-0.5.0/src/opendataframework/logger.py +408 -0
  9. opendataframework-0.5.0/src/opendataframework/notifications.py +304 -0
  10. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/project.py +7 -4
  11. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/view.py +16 -5
  12. opendataframework-0.3.0/src/opendataframework/logger.py +0 -140
  13. {opendataframework-0.3.0 → opendataframework-0.5.0}/LICENSE +0 -0
  14. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/agent.py +0 -0
  15. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/component.py +0 -0
  16. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/config.py +0 -0
  17. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/entity.py +0 -0
  18. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/layer.py +0 -0
  19. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/namespace.py +0 -0
  20. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/pipeline.py +0 -0
  21. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/py.typed +0 -0
  22. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/repository.py +0 -0
  23. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/service.py +0 -0
  24. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/task.py +0 -0
  25. {opendataframework-0.3.0 → opendataframework-0.5.0}/src/opendataframework/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opendataframework
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Lightweight dependency-injection framework for data applications.
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -26,7 +26,7 @@ Lightweight dependency-injection framework for data applications.
26
26
  This package provides structural abstractions —
27
27
  `Entity`, `Repository`, `Component`, `Service`, `Task`, `Pipeline`,
28
28
  `Agent`, `Function`, `Layer`, `Namespace`, `Context`, `Project`, `Config`,
29
- `Logger`, `View` — with zero third-party dependencies. No UI, no CLI, no MCP server.
29
+ `Logger`, `Events`, `Notifications`, `View` — with zero third-party dependencies. No UI, no CLI, no MCP server.
30
30
 
31
31
  > Need the CLI, UI, or MCP server? That's the
32
32
  > [`odf`](https://opendataframework.github.io/odf/) package, which
@@ -307,7 +307,10 @@ class Postgres:
307
307
 
308
308
  Per-component logging handle, injectable via constructor DI like any
309
309
  other dependency — writes land in that component's own log file with no
310
- name argument needed.
310
+ name argument needed. Logs are structured: one JSON record per line by
311
+ default, keyword arguments become fields, and every protocol call the
312
+ framework makes is logged with its call and parent ids, so a run can be
313
+ traced across files.
311
314
 
312
315
  ```python
313
316
  @Task
@@ -317,7 +320,40 @@ class ExportUsers:
317
320
  self.logger = logger
318
321
 
319
322
  def execute(self) -> None:
320
- self.logger.info("export starting")
323
+ self.logger.info("export starting", users=len(self.users.all()))
324
+ ```
325
+
326
+ ## Events
327
+
328
+ Reports every protocol call the framework makes — a `Service`'s `setup()`,
329
+ a `Task`'s `execute()`, a `@Function` call — as `started`, then `completed`
330
+ or `failed`, with timing and the `parent` call it ran inside.
331
+
332
+ ```python
333
+ @Component
334
+ class FailureAlerts:
335
+ def __init__(self, events: Events):
336
+ self._unsubscribe = events.subscribe(self.on_event)
337
+
338
+ def on_event(self, event: Event) -> None:
339
+ if event.state == "failed":
340
+ ...
341
+ ```
342
+
343
+ ## Notifications
344
+
345
+ Lets a component announce that something happened — a file arrived, an
346
+ order came in — so others can react without the publisher knowing who
347
+ they are. Never emitted by the framework itself.
348
+
349
+ ```python
350
+ @Task
351
+ class TakeOrders:
352
+ def __init__(self, notifications: Notifications):
353
+ self.notifications = notifications
354
+
355
+ def execute(self) -> None:
356
+ self.notifications.publish("orders.received", {"id": 7}, summary="Le Petit: 2 x baguette")
321
357
  ```
322
358
 
323
359
  ## Context
@@ -10,7 +10,7 @@ Lightweight dependency-injection framework for data applications.
10
10
  This package provides structural abstractions —
11
11
  `Entity`, `Repository`, `Component`, `Service`, `Task`, `Pipeline`,
12
12
  `Agent`, `Function`, `Layer`, `Namespace`, `Context`, `Project`, `Config`,
13
- `Logger`, `View` — with zero third-party dependencies. No UI, no CLI, no MCP server.
13
+ `Logger`, `Events`, `Notifications`, `View` — with zero third-party dependencies. No UI, no CLI, no MCP server.
14
14
 
15
15
  > Need the CLI, UI, or MCP server? That's the
16
16
  > [`odf`](https://opendataframework.github.io/odf/) package, which
@@ -291,7 +291,10 @@ class Postgres:
291
291
 
292
292
  Per-component logging handle, injectable via constructor DI like any
293
293
  other dependency — writes land in that component's own log file with no
294
- name argument needed.
294
+ name argument needed. Logs are structured: one JSON record per line by
295
+ default, keyword arguments become fields, and every protocol call the
296
+ framework makes is logged with its call and parent ids, so a run can be
297
+ traced across files.
295
298
 
296
299
  ```python
297
300
  @Task
@@ -301,7 +304,40 @@ class ExportUsers:
301
304
  self.logger = logger
302
305
 
303
306
  def execute(self) -> None:
304
- self.logger.info("export starting")
307
+ self.logger.info("export starting", users=len(self.users.all()))
308
+ ```
309
+
310
+ ## Events
311
+
312
+ Reports every protocol call the framework makes — a `Service`'s `setup()`,
313
+ a `Task`'s `execute()`, a `@Function` call — as `started`, then `completed`
314
+ or `failed`, with timing and the `parent` call it ran inside.
315
+
316
+ ```python
317
+ @Component
318
+ class FailureAlerts:
319
+ def __init__(self, events: Events):
320
+ self._unsubscribe = events.subscribe(self.on_event)
321
+
322
+ def on_event(self, event: Event) -> None:
323
+ if event.state == "failed":
324
+ ...
325
+ ```
326
+
327
+ ## Notifications
328
+
329
+ Lets a component announce that something happened — a file arrived, an
330
+ order came in — so others can react without the publisher knowing who
331
+ they are. Never emitted by the framework itself.
332
+
333
+ ```python
334
+ @Task
335
+ class TakeOrders:
336
+ def __init__(self, notifications: Notifications):
337
+ self.notifications = notifications
338
+
339
+ def execute(self) -> None:
340
+ self.notifications.publish("orders.received", {"id": 7}, summary="Le Petit: 2 x baguette")
305
341
  ```
306
342
 
307
343
  ## Context
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "opendataframework"
3
- version = "0.3.0"
3
+ version = "0.5.0"
4
4
  description = "Lightweight dependency-injection framework for data applications."
5
5
  authors = [
6
6
  {name = "mykytapavlov",email = "mykytapavlov@users.noreply.github.com"}
@@ -5,10 +5,12 @@ from opendataframework.component import Component
5
5
  from opendataframework.config import Config
6
6
  from opendataframework.context import Context, Lifecycle, Resolver
7
7
  from opendataframework.entity import Entity
8
- from opendataframework.function import Function
8
+ from opendataframework.events import Event, Events
9
+ from opendataframework.function import Function, FunctionProtocol
9
10
  from opendataframework.layer import Analytics, Api, Layer, Messaging, Monitoring, Security, Storage
10
11
  from opendataframework.logger import Logger
11
12
  from opendataframework.namespace import Namespace
13
+ from opendataframework.notifications import Notification, Notifications
12
14
  from opendataframework.pipeline import Pipeline, PipelineProtocol
13
15
  from opendataframework.project import Project
14
16
  from opendataframework.repository import (
@@ -51,7 +53,10 @@ __all__ = [
51
53
  "DataViewProtocol",
52
54
  "DocumentView",
53
55
  "Entity",
56
+ "Event",
57
+ "Events",
54
58
  "Function",
59
+ "FunctionProtocol",
55
60
  "ImageView",
56
61
  "Layer",
57
62
  "Lifecycle",
@@ -60,6 +65,8 @@ __all__ = [
60
65
  "Messaging",
61
66
  "Monitoring",
62
67
  "Namespace",
68
+ "Notification",
69
+ "Notifications",
63
70
  "Pipeline",
64
71
  "PipelineProtocol",
65
72
  "Project",