mockserver-client 5.16.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.
mockserver/client.py ADDED
@@ -0,0 +1,207 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import threading
5
+ from typing import Callable
6
+
7
+ from mockserver.async_client import AsyncMockServerClient
8
+ from mockserver.models import (
9
+ Delay,
10
+ Expectation,
11
+ HttpError,
12
+ HttpForward,
13
+ HttpOverrideForwardedRequest,
14
+ HttpRequest,
15
+ HttpRequestAndHttpResponse,
16
+ HttpResponse,
17
+ HttpTemplate,
18
+ OpenAPIExpectation,
19
+ TimeToLive,
20
+ Times,
21
+ VerificationTimes,
22
+ )
23
+
24
+
25
+ class SyncForwardChainExpectation:
26
+ def __init__(self, async_chain, run_fn: Callable) -> None:
27
+ self._async_chain = async_chain
28
+ self._run = run_fn
29
+
30
+ def with_id(self, id: str) -> SyncForwardChainExpectation:
31
+ self._async_chain.with_id(id)
32
+ return self
33
+
34
+ def with_priority(self, priority: int) -> SyncForwardChainExpectation:
35
+ self._async_chain.with_priority(priority)
36
+ return self
37
+
38
+ def respond(self, response_or_callback) -> list[Expectation]:
39
+ return self._run(self._async_chain.respond(response_or_callback))
40
+
41
+ def respond_with_delay(
42
+ self, response: HttpResponse, delay: Delay
43
+ ) -> list[Expectation]:
44
+ return self._run(self._async_chain.respond_with_delay(response, delay))
45
+
46
+ def forward(
47
+ self, forward_or_callback, response_callback: Callable | None = None
48
+ ) -> list[Expectation]:
49
+ return self._run(
50
+ self._async_chain.forward(forward_or_callback, response_callback)
51
+ )
52
+
53
+ def forward_with_delay(
54
+ self, forward: HttpForward, delay: Delay
55
+ ) -> list[Expectation]:
56
+ return self._run(self._async_chain.forward_with_delay(forward, delay))
57
+
58
+ def respond_with_sse(self, sse_response) -> list[Expectation]:
59
+ return self._run(self._async_chain.respond_with_sse(sse_response))
60
+
61
+ def respond_with_websocket(self, websocket_response) -> list[Expectation]:
62
+ return self._run(self._async_chain.respond_with_websocket(websocket_response))
63
+
64
+ def error(self, error: HttpError) -> list[Expectation]:
65
+ return self._run(self._async_chain.error(error))
66
+
67
+
68
+ class MockServerClient:
69
+ def __init__(
70
+ self,
71
+ host: str,
72
+ port: int,
73
+ context_path: str = "",
74
+ secure: bool = False,
75
+ ca_cert_path: str | None = None,
76
+ tls_verify: bool = True,
77
+ ) -> None:
78
+ self._loop = asyncio.new_event_loop()
79
+ self._thread = threading.Thread(
80
+ target=self._loop.run_forever, daemon=True
81
+ )
82
+ self._thread.start()
83
+ self._async_client = AsyncMockServerClient(
84
+ host, port, context_path, secure, ca_cert_path, tls_verify=tls_verify
85
+ )
86
+
87
+ def _run(self, coro):
88
+ future = asyncio.run_coroutine_threadsafe(coro, self._loop)
89
+ return future.result()
90
+
91
+ def upsert(self, *expectations: Expectation) -> list[Expectation]:
92
+ return self._run(self._async_client.upsert(*expectations))
93
+
94
+ def open_api_expectation(self, expectation: OpenAPIExpectation) -> None:
95
+ return self._run(self._async_client.open_api_expectation(expectation))
96
+
97
+ def clear(
98
+ self,
99
+ request: HttpRequest | None = None,
100
+ clear_type: str | None = None,
101
+ ) -> None:
102
+ return self._run(self._async_client.clear(request, clear_type))
103
+
104
+ def clear_by_id(
105
+ self,
106
+ expectation_id: str,
107
+ clear_type: str | None = None,
108
+ ) -> None:
109
+ return self._run(self._async_client.clear_by_id(expectation_id, clear_type))
110
+
111
+ def reset(self) -> None:
112
+ return self._run(self._async_client.reset())
113
+
114
+ def verify(
115
+ self,
116
+ request: HttpRequest,
117
+ times: VerificationTimes | None = None,
118
+ ) -> None:
119
+ return self._run(self._async_client.verify(request, times))
120
+
121
+ def verify_sequence(self, *requests: HttpRequest) -> None:
122
+ return self._run(self._async_client.verify_sequence(*requests))
123
+
124
+ def verify_zero_interactions(self) -> None:
125
+ return self._run(self._async_client.verify_zero_interactions())
126
+
127
+ def retrieve_recorded_requests(
128
+ self, request: HttpRequest | None = None
129
+ ) -> list[HttpRequest]:
130
+ return self._run(self._async_client.retrieve_recorded_requests(request))
131
+
132
+ def retrieve_active_expectations(
133
+ self, request: HttpRequest | None = None
134
+ ) -> list[Expectation]:
135
+ return self._run(self._async_client.retrieve_active_expectations(request))
136
+
137
+ def retrieve_recorded_expectations(
138
+ self, request: HttpRequest | None = None
139
+ ) -> list[Expectation]:
140
+ return self._run(self._async_client.retrieve_recorded_expectations(request))
141
+
142
+ def retrieve_recorded_requests_and_responses(
143
+ self, request: HttpRequest | None = None
144
+ ) -> list[HttpRequestAndHttpResponse]:
145
+ return self._run(
146
+ self._async_client.retrieve_recorded_requests_and_responses(request)
147
+ )
148
+
149
+ def retrieve_log_messages(
150
+ self, request: HttpRequest | None = None
151
+ ) -> list[str]:
152
+ return self._run(self._async_client.retrieve_log_messages(request))
153
+
154
+ def bind(self, *ports: int) -> list[int]:
155
+ return self._run(self._async_client.bind(*ports))
156
+
157
+ def stop(self) -> None:
158
+ return self._run(self._async_client.stop())
159
+
160
+ def has_started(self, attempts: int = 10, timeout: float = 0.5) -> bool:
161
+ return self._run(self._async_client.has_started(attempts, timeout))
162
+
163
+ def when(
164
+ self,
165
+ request: HttpRequest,
166
+ times: Times | None = None,
167
+ time_to_live: TimeToLive | None = None,
168
+ priority: int | None = None,
169
+ ) -> SyncForwardChainExpectation:
170
+ async_chain = self._async_client.when(request, times, time_to_live, priority)
171
+ return SyncForwardChainExpectation(async_chain, self._run)
172
+
173
+ def mock_with_callback(
174
+ self,
175
+ request: HttpRequest,
176
+ callback: Callable,
177
+ times: Times | None = None,
178
+ time_to_live: TimeToLive | None = None,
179
+ ) -> list[Expectation]:
180
+ return self._run(
181
+ self._async_client.mock_with_callback(request, callback, times, time_to_live)
182
+ )
183
+
184
+ def mock_with_forward_callback(
185
+ self,
186
+ request: HttpRequest,
187
+ forward_callback: Callable,
188
+ response_callback: Callable | None = None,
189
+ times: Times | None = None,
190
+ time_to_live: TimeToLive | None = None,
191
+ ) -> list[Expectation]:
192
+ return self._run(
193
+ self._async_client.mock_with_forward_callback(
194
+ request, forward_callback, response_callback, times, time_to_live
195
+ )
196
+ )
197
+
198
+ def close(self) -> None:
199
+ self._run(self._async_client.close())
200
+ self._loop.call_soon_threadsafe(self._loop.stop)
201
+ self._thread.join(timeout=5)
202
+
203
+ def __enter__(self) -> MockServerClient:
204
+ return self
205
+
206
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
207
+ self.close()
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ class MockServerError(Exception):
5
+ pass
6
+
7
+
8
+ class MockServerConnectionError(MockServerError):
9
+ pass
10
+
11
+
12
+ class MockServerVerificationError(MockServerError, AssertionError):
13
+ pass
14
+
15
+
16
+ class MockServerCallbackError(MockServerError):
17
+ pass
18
+
19
+
20
+ class MockServerWebSocketError(MockServerError):
21
+ pass
mockserver/fluent.py ADDED
@@ -0,0 +1,116 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import TYPE_CHECKING, Callable
5
+
6
+ from mockserver.models import (
7
+ Delay,
8
+ Expectation,
9
+ HttpError,
10
+ HttpForward,
11
+ HttpObjectCallback,
12
+ HttpOverrideForwardedRequest,
13
+ HttpResponse,
14
+ HttpSseResponse,
15
+ HttpTemplate,
16
+ HttpWebSocketResponse,
17
+ )
18
+
19
+ if TYPE_CHECKING:
20
+ from mockserver.async_client import AsyncMockServerClient
21
+
22
+
23
+ class ForwardChainExpectation:
24
+ def __init__(
25
+ self,
26
+ client: AsyncMockServerClient,
27
+ expectation: Expectation,
28
+ ) -> None:
29
+ self._client = client
30
+ self._expectation = expectation
31
+
32
+ def with_id(self, id: str) -> ForwardChainExpectation:
33
+ self._expectation.id = id
34
+ return self
35
+
36
+ def with_priority(self, priority: int) -> ForwardChainExpectation:
37
+ self._expectation.priority = priority
38
+ return self
39
+
40
+ async def respond(self, response_or_callback) -> list[Expectation]:
41
+ if callable(response_or_callback):
42
+ client_id = await self._client._register_websocket_callback(
43
+ "response", response_or_callback
44
+ )
45
+ self._expectation.http_response_object_callback = HttpObjectCallback(
46
+ client_id=client_id
47
+ )
48
+ elif isinstance(response_or_callback, HttpResponse):
49
+ self._expectation.http_response = response_or_callback
50
+ elif isinstance(response_or_callback, HttpTemplate):
51
+ self._expectation.http_response_template = response_or_callback
52
+ else:
53
+ raise TypeError(
54
+ f"Expected HttpResponse, HttpTemplate, or callable, got {type(response_or_callback).__name__}"
55
+ )
56
+ return await self._client.upsert(self._expectation)
57
+
58
+ async def respond_with_delay(
59
+ self, response: HttpResponse, delay: Delay
60
+ ) -> list[Expectation]:
61
+ response.delay = delay
62
+ self._expectation.http_response = response
63
+ return await self._client.upsert(self._expectation)
64
+
65
+ async def forward(
66
+ self,
67
+ forward_or_callback,
68
+ response_callback: Callable | None = None,
69
+ ) -> list[Expectation]:
70
+ if callable(forward_or_callback):
71
+ client_id = await self._client._register_websocket_callback(
72
+ "forward", forward_or_callback, response_callback
73
+ )
74
+ obj_callback = HttpObjectCallback(client_id=client_id)
75
+ if response_callback is not None:
76
+ obj_callback.response_callback = True
77
+ self._expectation.http_forward_object_callback = obj_callback
78
+ elif isinstance(forward_or_callback, HttpForward):
79
+ self._expectation.http_forward = forward_or_callback
80
+ elif isinstance(forward_or_callback, HttpOverrideForwardedRequest):
81
+ self._expectation.http_override_forwarded_request = forward_or_callback
82
+ elif isinstance(forward_or_callback, HttpTemplate):
83
+ self._expectation.http_forward_template = forward_or_callback
84
+ else:
85
+ raise TypeError(
86
+ f"Expected HttpForward, HttpOverrideForwardedRequest, HttpTemplate, or callable, got {type(forward_or_callback).__name__}"
87
+ )
88
+ return await self._client.upsert(self._expectation)
89
+
90
+ async def forward_with_delay(
91
+ self, forward: HttpForward, delay: Delay
92
+ ) -> list[Expectation]:
93
+ forward.delay = delay
94
+ self._expectation.http_forward = forward
95
+ return await self._client.upsert(self._expectation)
96
+
97
+ async def respond_with_sse(self, sse_response: HttpSseResponse) -> list[Expectation]:
98
+ if not isinstance(sse_response, HttpSseResponse):
99
+ raise TypeError(
100
+ f"Expected HttpSseResponse, got {type(sse_response).__name__}"
101
+ )
102
+ self._expectation.http_sse_response = sse_response
103
+ return await self._client.upsert(self._expectation)
104
+
105
+ async def respond_with_websocket(self, websocket_response: HttpWebSocketResponse) -> list[Expectation]:
106
+ if not isinstance(websocket_response, HttpWebSocketResponse):
107
+ raise TypeError(
108
+ f"Expected HttpWebSocketResponse, got {type(websocket_response).__name__}"
109
+ )
110
+ self._expectation.http_websocket_response = websocket_response
111
+ return await self._client.upsert(self._expectation)
112
+
113
+ async def error(self, error: HttpError) -> list[Expectation]:
114
+ self._expectation.http_error = error
115
+ return await self._client.upsert(self._expectation)
116
+