meshagent-api 0.19.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.
@@ -0,0 +1,96 @@
1
+ from .websocket_protocol import WebSocketClientProtocol
2
+ from .room_server_client import (
3
+ RequiredToolkit,
4
+ RequiredSchema,
5
+ RequiredTable,
6
+ Requirement,
7
+ RoomClient,
8
+ RoomMessage,
9
+ RoomException,
10
+ ToolDescription,
11
+ ToolkitDescription,
12
+ RemoteParticipant,
13
+ LocalParticipant,
14
+ MeshDocument,
15
+ FileHandle,
16
+ MessageStream,
17
+ MessageStreamChunk,
18
+ StorageEntry,
19
+ AgentDescription,
20
+ )
21
+
22
+ from .client import Meshagent
23
+ from .participant_token import ParticipantToken, ParticipantGrant, ApiScope
24
+ from .participant import Participant
25
+ from .schema import (
26
+ MeshSchema,
27
+ ElementType,
28
+ ChildProperty,
29
+ ValueProperty,
30
+ )
31
+ from .schema_document import Element
32
+ from .messaging import (
33
+ JsonResponse,
34
+ TextResponse,
35
+ FileResponse,
36
+ ErrorResponse,
37
+ EmptyResponse,
38
+ )
39
+ from .schema_registry import SchemaRegistration, SchemaRegistry
40
+ from .helpers import (
41
+ deploy_schema,
42
+ websocket_room_url,
43
+ participant_token,
44
+ websocket_protocol,
45
+ meshagent_base_url,
46
+ )
47
+ from .webhooks import WebhookServer, RoomStartedEvent, RoomEndedEvent, CallEvent
48
+ from .version import __version__
49
+
50
+ __all__ = [
51
+ Meshagent,
52
+ WebSocketClientProtocol,
53
+ RequiredToolkit,
54
+ RequiredSchema,
55
+ RequiredTable,
56
+ Requirement,
57
+ RoomClient,
58
+ RoomMessage,
59
+ RoomException,
60
+ ToolDescription,
61
+ ToolkitDescription,
62
+ RemoteParticipant,
63
+ LocalParticipant,
64
+ MeshDocument,
65
+ FileHandle,
66
+ MessageStream,
67
+ MessageStreamChunk,
68
+ StorageEntry,
69
+ AgentDescription,
70
+ ParticipantToken,
71
+ ParticipantGrant,
72
+ ApiScope,
73
+ Participant,
74
+ MeshSchema,
75
+ ElementType,
76
+ ChildProperty,
77
+ ValueProperty,
78
+ Element,
79
+ JsonResponse,
80
+ TextResponse,
81
+ FileResponse,
82
+ ErrorResponse,
83
+ EmptyResponse,
84
+ SchemaRegistration,
85
+ SchemaRegistry,
86
+ deploy_schema,
87
+ websocket_room_url,
88
+ participant_token,
89
+ websocket_protocol,
90
+ meshagent_base_url,
91
+ WebhookServer,
92
+ RoomStartedEvent,
93
+ RoomEndedEvent,
94
+ CallEvent,
95
+ __version__,
96
+ ]
meshagent/api/chan.py ADDED
@@ -0,0 +1,177 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import contextlib
5
+ from collections import deque
6
+ from typing import AsyncIterator, Deque, Generic, Protocol, TypeVar
7
+
8
+ T = TypeVar("T")
9
+ T_co = TypeVar("T_co", covariant=True)
10
+ T_contra = TypeVar("T_contra", contravariant=True)
11
+
12
+
13
+ # Based on asyncio.Queue, see https://github.com/python/cpython/blob/main/Lib/asyncio/queues.py
14
+
15
+
16
+ class ChanClosed(Exception):
17
+ pass
18
+
19
+
20
+ class ChanFull(Exception):
21
+ pass
22
+
23
+
24
+ class ChanEmpty(Exception):
25
+ pass
26
+
27
+
28
+ class ChanSender(Protocol[T_contra]):
29
+ async def send(self, value: T_contra) -> None: ...
30
+
31
+ def send_nowait(self, value: T_contra) -> None: ...
32
+
33
+ def close(self) -> None: ...
34
+
35
+
36
+ class ChanReceiver(Protocol[T_co]):
37
+ async def recv(self) -> T_co: ...
38
+
39
+ def recv_nowait(self) -> T_co: ...
40
+
41
+ def close(self) -> None: ...
42
+
43
+ def __aiter__(self) -> AsyncIterator[T_co]: ...
44
+
45
+ async def __anext__(self) -> T_co: ...
46
+
47
+
48
+ class Chan(Generic[T]):
49
+ def __init__(
50
+ self, maxsize: int = 0, loop: asyncio.AbstractEventLoop | None = None
51
+ ) -> None:
52
+ self._loop = loop or asyncio.get_event_loop()
53
+ self._maxsize = max(maxsize, 0)
54
+ # self._finished_ev = asyncio.Event()
55
+ self._close_ev = asyncio.Event()
56
+ self._closed = False
57
+ self._gets: Deque[asyncio.Future[T | None]] = deque()
58
+ self._puts: Deque[asyncio.Future[T | None]] = deque()
59
+ self._queue: Deque[T] = deque()
60
+
61
+ def _wakeup_next(self, waiters: deque[asyncio.Future[T | None]]):
62
+ while waiters:
63
+ waiter = waiters.popleft()
64
+ if not waiter.done():
65
+ waiter.set_result(None)
66
+ break
67
+
68
+ async def send(self, value: T) -> None:
69
+ while self.full() and not self._close_ev.is_set():
70
+ p = self._loop.create_future()
71
+ self._puts.append(p)
72
+ try:
73
+ await p
74
+ except ChanClosed:
75
+ raise
76
+ except:
77
+ p.cancel()
78
+ with contextlib.suppress(ValueError):
79
+ self._puts.remove(p)
80
+
81
+ if not self.full() and not p.cancelled():
82
+ self._wakeup_next(self._puts)
83
+ raise
84
+
85
+ self.send_nowait(value)
86
+
87
+ def send_nowait(self, value: T) -> None:
88
+ if self.full():
89
+ raise ChanFull
90
+
91
+ if self._close_ev.is_set():
92
+ raise ChanClosed
93
+
94
+ self._queue.append(value)
95
+ self._wakeup_next(self._gets)
96
+
97
+ async def recv(self) -> T:
98
+ while self.empty() and not self._close_ev.is_set():
99
+ g = self._loop.create_future()
100
+ self._gets.append(g)
101
+
102
+ try:
103
+ await g
104
+ except ChanClosed:
105
+ raise
106
+ except asyncio.CancelledError:
107
+ raise
108
+ except Exception:
109
+ g.cancel()
110
+ with contextlib.suppress(ValueError):
111
+ self._gets.remove(g)
112
+
113
+ if not self.empty() and not g.cancelled():
114
+ self._wakeup_next(self._gets)
115
+
116
+ raise
117
+
118
+ return self.recv_nowait()
119
+
120
+ def recv_nowait(self) -> T:
121
+ if self.empty():
122
+ if self._close_ev.is_set():
123
+ raise ChanClosed
124
+ else:
125
+ raise ChanEmpty
126
+ item = self._queue.popleft()
127
+ # if self.empty() and self._close_ev.is_set():
128
+ # self._finished_ev.set()
129
+ self._wakeup_next(self._puts)
130
+ return item
131
+
132
+ def close(self) -> None:
133
+ self._closed = True
134
+ self._close_ev.set()
135
+ for putter in self._puts:
136
+ if not putter.cancelled():
137
+ putter.set_exception(ChanClosed())
138
+
139
+ while len(self._gets) > self.qsize():
140
+ getter = self._gets.pop()
141
+ if not getter.cancelled():
142
+ getter.set_exception(ChanClosed())
143
+
144
+ while self._gets:
145
+ self._wakeup_next(self._gets)
146
+
147
+ # if self.empty():
148
+ # self._finished_ev.set()
149
+
150
+ @property
151
+ def closed(self) -> bool:
152
+ return self._closed
153
+
154
+ # async def join(self) -> None:
155
+ # await self._finished_ev.wait()
156
+
157
+ def qsize(self) -> int:
158
+ """the number of elements queued (unread) in the channel buffer"""
159
+ return len(self._queue)
160
+
161
+ def full(self) -> bool:
162
+ if self._maxsize <= 0:
163
+ return False
164
+ else:
165
+ return self.qsize() >= self._maxsize
166
+
167
+ def empty(self) -> bool:
168
+ return not self._queue
169
+
170
+ def __aiter__(self) -> AsyncIterator[T]:
171
+ return self
172
+
173
+ async def __anext__(self) -> T:
174
+ try:
175
+ return await self.recv()
176
+ except ChanClosed:
177
+ raise StopAsyncIteration