koi-net 1.0.0b19__py3-none-any.whl → 1.1.0b2__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.

Potentially problematic release.


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

koi_net/server.py ADDED
@@ -0,0 +1,128 @@
1
+ import logging
2
+ import uvicorn
3
+ from contextlib import asynccontextmanager
4
+ from fastapi import FastAPI, APIRouter
5
+ from fastapi.responses import JSONResponse
6
+ from .network.event_queue import NetworkEventQueue
7
+ from .network.response_handler import ResponseHandler
8
+ from .processor.interface import ProcessorInterface
9
+ from .protocol.api_models import (
10
+ PollEvents,
11
+ FetchRids,
12
+ FetchManifests,
13
+ FetchBundles,
14
+ EventsPayload,
15
+ RidsPayload,
16
+ ManifestsPayload,
17
+ BundlesPayload,
18
+ ErrorResponse
19
+ )
20
+ from .protocol.errors import ProtocolError
21
+ from .protocol.envelope import SignedEnvelope
22
+ from .protocol.consts import (
23
+ BROADCAST_EVENTS_PATH,
24
+ POLL_EVENTS_PATH,
25
+ FETCH_RIDS_PATH,
26
+ FETCH_MANIFESTS_PATH,
27
+ FETCH_BUNDLES_PATH
28
+ )
29
+ from .secure import Secure
30
+ from .lifecycle import NodeLifecycle
31
+ from .config import NodeConfig
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+
36
+ class NodeServer:
37
+ lifecycle: NodeLifecycle
38
+
39
+ def __init__(
40
+ self,
41
+ config: NodeConfig,
42
+ lifecycle: NodeLifecycle,
43
+ secure: Secure,
44
+ processor: ProcessorInterface,
45
+ event_queue: NetworkEventQueue,
46
+ response_handler: ResponseHandler
47
+ ):
48
+ self.config = config
49
+ self.lifecycle = lifecycle
50
+ self.secure = secure
51
+ self.processor = processor
52
+ self.event_queue = event_queue
53
+ self.response_handler = response_handler
54
+ self._build_app()
55
+
56
+ def _build_app(self):
57
+ self.app = FastAPI(
58
+ lifespan=self.lifespan,
59
+ title="KOI-net Protocol API",
60
+ version="1.0.0"
61
+ )
62
+
63
+ self.router = APIRouter(prefix="/koi-net")
64
+ self.app.add_exception_handler(ProtocolError, self.protocol_error_handler)
65
+
66
+ def _add_endpoint(path, func):
67
+ self.router.add_api_route(
68
+ path=path,
69
+ endpoint=self.secure.envelope_handler(func),
70
+ methods=["POST"]
71
+ )
72
+
73
+ _add_endpoint(BROADCAST_EVENTS_PATH, self.broadcast_events)
74
+ _add_endpoint(POLL_EVENTS_PATH, self.poll_events)
75
+ _add_endpoint(FETCH_RIDS_PATH, self.fetch_rids)
76
+ _add_endpoint(FETCH_MANIFESTS_PATH, self.fetch_manifests)
77
+ _add_endpoint(FETCH_BUNDLES_PATH, self.fetch_bundles)
78
+
79
+ self.app.include_router(self.router)
80
+
81
+ def run(self):
82
+ uvicorn.run(
83
+ app=self.app,
84
+ host=self.config.server.host,
85
+ port=self.config.server.port
86
+ )
87
+
88
+ @asynccontextmanager
89
+ async def lifespan(self, app: FastAPI):
90
+ self.lifecycle.start()
91
+ yield
92
+ self.lifecycle.stop()
93
+
94
+ def protocol_error_handler(self, request, exc: ProtocolError):
95
+ logger.info(f"caught protocol error: {exc}")
96
+ resp = ErrorResponse(error=exc.error_type)
97
+ logger.info(f"returning error response: {resp}")
98
+ return JSONResponse(
99
+ status_code=400,
100
+ content=resp.model_dump(mode="json")
101
+ )
102
+
103
+ async def broadcast_events(self, req: SignedEnvelope[EventsPayload]):
104
+ logger.info(f"Request to {BROADCAST_EVENTS_PATH}, received {len(req.payload.events)} event(s)")
105
+ for event in req.payload.events:
106
+ self.processor.handle(event=event, source=req.source_node)
107
+
108
+ async def poll_events(
109
+ self, req: SignedEnvelope[PollEvents]
110
+ ) -> SignedEnvelope[EventsPayload] | ErrorResponse:
111
+ logger.info(f"Request to {POLL_EVENTS_PATH}")
112
+ events = self.event_queue.flush_poll_queue(req.payload.rid)
113
+ return EventsPayload(events=events)
114
+
115
+ async def fetch_rids(
116
+ self, req: SignedEnvelope[FetchRids]
117
+ ) -> SignedEnvelope[RidsPayload] | ErrorResponse:
118
+ return self.response_handler.fetch_rids(req.payload)
119
+
120
+ async def fetch_manifests(
121
+ self, req: SignedEnvelope[FetchManifests]
122
+ ) -> SignedEnvelope[ManifestsPayload] | ErrorResponse:
123
+ return self.response_handler.fetch_manifests(req.payload)
124
+
125
+ async def fetch_bundles(
126
+ self, req: SignedEnvelope[FetchBundles]
127
+ ) -> SignedEnvelope[BundlesPayload] | ErrorResponse:
128
+ return self.response_handler.fetch_bundles(req.payload)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: koi-net
3
- Version: 1.0.0b19
3
+ Version: 1.1.0b2
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>
@@ -27,19 +27,20 @@ License: MIT License
27
27
  SOFTWARE.
28
28
  License-File: LICENSE
29
29
  Requires-Python: >=3.10
30
+ Requires-Dist: cryptography>=45.0.3
31
+ Requires-Dist: fastapi>=0.115.12
30
32
  Requires-Dist: httpx>=0.28.1
31
33
  Requires-Dist: networkx>=3.4.2
32
34
  Requires-Dist: pydantic>=2.10.6
33
35
  Requires-Dist: python-dotenv>=1.1.0
34
- Requires-Dist: rid-lib>=3.2.3
36
+ Requires-Dist: rid-lib>=3.2.7
35
37
  Requires-Dist: ruamel-yaml>=0.18.10
38
+ Requires-Dist: uvicorn>=0.34.2
36
39
  Provides-Extra: dev
37
40
  Requires-Dist: build; extra == 'dev'
38
41
  Requires-Dist: twine>=6.0; extra == 'dev'
39
42
  Provides-Extra: examples
40
- Requires-Dist: fastapi; extra == 'examples'
41
43
  Requires-Dist: rich; extra == 'examples'
42
- Requires-Dist: uvicorn; extra == 'examples'
43
44
  Description-Content-Type: text/markdown
44
45
 
45
46
  # KOI-net
@@ -0,0 +1,38 @@
1
+ koi_net/__init__.py,sha256=b0Ze0pZmJAuygpWUFHM6Kvqo3DkU_uzmkptv1EpAArw,31
2
+ koi_net/config.py,sha256=47XbQ59GRYFi4rlsoWKlnzMQATcnK70i3qmKTZAGOQk,4087
3
+ koi_net/context.py,sha256=JmbpCzusXFq_NCXiUp5Z56N6vpBdYMUK8eOs7ogO68A,1428
4
+ koi_net/core.py,sha256=wJjEaza-Q_QqTZL8xOWdlMkjOhCmX8Lj3uBy2GUGDF0,5565
5
+ koi_net/default_actions.py,sha256=TkQR9oj9CpO37Gb5bZLmFNl-Q8n3OxGiX4dvxQR7SaA,421
6
+ koi_net/effector.py,sha256=gSyZgRxQ91X04UL261e2pXWUfBHnQTGtjSHpc2JufxA,4097
7
+ koi_net/identity.py,sha256=FvIWksGTqwM7HCevIwmo_6l-t-2tnYkaaR4CanZatL4,569
8
+ koi_net/lifecycle.py,sha256=-J5y4i0JdernatLTed8hQbkK26Cs6rm1kZqlx3aQzZA,2727
9
+ koi_net/poller.py,sha256=tlqbDMTdkU8vCbi95rOBeHUEWLkrECKW3gnF9MYhKQw,1369
10
+ koi_net/secure.py,sha256=cGNF2assqCaYq0i0fhQBm7aREoAdpY-XVypDsE1ALaU,3970
11
+ koi_net/server.py,sha256=ONJMhC_9VNBTVTdHRMP66T9QIZ1UuSZY7C_KoRcVb9k,4199
12
+ koi_net/network/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ koi_net/network/behavior.py,sha256=NZLvWlrxR0uWriE3ZzCXmocUVccQthy7Xx8E_8KBwsg,1208
14
+ koi_net/network/error_handler.py,sha256=CrmCpBY2oj4nl7uXrIYusUHDKxPZ1HDuQAtiBSZarRI,1623
15
+ koi_net/network/event_queue.py,sha256=QV1dLOe-H85fNJVkc-e0ZRsUpHTkFcMLMbp3WU5gRNg,7225
16
+ koi_net/network/graph.py,sha256=NLstBsPa9By0luxcTjThnqVd3hxfQdFwn8tWgJ6u4l4,4144
17
+ koi_net/network/request_handler.py,sha256=77SHLO92gVHTusUXWo89KgjRnxU9vLG_Qi8HxTFtFBg,6376
18
+ koi_net/network/resolver.py,sha256=coIp4M6k0-8sUfAy4h2NMx_7zCNroWlCHKOj3AXZVhc,5412
19
+ koi_net/network/response_handler.py,sha256=tEfzSZWXKCRwUlXhM8Qp3Y6BKTQ4abfi-MrSaatlITI,1980
20
+ koi_net/processor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ koi_net/processor/default_handlers.py,sha256=SX1eP740W9LeG-IEoBOmsNrKJfOEDDuEQUSwnJEG_8w,8954
22
+ koi_net/processor/handler.py,sha256=_loaHjgVGVUxtCQdvAY9dQ0iqiq5co7wB2tK-usuv3Y,2355
23
+ koi_net/processor/interface.py,sha256=ebDwqggznFRfp2PT8-UJPUAvCwX8nZaaQ68FUeWQvmw,3682
24
+ koi_net/processor/knowledge_object.py,sha256=avQnsaeqqiJxy40P1VGljuQMtAGmJB-TBa4pmBXTaIs,3863
25
+ koi_net/processor/knowledge_pipeline.py,sha256=i7FpCFl0UIOwCI5zhP1i8M4PX4A48VN28iV9jruvN5k,9486
26
+ koi_net/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ koi_net/protocol/api_models.py,sha256=bHhbLeq8I7nVBuW-AXgKfb1O58_mLogHRG8A_LZt2IE,1188
28
+ koi_net/protocol/consts.py,sha256=bisbVEojPIHlLhkLafBzfIhH25TjNfvTORF1g6YXzIM,243
29
+ koi_net/protocol/edge.py,sha256=dQKtI0_eX2E6tD7kMExv6DeJMkqNo2cY-LxJMJbiK0E,963
30
+ koi_net/protocol/envelope.py,sha256=W-K3rjwqwAL9wCXb2_gpAUwnc2xOVdZ1UWMoDlLrqJY,1690
31
+ koi_net/protocol/errors.py,sha256=A83QiYe_fJdxW2lsNsLCujWxDr5sk1UmYYd3TGbSNJA,601
32
+ koi_net/protocol/event.py,sha256=eGgihEj1gliLoQRk8pVB2q_was0AGo-PbT3Hqnpn3oU,1379
33
+ koi_net/protocol/node.py,sha256=7GQzHORFr9cP4BqJgir6EGSWCskL-yqmvJksIiLfcWU,409
34
+ koi_net/protocol/secure.py,sha256=Reem9Z4le4uWXM9uczNOdmgVBg8p4YQav-7_c3pZ1CQ,3366
35
+ koi_net-1.1.0b2.dist-info/METADATA,sha256=k341N2GlyWwem7ojdmX1PH8tij0D4CQHfOjGnuv5XYQ,37118
36
+ koi_net-1.1.0b2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
37
+ koi_net-1.1.0b2.dist-info/licenses/LICENSE,sha256=03mgCL5qth2aD9C3F3qNVs4sFJSpK9kjtYCyOwdSp7s,1069
38
+ koi_net-1.1.0b2.dist-info/RECORD,,
@@ -1,25 +0,0 @@
1
- from rid_lib.core import RIDType
2
- from rid_lib.ext.bundle import Bundle
3
- from rid_lib.types import KoiNetEdge
4
- from rid_lib.types.koi_net_node import KoiNetNode
5
- from .edge import EdgeProfile, EdgeStatus, EdgeType
6
-
7
- def generate_edge_bundle(
8
- source: KoiNetNode,
9
- target: KoiNetNode,
10
- rid_types: list[RIDType],
11
- edge_type: EdgeType
12
- ) -> Bundle:
13
- edge_rid = KoiNetEdge.generate(source, target)
14
- edge_profile = EdgeProfile(
15
- source=source,
16
- target=target,
17
- rid_types=rid_types,
18
- edge_type=edge_type,
19
- status=EdgeStatus.PROPOSED
20
- )
21
- edge_bundle = Bundle.generate(
22
- edge_rid,
23
- edge_profile.model_dump()
24
- )
25
- return edge_bundle
@@ -1,25 +0,0 @@
1
- koi_net/__init__.py,sha256=b0Ze0pZmJAuygpWUFHM6Kvqo3DkU_uzmkptv1EpAArw,31
2
- koi_net/config.py,sha256=TIKb1kFTcEysqwdHp6yCNpcXeS84dlprcb-f0z2jF0Y,3160
3
- koi_net/core.py,sha256=IO8kqiNMYVeuNzilq7eHBA7IulsxRjrCbWnIAx6_abA,4406
4
- koi_net/identity.py,sha256=muc5vuQ8zUOebhwAB3-ql6W2pgQETiYXXQAFBv8bLyg,1288
5
- koi_net/network/__init__.py,sha256=r_RN-q_mDYC-2RAkN-lJoMUX76TXyfEUc_MVKW87z0g,39
6
- koi_net/network/graph.py,sha256=dsfPuHUTkCzlj0QeL0e7dgp7-FR5_AGP7eE8EpBPhC0,4710
7
- koi_net/network/interface.py,sha256=icpl0rzpC5yV86BQBAbjAjK7AWhgCFoyFLm_Fjf1mCI,10451
8
- koi_net/network/request_handler.py,sha256=66gjX2x4UnBWZYwKLjp_3WkhL-ekhR3VAyfGviHTcUs,4790
9
- koi_net/network/response_handler.py,sha256=CAwici2Etj9ESndERXdtYkMlc4gWHz_xc7jHgY2Qjcg,1830
10
- koi_net/processor/__init__.py,sha256=x4fAY0hvQEDcpfdTB3POIzxBQjYAtn0qQazPo1Xm0m4,41
11
- koi_net/processor/default_handlers.py,sha256=dP64lEJ64BJ7H8PhFK-GZI1pv51tVVINV4jAgcOtOhc,8669
12
- koi_net/processor/handler.py,sha256=7X6M6PP8m6-xdtsP1y4QO83g_MN5VSszNNikprITK80,2523
13
- koi_net/processor/interface.py,sha256=Kyw4SQos_1WdcPJJe-j2w4xDIfwtmpF4mfGlkRVRqUI,12876
14
- koi_net/processor/knowledge_object.py,sha256=RCgzkILsWm1Jw_NkSu4jTRYA9Ugga6mJ4jqKWwketQs,4090
15
- koi_net/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- koi_net/protocol/api_models.py,sha256=DYDKCRD2Uja633bBAyTsaxyb1oF9pX9yQ9NpNAbkczo,1070
17
- koi_net/protocol/consts.py,sha256=bisbVEojPIHlLhkLafBzfIhH25TjNfvTORF1g6YXzIM,243
18
- koi_net/protocol/edge.py,sha256=CcmvIY4P1HEBdKNJ4wFRDmwYMRMss24Besmbi7ZRFxQ,427
19
- koi_net/protocol/event.py,sha256=eGgihEj1gliLoQRk8pVB2q_was0AGo-PbT3Hqnpn3oU,1379
20
- koi_net/protocol/helpers.py,sha256=8ZkQrjb_G0QEaMIKe9wkFOBonl1bkmemx_pwKMwIiLg,695
21
- koi_net/protocol/node.py,sha256=2HhCh3LdBLlY2Z_kXNmKHzpVLKbP_ODob3HjHayFQtM,375
22
- koi_net-1.0.0b19.dist-info/METADATA,sha256=uVzxDiRiHRncwfjotk7j_frmm_ka6PEpI-kcA278HoE,37107
23
- koi_net-1.0.0b19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
- koi_net-1.0.0b19.dist-info/licenses/LICENSE,sha256=03mgCL5qth2aD9C3F3qNVs4sFJSpK9kjtYCyOwdSp7s,1069
25
- koi_net-1.0.0b19.dist-info/RECORD,,