httpdbg 1.2.1__tar.gz → 1.2.2__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 (92) hide show
  1. {httpdbg-1.2.1 → httpdbg-1.2.2}/PKG-INFO +1 -1
  2. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/__init__.py +1 -1
  3. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/generic.py +74 -45
  4. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/urllib3.py +2 -2
  5. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/utils.py +9 -4
  6. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/PKG-INFO +1 -1
  7. {httpdbg-1.2.1 → httpdbg-1.2.2}/LICENSE +0 -0
  8. {httpdbg-1.2.1 → httpdbg-1.2.2}/README.md +0 -0
  9. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/__main__.py +0 -0
  10. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/args.py +0 -0
  11. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/env.py +0 -0
  12. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/exception.py +0 -0
  13. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/__init__.py +0 -0
  14. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/aiohttp.py +0 -0
  15. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/all.py +0 -0
  16. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/external.py +0 -0
  17. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/fastapi.py +0 -0
  18. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/flask.py +0 -0
  19. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/http.py +0 -0
  20. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/httpx.py +0 -0
  21. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/pytest.py +0 -0
  22. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/requests.py +0 -0
  23. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/socket.py +0 -0
  24. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/starlette.py +0 -0
  25. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/template_sitecustomize.py +0 -0
  26. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/unittest.py +0 -0
  27. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/uvicorn.py +0 -0
  28. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/initiator.py +0 -0
  29. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/log.py +0 -0
  30. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_console.py +0 -0
  31. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_module.py +0 -0
  32. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_script.py +0 -0
  33. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/preview.py +0 -0
  34. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/records.py +0 -0
  35. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/server.py +0 -0
  36. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/utils.py +0 -0
  37. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/__init__.py +0 -0
  38. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/api.py +0 -0
  39. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/app.py +0 -0
  40. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/api.js +0 -0
  41. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/column.css +0 -0
  42. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/configuration.css +0 -0
  43. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/configuration.js +0 -0
  44. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/detail.css +0 -0
  45. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/favicon.ico +0 -0
  46. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/filter.js +0 -0
  47. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
  48. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
  49. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
  50. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/eye-blind-icon.svg +0 -0
  51. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/eye-icon.svg +0 -0
  52. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
  53. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
  54. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
  55. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/lock-line-icon.svg +0 -0
  56. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/lock-open-line-icon.svg +0 -0
  57. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
  58. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
  59. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
  60. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
  61. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
  62. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/index.htm +0 -0
  63. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/main.js +0 -0
  64. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/mustache.min.js +0 -0
  65. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/render.js +0 -0
  66. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/style.css +0 -0
  67. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/table.css +0 -0
  68. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/SOURCES.txt +0 -0
  69. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/dependency_links.txt +0 -0
  70. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/entry_points.txt +0 -0
  71. {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/top_level.txt +0 -0
  72. {httpdbg-1.2.1 → httpdbg-1.2.2}/pyproject.toml +0 -0
  73. {httpdbg-1.2.1 → httpdbg-1.2.2}/setup.cfg +0 -0
  74. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_api.py +0 -0
  75. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_cli.py +0 -0
  76. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_context_manager.py +0 -0
  77. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_aiohttp.py +0 -0
  78. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_httpx.py +0 -0
  79. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_pytest.py +0 -0
  80. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_requests.py +0 -0
  81. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_unittest.py +0 -0
  82. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_urllib3.py +0 -0
  83. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_initiator.py +0 -0
  84. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_console.py +0 -0
  85. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_module_pytest.py +0 -0
  86. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_script.py +0 -0
  87. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_multiprocess.py +0 -0
  88. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_preview.py +0 -0
  89. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_pyhttpdbg_server.py +0 -0
  90. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server.py +0 -0
  91. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server_hook_fastapi.py +0 -0
  92. {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server_hook_flask.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpdbg
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: A very simple tool to debug HTTP(S) client and server requests.
5
5
  Author-email: cle-b <cle@tictac.pm>
6
6
  License: Apache-2.0
@@ -3,6 +3,6 @@ from httpdbg.hooks.all import httprecord
3
3
  from httpdbg.records import HTTPRecords
4
4
 
5
5
 
6
- __version__ = "1.2.1"
6
+ __version__ = "1.2.2"
7
7
 
8
8
  __all__ = ["httprecord", "HTTPRecords"]
@@ -1,9 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
+ import builtins
3
+ from collections.abc import Callable
2
4
  from contextlib import contextmanager
3
- import glob
5
+ import functools
4
6
  import importlib
5
7
  import inspect
6
- from pathlib import Path
7
8
  import traceback
8
9
  from types import ModuleType
9
10
  from typing import Any
@@ -50,55 +51,83 @@ def set_hook_for_generic(records: HTTPRecords, method: Any):
50
51
  def hook_generic(
51
52
  records: HTTPRecords, initiators: Union[List[str], None] = None
52
53
  ) -> Generator[None, None, None]:
53
- hooks = []
54
-
55
- if not initiators:
56
- initiators = []
57
-
58
- for initiator in initiators:
59
- logger().info(f"HOOK_GENERIC add initiator - {initiator}")
60
- hooks += list_callables_from_package(records, initiator)
54
+ if initiators:
55
+ # we add a hook for a generic initiator only if the module is imported
56
+
57
+ hooks: List[Callable] = []
58
+ already_hooked: List[str] = []
59
+
60
+ original_builtin_import = builtins.__import__
61
+
62
+ def __hook__import__(
63
+ name,
64
+ globals=None,
65
+ locals=None,
66
+ fromlist=(),
67
+ level=0,
68
+ records=None,
69
+ initiators=None,
70
+ hooks=None,
71
+ already_hooked=None,
72
+ ):
73
+ if initiators is None:
74
+ raise Exception("initiators must not be None")
75
+ if hooks is None:
76
+ raise Exception("hooks must not be None")
77
+ if already_hooked is None:
78
+ raise Exception("already_hooked must not be None")
79
+
80
+ if (
81
+ name not in already_hooked
82
+ ): # avoids parsing the same module multiple times
83
+ if (records is not None) and initiators:
84
+ if (name in initiators) or (
85
+ any(
86
+ [
87
+ name.startswith(f"{initiator}.")
88
+ for initiator in initiators
89
+ ]
90
+ )
91
+ ):
92
+ logger().debug(f"HOOK IMPORT {name} - fromlist={fromlist}")
93
+ already_hooked.append(name)
94
+ hooks += list_callables_from_module(records, name)
95
+
96
+ # we temporarily restore the original built-in import function to avoid infinite recursion during import
97
+ __custom_import = builtins.__import__
98
+ builtins.__import__ = original_builtin_import
99
+ r = original_builtin_import(
100
+ name=name,
101
+ globals=globals,
102
+ locals=locals,
103
+ fromlist=fromlist,
104
+ level=level,
105
+ )
106
+ builtins.__import__ = __custom_import
107
+ return r
108
+
109
+ __hook__import_with_records_initiators_hooks_alreadyhooked__ = (
110
+ functools.partial(
111
+ __hook__import__,
112
+ records=records,
113
+ initiators=initiators,
114
+ hooks=hooks,
115
+ already_hooked=already_hooked,
116
+ )
117
+ )
61
118
 
62
- try:
63
- logger().info(
64
- f"HOOK_GENERIC add initiator - hooks - {[hook.__httpdbg__.__name__ for hook in hooks]}"
119
+ builtins.__import__ = (
120
+ __hook__import_with_records_initiators_hooks_alreadyhooked__
65
121
  )
66
- except Exception:
67
- pass
68
122
 
69
123
  yield
70
124
 
71
- if hooks:
72
- for fnc in hooks:
73
- fnc = undecorate(fnc)
125
+ if initiators:
126
+ builtins.__import__ == original_builtin_import
74
127
 
75
-
76
- def list_callables_from_package(records: HTTPRecords, package: str) -> List[Any]:
77
- callables = []
78
-
79
- try:
80
- logger().info(f"LIST_CALLABLES_FROM_PACKAGE {package}")
81
-
82
- callables += list_callables_from_module(records, package)
83
-
84
- imported_package = importlib.import_module(package)
85
- if hasattr(imported_package, "__path__"):
86
- for p in glob.glob(f"{list(imported_package.__path__)[0]}/*"):
87
- file_or_dir = Path(p)
88
- if file_or_dir.is_file():
89
- if file_or_dir.name.endswith(".py"):
90
- callables += list_callables_from_module(
91
- records, f"{package}.{file_or_dir.name[:-3]}"
92
- )
93
- elif file_or_dir.is_dir():
94
- if not file_or_dir.name.startswith("__"): # __pycache__
95
- callables += list_callables_from_package(
96
- records, f"{package}.{file_or_dir.name}"
97
- )
98
- except Exception as ex:
99
- logger().info(f"LIST_CALLABLES_FROM_PACKAGE {package} - error - {str(ex)}")
100
-
101
- return callables
128
+ if hooks:
129
+ for fnc in hooks:
130
+ fnc = undecorate(fnc)
102
131
 
103
132
 
104
133
  def list_callables_from_module(records: HTTPRecords, module: str) -> List[Any]:
@@ -52,7 +52,7 @@ def hook_urllib3(records: HTTPRecords) -> Generator[None, None, None]:
52
52
  )
53
53
  # v2
54
54
  if hasattr(urllib3, "request"):
55
- urllib3.request = decorate(records, urllib3.request, set_hook_for_urllib3)
55
+ urllib3.request = decorate(records, urllib3.request, set_hook_for_urllib3) # type: ignore[arg-type]
56
56
 
57
57
  hooks = True
58
58
  except ImportError:
@@ -70,4 +70,4 @@ def hook_urllib3(records: HTTPRecords) -> Generator[None, None, None]:
70
70
  )
71
71
  # v2
72
72
  if hasattr(urllib3, "request"):
73
- urllib3.request = undecorate(urllib3.request)
73
+ urllib3.request = undecorate(urllib3.request) # type: ignore[arg-type]
@@ -1,8 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
+ from collections.abc import Callable
2
3
  import inspect
4
+ import typing
3
5
 
4
6
  from httpdbg.log import logger
5
7
 
8
+ if typing.TYPE_CHECKING:
9
+ from httpdbg.records import HTTPRecords
10
+
6
11
 
7
12
  def getcallargs(original_method, *args, **kwargs):
8
13
  while hasattr(
@@ -28,12 +33,12 @@ def getcallargs(original_method, *args, **kwargs):
28
33
  return callargs
29
34
 
30
35
 
31
- def decorate(records, method, hook):
36
+ def decorate(records: "HTTPRecords", method: Callable, hook: Callable):
32
37
  ori = method
33
38
  method = hook(records, method)
34
- method.__httpdbg__ = ori
39
+ method.__httpdbg__ = ori # type: ignore[attr-defined]
35
40
  return method
36
41
 
37
42
 
38
- def undecorate(method):
39
- return method.__httpdbg__
43
+ def undecorate(method: Callable):
44
+ return method.__httpdbg__ # type: ignore[attr-defined]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpdbg
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: A very simple tool to debug HTTP(S) client and server requests.
5
5
  Author-email: cle-b <cle@tictac.pm>
6
6
  License: Apache-2.0
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes