mockserver-client 7.2.0__tar.gz → 7.3.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 (35) hide show
  1. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/PKG-INFO +79 -2
  2. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/README.md +78 -1
  3. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/__init__.py +22 -0
  4. mockserver_client-7.3.0/mockserver/a2a.py +527 -0
  5. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/async_client.py +483 -0
  6. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/client.py +213 -0
  7. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/models.py +280 -7
  8. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver_client.egg-info/PKG-INFO +79 -2
  9. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver_client.egg-info/SOURCES.txt +3 -0
  10. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/pyproject.toml +1 -1
  11. mockserver_client-7.3.0/tests/test_a2a.py +363 -0
  12. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_async_client.py +226 -0
  13. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_client.py +212 -0
  14. mockserver_client-7.3.0/tests/test_control_plane.py +361 -0
  15. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/exceptions.py +0 -0
  16. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/fluent.py +0 -0
  17. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/launcher.py +0 -0
  18. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/llm.py +0 -0
  19. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/mcp.py +0 -0
  20. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver/websocket_client.py +0 -0
  21. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver_client.egg-info/dependency_links.txt +0 -0
  22. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver_client.egg-info/requires.txt +0 -0
  23. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/mockserver_client.egg-info/top_level.txt +0 -0
  24. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/setup.cfg +0 -0
  25. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_auth_tls.py +0 -0
  26. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_breakpoint.py +0 -0
  27. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_exceptions.py +0 -0
  28. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_fluent.py +0 -0
  29. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_init.py +0 -0
  30. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_integration.py +0 -0
  31. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_launcher.py +0 -0
  32. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_llm.py +0 -0
  33. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_mcp.py +0 -0
  34. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_models.py +0 -0
  35. {mockserver_client-7.2.0 → mockserver_client-7.3.0}/tests/test_websocket_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mockserver-client
3
- Version: 7.2.0
3
+ Version: 7.3.0
4
4
  Summary: Official Python client for MockServer — create expectations, verify requests, and register dynamic callbacks via WebSocket
5
5
  Author-email: James Bloom <jamesdbloom@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -228,6 +228,83 @@ if client.has_started():
228
228
  client.stop()
229
229
  ```
230
230
 
231
+ ## AI Protocol Mocking
232
+
233
+ Declarative builders mock an MCP (Model Context Protocol) server or an A2A
234
+ (Agent-to-Agent) server with a single fluent chain. Each builder produces a set of
235
+ HTTP expectations that speak JSON-RPC 2.0 and echo the incoming request id.
236
+
237
+ ```python
238
+ from mockserver import mcp_mock, a2a_mock
239
+
240
+ # Mock an MCP server (Streamable HTTP, JSON-RPC 2.0) on /mcp
241
+ mcp_mock() \
242
+ .with_tool("get_weather") \
243
+ .with_description("Get weather for a city") \
244
+ .with_input_schema('{"type": "object", "properties": {"city": {"type": "string"}}}') \
245
+ .responding_with("72F and sunny") \
246
+ .and_() \
247
+ .apply_to(client)
248
+
249
+ # Mock an A2A agent on /a2a (agent card + tasks/send|get|cancel)
250
+ a2a_mock() \
251
+ .with_agent_name("TranslatorAgent") \
252
+ .with_skill("translate") \
253
+ .with_name("Translation") \
254
+ .with_description("Translates text between languages") \
255
+ .with_tag("i18n") \
256
+ .with_example("Translate hello to Spanish") \
257
+ .and_() \
258
+ .on_task_send() \
259
+ .matching_message("translate.*") \
260
+ .responding_with("Hola") \
261
+ .and_() \
262
+ .apply_to(client)
263
+ ```
264
+
265
+ The A2A builder also supports streaming (SSE) and push notifications:
266
+
267
+ ```python
268
+ a2a_mock() \
269
+ .with_streaming() \
270
+ .with_push_notifications("http://localhost:1234/callback") \
271
+ .apply_to(client)
272
+ ```
273
+
274
+ `build()` returns the list of `Expectation` objects without registering them, so
275
+ you can inspect or persist them; `apply_to(client)` registers them via `upsert`.
276
+
277
+ ## SRE / Resilience
278
+
279
+ Verify a service-level objective over recorded SLI samples, or run a scheduled
280
+ multi-stage chaos experiment. Both require the corresponding server feature to be
281
+ enabled (`sloTrackingEnabled`, chaos experiments).
282
+
283
+ ```python
284
+ # Verify an SLO — a FAIL verdict (HTTP 406) raises MockServerVerificationError
285
+ verdict = client.verify_slo({
286
+ "name": "checkout",
287
+ "minimumSampleCount": 100,
288
+ "objectives": [
289
+ {"sli": "errorRate", "comparator": "LESS_THAN", "threshold": 0.01},
290
+ {"sli": "p99LatencyMs", "comparator": "LESS_THAN", "threshold": 250},
291
+ ],
292
+ })
293
+ print(verdict["result"]) # PASS or INCONCLUSIVE
294
+
295
+ # Start a multi-stage chaos experiment (only one may be active at a time)
296
+ client.start_chaos_experiment({
297
+ "name": "latency-injection",
298
+ "loop": False,
299
+ "stages": [
300
+ {"durationMillis": 60000, "profiles": {"payments.svc": {"latencyMs": 500}}},
301
+ ],
302
+ })
303
+ ```
304
+
305
+ Both methods are available on the async client too (`await client.verify_slo(...)`,
306
+ `await client.start_chaos_experiment(...)`).
307
+
231
308
  ## TLS Support
232
309
 
233
310
  ```python
@@ -352,7 +429,7 @@ launcher_path = ensure_binary() # returns Path to the launcher executable
352
429
  ```python
353
430
  from mockserver.launcher import start
354
431
 
355
- server = start(port=1080, version="7.2.0")
432
+ server = start(port=1080, version="7.3.0")
356
433
  # ...
357
434
  server.stop()
358
435
  ```
@@ -198,6 +198,83 @@ if client.has_started():
198
198
  client.stop()
199
199
  ```
200
200
 
201
+ ## AI Protocol Mocking
202
+
203
+ Declarative builders mock an MCP (Model Context Protocol) server or an A2A
204
+ (Agent-to-Agent) server with a single fluent chain. Each builder produces a set of
205
+ HTTP expectations that speak JSON-RPC 2.0 and echo the incoming request id.
206
+
207
+ ```python
208
+ from mockserver import mcp_mock, a2a_mock
209
+
210
+ # Mock an MCP server (Streamable HTTP, JSON-RPC 2.0) on /mcp
211
+ mcp_mock() \
212
+ .with_tool("get_weather") \
213
+ .with_description("Get weather for a city") \
214
+ .with_input_schema('{"type": "object", "properties": {"city": {"type": "string"}}}') \
215
+ .responding_with("72F and sunny") \
216
+ .and_() \
217
+ .apply_to(client)
218
+
219
+ # Mock an A2A agent on /a2a (agent card + tasks/send|get|cancel)
220
+ a2a_mock() \
221
+ .with_agent_name("TranslatorAgent") \
222
+ .with_skill("translate") \
223
+ .with_name("Translation") \
224
+ .with_description("Translates text between languages") \
225
+ .with_tag("i18n") \
226
+ .with_example("Translate hello to Spanish") \
227
+ .and_() \
228
+ .on_task_send() \
229
+ .matching_message("translate.*") \
230
+ .responding_with("Hola") \
231
+ .and_() \
232
+ .apply_to(client)
233
+ ```
234
+
235
+ The A2A builder also supports streaming (SSE) and push notifications:
236
+
237
+ ```python
238
+ a2a_mock() \
239
+ .with_streaming() \
240
+ .with_push_notifications("http://localhost:1234/callback") \
241
+ .apply_to(client)
242
+ ```
243
+
244
+ `build()` returns the list of `Expectation` objects without registering them, so
245
+ you can inspect or persist them; `apply_to(client)` registers them via `upsert`.
246
+
247
+ ## SRE / Resilience
248
+
249
+ Verify a service-level objective over recorded SLI samples, or run a scheduled
250
+ multi-stage chaos experiment. Both require the corresponding server feature to be
251
+ enabled (`sloTrackingEnabled`, chaos experiments).
252
+
253
+ ```python
254
+ # Verify an SLO — a FAIL verdict (HTTP 406) raises MockServerVerificationError
255
+ verdict = client.verify_slo({
256
+ "name": "checkout",
257
+ "minimumSampleCount": 100,
258
+ "objectives": [
259
+ {"sli": "errorRate", "comparator": "LESS_THAN", "threshold": 0.01},
260
+ {"sli": "p99LatencyMs", "comparator": "LESS_THAN", "threshold": 250},
261
+ ],
262
+ })
263
+ print(verdict["result"]) # PASS or INCONCLUSIVE
264
+
265
+ # Start a multi-stage chaos experiment (only one may be active at a time)
266
+ client.start_chaos_experiment({
267
+ "name": "latency-injection",
268
+ "loop": False,
269
+ "stages": [
270
+ {"durationMillis": 60000, "profiles": {"payments.svc": {"latencyMs": 500}}},
271
+ ],
272
+ })
273
+ ```
274
+
275
+ Both methods are available on the async client too (`await client.verify_slo(...)`,
276
+ `await client.start_chaos_experiment(...)`).
277
+
201
278
  ## TLS Support
202
279
 
203
280
  ```python
@@ -322,7 +399,7 @@ launcher_path = ensure_binary() # returns Path to the launcher executable
322
399
  ```python
323
400
  from mockserver.launcher import start
324
401
 
325
- server = start(port=1080, version="7.2.0")
402
+ server = start(port=1080, version="7.3.0")
326
403
  # ...
327
404
  server.stop()
328
405
  ```
@@ -31,10 +31,16 @@ from mockserver.models import (
31
31
  JsonPathBody,
32
32
  JsonRpcBody,
33
33
  KeyToMultiValue,
34
+ LoadCapture,
35
+ LoadFeeder,
36
+ LoadPacing,
34
37
  LoadProfile,
35
38
  LoadScenario,
39
+ LoadShape,
36
40
  LoadStage,
37
41
  LoadStep,
42
+ LoadThreshold,
43
+ MockMode,
38
44
  OpenAPIDefinition,
39
45
  OpenAPIExpectation,
40
46
  Ports,
@@ -95,6 +101,12 @@ from mockserver.mcp import (
95
101
  McpToolBuilder,
96
102
  mcp_mock,
97
103
  )
104
+ from mockserver.a2a import (
105
+ A2aMockBuilder,
106
+ A2aSkillBuilder,
107
+ A2aTaskHandlerBuilder,
108
+ a2a_mock,
109
+ )
98
110
  from mockserver.async_client import AsyncMockServerClient
99
111
  from mockserver.launcher import (
100
112
  MockServerProcess,
@@ -139,10 +151,16 @@ __all__ = [
139
151
  "JsonPathBody",
140
152
  "JsonRpcBody",
141
153
  "KeyToMultiValue",
154
+ "LoadCapture",
155
+ "LoadFeeder",
156
+ "LoadPacing",
142
157
  "LoadProfile",
143
158
  "LoadScenario",
159
+ "LoadShape",
144
160
  "LoadStage",
145
161
  "LoadStep",
162
+ "LoadThreshold",
163
+ "MockMode",
146
164
  "Completion",
147
165
  "ConversationPredicates",
148
166
  "EmbeddingResponse",
@@ -177,6 +195,10 @@ __all__ = [
177
195
  "McpResourceBuilder",
178
196
  "McpToolBuilder",
179
197
  "mcp_mock",
198
+ "A2aMockBuilder",
199
+ "A2aSkillBuilder",
200
+ "A2aTaskHandlerBuilder",
201
+ "a2a_mock",
180
202
  "MockServerCallbackError",
181
203
  "MockServerClient",
182
204
  "MockServerConnectionError",