First Check
Commit to Help
Example Code
import typer
import requests
from rich import print
import logging
from rich.logging import RichHandler
logging.basicConfig(
level="DEBUG",
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler(rich_tracebacks=True)],
)
log = logging.getLogger("rich")
app = typer.Typer(pretty_exceptions_show_locals=False)
greetings_login = "Login with your Portainer Url, Username and Password to deploy projects to your Portainer i.e.: https://my-portainer.example.com"
@app.command()
def login(
url: str = typer.Option(..., prompt=f'{greetings_login}\nUrl'),
username: str = typer.Option(..., prompt=True),
password: str = typer.Option(..., prompt=True, hide_input=True)
):
url = f'{url}/api/auth'
payload = {
"Username": username,
"Password": password
}
try:
response = requests.request("POST", url, json=payload)
if (response.status_code == 200):
print('[green]Successful login ✅[/green] saving credentials...')
with open("./.jwt", "w") as f:
f.write(response.text)
else:
print(f'Error: {response.reason}')
except Exception as e:
log.exception(e)
@app.command()
def logout(
force: bool = typer.Option(..., prompt="Are you sure you want to log out?"),
):
if force:
print(f"Deleting credentials")
#TODO implement check .jwt exist then delete
else:
print("Operation cancelled")
if __name__ == "__main__":
app()
Description
I am noob at python trying to write a Portainer CLI client inspired by docker CLI, for learning purposes and speed up personal deployments.
The code shown is just my first try at create a persisted login based on a .jwt local file once a succesful 200 response (and etc... future checks)
Obviously there are tons of unhandled errors and you might notice I am a completely uneducated illiterate when it comes to error handling. My application will burst in imaginative ways I am not even prepared to unit test them
Anyway, when I am checking the login() flow, I test it for breaking inputs like bad Url, bad credentials etc...
Then I got several raised errors from requests or whatever imported lib which is giving up:
[21:07:29] ERROR Invalid URL 'asdfasdf/api/auth': No scheme supplied. Perhaps you meant http://asdfasdf/api/auth? main.py:52
╭────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────╮
│ /home/becareo/passbolt/main.py:44 in login │
│ │
│ 41 │ } │
│ 42 │ │
│ 43 │ try: │
│ ❱ 44 │ │ response = requests.request("POST", url, json=payload) │
│ 45 │ │ if (response.status_code == 200): │
│ 46 │ │ │ print('[green]Successful login ✅[/green] saving credentials...') │
│ 47 │ │ │ with open("./.jwt", "w") as f: │
│ │
│ /home/becareo/passbolt/.venv/lib/python3.11/site-packages/requests/api.py:59 in request │
│ │
│ 56 │ # avoid leaving sockets open which can trigger a ResourceWarning in some │
│ 57 │ # cases, and look like a memory leak in others. │
│ 58 │ with sessions.Session() as session: │
│ ❱ 59 │ │ return session.request(method=method, url=url, **kwargs) │
│ 60 │
│ 61 │
│ 62 def get(url, params=None, **kwargs): │
│ │
│ /home/becareo/passbolt/.venv/lib/python3.11/site-packages/requests/sessions.py:573 in request │
│ │
│ 570 │ │ │ cookies=cookies, │
│ 571 │ │ │ hooks=hooks, │
│ 572 │ │ ) │
│ ❱ 573 │ │ prep = self.prepare_request(req) │
│ 574 │ │ │
│ 575 │ │ proxies = proxies or {} │
│ 576 │
│ │
│ /home/becareo/passbolt/.venv/lib/python3.11/site-packages/requests/sessions.py:484 in prepare_request │
│ │
│ 481 │ │ │ auth = get_netrc_auth(request.url) │
│ 482 │ │ │
│ 483 │ │ p = PreparedRequest() │
│ ❱ 484 │ │ p.prepare( │
│ 485 │ │ │ method=request.method.upper(), │
│ 486 │ │ │ url=request.url, │
│ 487 │ │ │ files=request.files, │
│ │
│ /home/becareo/passbolt/.venv/lib/python3.11/site-packages/requests/models.py:368 in prepare │
│ │
│ 365 │ │ """Prepares the entire request with the given parameters.""" │
│ 366 │ │ │
│ 367 │ │ self.prepare_method(method) │
│ ❱ 368 │ │ self.prepare_url(url, params) │
│ 369 │ │ self.prepare_headers(headers) │
│ 370 │ │ self.prepare_cookies(cookies) │
│ 371 │ │ self.prepare_body(data, files, json) │
│ │
│ /home/becareo/passbolt/.venv/lib/python3.11/site-packages/requests/models.py:439 in prepare_url │
│ │
│ 436 │ │ │ raise InvalidURL(*e.args) │
│ 437 │ │ │
│ 438 │ │ if not scheme: │
│ ❱ 439 │ │ │ raise MissingSchema( │
│ 440 │ │ │ │ f"Invalid URL {url!r}: No scheme supplied. " │
│ 441 │ │ │ │ f"Perhaps you meant http://{url}?" │
│ 442 │ │ │ ) │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
MissingSchema: Invalid URL 'asdfasdf/api/auth': No scheme supplied. Perhaps you meant http://asdfasdf/api/auth?
I will pack this CLI with pyinstaller hiding its implementation and most important thing, hiding stressful tracebacks for the average user, preserving usefull error like the last raised one:
MissingSchema: Invalid URL 'asdfasdf/api/auth': No scheme supplied. Perhaps you meant http://asdfasdf/api/auth?
I have searched for the correct way to preserve useful errors for the user, hiding the tracebacks and I have come across sys.excepthook exception handlers with no luck.
Tracebacks are enabled with any code hack I've tried. I am a bit lost with providing a usefull error handling for the user here.
Would be awesome if someone more experience could point me to the right direction with useful tips about this
Operating System
Linux, Windows
Operating System Details
Windows 11
WSL2
Poetry
Typer Version
extras = ["all"], version = "^0.7.0"
Python Version
3.11.0
Additional Context
No response
First Check
Commit to Help
Example Code
Description
I am noob at python trying to write a Portainer CLI client inspired by docker CLI, for learning purposes and speed up personal deployments.
The code shown is just my first try at create a persisted login based on a .jwt local file once a succesful 200 response (and etc... future checks)
Obviously there are tons of unhandled errors and you might notice I am a completely uneducated illiterate when it comes to error handling. My application will burst in imaginative ways I am not even prepared to unit test them
Anyway, when I am checking the login() flow, I test it for breaking inputs like bad Url, bad credentials etc...
Then I got several raised errors from
requestsor whatever imported lib which is giving up:I will pack this CLI with
pyinstallerhiding its implementation and most important thing, hiding stressful tracebacks for the average user, preserving usefull error like the last raised one:I have searched for the correct way to preserve useful errors for the user, hiding the tracebacks and I have come across
sys.excepthookexception handlers with no luck.Tracebacks are enabled with any code hack I've tried. I am a bit lost with providing a usefull error handling for the user here.
Would be awesome if someone more experience could point me to the right direction with useful tips about this
Operating System
Linux, Windows
Operating System Details
Windows 11
WSL2
Poetry
Typer Version
extras = ["all"], version = "^0.7.0"
Python Version
3.11.0
Additional Context
No response