koi-net 1.1.0b3__tar.gz → 1.1.0b4__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.

Potentially problematic release.


This version of koi-net might be problematic. Click here for more details.

Files changed (43) hide show
  1. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/PKG-INFO +1 -1
  2. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/pyproject.toml +1 -1
  3. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/context.py +5 -2
  4. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/core.py +1 -0
  5. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/event_queue.py +7 -5
  6. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/request_handler.py +21 -4
  7. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/default_handlers.py +14 -1
  8. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/.github/workflows/publish-to-pypi.yml +0 -0
  9. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/.gitignore +0 -0
  10. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/LICENSE +0 -0
  11. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/README.md +0 -0
  12. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/examples/coordinator.py +0 -0
  13. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/examples/partial.py +0 -0
  14. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/requirements.txt +0 -0
  15. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/__init__.py +0 -0
  16. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/config.py +0 -0
  17. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/default_actions.py +0 -0
  18. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/effector.py +0 -0
  19. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/identity.py +0 -0
  20. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/lifecycle.py +0 -0
  21. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/__init__.py +0 -0
  22. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/behavior.py +0 -0
  23. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/error_handler.py +0 -0
  24. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/graph.py +0 -0
  25. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/resolver.py +0 -0
  26. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/network/response_handler.py +0 -0
  27. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/poller.py +0 -0
  28. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/__init__.py +0 -0
  29. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/handler.py +0 -0
  30. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/interface.py +0 -0
  31. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/knowledge_object.py +0 -0
  32. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/processor/knowledge_pipeline.py +0 -0
  33. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/__init__.py +0 -0
  34. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/api_models.py +0 -0
  35. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/consts.py +0 -0
  36. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/edge.py +0 -0
  37. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/envelope.py +0 -0
  38. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/errors.py +0 -0
  39. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/event.py +0 -0
  40. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/node.py +0 -0
  41. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/protocol/secure.py +0 -0
  42. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/secure.py +0 -0
  43. {koi_net-1.1.0b3 → koi_net-1.1.0b4}/src/koi_net/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: koi-net
3
- Version: 1.1.0b3
3
+ Version: 1.1.0b4
4
4
  Summary: Implementation of KOI-net protocol in Python
5
5
  Project-URL: Homepage, https://github.com/BlockScience/koi-net/
6
6
  Author-email: Luke Miller <luke@block.science>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "koi-net"
7
- version = "1.1.0-beta.3"
7
+ version = "1.1.0-beta.4"
8
8
  description = "Implementation of KOI-net protocol in Python"
9
9
  authors = [
10
10
  {name = "Luke Miller", email = "luke@block.science"}
@@ -1,6 +1,6 @@
1
-
2
- from koi_net.effector import Effector
3
1
  from rid_lib.ext import Cache
2
+ from .config import NodeConfig
3
+ from .effector import Effector
4
4
  from .network.graph import NetworkGraph
5
5
  from .network.event_queue import NetworkEventQueue
6
6
  from .network.request_handler import RequestHandler
@@ -23,6 +23,7 @@ class ActionContext:
23
23
 
24
24
  class HandlerContext:
25
25
  identity: NodeIdentity
26
+ config: NodeConfig
26
27
  cache: Cache
27
28
  event_queue: NetworkEventQueue
28
29
  graph: NetworkGraph
@@ -33,6 +34,7 @@ class HandlerContext:
33
34
  def __init__(
34
35
  self,
35
36
  identity: NodeIdentity,
37
+ config: NodeConfig,
36
38
  cache: Cache,
37
39
  event_queue: NetworkEventQueue,
38
40
  graph: NetworkGraph,
@@ -40,6 +42,7 @@ class HandlerContext:
40
42
  effector: Effector
41
43
  ):
42
44
  self.identity = identity
45
+ self.config = config
43
46
  self.cache = cache
44
47
  self.event_queue = event_queue
45
48
  self.graph = graph
@@ -132,6 +132,7 @@ class NodeInterface(Generic[T]):
132
132
 
133
133
  self.handler_context = (HandlerContextOverride or HandlerContext)(
134
134
  identity=self.identity,
135
+ config=self.config,
135
136
  cache=self.cache,
136
137
  event_queue=self.event_queue,
137
138
  graph=self.graph,
@@ -7,7 +7,7 @@ from rid_lib.ext import Cache
7
7
  from rid_lib.types import KoiNetNode
8
8
 
9
9
  from .graph import NetworkGraph
10
- from .request_handler import RequestHandler
10
+ from .request_handler import NodeNotFoundError, RequestHandler
11
11
  from ..protocol.node import NodeProfile, NodeType
12
12
  from ..protocol.edge import EdgeProfile, EdgeType
13
13
  from ..protocol.event import Event
@@ -187,11 +187,13 @@ class NetworkEventQueue:
187
187
 
188
188
  try:
189
189
  self.request_handler.broadcast_events(node, events=events)
190
- return True
190
+
191
+ except NodeNotFoundError:
192
+ logger.warning("Broadcast failed (node not found)")
193
+
191
194
  except httpx.ConnectError:
192
- logger.warning("Broadcast failed")
195
+ logger.warning("Broadcast failed (couldn't connect)")
193
196
 
194
197
  if requeue_on_fail:
195
198
  for event in events:
196
- self.push_event_to(event, node)
197
- return False
199
+ self.push_event_to(event, node)
@@ -37,6 +37,23 @@ if TYPE_CHECKING:
37
37
  logger = logging.getLogger(__name__)
38
38
 
39
39
 
40
+ # Custom error types for request handling
41
+ class SelfRequestError(Exception):
42
+ """Raised when a node tries to request itself."""
43
+ pass
44
+
45
+ class PartialNodeQueryError(Exception):
46
+ """Raised when attempting to query a partial node."""
47
+ pass
48
+
49
+ class NodeNotFoundError(Exception):
50
+ """Raised when a node URL cannot be found."""
51
+ pass
52
+
53
+ class UnknownPathError(Exception):
54
+ """Raised when an unknown path is requested."""
55
+ pass
56
+
40
57
  class RequestHandler:
41
58
  """Handles making requests to other KOI nodes."""
42
59
 
@@ -65,7 +82,7 @@ class RequestHandler:
65
82
  node_url = None
66
83
 
67
84
  if node_rid == self.identity.rid:
68
- raise Exception("Don't talk to yourself")
85
+ raise SelfRequestError("Don't talk to yourself")
69
86
 
70
87
  node_bundle = self.effector.deref(node_rid)
71
88
 
@@ -73,7 +90,7 @@ class RequestHandler:
73
90
  node_profile = node_bundle.validate_contents(NodeProfile)
74
91
  logger.debug(f"Found node profile: {node_profile}")
75
92
  if node_profile.node_type != NodeType.FULL:
76
- raise Exception("Can't query partial node")
93
+ raise PartialNodeQueryError("Can't query partial node")
77
94
  node_url = node_profile.base_url
78
95
 
79
96
  else:
@@ -82,7 +99,7 @@ class RequestHandler:
82
99
  node_url = self.identity.config.koi_net.first_contact.url
83
100
 
84
101
  if not node_url:
85
- raise Exception("Node not found")
102
+ raise NodeNotFoundError("Node not found")
86
103
 
87
104
  logger.debug(f"Resolved {node_rid!r} to {node_url}")
88
105
  return node_url
@@ -124,7 +141,7 @@ class RequestHandler:
124
141
  elif path == FETCH_BUNDLES_PATH:
125
142
  EnvelopeModel = SignedEnvelope[BundlesPayload]
126
143
  else:
127
- raise Exception(f"Unknown path '{path}'")
144
+ raise UnknownPathError(f"Unknown path '{path}'")
128
145
 
129
146
  resp_envelope = EnvelopeModel.model_validate_json(result.text)
130
147
  self.secure.validate_envelope(resp_envelope)
@@ -233,4 +233,17 @@ def basic_network_output_filter(ctx: HandlerContext, kobj: KnowledgeObject):
233
233
  kobj.network_targets.update(subscribers)
234
234
 
235
235
  return kobj
236
-
236
+
237
+ @KnowledgeHandler.create(HandlerType.Final, rid_types=[KoiNetNode])
238
+ def forget_edge_on_node_deletion(ctx: HandlerContext, kobj: KnowledgeObject):
239
+ if kobj.normalized_event_type != EventType.FORGET:
240
+ return
241
+
242
+ for edge_rid in ctx.graph.get_edges():
243
+ edge_bundle = ctx.cache.read(edge_rid)
244
+ if not edge_bundle: continue
245
+ edge_profile = edge_bundle.validate_contents(EdgeProfile)
246
+
247
+ if kobj.rid in (edge_profile.source, edge_profile.target):
248
+ logger.debug("Identified edge with forgotten node")
249
+ ctx.handle(rid=edge_rid, event_type=EventType.FORGET)
File without changes
File without changes
File without changes
File without changes
File without changes