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.
- {httpdbg-1.2.1 → httpdbg-1.2.2}/PKG-INFO +1 -1
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/__init__.py +1 -1
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/generic.py +74 -45
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/urllib3.py +2 -2
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/utils.py +9 -4
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/PKG-INFO +1 -1
- {httpdbg-1.2.1 → httpdbg-1.2.2}/LICENSE +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/README.md +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/__main__.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/args.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/env.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/exception.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/__init__.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/aiohttp.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/all.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/external.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/fastapi.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/flask.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/http.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/httpx.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/pytest.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/requests.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/socket.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/starlette.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/template_sitecustomize.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/unittest.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/hooks/uvicorn.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/initiator.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/log.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_console.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_module.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/mode_script.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/preview.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/records.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/server.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/utils.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/__init__.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/api.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/app.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/api.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/column.css +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/configuration.css +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/configuration.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/detail.css +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/favicon.ico +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/filter.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/eye-blind-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/eye-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/lock-line-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/lock-open-line-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/index.htm +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/main.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/mustache.min.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/render.js +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/style.css +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/table.css +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/SOURCES.txt +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/dependency_links.txt +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/entry_points.txt +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg.egg-info/top_level.txt +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/pyproject.toml +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/setup.cfg +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_api.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_cli.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_context_manager.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_aiohttp.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_httpx.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_pytest.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_requests.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_unittest.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_hook_urllib3.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_initiator.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_console.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_module_pytest.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_mode_script.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_multiprocess.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_preview.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_pyhttpdbg_server.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server_hook_fastapi.py +0 -0
- {httpdbg-1.2.1 → httpdbg-1.2.2}/tests/test_server_hook_flask.py +0 -0
|
@@ -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
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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
|
|
72
|
-
|
|
73
|
-
fnc = undecorate(fnc)
|
|
125
|
+
if initiators:
|
|
126
|
+
builtins.__import__ == original_builtin_import
|
|
74
127
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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]
|
|
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
|
|
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
|
{httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{httpdbg-1.2.1 → httpdbg-1.2.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|