Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/SK-1229 | Project resource for CLI extension #784

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions fedn/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from .client_cmd import client_cmd # noqa: F401
from .combiner_cmd import combiner_cmd # noqa: F401
from .config_cmd import config_cmd # noqa: F401
from .controller_cmd import controller_cmd # noqa: F401
from .hooks_cmd import hooks_cmd # noqa: F401
from .login_cmd import login_cmd # noqa: F401
from .main import main # noqa: F401
from .model_cmd import model_cmd # noqa: F401
from .package_cmd import package_cmd # noqa: F401
from .project_cmd import project_cmd # noqa: F401
from .round_cmd import round_cmd # noqa: F401
from .run_cmd import run_cmd # noqa: F401
from .session_cmd import session_cmd # noqa: F401
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
14 changes: 5 additions & 9 deletions fedn/cli/client_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ def list_clients(ctx, protocol: str, host: str, port: str, token: str = None, n_
if n_max:
headers["X-Limit"] = n_max

_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token


try:
response = requests.get(url, headers=headers)
print_response(response, "clients", None)
except requests.exceptions.ConnectionError:
click.echo(f"Error: Could not connect to {url}")


@click.option("-p", "--protocol", required=False, default=CONTROLLER_DEFAULTS["protocol"], help="Communication protocol of controller (api)")
@click.option("-H", "--host", required=False, default=CONTROLLER_DEFAULTS["host"], help="Hostname of controller (api)")
@click.option("-P", "--port", required=False, default=CONTROLLER_DEFAULTS["port"], help="Port of controller (api)")
Expand All @@ -80,19 +80,15 @@ def get_client(ctx, protocol: str, host: str, port: str, token: str = None, id:
- result: client with given id

"""
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="clients")
_url = get_api_url(protocol=protocol, host=host, port=port, endpoint="clients")
url = f"{_url}{id}"
headers = {}


_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token

if id:
url = f"{url}{id}"


try:
response = requests.get(url, headers=headers)
print_response(response, "client", id)
Expand Down
10 changes: 4 additions & 6 deletions fedn/cli/combiner_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def list_combiners(ctx, protocol: str, host: str, port: str, token: str = None,
if n_max:
headers["X-Limit"] = n_max

_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token
Expand All @@ -108,17 +108,15 @@ def get_combiner(ctx, protocol: str, host: str, port: str, token: str = None, id
- result: combiner with given id

"""
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="combiners")
_url = get_api_url(protocol=protocol, host=host, port=port, endpoint="combiners")
url = f"{_url}{id}"
headers = {}

_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token

if id:
url = f"{url}{id}"

try:
response = requests.get(url, headers=headers)
print_response(response, "combiner", id)
Expand Down
68 changes: 53 additions & 15 deletions fedn/cli/login_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import yaml

from .main import main
from .shared import STUDIO_DEFAULTS, get_api_url, get_token

# Replace this with the platform's actual login endpoint
home_dir = os.path.expanduser("~")
Expand All @@ -19,8 +20,8 @@ def login_cmd(ctx):


@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.option("-p", "--protocol", required=False, default=STUDIO_DEFAULTS["protocol"], help="Communication protocol of studio (api)")
@click.option("-H", "--host", required=False, default=STUDIO_DEFAULTS["host"], help="Hostname of studio (api)")
@click.pass_context
def login_cmd(ctx, protocol: str, host: str):
"""Logging into FEDn Studio"""
Expand All @@ -44,18 +45,55 @@ def login_cmd(ctx, protocol: str, host: str):

# 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")
context_data = get_context(response, protocol, host)

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vad händer om det redan finns en context.yaml med innehåll?

yaml.dump(context_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(f"Unexpected error: {response.text}", fg="red")


def get_context(response, protocol, host):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add typing

user_token_data = response.json()
if user_token_data.get("access"):
studio_api = True
url_projects = get_api_url(protocol=protocol, host=host, port=None, endpoint="projects", usr_api=studio_api)
headers_projects = {}
user_access_token = user_token_data.get("access")
_token = get_token(user_access_token, True)
if _token:
headers_projects["Authorization"] = _token

try:
response_projects = requests.get(url_projects, headers=headers_projects)
Wrede marked this conversation as resolved.
Show resolved Hide resolved
projects_response_json = response_projects.json()
except requests.exceptions.ConnectionError:
click.echo(f"Error: Could not connect to {url_projects}")

slug = projects_response_json[0].get("slug")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hårdkodat att alltid ta första projektet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja, i alla fall när man loggar in så aktiveras senast skapade projektet som default. Kan ju ändra så att det senast aktiverade projektet behålls istället, men uppstår fall som jag inte på rak arm vet hur jag ska hantera. T.ex. om man loggar in på annat konto på samma dator typ. Skulle typ kunna lägga in owner # i context-filen också?

headers_projects["X-Project-Slug"] = slug
url_project_token = get_api_url(protocol=protocol, host=host, port=None, endpoint="admin-token", usr_api=studio_api)

try:
response_project_tokens = requests.get(url_project_token, headers=headers_projects)
project_tokens = response_project_tokens.json()
except requests.exceptions.ConnectionError:
click.echo(f"Error: Could not connect to {url_project_token}")

controller_url = f"{protocol}://{host}/{slug}-fedn-reducer"
Wrede marked this conversation as resolved.
Show resolved Hide resolved
context_data = {
"User tokens": user_token_data,
"Active project tokens": project_tokens,
"Active project slug": slug,
"Active project url": controller_url,
}
click.secho("Login successful!", fg="green")
return context_data
else:
click.secho("Login failed. Please check your credentials.", fg="red")
12 changes: 3 additions & 9 deletions fedn/cli/model_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
@main.group("model")
@click.pass_context
def model_cmd(ctx):
""":param ctx:
"""
""":param ctx:"""
pass


Expand All @@ -30,21 +29,19 @@ def list_models(ctx, protocol: str, host: str, port: str, token: str = None, ses
"""
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="models")


headers = {}

if n_max:
headers["X-Limit"] = n_max

_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token

if session_id:
url = f"{url}?session_id={session_id}"


try:
response = requests.get(url, headers=headers)
print_response(response, "models", None)
Expand All @@ -67,19 +64,16 @@ def get_model(ctx, protocol: str, host: str, port: str, token: str = None, id: s
"""
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="models")


headers = {}


_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token

if id:
url = f"{url}{id}"


try:
response = requests.get(url, headers=headers)
print_response(response, "model", id)
Expand Down
16 changes: 5 additions & 11 deletions fedn/cli/package_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
@main.group("package")
@click.pass_context
def package_cmd(ctx):
""":param ctx:
"""
""":param ctx:"""
pass


Expand Down Expand Up @@ -61,12 +60,11 @@ def list_packages(ctx, protocol: str, host: str, port: str, token: str = None, n
if n_max:
headers["X-Limit"] = n_max

_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token


try:
response = requests.get(url, headers=headers)
print_response(response, "packages", None)
Expand All @@ -87,19 +85,15 @@ def get_package(ctx, protocol: str, host: str, port: str, token: str = None, id:
- result: package with given id

"""
url = get_api_url(protocol=protocol, host=host, port=port, endpoint="packages")
_url = get_api_url(protocol=protocol, host=host, port=port, endpoint="packages")
url = f"{_url}{id}"
headers = {}


_token = get_token(token)
_token = get_token(token, False)

if _token:
headers["Authorization"] = _token

if id:
url = f"{url}{id}"


try:
response = requests.get(url, headers=headers)
print_response(response, "package", id)
Expand Down
Loading
Loading