spot-sdk-python 2.1.0b2__py3-none-any.whl → 2.1.1__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.
spot_sdk/hosting.py CHANGED
@@ -44,7 +44,11 @@ could expand past the bound once decoded."""
44
44
 
45
45
 
46
46
  class AnswerRefusedError(Exception):
47
- """A plugin's answer that is not read: encoded, or longer than ``MAX_ANSWER_BYTES``."""
47
+ """A plugin's answer that is not read: encoded, or longer than its bound."""
48
+
49
+
50
+ class AnswerTooLargeError(AnswerRefusedError):
51
+ """An answer longer than its bound, which a caller may treat apart from an encoded one."""
48
52
 
49
53
 
50
54
  class InvalidResponseError(Exception):
@@ -53,8 +57,10 @@ class InvalidResponseError(Exception):
53
57
 
54
58
  def isolated(egress: Egress | None) -> bool:
55
59
  """Whether a plugin of this egress class runs on a network without a route
56
- out: class none. An unrecorded class (None) counts as content."""
57
- return egress == Egress.NONE
60
+ out: every class, from SPOT 2.1 (spot/spot#148). A plugin reaches the
61
+ hosts its settings of type url name, through SPOT's egress gateway, and
62
+ nothing else: its class says what it sends out, not where it runs."""
63
+ return True
58
64
 
59
65
 
60
66
  def limits(resources: Resources) -> dict[str, Any]:
@@ -119,11 +125,14 @@ def secrets_archive(secrets: Mapping[str, str]) -> bytes:
119
125
  return buffer.getvalue()
120
126
 
121
127
 
122
- async def read_answer(response: httpx2.Response) -> bytes:
123
- """A streamed answer's body, as sent, read up to ``MAX_ANSWER_BYTES``.
128
+ async def read_answer(
129
+ response: httpx2.Response, max_bytes: int = MAX_ANSWER_BYTES
130
+ ) -> bytes:
131
+ """A streamed answer's body, as sent, read up to ``max_bytes``.
124
132
 
125
133
  Raises:
126
- AnswerRefusedError: the answer is encoded, or longer than ``MAX_ANSWER_BYTES``
134
+ AnswerRefusedError: the answer is encoded
135
+ AnswerTooLargeError: the answer is longer than ``max_bytes``
127
136
  """
128
137
  if (
129
138
  response.headers.get("content-encoding", "identity").strip().lower()
@@ -133,8 +142,8 @@ async def read_answer(response: httpx2.Response) -> bytes:
133
142
  body = bytearray()
134
143
  async for chunk in response.aiter_raw():
135
144
  body += chunk
136
- if len(body) > MAX_ANSWER_BYTES:
137
- raise AnswerRefusedError("response too large")
145
+ if len(body) > max_bytes:
146
+ raise AnswerTooLargeError(f"response too large: over {max_bytes} bytes")
138
147
  return bytes(body)
139
148
 
140
149
 
@@ -1,14 +1,14 @@
1
1
  """A plugin's image run as SPOT runs it, and checked: ``run_plugin_test``.
2
2
 
3
3
  The engine runs in a container that reaches the Docker daemon: spot-cli's
4
- image, given the socket. For each run it creates a network, without a route
5
- out for a plugin of egress class none as ``spot-plugins-isolated`` is, and
6
- joins it under SPOT's names, so that the plugin reaches the fake SPOT where it
7
- reaches SPOT. The plugin's container gets the plugin-manager's options and
8
- limits, a new token and its secret settings as files (``spot_sdk.hosting``).
9
- The network and the container carry the label ``spot.test.run=<run>``, by
10
- which the run removes them when it ends, however it ends: even one the daemon
11
- made while the call that asked for it failed. The image is never pulled.
4
+ image, given the socket. For each run it creates a network without a route
5
+ out, as SPOT runs every plugin (``isolated``), and joins it under SPOT's
6
+ names, so that the plugin reaches the fake SPOT where it reaches SPOT. The
7
+ plugin's container gets the plugin-manager's options and limits, a new token
8
+ and its secret settings as files (``spot_sdk.hosting``). The network and the
9
+ container carry the label ``spot.test.run=<run>``, by which the run removes
10
+ them when it ends, however it ends: even one the daemon made while the call
11
+ that asked for it failed. The image is never pulled.
12
12
  Needs the ``testing`` extra: ``pip install "spot-sdk-python[testing]"``.
13
13
  """
14
14
 
@@ -93,8 +93,8 @@ def run_plugin_test(
93
93
  """Run the plugin's image as SPOT runs it, against ``corpus``, and report.
94
94
 
95
95
  It runs in a container that reaches the Docker daemon: spot-cli's image,
96
- given the socket. It creates the plugin's network (internal for egress
97
- class none), joins it as SPOT's services, starts the plugin with the
96
+ given the socket. It creates the plugin's network (internal, as for every
97
+ plugin), joins it as SPOT's services, starts the plugin with the
98
98
  plugin-manager's options, its limits, a new token and its secrets as
99
99
  files, serves the fake SPOT, runs the checks and removes what it
100
100
  created, whatever happens.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spot-sdk-python
3
- Version: 2.1.0b2
3
+ Version: 2.1.1
4
4
  Summary: SPOT plugin SDK: the plugin contract, the plugin runtime, its clients and test helpers
5
5
  Author: SPOT Project
6
6
  Author-email: SPOT Project <spot@sonn.lu>
@@ -7,7 +7,7 @@ spot_sdk/config.py,sha256=sMSCOI_eVlcNiPamj4Nyuq7p44KZr06LFZVDlYgcqiI,1560
7
7
  spot_sdk/correlation.py,sha256=tgIL122V_d0htaR005zBHt2iLOoQnj3E-X-yKyPT6dc,2184
8
8
  spot_sdk/email.py,sha256=ifZHG9M0x-sTrOtohrU1NStsL4qeVddn18JoqLFawIQ,7313
9
9
  spot_sdk/errors.py,sha256=HTaRaoDfn5XV4v03qD4eCM-IgNaR7upQ08UF-I-1qaI,813
10
- spot_sdk/hosting.py,sha256=4Zb2bBmmrPelDSulNEJOub7V8cYUpVFjNZBWCIWumUo,5481
10
+ spot_sdk/hosting.py,sha256=3yQl5xEiFlVAts065e-LT6-qsajxAVhQ4KetHHmYpNE,5836
11
11
  spot_sdk/knowledge.py,sha256=TiBFPTekknqPuOGcH4FnkEsYBc5zZkmW7ToZTfTstqc,12405
12
12
  spot_sdk/knowledge_tags.py,sha256=BGhDsNeF8Q0MMNEIZjWrgQWjwH_Vf7dGBNN_hlBqTXs,978
13
13
  spot_sdk/llm.py,sha256=IEWhBbEat-7oHSNDg9_QOb7ylzv2g0B9uACpZq9-vMk,18610
@@ -23,7 +23,7 @@ spot_sdk/settings.py,sha256=4FN8WYSEoxY-Gf4D0jaSU-5z6o0EqrQXFbnD03qhd0Q,2884
23
23
  spot_sdk/signals.py,sha256=DkTqCSCcGbbtJjoTFrXExY9TcKFDXb-4SLR8wAgJUx0,1517
24
24
  spot_sdk/testing/README.md,sha256=N-42IBZOCxf0KbrfZ0nO64eBEC-l2hlQAjq4qIRJLQU,2786
25
25
  spot_sdk/testing/__init__.py,sha256=4pTiWDdyYBFJwQnrhiC8PK8Ag-puKGEAHQG4hv8zfRs,555
26
- spot_sdk/testing/container.py,sha256=2n4NMLb7ONEbCpO0GAb8Tj8O7QPrNIq7-acRz-IGYaE,18530
26
+ spot_sdk/testing/container.py,sha256=I4R-K-sWjT-AHPf-DoXacrBvLO-2fVqxPLwTgv0XofM,18504
27
27
  spot_sdk/testing/contract.py,sha256=t4J9HYIw2GF9esViY9362HYWoQunI3t9q6SraQhl0gA,10720
28
28
  spot_sdk/testing/corpus.py,sha256=O1tEjwOR2VHPI_kWelQmvFjUXs_0OUtUEFtKfpdighc,9240
29
29
  spot_sdk/testing/engine.py,sha256=IviyvQGvSGUiUSaK4Bbpv5O8sRs0LCpw49pXhR3kCZI,16280
@@ -37,6 +37,6 @@ spot_sdk/testing/views.py,sha256=Su45wOqCQG_O2WcpZhFnCZCLEc8yd9KsUl3YkjvvM9g,164
37
37
  spot_sdk/urls.py,sha256=pAz5Zara9UkNRoN2Vtx-33pARfBDy3JIA8xi-bkFdmk,1637
38
38
  spot_sdk/verdict.py,sha256=FUtAcsajJKgO_LaAfEJtHYq1K9BwG7a6sfpVkITjs_w,4429
39
39
  spot_sdk/workflow.py,sha256=sxD_Ms-t8Emv2vn4vf7ftJRIsPR9Fy7LumwFji60LP0,6993
40
- spot_sdk_python-2.1.0b2.dist-info/WHEEL,sha256=rp-k_VZaX8oABFEtLwG_Df95p8LSKt9-uPyQ4jKH0P4,81
41
- spot_sdk_python-2.1.0b2.dist-info/METADATA,sha256=nKguIZfBOVLkWplqSAOHF4bAVZALyDDpcr1jiY6zQ8k,4078
42
- spot_sdk_python-2.1.0b2.dist-info/RECORD,,
40
+ spot_sdk_python-2.1.1.dist-info/WHEEL,sha256=rp-k_VZaX8oABFEtLwG_Df95p8LSKt9-uPyQ4jKH0P4,81
41
+ spot_sdk_python-2.1.1.dist-info/METADATA,sha256=9IdM1c1gi71oI5OEBll8YkkOS47u8qtUXV7E47oyjRs,4076
42
+ spot_sdk_python-2.1.1.dist-info/RECORD,,