httpdbg 2.0.1__tar.gz → 2.0.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 (98) hide show
  1. {httpdbg-2.0.1 → httpdbg-2.0.2}/PKG-INFO +1 -1
  2. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/__init__.py +1 -1
  3. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/initiator.py +55 -47
  4. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg.egg-info/PKG-INFO +1 -1
  5. {httpdbg-2.0.1 → httpdbg-2.0.2}/LICENSE +0 -0
  6. {httpdbg-2.0.1 → httpdbg-2.0.2}/README.md +0 -0
  7. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/__main__.py +0 -0
  8. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/args.py +0 -0
  9. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/env.py +0 -0
  10. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/exception.py +0 -0
  11. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/__init__.py +0 -0
  12. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/aiohttp.py +0 -0
  13. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/all.py +0 -0
  14. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/external.py +0 -0
  15. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/fastapi.py +0 -0
  16. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/flask.py +0 -0
  17. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/generic.py +0 -0
  18. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/h2.py +0 -0
  19. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/http.py +0 -0
  20. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/httpx.py +0 -0
  21. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/pytest.py +0 -0
  22. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/record.py +0 -0
  23. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/recordhttp1.py +0 -0
  24. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/recordhttp2.py +0 -0
  25. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/requests.py +0 -0
  26. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/socket.py +0 -0
  27. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/starlette.py +0 -0
  28. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/template_sitecustomize.py +0 -0
  29. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/unittest.py +0 -0
  30. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/urllib3.py +0 -0
  31. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/utils.py +0 -0
  32. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/hooks/uvicorn.py +0 -0
  33. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/http_status_code.py +0 -0
  34. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/log.py +0 -0
  35. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/mode_console.py +0 -0
  36. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/mode_module.py +0 -0
  37. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/mode_script.py +0 -0
  38. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/preview.py +0 -0
  39. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/records.py +0 -0
  40. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/server.py +0 -0
  41. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/utils.py +0 -0
  42. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/__init__.py +0 -0
  43. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/api.py +0 -0
  44. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/app.py +0 -0
  45. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/api.js +0 -0
  46. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/column.css +0 -0
  47. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/configuration.css +0 -0
  48. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/configuration.js +0 -0
  49. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/detail.css +0 -0
  50. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/favicon.ico +0 -0
  51. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/filter.js +0 -0
  52. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
  53. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
  54. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
  55. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/eye-blind-icon.svg +0 -0
  56. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/eye-icon.svg +0 -0
  57. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
  58. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
  59. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
  60. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/lock-line-icon.svg +0 -0
  61. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/lock-open-line-icon.svg +0 -0
  62. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
  63. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
  64. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
  65. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
  66. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
  67. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/index.htm +0 -0
  68. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/main.js +0 -0
  69. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/mustache.min.js +0 -0
  70. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/render.js +0 -0
  71. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/style.css +0 -0
  72. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg/webapp/static/table.css +0 -0
  73. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg.egg-info/SOURCES.txt +0 -0
  74. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg.egg-info/dependency_links.txt +0 -0
  75. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg.egg-info/entry_points.txt +0 -0
  76. {httpdbg-2.0.1 → httpdbg-2.0.2}/httpdbg.egg-info/top_level.txt +0 -0
  77. {httpdbg-2.0.1 → httpdbg-2.0.2}/pyproject.toml +0 -0
  78. {httpdbg-2.0.1 → httpdbg-2.0.2}/setup.cfg +0 -0
  79. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_api.py +0 -0
  80. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_cli.py +0 -0
  81. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_context_manager.py +0 -0
  82. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_aiohttp.py +0 -0
  83. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_h2.py +0 -0
  84. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_httpx.py +0 -0
  85. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_pytest.py +0 -0
  86. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_requests.py +0 -0
  87. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_unittest.py +0 -0
  88. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_hook_urllib3.py +0 -0
  89. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_initiator.py +0 -0
  90. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_mode_console.py +0 -0
  91. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_mode_module_pytest.py +0 -0
  92. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_mode_script.py +0 -0
  93. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_multiprocess.py +0 -0
  94. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_preview.py +0 -0
  95. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_pyhttpdbg_server.py +0 -0
  96. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_server.py +0 -0
  97. {httpdbg-2.0.1 → httpdbg-2.0.2}/tests/test_server_hook_fastapi.py +0 -0
  98. {httpdbg-2.0.1 → httpdbg-2.0.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: 2.0.1
3
+ Version: 2.0.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
@@ -2,6 +2,6 @@ from httpdbg.hooks.all import httprecord
2
2
  from httpdbg.records import HTTPRecords
3
3
 
4
4
 
5
- __version__ = "2.0.1"
5
+ __version__ = "2.0.2"
6
6
 
7
7
  __all__ = ["httprecord", "HTTPRecords"]
@@ -2,7 +2,9 @@
2
2
  from collections.abc import Callable
3
3
  from contextlib import contextmanager
4
4
  import datetime
5
+ import functools
5
6
  import inspect
7
+ import linecache
6
8
  import os
7
9
  import platform
8
10
  import traceback
@@ -98,9 +100,9 @@ def in_lib(line: str, packages: list[str] = None):
98
100
  def get_current_instruction(
99
101
  extracted_stack: traceback.StackSummary,
100
102
  ) -> tuple[str, str, list[str]]:
101
- instruction = ""
102
- short_stack = ""
103
- stack = []
103
+ instruction: str = ""
104
+ short_stack: str = ""
105
+ stack: list[str] = []
104
106
 
105
107
  try:
106
108
  n_stack = -2
@@ -114,12 +116,7 @@ def get_current_instruction(
114
116
  n_stack -= 1
115
117
  framesummary = extracted_stack[n_stack - 1]
116
118
 
117
- short_stack = f'File "{framesummary.filename}", line {framesummary.lineno}, in {framesummary.name}\n'
118
119
  if os.path.exists(framesummary.filename) and framesummary.lineno is not None:
119
- instruction, s_stack = extract_short_stack_from_file(
120
- framesummary.filename, framesummary.lineno, 0, 8
121
- )
122
- short_stack += s_stack
123
120
 
124
121
  # stack
125
122
  to_include = False
@@ -131,14 +128,20 @@ def get_current_instruction(
131
128
  and ("importlib" not in fs.filename)
132
129
  ) # remove the stack before to start the user part
133
130
  if to_include:
134
- _, s_stack = extract_short_stack_from_file(
131
+ instruction, s_stack, l_stack = extract_short_stack_from_file(
135
132
  fs.filename,
136
133
  fs.lineno if fs.lineno else 0,
137
- 4 if last_stack else 0,
138
- 8,
139
134
  not last_stack,
140
135
  )
141
- stack.append(f'File "{fs.filename}", line {fs.lineno}, \n{s_stack}')
136
+ if last_stack:
137
+ short_stack = (
138
+ f'File "{fs.filename}", line {fs.lineno}, in {fs.name}\n'
139
+ )
140
+ short_stack += s_stack
141
+
142
+ stack.append(
143
+ f'File "{fs.filename}", line {fs.lineno}, \n{l_stack}\n'
144
+ )
142
145
 
143
146
  else:
144
147
  instruction = framesummary.line if framesummary.line else "console"
@@ -152,52 +155,57 @@ def get_current_instruction(
152
155
  return instruction.replace("\n", " "), short_stack, stack
153
156
 
154
157
 
158
+ @functools.cache
155
159
  def extract_short_stack_from_file(
156
160
  filename: str,
157
161
  lineno: int,
158
- before: int,
159
- after: int,
160
162
  stop_if_instruction_ends: bool = True,
161
- ) -> tuple[str, str]:
162
- instruction = ""
163
- short_stack = ""
163
+ ) -> tuple[str, str, str]:
164
+ before: int = 4
165
+ after: int = 8
166
+ instruction: str = ""
167
+ short_stack: str = ""
168
+ long_stack: str = ""
164
169
 
165
170
  try:
166
171
  if os.path.exists(filename):
167
- with open(filename, "r") as src:
168
- lines = src.read().splitlines()
169
-
170
- # copy the lines before
171
- for i in range(
172
- max(0, lineno - 1 - before), min(lineno - 1, len(lines))
173
- ):
174
- line = lines[i]
175
- short_stack += f" {i+1}. {line}\n"
176
-
177
- # try to recompose the instruction if on multi-lines
178
- end_of_instruction_found = False
179
- for i in range(max(0, lineno - 1), min(lineno - 1 + after, len(lines))):
180
- line = lines[i]
181
- if not end_of_instruction_found:
182
- instruction += line.strip()
183
- short_stack += f" {i+1}. {line}{' <====' if (before > 0 and i + 1 == lineno) else ''}\n"
184
- nb_parenthesis = 0
185
- for c in instruction[instruction.find("(") :]:
186
- if c == "(":
187
- nb_parenthesis += 1
188
- if c == ")":
189
- nb_parenthesis -= 1
190
- if nb_parenthesis == 0:
191
- end_of_instruction_found = True
192
- break
193
- if end_of_instruction_found and stop_if_instruction_ends:
172
+ # copy the lines before, only for the "long" stack (if they are not empty)
173
+ copyit = False
174
+ for i in range(max(0, lineno - before), lineno):
175
+ line = linecache.getline(filename, i).removesuffix("\n").rstrip()
176
+ copyit = copyit or (line != "")
177
+ if copyit:
178
+ long_stack += f" {i}. {line}\n"
179
+
180
+ # try to recompose the instruction if on multi-lines
181
+ end_of_instruction_found = False
182
+ for i in range(max(0, lineno), lineno + after):
183
+ line = linecache.getline(filename, i).removesuffix("\n").rstrip()
184
+ if not end_of_instruction_found:
185
+ instruction += line.strip()
186
+ short_stack += f" {i}. {line}\n"
187
+ long_stack += (
188
+ f" {i}. {line}{' <====' if (before > 0 and i == lineno) else ''}\n"
189
+ )
190
+ nb_parenthesis = 0
191
+ for c in instruction[instruction.find("(") :]:
192
+ if c == "(":
193
+ nb_parenthesis += 1
194
+ if c == ")":
195
+ nb_parenthesis -= 1
196
+ if nb_parenthesis == 0:
197
+ end_of_instruction_found = True
194
198
  break
199
+ if end_of_instruction_found and stop_if_instruction_ends:
200
+ break
195
201
  except Exception as ex:
202
+ tb = traceback.extract_tb(ex.__traceback__)
203
+ _, lineno, _, _ = tb[-1]
196
204
  logger().info(
197
- f"EXTRACT_SHORT_STACK_FROM_FILE {filename} lineno={lineno} before={before} after={after}- error - {str(ex)}"
205
+ f"EXTRACT_SHORT_STACK_FROM_FILE {filename} lineno={lineno} before={before} after={after}- error (line {lineno}) - {str(ex)}",
198
206
  )
199
207
 
200
- return instruction, short_stack
208
+ return instruction, short_stack, long_stack
201
209
 
202
210
 
203
211
  def construct_call_str(original_method, *args, **kwargs):
@@ -345,7 +353,7 @@ def httpdbg_endpoint(
345
353
  filename = inspect.getsourcefile(original_method)
346
354
  if filename:
347
355
  _, lineno = inspect.getsourcelines(original_method)
348
- instruction, s_stack = extract_short_stack_from_file(filename, lineno, 0, 8)
356
+ instruction, s_stack, _ = extract_short_stack_from_file(filename, lineno)
349
357
  full_label = (
350
358
  f'File "{filename}", line {lineno}, in {original_method.__name__}\n'
351
359
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpdbg
3
- Version: 2.0.1
3
+ Version: 2.0.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
File without changes
File without changes
File without changes