From 403f4c94917b1fa196d30f2613d1eeef59c55150 Mon Sep 17 00:00:00 2001 From: Katja Hellgren <96579188+KatHellg@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:10:11 +0100 Subject: [PATCH] Feature/SK-1202 | Added log-in functionality (#759) --- fedn/cli/__init__.py | 1 + fedn/cli/combiner_cmd.py | 3 -- fedn/cli/login_cmd.py | 61 ++++++++++++++++++++++++++++++++++++++++ fedn/utils/dist.py | 2 +- 4 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 fedn/cli/login_cmd.py diff --git a/fedn/cli/__init__.py b/fedn/cli/__init__.py index 7028dbfa6..be680eb23 100644 --- a/fedn/cli/__init__.py +++ b/fedn/cli/__init__.py @@ -11,3 +11,4 @@ from .status_cmd import status_cmd # noqa: F401 from .validation_cmd import validation_cmd # noqa: F401 from .controller_cmd import controller_cmd # noqa: F401 +from .login_cmd import login_cmd # noqa: F401 diff --git a/fedn/cli/combiner_cmd.py b/fedn/cli/combiner_cmd.py index dd45fbd1b..0a6403587 100644 --- a/fedn/cli/combiner_cmd.py +++ b/fedn/cli/combiner_cmd.py @@ -88,7 +88,6 @@ def list_combiners(ctx, protocol: str, host: str, port: str, token: str = None, if _token: headers["Authorization"] = _token - try: response = requests.get(url, headers=headers) print_response(response, "combiners", None) @@ -112,7 +111,6 @@ def get_combiner(ctx, protocol: str, host: str, port: str, token: str = None, id url = get_api_url(protocol=protocol, host=host, port=port, endpoint="combiners") headers = {} - _token = get_token(token) if _token: @@ -121,7 +119,6 @@ def get_combiner(ctx, protocol: str, host: str, port: str, token: str = None, id if id: url = f"{url}{id}" - try: response = requests.get(url, headers=headers) print_response(response, "combiner", id) diff --git a/fedn/cli/login_cmd.py b/fedn/cli/login_cmd.py new file mode 100644 index 000000000..d2ce8ac90 --- /dev/null +++ b/fedn/cli/login_cmd.py @@ -0,0 +1,61 @@ +import os +from getpass import getpass + +import click +import requests +import yaml + +from .main import main + +# Replace this with the platform's actual login endpoint +home_dir = os.path.expanduser("~") + + +@main.group("studio") +@click.pass_context +def login_cmd(ctx): + """:param ctx:""" + pass + + +@login_cmd.command("login") +@click.option("-p", "--protocol", required=False, default="https", help="Communication protocol") +@click.option("-H", "--host", required=False, default="fedn.scaleoutsystems.com", help="Hostname of controller (api)") +@click.pass_context +def login_cmd(ctx, protocol: str, host: str): + """Logging into FEDn Studio""" + # Step 1: Display welcome message + click.secho("Welcome to Scaleout FEDn!", fg="green") + + url = f"{protocol}://{host}/api/token/" + + # Step 3: Prompt for username and password + username = input("Please enter your username: ") + password = getpass("Please enter your password: ") + + # Call the authentication API + try: + response = requests.post(url, json={"username": username, "password": password}, headers={"Content-Type": "application/json"}) + response.raise_for_status() # Raise an error for HTTP codes 4xx/5xx + except requests.exceptions.RequestException as e: + click.secho("Error connecting to the platform. Please try again.", fg="red") + click.secho(str(e), fg="red") + return + + # Handle the response + if response.status_code == 200: + data = response.json() + if data.get("access"): + click.secho("Login successful!", fg="green") + context_path = os.path.join(home_dir, ".fedn") + if not os.path.exists(context_path): + os.makedirs(context_path) + try: + with open(f"{context_path}/context.yaml", "w") as yaml_file: + yaml.dump(data, yaml_file, default_flow_style=False) # Add access and refresh tokens to context yaml file + except Exception as e: + print(f"Error: Failed to write to YAML file. Details: {e}") + else: + click.secho("Login failed. Please check your credentials.", fg="red") + else: + click.secho(f"Unexpected error: {response.text}", fg="red") diff --git a/fedn/utils/dist.py b/fedn/utils/dist.py index e5fa7192b..82812dfc3 100644 --- a/fedn/utils/dist.py +++ b/fedn/utils/dist.py @@ -3,7 +3,7 @@ import fedn -def get_version(pacakge): +def get_version(package): # Dynamically get the version of the package try: version = importlib.metadata.version("fedn")