Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion .env-example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
API_BASE_URL=""
API_BASE_URL=""
MLOPS_API=""
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ AUTHORS.TXT
#VSCode stuff..
.vscode/
# Mac OS X stuff...
.DS_Store
.DS_Store

mlruns/
2 changes: 0 additions & 2 deletions cranecloud.egg-info/entry_points.txt

This file was deleted.

1 change: 0 additions & 1 deletion cranecloud.egg-info/top_level.txt

This file was deleted.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "cranecloud"
version = "0.0.5"
version = "0.0.6"
authors = [
{ name="cranecloud", email="allan@cranecloud.io" },
]
Expand Down Expand Up @@ -38,10 +38,10 @@ Homepage = "https://github.com/crane-cloud/cranecloud-cli"
Issues = "https://github.com/crane-cloud/cranecloud-cli/issues"

[project.scripts]
cranecloud = "src.cranecloud:cli"
cranecloud = "cranecloud:cli"

[entry_points]
console_scripts =[
'cranecloud = src.cranecloud:cli',
'cranecloud = cranecloud:cli',
]

5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
setup(
name='cranecloud',
version='0.1.0',
packages=find_packages(),
package_dir={'': 'src'},
packages=find_packages(where='src'),
include_package_data=True,
entry_points={
'console_scripts': [
'cranecloud=src.cranecloud:cli',
'cranecloud=cranecloud:cli',
],
},
)
4 changes: 3 additions & 1 deletion src/config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from src.cranecloud.utils.config import create_config, read_config
from cranecloud.utils.config import create_config, read_config

# Example usage of the config values
config_file = read_config()
try:
API_BASE_URL = config_file['GlobalSettings']['base_url']
MLOPS_API_BASE_URL = config_file['GlobalSettings']['mlops_base_url']
except KeyError:
create_config()
config_file = read_config()
API_BASE_URL = config_file['GlobalSettings'].get('base_url')
API_BASE_URL = config_file['GlobalSettings'].get('mlops_base_url')
try:
CURRENT_PROJECT = config_file['current_project']
except KeyError:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Metadata-Version: 2.4
Name: cranecloud
Version: 0.0.5
Version: 0.0.6
Summary: Cranecloud CLI client
Author-email: cranecloud <allan@cranecloud.io>
Project-URL: Homepage, https://github.com/crane-cloud/cranecloud-cli
Expand All @@ -26,6 +26,7 @@ Provides-Extra: dev
Requires-Dist: twine; extra == "dev"
Requires-Dist: pip-tools; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# Cranecloud CLI Client

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ LICENSE
README.md
pyproject.toml
setup.py
cranecloud.egg-info/PKG-INFO
cranecloud.egg-info/SOURCES.txt
cranecloud.egg-info/dependency_links.txt
cranecloud.egg-info/entry_points.txt
cranecloud.egg-info/requires.txt
cranecloud.egg-info/top_level.txt
src/__init__.py
src/config.py
src/cranecloud/__init__.py
src/cranecloud.egg-info/PKG-INFO
src/cranecloud.egg-info/SOURCES.txt
src/cranecloud.egg-info/dependency_links.txt
src/cranecloud.egg-info/entry_points.txt
src/cranecloud.egg-info/requires.txt
src/cranecloud.egg-info/top_level.txt
src/cranecloud/commands/__init__.py
src/cranecloud/commands/apps.py
src/cranecloud/commands/clusters.py
src/cranecloud/commands/config_management.py
src/cranecloud/commands/ml_ops.py
src/cranecloud/commands/projects.py
src/cranecloud/commands/test_user_management.py
src/cranecloud/commands/user_management.py
src/cranecloud/core/__init__.py
src/cranecloud/core/ml_ops.py
src/cranecloud/utils/__init__.py
src/cranecloud/utils/config.py
2 changes: 2 additions & 0 deletions src/cranecloud.egg-info/entry_points.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[console_scripts]
cranecloud = cranecloud:cli
File renamed without changes.
1 change: 1 addition & 0 deletions src/cranecloud.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cranecloud
17 changes: 10 additions & 7 deletions src/cranecloud/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from src.cranecloud.commands.apps import apps_group
from src.cranecloud.commands.clusters import clusters_group
from cranecloud.commands.apps import apps_group
from cranecloud.commands.clusters import clusters_group
import click
from os.path import join, dirname
from dotenv import load_dotenv
from src.cranecloud.utils.config import create_config
from src.cranecloud.commands.user_management import user_group
from src.cranecloud.commands.projects import projects_group
from src.cranecloud.commands.config_management import config_group
from cranecloud.utils.config import create_config
from cranecloud.commands.user_management import user_group
from cranecloud.commands.projects import projects_group
from cranecloud.commands.config_management import config_group
from cranecloud.commands.ml_ops import mlops_group
from cranecloud.core.ml_ops import MLOpsClient


dotenv_path = join(dirname(__file__), '.env')
Expand All @@ -19,8 +21,9 @@ def cli():


cli = click.CommandCollection(
sources=[user_group, projects_group, apps_group, clusters_group, config_group])
sources=[user_group, projects_group, apps_group, clusters_group, config_group, mlops_group])

__all__ = ["MLOpsClient"]

def create_initial_config():
create_config()
6 changes: 3 additions & 3 deletions src/cranecloud/commands/apps.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import json
import click
import requests
from src.config import API_BASE_URL
from config import API_BASE_URL
from tabulate import tabulate
from src.config import CURRENT_PROJECT
from src.cranecloud.utils import get_token
from config import CURRENT_PROJECT
from cranecloud.utils import get_token


@click.group()
Expand Down
6 changes: 3 additions & 3 deletions src/cranecloud/commands/clusters.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import click
import requests
from src.cranecloud.utils.config import write_config
from src.config import API_BASE_URL, CURRENT_CLUSTER
from cranecloud.utils.config import write_config
from config import API_BASE_URL, CURRENT_CLUSTER
from tabulate import tabulate

from src.cranecloud.utils import get_token
from cranecloud.utils import get_token


@click.group()
Expand Down
7 changes: 4 additions & 3 deletions src/cranecloud/commands/config_management.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import click
from tabulate import SEPARATING_LINE, tabulate
from src.cranecloud.commands.projects import set_use_project
from src.config import CURRENT_CLUSTER, CURRENT_PROJECT, CURRENT_USER
from src.cranecloud.utils.config import read_config
from cranecloud.commands.projects import set_use_project
from config import CURRENT_CLUSTER, CURRENT_PROJECT, CURRENT_USER
from cranecloud.utils.config import read_config


@click.group()
Expand Down Expand Up @@ -34,6 +34,7 @@ def get_config():

config_data = {
'base_url': global_settings.get('base_url'),
'mlops_url': global_settings.get('mlops_base_url'),
'current_project': current_project,
'current_user': current_user,
'current_cluster': current_cluster,
Expand Down
43 changes: 43 additions & 0 deletions src/cranecloud/commands/ml_ops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import click
import requests
import subprocess
import json

from config import MLOPS_API_BASE_URL
from cranecloud.utils import get_token
from cranecloud.core.ml_ops import MLOpsClient


mlops_client = MLOpsClient()


@click.group()
def mlops_group():
pass


@mlops_group.group(name='mlops')
def mlops():
"""
MLOps management commands.
"""
pass


@mlops.command('create-experiment', help='Create an MLOps experiment.')
@click.option('--user-id', required=True, help='User ID')
@click.option('--app-alias', required=True, help='App alias')
def create_experiment(user_id, app_alias):
"""Create a new experiment ."""
try:
# Use the core client to do the actual work
tracking_uri, experiment_id = mlops_client.create_experiment(
user_id, app_alias, verbose=True)

click.echo(f"Experiment created with ID: {experiment_id}")
return tracking_uri, experiment_id
except requests.exceptions.RequestException as e:
error_data = {"error": str(e)}
if e.response is not None:
error_data["details"] = e.response.text
click.echo(json.dumps(error_data))
6 changes: 3 additions & 3 deletions src/cranecloud/commands/projects.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import click
import requests
from tabulate import tabulate
from src.config import (API_BASE_URL, CURRENT_PROJECT,
from config import (API_BASE_URL, CURRENT_PROJECT,
CURRENT_CLUSTER, CURRENT_USER)
from src.cranecloud.utils.config import write_config
from cranecloud.utils.config import write_config

from src.cranecloud.utils import get_token
from cranecloud.utils import get_token


@click.group()
Expand Down
6 changes: 3 additions & 3 deletions src/cranecloud/commands/user_management.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import click
import requests
from src.config import API_BASE_URL
from config import API_BASE_URL
import keyring
from tabulate import tabulate
from src.cranecloud.utils import get_token
from src.cranecloud.utils.config import write_config
from cranecloud.utils import get_token
from cranecloud.utils.config import write_config


@click.group()
Expand Down
Empty file added src/cranecloud/core/__init__.py
Empty file.
43 changes: 43 additions & 0 deletions src/cranecloud/core/ml_ops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import click
import requests
import subprocess
import logging
from config import MLOPS_API_BASE_URL
from cranecloud.utils import get_token

class MLOpsClient:
def __init__(self):
pass

def create_experiment(self, user_id, app_alias, verbose=False):
"""Create a new experiment."""
token = get_token()
endpoint = f"{MLOPS_API_BASE_URL}/experiments"
params = {
"user_id": user_id,
"app_alias": app_alias
}

headers = {
"accept": "application/json"
}

if verbose: print(f"Creating experiment for user '{user_id}' on app '{app_alias}'...")
try:
response = requests.post(endpoint, params=params, headers=headers)
response.raise_for_status()
result = response.json()

tracking_uri = result.get("tracking_uri")
experiment_id = result.get("experiment_id")

if verbose: print("✅ Experiment created successfully!")
return tracking_uri, experiment_id
except requests.exceptions.RequestException as e:
if verbose:
print(f"Error: {e}")
if e.response is not None:
print(e.response.text)
raise


2 changes: 2 additions & 0 deletions src/cranecloud/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ def get_base_dir():

def create_config():
default_base_url = os.getenv('API_BASE_URL', "https://api.cranecloud.io")
default_mlops_base_url = os.getenv('MLOPS_API_BASE_URL', "https://staging-mlops.cranecloud.io")
write_config('base_url', default_base_url)
write_config('mlops_base_url', default_mlops_base_url)


def read_config():
Expand Down