mimicker 2.0.2__tar.gz → 2.0.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mimicker
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: A lightweight HTTP mocking server for Python
5
5
  License: MIT
6
6
  Keywords: http,mocking,testing,mock-server,stubbing,ci-cd,http-server,testing-tools,stub-server,purepython
@@ -242,6 +242,33 @@ mimicker(8080).routes(
242
242
 
243
243
  ```
244
244
 
245
+ ### Dynamic Responses with `response_func`
246
+
247
+ Mimicker allows dynamic responses based on the request data using `response_func`.
248
+ This feature enables you to build mock responses that adapt based on request parameters, headers, and body.
249
+
250
+ ```python
251
+ from mimicker.mimicker import mimicker, post
252
+
253
+ # Available for use with response_func:
254
+ # kwargs.get("payload")
255
+ # kwargs.get("headers")
256
+ # kwargs.get("params")
257
+
258
+ def custom_response(**kwargs):
259
+ request_payload = kwargs.get("payload")
260
+ return 200, {"message": f"Hello {request_payload.get('name', 'Guest')}"}
261
+
262
+ mimicker(8080).routes(
263
+ post("/greet")
264
+ .response_func(custom_response)
265
+ )
266
+
267
+ # POST /greet with body {"name": "World"} -> {"message": "Hello World"}
268
+ # POST /greet with empty body -> {"message": "Hello Guest"}
269
+ ```
270
+
271
+
245
272
  ## Available Features:
246
273
 
247
274
  * `get(path)`: Defines a `GET` endpoint.
@@ -253,6 +280,8 @@ mimicker(8080).routes(
253
280
  * `.body(content)`: Defines the response `body`.
254
281
  * `.status(code)`: Defines the response `status code`.
255
282
  * `.headers(headers)`: Defines response `headers`.
283
+ * `.response_func(func)`: Defines a dynamic response function based on the request data.
284
+
256
285
 
257
286
  ## Requirements
258
287
  Mimicker supports Python 3.7 and above.
@@ -220,6 +220,33 @@ mimicker(8080).routes(
220
220
 
221
221
  ```
222
222
 
223
+ ### Dynamic Responses with `response_func`
224
+
225
+ Mimicker allows dynamic responses based on the request data using `response_func`.
226
+ This feature enables you to build mock responses that adapt based on request parameters, headers, and body.
227
+
228
+ ```python
229
+ from mimicker.mimicker import mimicker, post
230
+
231
+ # Available for use with response_func:
232
+ # kwargs.get("payload")
233
+ # kwargs.get("headers")
234
+ # kwargs.get("params")
235
+
236
+ def custom_response(**kwargs):
237
+ request_payload = kwargs.get("payload")
238
+ return 200, {"message": f"Hello {request_payload.get('name', 'Guest')}"}
239
+
240
+ mimicker(8080).routes(
241
+ post("/greet")
242
+ .response_func(custom_response)
243
+ )
244
+
245
+ # POST /greet with body {"name": "World"} -> {"message": "Hello World"}
246
+ # POST /greet with empty body -> {"message": "Hello Guest"}
247
+ ```
248
+
249
+
223
250
  ## Available Features:
224
251
 
225
252
  * `get(path)`: Defines a `GET` endpoint.
@@ -231,6 +258,8 @@ mimicker(8080).routes(
231
258
  * `.body(content)`: Defines the response `body`.
232
259
  * `.status(code)`: Defines the response `status code`.
233
260
  * `.headers(headers)`: Defines response `headers`.
261
+ * `.response_func(func)`: Defines a dynamic response function based on the request data.
262
+
234
263
 
235
264
  ## Requirements
236
265
  Mimicker supports Python 3.7 and above.
@@ -28,21 +28,22 @@ class MimickerHandler(http.server.SimpleHTTPRequestHandler):
28
28
 
29
29
  def _handle_request(self, method: str):
30
30
  request_headers = {key.lower(): value for key, value in self.headers.items()}
31
+ request_body = self._get_request_body()
31
32
  matched_stub, path_params = self.stub_matcher.match(
32
33
  method, self.path, request_headers=request_headers
33
34
  )
34
35
 
35
36
  if matched_stub:
36
- self._send_response(matched_stub, path_params)
37
+ self._send_response(matched_stub, path_params, request_body, request_headers)
37
38
  else:
38
39
  self._send_404_response(method)
39
40
 
40
- def _send_response(self, matched_stub: Stub, path_params: Dict[str, str]):
41
+ def _send_response(self, matched_stub: Stub, path_params: Dict[str, str], request_body: Any, request_headers: Dict[str, str]):
41
42
  status_code, delay, response, response_func, headers = matched_stub
42
43
  if delay > 0:
43
44
  sleep(delay)
44
45
  if response_func:
45
- status_code, response = response_func()
46
+ status_code, response = response_func(payload=request_body, headers=request_headers, params=path_params)
46
47
 
47
48
  self.send_response(status_code)
48
49
  self._set_headers(headers)
@@ -77,3 +78,14 @@ class MimickerHandler(http.server.SimpleHTTPRequestHandler):
77
78
  def _format_response(response: dict, path_params: dict):
78
79
  return {k: (v.format(**path_params) if isinstance(v, str) else v)
79
80
  for k, v in response.items()}
81
+
82
+ def _get_request_body(self) -> Optional[dict]:
83
+ content_length = self.headers.get('content-length')
84
+ if content_length:
85
+ try:
86
+ length = int(content_length)
87
+ body = self.rfile.read(length).decode('utf-8')
88
+ return json.loads(body) if body else None
89
+ except (ValueError, json.JSONDecodeError):
90
+ return None
91
+ return None
@@ -21,7 +21,7 @@ class Route:
21
21
  self._delay = 0.
22
22
  self._status = 200
23
23
  self._headers: List[Tuple[str, str]] = []
24
- self._response_func: Optional[Callable[[], Tuple[int, Any]]] = None
24
+ self._response_func: Optional[Callable[..., Tuple[int, Any]]] = None
25
25
 
26
26
  escaped_path = re.escape(path)
27
27
  parameterized_path = re.sub(r'\\{(\w+)\\}',
@@ -81,12 +81,12 @@ class Route:
81
81
  self._headers = headers
82
82
  return self
83
83
 
84
- def response_func(self, func: Callable[[], Tuple[int, Any]]):
84
+ def response_func(self, func: Callable[..., Tuple[int, Any]]):
85
85
  """
86
86
  Sets a custom response function for dynamic responses.
87
87
 
88
88
  Args:
89
- func (Callable[[], Tuple[int, Any]]): A function returning a tuple (status_code, response_body).
89
+ func (Callable[..., Tuple[int, Any]]): A function that returns (status_code, response_body).
90
90
 
91
91
  Returns:
92
92
  Route: The current Route instance (for method chaining).
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "mimicker"
3
- version = "2.0.2"
3
+ version = "2.0.3"
4
4
  description = "A lightweight HTTP mocking server for Python"
5
5
  authors = ["Amazia Gur <amaziagur@gmail.com>"]
6
6
  license = "MIT"
File without changes
File without changes
File without changes
File without changes