pyntcli 0.1.85__py3-none-any.whl → 0.1.87__py3-none-any.whl

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.
pyntcli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.85"
1
+ __version__ = "0.1.87"
pyntcli/commands/burp.py CHANGED
@@ -144,6 +144,7 @@ def burp_usage():
144
144
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
145
145
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
146
146
  .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default)")
147
+ .with_line("\t--verbose - Use to get more detailed information about the run")
147
148
  )
148
149
 
149
150
 
@@ -261,6 +262,7 @@ class BurpCommand(sub_command.PyntSubCommand):
261
262
  )
262
263
  return
263
264
 
265
+ ui_thread.print_verbose("Parsing burp xml")
264
266
  doc = parse_xml(args.xml)
265
267
  if not doc:
266
268
  ui_thread.print(
@@ -290,8 +292,9 @@ class BurpCommand(sub_command.PyntSubCommand):
290
292
  ui_thread.print_generator(proxy_docker.stdout)
291
293
 
292
294
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
295
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
293
296
  ui_thread.print(ui_thread.PrinterText(
294
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
297
+ "Pynt docker is ready",
295
298
  ui_thread.PrinterText.INFO,
296
299
  ))
297
300
 
@@ -35,9 +35,11 @@ def command_usage():
35
35
  .with_line("\t--proxy-port - Set the port proxied traffic should be routed to (DEFAULT: 6666)")
36
36
  .with_line("\t--report - If present will save the generated report in this path.")
37
37
  .with_line("\t--insecure - Use when target uses self signed certificates")
38
+ .with_line("\t--self-signed - Use when the functional test verify SSL")
38
39
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
39
40
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
40
41
  .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) ")
42
+ .with_line("\t--verbose - Use to get more detailed information about the run")
41
43
  )
42
44
 
43
45
 
@@ -61,6 +63,7 @@ class CommandSubCommand(sub_command.PyntSubCommand):
61
63
  proxy_cmd.add_argument("--test-name", help="", default="", required=False)
62
64
  proxy_cmd.add_argument("--allow-errors", action="store_true")
63
65
  proxy_cmd.add_argument("--ca-path", type=str, default="")
66
+ proxy_cmd.add_argument("--self-signed", action="store_true")
64
67
  proxy_cmd.add_argument("--report", type=str, default="")
65
68
  proxy_cmd.add_argument("--return-error", choices=["all-findings", "errors-only", "never"], default="never")
66
69
  proxy_cmd.print_usage = self.print_usage
@@ -69,6 +72,16 @@ class CommandSubCommand(sub_command.PyntSubCommand):
69
72
 
70
73
  def _updated_environment(self, args):
71
74
  env_copy = deepcopy(os.environ)
75
+ if "self_signed" in args and args.self_signed:
76
+ cert_path = os.path.join(os.path.expanduser('~'), '.pynt', 'cert')
77
+ cert_file_path = os.path.join(cert_path, 'mitmproxy-ca-cert.pem')
78
+ env_copy.update(
79
+ {
80
+ "REQUESTS_CA_BUNDLE": cert_file_path,
81
+ "SSL_CERT_FILE": cert_file_path,
82
+ "NODE_EXTRA_CA_CERTS": cert_file_path
83
+ }
84
+ )
72
85
  return env_copy.update(
73
86
  {
74
87
  "HTTP_PROXY": "http://localhost:{}".format(args.proxy_port),
@@ -161,8 +174,9 @@ class CommandSubCommand(sub_command.PyntSubCommand):
161
174
  ui_thread.print_generator(proxy_docker.stdout)
162
175
 
163
176
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
177
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
164
178
  ui_thread.print(ui_thread.PrinterText(
165
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
179
+ "Pynt docker is ready",
166
180
  ui_thread.PrinterText.INFO,
167
181
  ))
168
182
 
@@ -199,10 +213,10 @@ class CommandSubCommand(sub_command.PyntSubCommand):
199
213
  self._stop_proxy(args)
200
214
 
201
215
  with ui_thread.progress(
202
- "ws://localhost:{}/progress?scanId={}".format(args.port, self.scan_id),
203
- partial(lambda *args: None),
204
- "scan in progress...",
205
- 100,
216
+ "ws://localhost:{}/progress?scanId={}".format(args.port, self.scan_id),
217
+ partial(lambda *args: None),
218
+ "scan in progress...",
219
+ 100,
206
220
  ):
207
221
  html_report = self._get_report(args, "html")
208
222
  html_report_path = os.path.join(
pyntcli/commands/har.py CHANGED
@@ -28,6 +28,7 @@ def har_usage():
28
28
  .with_line(
29
29
  "\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN."
30
30
  )
31
+ .with_line("\t--verbose - Use to get more detailed information about the run")
31
32
  .with_line("")
32
33
  )
33
34
 
@@ -51,6 +52,7 @@ class HarSubCommand(sub_command.PyntSubCommand):
51
52
  return har_cmd
52
53
 
53
54
  def run_cmd(self, args: argparse.Namespace):
55
+ ui_thread.print_verbose("Building container")
54
56
  port = util.find_open_port()
55
57
  container = pynt_container.get_container_with_arguments(
56
58
  args, pynt_container.PyntDockerPort(src=str(port), dest=port, name="--port")
@@ -94,18 +96,19 @@ class HarSubCommand(sub_command.PyntSubCommand):
94
96
  )
95
97
 
96
98
  healthcheck()
99
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
97
100
  ui_thread.print(ui_thread.PrinterText(
98
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
101
+ "Pynt docker is ready",
99
102
  ui_thread.PrinterText.INFO,
100
103
  ))
101
104
 
102
105
  ui_thread.print_generator(ui_thread.AnsiText.wrap_gen(har_docker.stdout))
103
106
 
104
107
  with ui_thread.progress(
105
- "ws://localhost:{}/progress".format(port),
106
- healthcheck,
107
- "scan in progress...",
108
- 100,
108
+ "ws://localhost:{}/progress".format(port),
109
+ healthcheck,
110
+ "scan in progress...",
111
+ 100,
109
112
  ):
110
113
  while har_docker.is_alive():
111
114
  time.sleep(1)
@@ -34,6 +34,7 @@ def listen_usage():
34
34
  .with_line("\t--insecure - use when target uses self signed certificates")
35
35
  .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
36
36
  .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) ")
37
+ .with_line("\t--verbose - Use to get more detailed information about the run")
37
38
  )
38
39
 
39
40
 
@@ -57,7 +58,7 @@ class ListenSubCommand(sub_command.PyntSubCommand):
57
58
  listen_cmd.add_argument("--allow-errors", action="store_true")
58
59
  listen_cmd.add_argument("--ca-path", type=str, default="")
59
60
  listen_cmd.add_argument("--report", type=str, default="")
60
- listen_cmd.add_argument("--return-error", choices=["all-findings", "errors-only", "never"], default="never" )
61
+ listen_cmd.add_argument("--return-error", choices=["all-findings", "errors-only", "never"], default="never")
61
62
  listen_cmd.print_usage = self.print_usage
62
63
  listen_cmd.print_help = self.print_usage
63
64
  return listen_cmd
@@ -140,8 +141,9 @@ class ListenSubCommand(sub_command.PyntSubCommand):
140
141
  ui_thread.print_generator(proxy_docker.stdout)
141
142
 
142
143
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
144
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
143
145
  ui_thread.print(ui_thread.PrinterText(
144
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
146
+ "Pynt docker is ready",
145
147
  ui_thread.PrinterText.INFO,
146
148
  ))
147
149
 
@@ -170,9 +172,9 @@ class ListenSubCommand(sub_command.PyntSubCommand):
170
172
  self._stop_proxy(args)
171
173
 
172
174
  with ui_thread.progress(
173
- "ws://localhost:{}/progress?scanId={}".format(args.port, self.scan_id),
174
- partial(lambda *args: None),
175
- "scan in progress...",100):
175
+ "ws://localhost:{}/progress?scanId={}".format(args.port, self.scan_id),
176
+ partial(lambda *args: None),
177
+ "scan in progress...", 100):
176
178
  html_report = self._get_report(args, "html")
177
179
  html_report_path = os.path.join(
178
180
  tempfile.gettempdir(), "pynt_report_{}.html".format(int(time.time()))
@@ -189,12 +191,12 @@ class ListenSubCommand(sub_command.PyntSubCommand):
189
191
  json_report_path = util.get_user_report_path(full_path, "json")
190
192
 
191
193
  if html_report:
192
- with open(html_report_path, "w",encoding="utf-8") as html_file:
194
+ with open(html_report_path, "w", encoding="utf-8") as html_file:
193
195
  html_file.write(html_report)
194
196
  webbrowser.open("file://{}".format(html_report_path))
195
197
 
196
198
  if json_report:
197
- with open(json_report_path, "w",encoding="utf-8") as json_file:
199
+ with open(json_report_path, "w", encoding="utf-8") as json_file:
198
200
  json_file.write(json_report)
199
201
  reporter = cli_reporter.PyntReporter(json_report_path)
200
202
  reporter.print_summary()
@@ -31,6 +31,7 @@ def newman_usage():
31
31
  .with_line(
32
32
  "\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) "
33
33
  )
34
+ .with_line("\t--verbose - Use to get more detailed information about the run")
34
35
  )
35
36
 
36
37
 
@@ -116,8 +117,9 @@ class NewmanSubCommand(sub_command.PyntSubCommand):
116
117
  )
117
118
 
118
119
  healthcheck()
120
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
119
121
  ui_thread.print(ui_thread.PrinterText(
120
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
122
+ "Pynt docker is ready",
121
123
  ui_thread.PrinterText.INFO,
122
124
  ))
123
125
 
@@ -35,7 +35,8 @@ def postman_usage():
35
35
  .with_line("Options:", style=ui_thread.PrinterText.HEADER) \
36
36
  .with_line("\t--port - set the port pynt will listen to (DEFAULT: 5001)") \
37
37
  .with_line("\t--insecure - use when target uses self signed certificates") \
38
- .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
38
+ .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.") \
39
+ .with_line("\t--verbose - Use to get more detailed information about the run")
39
40
 
40
41
 
41
42
  class PostmanSubCommand(sub_command.PyntSubCommand):
@@ -94,7 +95,6 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
94
95
 
95
96
  container = pynt_container.get_container_with_arguments(args, pynt_container.PyntDockerPort("5001", args.port, name="--port"))
96
97
 
97
-
98
98
  postman_docker = pynt_container.PyntContainer(image_name=pynt_container.PYNT_DOCKER_IMAGE,
99
99
  tag="postman-latest",
100
100
  detach=True,
@@ -104,8 +104,9 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
104
104
  ui_thread.print_generator(postman_docker.stdout)
105
105
 
106
106
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
107
+ ui_thread.print_verbose(util.GOT_INITIAL_HEALTHCHECK_MESSAGE)
107
108
  ui_thread.print(ui_thread.PrinterText(
108
- util.GOT_INITIAL_HEALTHCHECK_MESSAGE,
109
+ "Pynt docker is ready",
109
110
  ui_thread.PrinterText.INFO,
110
111
  ))
111
112
 
pyntcli/commands/root.py CHANGED
@@ -22,7 +22,7 @@ def root_usage():
22
22
  .with_line("\tpynt-id - view your pynt-id to use when running pynt in CI pipeline")
23
23
  .with_line("\tlogout - log out from your user")
24
24
  .with_line("")
25
- .with_line("Run pynt [COMMAND] -h to get help on a specific command", style=ui_thread.PrinterText.INFO,)
25
+ .with_line("Run pynt [COMMAND] -h to get help on a specific command", style=ui_thread.PrinterText.INFO, )
26
26
  )
27
27
 
28
28
 
@@ -68,6 +68,13 @@ class BaseCommand:
68
68
  parser.add_argument("--transport-config", type=str, default="")
69
69
  parser.add_argument("--application-id", type=str, default="", required=False)
70
70
  parser.add_argument("--proxy", type=str, default="", required=False)
71
+ parser.add_argument(
72
+ "--verbose",
73
+ default=False,
74
+ required=False,
75
+ action="store_true",
76
+ help="use to get more detailed execution information",
77
+ )
71
78
 
72
79
  def get_subparser(self) -> argparse._SubParsersAction:
73
80
  if self.subparser is None:
pyntcli/main.py CHANGED
@@ -33,18 +33,17 @@ def signal_handler(signal_number, frame):
33
33
  exit(0)
34
34
 
35
35
 
36
- def check_for_dependecies():
36
+ def assert_docker_availability():
37
37
  pynt_container.get_docker_type()
38
38
 
39
39
 
40
40
  def print_header():
41
41
  ui_thread.print(ui_thread.PrinterText(*ui_thread.pynt_header())
42
- .with_line(*ui_thread.pynt_version())
43
- .with_line(""))
42
+ .with_line(*ui_thread.pynt_version())
43
+ .with_line(""))
44
44
 
45
45
 
46
- def start_analytics():
47
- user_id = login.user_id()
46
+ def start_analytics(user_id: str):
48
47
  if user_id:
49
48
  analytics.set_user_id(user_id)
50
49
  log.add_user_details(user_id)
@@ -72,9 +71,14 @@ def main():
72
71
  if argv[1] == "logout":
73
72
  logout()
74
73
  return
74
+ if [n for n in argv if "--verbose" in n]:
75
+ ui_thread.VERBOSE = True
75
76
  log.set_source(__version__)
76
- start_analytics()
77
- check_for_dependecies()
77
+ ui_thread.print_verbose("Logging in...")
78
+ user_id = login.user_id()
79
+ start_analytics(user_id)
80
+ ui_thread.print_verbose("Asserting docker is properly installed")
81
+ assert_docker_availability()
78
82
  signal.signal(signal.SIGINT, signal_handler)
79
83
  cli = pynt_cmd.PyntCommand()
80
84
  cli.run_cmd(cli.parse_args(argv[1:]))
@@ -85,7 +89,8 @@ def main():
85
89
  ui_thread.print(ui_thread.PrinterText("Docker was unavailable, please make sure docker is installed and running.", ui_thread.PrinterText.WARNING))
86
90
  analytics.emit(analytics.ERROR, {"error": "docker unavailable. e: {}".format(e)})
87
91
  except SSLError as e:
88
- ui_thread.print(ui_thread.PrinterText("We encountered SSL issues and could not proceed, this may be the cause of a VPN or a Firewall in place. Run again with --insecure", ui_thread.PrinterText.WARNING))
92
+ ui_thread.print(
93
+ ui_thread.PrinterText("We encountered SSL issues and could not proceed, this may be the cause of a VPN or a Firewall in place. Run again with --insecure", ui_thread.PrinterText.WARNING))
89
94
  analytics.emit(analytics.ERROR, {"error": "ssl error. e: {}".format(e)})
90
95
  except login.Timeout as e:
91
96
  ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to incomplete registration, please try again.", ui_thread.PrinterText.WARNING))
@@ -117,7 +122,8 @@ def main():
117
122
  exit(1)
118
123
  except Exception as e:
119
124
  analytics.emit(analytics.ERROR, {"error": "{}".format(e)})
120
- pynt_errors.unexpected_error()
125
+ pynt_errors.unexpected_error(e)
126
+
121
127
  finally:
122
128
  log.flush_logger()
123
129
  shutdown_cli()
@@ -106,6 +106,14 @@ def get_container_with_arguments(args: argparse.Namespace, *port_args: PyntDocke
106
106
  docker_arguments += ["--transport-config", tc_name]
107
107
  mounts.append(create_mount(os.path.abspath(args.transport_config), "/etc/pynt/{}".format(tc_name)))
108
108
 
109
+ if "verbose" in args and args.verbose:
110
+ docker_arguments.append("--verbose")
111
+
112
+ creds_path = os.path.dirname(CredStore().file_location)
113
+ mitm_cert_path = os.path.join(creds_path,"cert")
114
+ os.makedirs(mitm_cert_path,exist_ok=True)
115
+ mounts.append(create_mount(mitm_cert_path, "/root/.mitmproxy"))
116
+
109
117
  env = {PYNT_ID: CredStore().get_tokens(), "PYNT_SAAS_URL": PYNT_SAAS}
110
118
  if user_set_all_variables():
111
119
  add_env_variables(env)
@@ -184,7 +192,8 @@ class PyntContainer():
184
192
  return self.docker_client.images.pull(self.image, tag=self.tag)
185
193
  except APIError as e:
186
194
  analytics.emit(analytics.ERROR, {"error": "Unable to pull image from ghcr: {}".format(e)})
187
- ui_thread.print(ui_thread.PrinterText("Error: Docker unable to pull latest Pynt image due to VPN/proxy. If using a mirror for Docker images, visit docs.pynt.io for help.", ui_thread.PrinterText.WARNING))
195
+ ui_thread.print(ui_thread.PrinterText("Error: Docker unable to pull latest Pynt image due to VPN/proxy. If using a mirror for Docker images, visit docs.pynt.io for help.",
196
+ ui_thread.PrinterText.WARNING))
188
197
  return None
189
198
 
190
199
  def get_image(self):
@@ -202,6 +211,8 @@ class PyntContainer():
202
211
  self._create_docker_client()
203
212
 
204
213
  self.running = True
214
+
215
+ ui_thread.print_verbose("Killing other pynt containers if such exist")
205
216
  self.kill_other_instances()
206
217
 
207
218
  ui_thread.print(ui_thread.PrinterText("Pulling latest docker", ui_thread.PrinterText.INFO))
@@ -222,6 +233,7 @@ class PyntContainer():
222
233
 
223
234
  run_arguments.update(self.base_container.docker_type.get_argumets())
224
235
 
236
+ ui_thread.print_verbose("Running pynt docker with arguments:\n {}".format(" ".join(args)))
225
237
  c = self.docker_client.containers.run(**run_arguments)
226
238
  self.container_name = c.name
227
239
  self.stdout = c.logs(stream=True)
pyntcli/ui/pynt_errors.py CHANGED
@@ -1,7 +1,18 @@
1
1
  from pyntcli.ui import ui_thread
2
2
 
3
- def unexpected_error():
4
- ui_thread.print(ui_thread.PrinterText("An Unexpected Error Occurred",style=ui_thread.PrinterText.WARNING) \
5
- .with_line("") \
6
- .with_line("Please tell us about it in our community channel and we will help you figure it out:",style=ui_thread.PrinterText.HEADER) \
7
- .with_line("https://join.slack.com/t/pynt-community/shared_invite/zt-1mvacojz5-WNjbH4HN8iksmKpCLTxOiQ",style=ui_thread.PrinterText.HEADER))
3
+
4
+ def unexpected_error(original):
5
+ printer_text = ui_thread.PrinterText("An Unexpected Error Occurred", style=ui_thread.PrinterText.WARNING) \
6
+ .with_line("")
7
+
8
+ msg = str(original) or repr(original)
9
+ if msg:
10
+ printer_text.with_line(f"e: {msg}")
11
+
12
+ printer_text = printer_text.with_line(
13
+ "Please tell us about it in our community channel and we will help you figure it out:",
14
+ style=ui_thread.PrinterText.HEADER) \
15
+ .with_line("https://join.slack.com/t/pynt-community/shared_invite/zt-1mvacojz5-WNjbH4HN8iksmKpCLTxOiQ",
16
+ style=ui_thread.PrinterText.HEADER)
17
+
18
+ ui_thread.print(printer_text)
pyntcli/ui/ui_thread.py CHANGED
@@ -12,13 +12,16 @@ from typing import Tuple
12
12
  from pyntcli import __version__ as cli_version
13
13
  from pyntcli.ui.progress import PyntProgress
14
14
 
15
+ VERBOSE = False
16
+
17
+
15
18
  class PrinterText():
16
19
  DEFAULT = 0
17
20
  HEADER = 1
18
21
  INFO = 2
19
22
  WARNING = 3
20
23
 
21
- def __init__(self,text,style=DEFAULT):
24
+ def __init__(self, text, style=DEFAULT):
22
25
  self.text = Text(text, PrinterText.get_style(style))
23
26
 
24
27
  @staticmethod
@@ -37,57 +40,67 @@ class PrinterText():
37
40
  self.text.append(Text(line, PrinterText.get_style(style)))
38
41
  return self
39
42
 
43
+
40
44
  class AnsiText():
41
45
  def __init__(self, data) -> None:
42
46
  self.data = data
43
-
47
+
44
48
  @staticmethod
45
49
  def wrap_gen(gen):
46
50
  for v in gen:
47
51
  yield AnsiText(v)
48
52
 
53
+
49
54
  class Spinner():
50
55
  def __init__(self, prompt, style) -> None:
51
56
  self.prompt = prompt
52
- self.style = style
57
+ self.style = style
53
58
  self.runnning = False
54
-
59
+
55
60
  def __enter__(self):
56
- return self
61
+ return self
57
62
 
58
63
  def __exit__(self, exc_type, exc_value, exc_traceback):
59
64
  self.running = False
60
65
 
61
- def pynt_version()-> Tuple[str,int]:
62
- return "Pynt CLI version " + cli_version,PrinterText.DEFAULT
63
66
 
64
- def pynt_header()-> Tuple[str,int]:
65
- return "API Security testing autopilot",PrinterText.DEFAULT
67
+ def pynt_version() -> Tuple[str, int]:
68
+ return "Pynt CLI version " + cli_version, PrinterText.DEFAULT
69
+
70
+
71
+ def pynt_header() -> Tuple[str, int]:
72
+ return "API Security testing autopilot", PrinterText.DEFAULT
73
+
66
74
 
67
75
  def gen_func_loop(gen):
68
76
  for l in gen:
69
77
  data = l
70
- if type(data) == bytes:
78
+ if type(data) == bytes:
71
79
  data = l.decode("utf-8")
72
80
  if not isinstance(data, AnsiText) and data[-1] == "\n":
73
81
  data = data[:-1]
74
82
  _print(data)
75
-
83
+
84
+
76
85
  def print_generator(gen):
77
- t = Thread(target=gen_func_loop, args=(gen,), daemon=True)
86
+ t = Thread(target=gen_func_loop, args=(gen,), daemon=True)
78
87
  t.start()
79
88
 
80
- def _print(s):
89
+
90
+ def _print(s):
81
91
  Printer.instance().print(s)
82
92
 
83
- def print(s):
84
- if type(s) == bytes:
93
+
94
+ def print(s):
95
+ if type(s) == bytes:
85
96
  s = s.decode("utf-8")
86
97
  _print(s)
87
98
 
99
+
88
100
  def stop():
89
101
  Printer.instance().stop()
90
102
 
103
+
91
104
  class Printer():
92
105
  _instace = None
93
106
 
@@ -96,31 +109,31 @@ class Printer():
96
109
  self.run_thread = Thread(target=self._print_in_loop, daemon=True)
97
110
  self.print_queue = queue.Queue()
98
111
  self.console = Console(tab_size=4)
99
-
100
- @staticmethod
112
+
113
+ @staticmethod
101
114
  def instance():
102
115
  if not Printer._instace:
103
- Printer._instace = Printer()
104
- Printer._instace.start()
116
+ Printer._instace = Printer()
117
+ Printer._instace.start()
105
118
 
106
119
  return Printer._instace
107
120
 
108
121
  def start(self):
109
122
  self.running = True
110
123
  self.run_thread.start()
111
-
124
+
112
125
  def _handle_spinner(self, spinner):
113
- spinner.running = True
126
+ spinner.running = True
114
127
  s = Status(spinner.prompt, spinner=spinner.style, console=self.console)
115
128
  s.start()
116
129
  while spinner.running and self.running:
117
130
  time.sleep(0.5)
118
131
  s.stop()
119
-
132
+
120
133
  def _handle_progress(self, progress):
121
134
  if not progress.trackable:
122
135
  return
123
- progress.running = True
136
+ progress.running = True
124
137
  with Progress(console=self.console, transient=True) as p:
125
138
  t = p.add_task(description=progress.description, total=progress.total)
126
139
  for update in progress.trackable:
@@ -131,9 +144,9 @@ class Printer():
131
144
 
132
145
  def _print_in_loop(self):
133
146
  while self.running:
134
- try:
147
+ try:
135
148
  data = self.print_queue.get(timeout=1)
136
- if isinstance(data, list):
149
+ if isinstance(data, list):
137
150
  data = data[0]
138
151
  if isinstance(data, Spinner):
139
152
  self._handle_spinner(data)
@@ -148,29 +161,34 @@ class Printer():
148
161
  self.console.print(data)
149
162
  except queue.Empty:
150
163
  pass
151
-
164
+
152
165
  while not self.print_queue.empty():
153
166
  self.console.print(self.print_queue.get())
154
167
 
155
-
156
168
  def print(self, data):
157
- if isinstance(data,PrinterText):
169
+ if isinstance(data, PrinterText):
158
170
  data = data.text
159
171
  if isinstance(data, AnsiText):
160
172
  data = Text.from_ansi(data.data.decode())
161
173
  self.print_queue.put(data)
162
-
174
+
163
175
  def stop(self):
164
176
  self.running = False
165
177
  self.run_thread.join()
166
178
 
167
- def spinner(prompt, style):
179
+
180
+ def spinner(prompt, style):
168
181
  s = Spinner(prompt, style)
169
182
  _print([s])
170
183
  return s
171
184
 
172
- def progress(what_to_track,healthcheck, description, total=100):
173
- pointer_to_progress = [PyntProgress(what_to_track,healthcheck, total, description)]
185
+
186
+ def progress(what_to_track, healthcheck, description, total=100):
187
+ pointer_to_progress = [PyntProgress(what_to_track, healthcheck, total, description)]
174
188
  _print(pointer_to_progress)
175
189
  return pointer_to_progress[0]
176
190
 
191
+
192
+ def print_verbose(text: str):
193
+ if VERBOSE:
194
+ print(PrinterText(text, PrinterText.INFO))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyntcli
3
- Version: 0.1.85
3
+ Version: 0.1.87
4
4
  Summary: Command line utility to handle all of Pynt's different integrations
5
5
  Author-email: Pynt-io <support@pynt.io>
6
6
  Project-URL: Homepage, https://pynt.io
@@ -1,19 +1,19 @@
1
- pyntcli/__init__.py,sha256=wY2suKf-e8VDtbBWRFlwNkTJ9Nff03BK8zzI8EWGc48,23
2
- pyntcli/main.py,sha256=5L3FXlkaxen79P5NPl72K0fmLMsk-Kjq_yjjlsxFkI8,5769
1
+ pyntcli/__init__.py,sha256=DqFIxZO1qWYGIooEyrZV7d6zn4AaSeN_vya1dM6dtRc,23
2
+ pyntcli/main.py,sha256=eJFpT-haLVQAYP71_ZHjNaA5iG2wvDXy8km84GU0Mwo,6009
3
3
  pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  pyntcli/analytics/send.py,sha256=pJOyOWl3g_Vm9apKK3LzNVqsnC6zsWA1bCK3ZegbLpc,3637
5
5
  pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pyntcli/auth/login.py,sha256=TljsRXbEkNI1YUrKm5mlTw4YiecYScYUsit8Z8vstss,5228
7
7
  pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- pyntcli/commands/burp.py,sha256=dSwFo_55b9e3YSaYh3SgPIIkR-zwmPf-FCn7qxodMHk,11645
9
- pyntcli/commands/command.py,sha256=uvvxLXGHHmVdfKyazoyN5scY7OBw2wUJ6bOPH-SSSFI,9643
10
- pyntcli/commands/har.py,sha256=o6GnRnLCXwoxucO3NPRl3MP4aNoJ37bhfU08Oq6KEbg,3846
8
+ pyntcli/commands/burp.py,sha256=O-KKyp6kcbTeHMEKsABlLQfI6rFqz229pef53UkpGlQ,11840
9
+ pyntcli/commands/command.py,sha256=0lCMxXIyj3vAd8NfeQ2Ik1WhV8RHq17cwwaQn2isRzQ,10411
10
+ pyntcli/commands/har.py,sha256=iBFd_Zqjths3JztmHHJBvIbrfT98ANVK180tVXqFXFk,4063
11
11
  pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
12
- pyntcli/commands/listen.py,sha256=Q6T_YGH1-DEu7lRxnTcAzWrb0xwooim4KM67PHaQGBI,8632
13
- pyntcli/commands/newman.py,sha256=v1XOEvM8l59fVW3IjeeQPhcOTVPfOEJ_ni0_i87Mucs,5034
14
- pyntcli/commands/postman.py,sha256=VTi5qrMlCZ7mTQJ9KZ-t__K08RHnMnfjEnco9IXzGOc,4869
12
+ pyntcli/commands/listen.py,sha256=L8lpa8r-mZor9F_ad9L7KQAznljSEOgn_LPURm4e6dM,8789
13
+ pyntcli/commands/newman.py,sha256=MQ7EG1QTm-Xnb_gfpx_DYo1BeoV_Y5SFIBJrtKCZZB8,5181
14
+ pyntcli/commands/postman.py,sha256=wh0sgJTTkUDY5GFKxCKMrcE9OmSZk6nufltsIlJb6As,5013
15
15
  pyntcli/commands/pynt_cmd.py,sha256=KOl9guUtesO2JcMM5nPKKkjnK6F9HV4jHHcoUk4KVhw,2825
16
- pyntcli/commands/root.py,sha256=dmgdzoFuf5LkwrkwvWf1MtlwTBgsVpS85Yr_cQCVuGA,3291
16
+ pyntcli/commands/root.py,sha256=inffMhaMJykoRC0T2f7uF3f5BEdJw_c6Q1e2FTG4bfU,3511
17
17
  pyntcli/commands/static_file_extensions.py,sha256=PZJb02BI-64tbU-j3rdCNsXzTh7gkIDGxGKbKNw3h5k,1995
18
18
  pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
19
19
  pyntcli/commands/util.py,sha256=spTI_3z-fd0q7o1htvl-mw9-yKbO2ZESDAL-AsgWCb0,3217
@@ -21,7 +21,7 @@ pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
21
21
  pyntcli/log/log.py,sha256=cWCdWmUaAwePwdhYDcgNMEG9d9RM34sGahxBCYEdv2Y,1069
22
22
  pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
23
23
  pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
24
- pyntcli/pynt_docker/pynt_container.py,sha256=y4m8wZU16gqFPaMzEJKKHut4DbjPxr_du8g7I4-AcHk,8761
24
+ pyntcli/pynt_docker/pynt_container.py,sha256=Lz4WJlzJj3YeRQ6bb9D34oeLGnY1c0UDIugoHu-zBWA,9318
25
25
  pyntcli/store/__init__.py,sha256=xuS9OB21F6B1sUx5XPGxz_6WpG6-KTMbuq50RrZS5OY,29
26
26
  pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
27
27
  pyntcli/store/store.py,sha256=9KwalOd1EA1VtYwr9oJgBsPgUYakX5uyif_sNXGQ614,1917
@@ -30,14 +30,14 @@ pyntcli/transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
30
30
  pyntcli/transport/pynt_requests.py,sha256=KiEG3hNcwY7DLIJDCq-7LIPq54yYQcDBhHe3KhpqRTc,1563
31
31
  pyntcli/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  pyntcli/ui/progress.py,sha256=RrnO_jJNunoyupylakmWmHOEPw3lh99OHpKBzL6OBiE,1008
33
- pyntcli/ui/pynt_errors.py,sha256=UAr8OV5EM4zLhfWSmK_qss8nal2Ezo66Dk8ZMvR_RTs,546
33
+ pyntcli/ui/pynt_errors.py,sha256=00UprD4tFViREv7kuXGQ99PAKGTpXYixxi3Ndeoeiew,689
34
34
  pyntcli/ui/report.py,sha256=W-icPSZrGLOubXgam0LpOvHLl_aZg9Zx9qIkL8Ym5PE,1930
35
- pyntcli/ui/ui_thread.py,sha256=OVTbiIFMg2KgxAvHf7yy86xGm4RVS2vj_VYZkMi-SRY,4956
35
+ pyntcli/ui/ui_thread.py,sha256=4YzpO5dDrWpbTovMdHvv9ZQdLFJamZEAKXjF9rIIIoQ,5039
36
36
  tests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
37
37
  tests/auth/test_login.py,sha256=KFlzWhXBAuwdi7GXf16gCB3ya94LQG2wjcSChE149rQ,3798
38
38
  tests/store/test_cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
39
- pyntcli-0.1.85.dist-info/METADATA,sha256=hAEzszpQdHQ9E10oXo6pKK2XMpgPqTz9r4DISaACCLw,463
40
- pyntcli-0.1.85.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
41
- pyntcli-0.1.85.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
42
- pyntcli-0.1.85.dist-info/top_level.txt,sha256=u9MDStwVHB7UG8PUcODeWCul_NvzL2EzoLvSlgwLHFs,30
43
- pyntcli-0.1.85.dist-info/RECORD,,
39
+ pyntcli-0.1.87.dist-info/METADATA,sha256=buf6PtP3EoTWbUyD7cqhPJpPkj_stwuVePNRSfMzoDY,463
40
+ pyntcli-0.1.87.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
41
+ pyntcli-0.1.87.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
42
+ pyntcli-0.1.87.dist-info/top_level.txt,sha256=u9MDStwVHB7UG8PUcODeWCul_NvzL2EzoLvSlgwLHFs,30
43
+ pyntcli-0.1.87.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5