Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
fae2ce0
refactor: move functionality from main file
danielboloc Jan 27, 2026
deb62c3
test: update imports
danielboloc Jan 27, 2026
300868a
docs: updage changes and version
danielboloc Jan 28, 2026
69d39b7
refactor: jobs
danielboloc Jan 28, 2026
44517f6
refactor: update missing code
danielboloc Jan 28, 2026
20d6c29
refactor: link
danielboloc Jan 28, 2026
8b5c571
ci: add run and abort
danielboloc Jan 29, 2026
e05a81e
ci: adds job resume
danielboloc Jan 29, 2026
0030ddf
ci: adds configure tests
danielboloc Jan 29, 2026
4fa5d87
ci: adds configure tests + workdir --delete
danielboloc Jan 29, 2026
e24b504
ci: remove typo duplicate
danielboloc Jan 29, 2026
3b8d3a6
ci: update resume option
danielboloc Jan 29, 2026
76324f7
ci: refactor to not have hardcoded jobs
danielboloc Jan 29, 2026
0dc66aa
ci: update job_workdir, job_resume to run before delete_workdir
danielboloc Jan 29, 2026
f95f64b
ci: add job id dependency
danielboloc Jan 29, 2026
960586f
refactor: remove unsed files
danielboloc Feb 3, 2026
3324304
ci: change dependency for workdir --delete
danielboloc Feb 3, 2026
bc6b34a
ci: update workdir --delete
danielboloc Feb 3, 2026
a5f9e77
ci: update resume
danielboloc Feb 3, 2026
daf0f16
ci: update resume
danielboloc Feb 3, 2026
6481003
update wait completion
danielboloc Feb 3, 2026
65ad173
update resume job id
danielboloc Feb 3, 2026
14c5e9d
ci: update resume output
danielboloc Feb 3, 2026
7d5745f
review: add debug to all commands
danielboloc Feb 11, 2026
14ce493
review: resolve Leila's conversations
danielboloc Feb 11, 2026
c24d2bb
review: add python versions 3.9, 3.11, 3.15 for all the tests
danielboloc Feb 11, 2026
70b2a2f
review: change latest supported python versions 3.13 for all the tests
danielboloc Feb 11, 2026
f5d2363
review: use exit 1
danielboloc Feb 11, 2026
379bcd7
review: moved imports at the top
danielboloc Feb 11, 2026
d85f68b
Update CHANGELOG.md
danielboloc Feb 11, 2026
dbe0389
Update cloudos_cli/_version.py
danielboloc Feb 11, 2026
150fd44
revert: use python 3.9 only for now in platform tests
danielboloc Feb 11, 2026
c6c4ad8
refactor: add missing variable
danielboloc Feb 11, 2026
7869693
ci: update versions
danielboloc Feb 12, 2026
dac4d2c
refactor: add constants in own file
danielboloc Feb 12, 2026
f099f1a
ci: filter by default queue
danielboloc Feb 12, 2026
7b92ab6
ci: fix intermittent failure
danielboloc Feb 12, 2026
b7ac096
refactor: remove unused interpolations
danielboloc Feb 12, 2026
0b310f2
style: remove whitespaces
danielboloc Feb 12, 2026
58ff636
style: remove whitespaces
danielboloc Feb 12, 2026
2ec054c
ci: temporarily disable filter-queue
danielboloc Feb 12, 2026
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
258 changes: 217 additions & 41 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## lifebit-ai/cloudos-cli: changelog

## v2.79.0 (2026-01-28)

### Patch

- Refactor `__main__.py` to move commands into separate files for better organization
- Improve CI/CD pipeline to test additional functionalities and use dynamically generated job IDs from tests instead of predefined values

## v2.78.0 (2026-01-13)

### Feat
Expand Down
4,371 changes: 36 additions & 4,335 deletions cloudos_cli/__main__.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cloudos_cli/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.78.0'
__version__ = '2.79.0'
1 change: 1 addition & 0 deletions cloudos_cli/bash/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Bash job-related CLI commands."""
566 changes: 566 additions & 0 deletions cloudos_cli/bash/cli.py

Large diffs are not rendered by default.

150 changes: 72 additions & 78 deletions cloudos_cli/clos.py

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions cloudos_cli/configure/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""CLI commands for CloudOS configuration management."""

import rich_click as click
from cloudos_cli.configure.configure import ConfigurationProfile
from cloudos_cli.logging.logger import update_command_context_from_click
from cloudos_cli.utils.cli_helpers import pass_debug_to_subcommands


# Create the configure group
@click.group(cls=pass_debug_to_subcommands(), invoke_without_command=True)
@click.option('--profile', help='Profile to use from the config file', default='default')
@click.option('--make-default',
is_flag=True,
help='Make the profile the default one.')
@click.pass_context
def configure(ctx, profile, make_default):
"""CloudOS configuration."""
print(configure.__doc__ + '\n')
update_command_context_from_click(ctx)
profile = profile or ctx.obj['profile']
config_manager = ConfigurationProfile()

if ctx.invoked_subcommand is None and profile == "default" and not make_default:
config_manager.create_profile_from_input(profile_name="default")

if profile != "default" and not make_default:
config_manager.create_profile_from_input(profile_name=profile)
if make_default:
config_manager.make_default_profile(profile_name=profile)


@configure.command('list-profiles')
def list_profiles():
"""List all available configuration profiles."""
config_manager = ConfigurationProfile()
config_manager.list_profiles()


@configure.command('remove-profile')
@click.option('--profile',
help='Name of the profile. Not using this option will lead to profile named "deafults" being generated',
required=True)
@click.pass_context
def remove_profile(ctx, profile):
"""Remove a configuration profile."""
update_command_context_from_click(ctx)
profile = profile or ctx.obj['profile']
config_manager = ConfigurationProfile()
config_manager.remove_profile(profile)
32 changes: 14 additions & 18 deletions cloudos_cli/configure/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import configparser
import click
from cloudos_cli.logging.logger import update_command_context_from_click
from cloudos_cli.constants import CLOUDOS_URL, INIT_PROFILE


class ConfigurationProfile:
Expand Down Expand Up @@ -257,7 +258,7 @@ def create_profile_from_input(self, profile_name):
config[profile_name]['default'] = str(default_profile)
if session_id is not None:
config[profile_name]['session_id'] = session_id


with open(self.config_file, 'w') as conf_file:
config.write(conf_file)
Expand Down Expand Up @@ -361,10 +362,10 @@ def make_default_profile(self, profile_name):

def load_profile(self, profile_name):
"""Load a profile from the config and credentials files dynamically.

This method now returns ALL parameters from the profile, not just predefined ones.
This makes it extensible - you can add new parameters to profiles without modifying this method.

Parameters:
----------
profile_name : str
Expand All @@ -374,12 +375,12 @@ def load_profile(self, profile_name):
dict
A dictionary containing all profile parameters. Returns all keys from both
credentials and config files for the specified profile.

Examples
--------
# If you add accelerate_saving_results to your profile config:
config[profile_name]['accelerate_saving_results'] = 'true'

# It will automatically be included in the returned dictionary:
profile_data = load_profile('myprofile')
# profile_data will contain 'accelerate_saving_results': 'true'
Expand All @@ -399,19 +400,19 @@ def load_profile(self, profile_name):

# Dynamically load all parameters from the profile
profile_data = {}

# Load all items from credentials file
if credentials.has_section(profile_name):
for key, value in credentials[profile_name].items():
profile_data[key] = value

# Load all items from config file
if config.has_section(profile_name):
for key, value in config[profile_name].items():
# Skip the 'default' flag as it's not a user parameter
if key != 'default':
profile_data[key] = value

return profile_data

def check_if_profile_exists(self, profile_name):
Expand Down Expand Up @@ -480,7 +481,7 @@ def get_param_value(ctx, param_value, param_name, default_value, required=False,
def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default, profile, required_dict, **cli_params):
"""
Load profile data and validate required parameters dynamically.

This method now accepts any parameters via **cli_params, making it extensible.
You can add new parameters to profiles (like accelerate_saving_results) without
modifying this method.
Expand All @@ -500,7 +501,7 @@ def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default,
**cli_params : dict
All CLI parameters passed as keyword arguments. Any parameter can be passed here
and will be resolved from the profile if available.

Examples: apikey, cloudos_url, workspace_id, project_name, workflow_name,
execution_platform, repository_platform, session_id, procurement_id,
accelerate_saving_results, etc.
Expand All @@ -509,7 +510,7 @@ def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default,
-------
dict
A dictionary containing all loaded and validated parameters.

Examples
--------
# Add a new parameter to profile without changing this method:
Expand All @@ -524,7 +525,7 @@ def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default,
if profile != init_profile:
# Load profile data
profile_data = self.load_profile(profile_name=profile)

# Dynamically process all parameters passed in cli_params
for param_name, cli_value in cli_params.items():
profile_value = profile_data.get(param_name, "")
Expand All @@ -539,7 +540,7 @@ def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default,
required=is_required,
missing_required_params=missing
)

# Convert empty strings to None for optional parameters
# This prevents issues with functions that expect None for unset values
if resolved_value == "" and not is_required:
Expand Down Expand Up @@ -592,11 +593,6 @@ def load_profile_and_validate_data(self, ctx, init_profile, cloudos_url_default,
return resolved_params


# Not part of the class, but related to configuration
# Global constants for CloudOS CLI
CLOUDOS_URL = 'https://cloudos.lifebit.ai'
INIT_PROFILE = 'initialisingProfile'

# Define all standard configuration keys with their default empty values
# This is the single source of truth for configuration fields
STANDARD_CONFIG_KEYS = {
Expand Down
24 changes: 24 additions & 0 deletions cloudos_cli/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Global constants for CloudOS CLI."""

# Job status constants
JOB_COMPLETED = 'completed'
JOB_FAILED = 'failed'
JOB_ABORTED = 'aborted'

# Nextflow version constants
AWS_NEXTFLOW_VERSIONS = ['22.10.8', '24.04.4']
AZURE_NEXTFLOW_VERSIONS = ['22.11.1-edge']
HPC_NEXTFLOW_VERSIONS = ['22.10.8']
AWS_NEXTFLOW_LATEST = '24.04.4'
AZURE_NEXTFLOW_LATEST = '22.11.1-edge'
HPC_NEXTFLOW_LATEST = '22.10.8'

# Job abort states
ABORT_JOB_STATES = ['running', 'initializing']

# Request interval for Cromwell
REQUEST_INTERVAL_CROMWELL = 30

# Global constants for CloudOS CLI
CLOUDOS_URL = 'https://cloudos.lifebit.ai'
INIT_PROFILE = 'initialisingProfile'
1 change: 1 addition & 0 deletions cloudos_cli/cromwell/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Cromwell server-related CLI commands."""
Loading