edq-utils 0.1.6__tar.gz → 0.1.8__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.

Potentially problematic release.


This version of edq-utils might be problematic. Click here for more details.

Files changed (105) hide show
  1. {edq_utils-0.1.6 → edq_utils-0.1.8}/.github/workflows/main.yml +1 -1
  2. {edq_utils-0.1.6 → edq_utils-0.1.8}/PKG-INFO +1 -1
  3. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/__init__.py +1 -1
  4. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/httpserver.py +28 -3
  5. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/net.py +29 -12
  6. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq_utils.egg-info/PKG-INFO +1 -1
  7. {edq_utils-0.1.6 → edq_utils-0.1.8}/.gitignore +0 -0
  8. {edq_utils-0.1.6 → edq_utils-0.1.8}/.mypy.ini +0 -0
  9. {edq_utils-0.1.6 → edq_utils-0.1.8}/.pylintrc +0 -0
  10. {edq_utils-0.1.6 → edq_utils-0.1.8}/LICENSE +0 -0
  11. {edq_utils-0.1.6 → edq_utils-0.1.8}/README.md +0 -0
  12. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/__init__.py +0 -0
  13. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/config/__init__.py +0 -0
  14. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/config/list.py +0 -0
  15. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/http/__init__.py +0 -0
  16. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/http/exchange-server.py +0 -0
  17. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/http/send-exchange.py +0 -0
  18. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/http/verify-exchanges.py +0 -0
  19. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/testing/__init__.py +0 -0
  20. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/testing/cli-test.py +0 -0
  21. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/cli/version.py +0 -0
  22. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/__init__.py +0 -0
  23. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/argparser.py +0 -0
  24. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/argparser_test.py +0 -0
  25. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/config.py +0 -0
  26. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/config_test.py +0 -0
  27. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/log.py +0 -0
  28. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/core/version.py +0 -0
  29. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/procedure/__init__.py +0 -0
  30. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/procedure/verify_exchanges.py +0 -0
  31. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/py.typed +0 -0
  32. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/__init__.py +0 -0
  33. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/asserts.py +0 -0
  34. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/cli.py +0 -0
  35. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/cli_test.py +0 -0
  36. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/httpserver_test.py +0 -0
  37. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/run.py +0 -0
  38. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/data/configs/empty/edq-config.json +0 -0
  39. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/data/configs/simple-1/edq-config.json +0 -0
  40. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/data/configs/simple-2/edq-config.json +0 -0
  41. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/data/configs/value-number/edq-config.json +0 -0
  42. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_base.txt +0 -0
  43. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_config_value_number.txt +0 -0
  44. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_ignore_config.txt +0 -0
  45. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_no_config.txt +0 -0
  46. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_show_origin.txt +0 -0
  47. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/config/list/config_list_skip_header.txt +0 -0
  48. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/help_base.txt +0 -0
  49. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/platform_skip.txt +0 -0
  50. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/cli/tests/version_base.txt +0 -0
  51. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple.httpex.json +0 -0
  52. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_anchor.httpex.json +0 -0
  53. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file.httpex.json +0 -0
  54. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_binary.httpex.json +0 -0
  55. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_get_params.httpex.json +0 -0
  56. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_multiple.httpex.json +0 -0
  57. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_name.httpex.json +0 -0
  58. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_post_multiple.httpex.json +0 -0
  59. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_file_post_params.httpex.json +0 -0
  60. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_headers.httpex.json +0 -0
  61. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_jsonresponse_dict.httpex.json +0 -0
  62. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_jsonresponse_list.httpex.json +0 -0
  63. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_params.httpex.json +0 -0
  64. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_post.httpex.json +0 -0
  65. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_post_params.httpex.json +0 -0
  66. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_post_urlparams.httpex.json +0 -0
  67. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/simple_urlparams.httpex.json +0 -0
  68. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/specialcase_listparams_explicit.httpex.json +0 -0
  69. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/exchanges/specialcase_listparams_url.httpex.json +0 -0
  70. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/files/a.txt +0 -0
  71. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/testdata/http/files/tiny.png +0 -0
  72. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/testing/unittest.py +0 -0
  73. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/__init__.py +0 -0
  74. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/dirent.py +0 -0
  75. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/dirent_test.py +0 -0
  76. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/hash.py +0 -0
  77. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/hash_test.py +0 -0
  78. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/json.py +0 -0
  79. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/json_test.py +0 -0
  80. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/parse.py +0 -0
  81. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/pyimport.py +0 -0
  82. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/pyimport_test.py +0 -0
  83. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/reflection.py +0 -0
  84. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/time.py +0 -0
  85. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq/util/time_test.py +0 -0
  86. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq_utils.egg-info/SOURCES.txt +0 -0
  87. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq_utils.egg-info/dependency_links.txt +0 -0
  88. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq_utils.egg-info/requires.txt +0 -0
  89. {edq_utils-0.1.6 → edq_utils-0.1.8}/edq_utils.egg-info/top_level.txt +0 -0
  90. {edq_utils-0.1.6 → edq_utils-0.1.8}/pyproject.toml +0 -0
  91. {edq_utils-0.1.6 → edq_utils-0.1.8}/requirements-dev.txt +0 -0
  92. {edq_utils-0.1.6 → edq_utils-0.1.8}/requirements.txt +0 -0
  93. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/build_site.sh +0 -0
  94. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/check_all.sh +0 -0
  95. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/check_lint.sh +0 -0
  96. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/check_python_version.sh +0 -0
  97. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/check_strict_types.sh +0 -0
  98. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/check_types.sh +0 -0
  99. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/gen_docs.sh +0 -0
  100. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/run_tests.sh +0 -0
  101. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/template/html/css/style.css +0 -0
  102. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/template/html/favicon.ico +0 -0
  103. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/template/html/images/favicon.png +0 -0
  104. {edq_utils-0.1.6 → edq_utils-0.1.8}/scripts/template/html/index.html +0 -0
  105. {edq_utils-0.1.6 → edq_utils-0.1.8}/setup.cfg +0 -0
@@ -10,7 +10,7 @@ jobs:
10
10
  fail-fast: false
11
11
  matrix:
12
12
  python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
13
- os: ['ubuntu-22.04', 'ubuntu-24.04', 'macos-13', 'macos-14', 'macos-15', 'windows-2022', 'windows-2025']
13
+ os: ['ubuntu-22.04', 'ubuntu-24.04', 'macos-14', 'macos-15', 'windows-2022', 'windows-2025']
14
14
 
15
15
  runs-on: ${{ matrix.os }}
16
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edq-utils
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Common utilities used by EduLinq Python projects.
5
5
  Author-email: Eriq Augustine <eriq@edulinq.org>
6
6
  License: MIT License
@@ -2,4 +2,4 @@
2
2
  General Python tools used by several EduLinq projects.
3
3
  """
4
4
 
5
- __version__ = '0.1.6'
5
+ __version__ = '0.1.8'
@@ -328,16 +328,41 @@ class _TestHTTPHandler(http.server.BaseHTTPRequestHandler):
328
328
  def log_message(self, format: str, *args: typing.Any) -> None: # pylint: disable=redefined-builtin
329
329
  pass
330
330
 
331
- def do_POST(self) -> None: # pylint: disable=invalid-name
332
- """ A handler for POST requests. """
331
+ def do_DELETE(self) -> None: # pylint: disable=invalid-name
332
+ """ A handler for DELETE requests. """
333
333
 
334
- self._do_request('POST')
334
+ self._do_request('DELETE')
335
335
 
336
336
  def do_GET(self) -> None: # pylint: disable=invalid-name
337
337
  """ A handler for GET requests. """
338
338
 
339
339
  self._do_request('GET')
340
340
 
341
+ def do_HEAD(self) -> None: # pylint: disable=invalid-name
342
+ """ A handler for HEAD requests. """
343
+
344
+ self._do_request('HEAD')
345
+
346
+ def do_OPTIONS(self) -> None: # pylint: disable=invalid-name
347
+ """ A handler for OPTIONS requests. """
348
+
349
+ self._do_request('OPTIONS')
350
+
351
+ def do_PATCH(self) -> None: # pylint: disable=invalid-name
352
+ """ A handler for PATCH requests. """
353
+
354
+ self._do_request('PATCH')
355
+
356
+ def do_POST(self) -> None: # pylint: disable=invalid-name
357
+ """ A handler for POST requests. """
358
+
359
+ self._do_request('POST')
360
+
361
+ def do_PUT(self) -> None: # pylint: disable=invalid-name
362
+ """ A handler for PUT requests. """
363
+
364
+ self._do_request('PUT')
365
+
341
366
  def _do_request(self, method: str) -> None:
342
367
  """ A common handler for multiple types of requests. """
343
368
 
@@ -41,9 +41,13 @@ Anchors are not traditionally sent in requests, but this will allow exchanges to
41
41
  """
42
42
 
43
43
  ALLOWED_METHODS: typing.List[str] = [
44
+ 'DELETE',
44
45
  'GET',
46
+ 'HEAD',
47
+ 'OPTIONS',
48
+ 'PATCH',
45
49
  'POST',
46
- 'PUT'
50
+ 'PUT',
47
51
  ]
48
52
  """ Allowed HTTP methods for an HTTPExchange. """
49
53
 
@@ -62,6 +66,7 @@ DEFAULT_EXCHANGE_IGNORE_HEADERS: typing.List[str] = [
62
66
  'etag',
63
67
  'host',
64
68
  'link',
69
+ 'location',
65
70
  'priority',
66
71
  'referrer-policy',
67
72
  'sec-fetch-dest',
@@ -174,11 +179,11 @@ class HTTPExchange(edq.util.json.DictConverter):
174
179
  parameters: typing.Union[typing.Dict[str, typing.Any], None] = None,
175
180
  files: typing.Union[typing.List[typing.Union[FileInfo, typing.Dict[str, str]]], None] = None,
176
181
  headers: typing.Union[typing.Dict[str, typing.Any], None] = None,
182
+ allow_redirects: typing.Union[bool, None] = None,
177
183
  response_code: int = http.HTTPStatus.OK,
178
184
  response_headers: typing.Union[typing.Dict[str, typing.Any], None] = None,
179
185
  json_body: typing.Union[bool, None] = None,
180
186
  response_body: typing.Union[str, dict, list, None] = None,
181
- read_write: bool = False,
182
187
  source_path: typing.Union[str, None] = None,
183
188
  response_modifier: typing.Union[str, None] = None,
184
189
  extra_options: typing.Union[typing.Dict[str, typing.Any], None] = None,
@@ -239,6 +244,12 @@ class HTTPExchange(edq.util.json.DictConverter):
239
244
  self.headers: typing.Dict[str, typing.Any] = headers
240
245
  """ Headers in the request. """
241
246
 
247
+ if (allow_redirects is None):
248
+ allow_redirects = True
249
+
250
+ self.allow_redirects: bool = allow_redirects
251
+ """ Follow redirects. """
252
+
242
253
  self.response_code: int = response_code
243
254
  """ The HTTP status code of the response. """
244
255
 
@@ -266,13 +277,6 @@ class HTTPExchange(edq.util.json.DictConverter):
266
277
  The response that should be sent in this exchange.
267
278
  """
268
279
 
269
- self.read_write: bool = read_write
270
- """
271
- Indicates that this exchange will change data on the server (regardless of the HTTP method).
272
- This field may be ignored by test servers,
273
- but may be observed by tools that generate or validate test data.
274
- """
275
-
276
280
  self.response_modifier: typing.Union[str, None] = response_modifier
277
281
  """
278
282
  This function reference will be used to modify responses (in HTTPExchange.make_request() and HTTPExchange.from_response())
@@ -320,7 +324,7 @@ class HTTPExchange(edq.util.json.DictConverter):
320
324
  if (url_path is not None):
321
325
  url_path = url_path.strip()
322
326
  if (url_path == ''):
323
- url_path = None
327
+ url_path = ''
324
328
  else:
325
329
  url_path = url_path.lstrip('/')
326
330
 
@@ -488,6 +492,7 @@ class HTTPExchange(edq.util.json.DictConverter):
488
492
  data = self.parameters,
489
493
  files = files,
490
494
  raise_for_status = raise_for_status,
495
+ allow_redirects = self.allow_redirects,
491
496
  **kwargs,
492
497
  )
493
498
 
@@ -577,6 +582,7 @@ class HTTPExchange(edq.util.json.DictConverter):
577
582
  response: requests.Response,
578
583
  headers_to_skip: typing.Union[typing.List[str], None] = None,
579
584
  params_to_skip: typing.Union[typing.List[str], None] = None,
585
+ allow_redirects: typing.Union[bool, None] = None,
580
586
  ) -> 'HTTPExchange':
581
587
  """ Create a full excahnge from a response. """
582
588
 
@@ -622,6 +628,7 @@ class HTTPExchange(edq.util.json.DictConverter):
622
628
  'response_headers': response_headers,
623
629
  'response_body': body,
624
630
  'response_modifier': _exchanges_clean_func,
631
+ 'allow_redirects': allow_redirects,
625
632
  }
626
633
 
627
634
  return HTTPExchange(**data)
@@ -688,6 +695,7 @@ def make_request(method: str, url: str,
688
695
  add_http_prefix: bool = True,
689
696
  additional_requests_options: typing.Union[typing.Dict[str, typing.Any], None] = None,
690
697
  exchange_complete_func: typing.Union[HTTPExchangeComplete, None] = None,
698
+ allow_redirects: typing.Union[bool, None] = None,
691
699
  **kwargs: typing.Any) -> typing.Tuple[requests.Response, str]:
692
700
  """
693
701
  Make an HTTP request and return the response object and text body.
@@ -725,6 +733,9 @@ def make_request(method: str, url: str,
725
733
  'timeout': timeout_secs,
726
734
  })
727
735
 
736
+ if (allow_redirects is not None):
737
+ options['allow_redirects'] = allow_redirects
738
+
728
739
  if (method == 'GET'):
729
740
  options['params'] = data
730
741
  else:
@@ -745,10 +756,16 @@ def make_request(method: str, url: str,
745
756
 
746
757
  exchange = None
747
758
  if ((output_dir is not None) or (exchange_complete_func is not None) or (_make_request_exchange_complete_func is not None)):
748
- exchange = HTTPExchange.from_response(response, headers_to_skip = headers_to_skip, params_to_skip = params_to_skip)
759
+ exchange = HTTPExchange.from_response(response,
760
+ headers_to_skip = headers_to_skip, params_to_skip = params_to_skip,
761
+ allow_redirects = options.get('allow_redirects', None))
749
762
 
750
763
  if ((output_dir is not None) and (exchange is not None)):
751
- path = os.path.abspath(os.path.join(output_dir, *exchange.get_url().split('/')))
764
+ url = exchange.get_url()
765
+ if (url == ''):
766
+ url = '_index_'
767
+
768
+ path = os.path.abspath(os.path.join(output_dir, *url.split('/')))
752
769
 
753
770
  query = urllib.parse.urlencode(exchange.parameters)
754
771
  if (query != ''):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edq-utils
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Common utilities used by EduLinq Python projects.
5
5
  Author-email: Eriq Augustine <eriq@edulinq.org>
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes