Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8fbd607
chore: pin manifest-validation branch of sdk-v2
guptadev21 Sep 29, 2025
4581356
refactor: remove managed service functionality and related imports
guptadev21 Sep 29, 2025
a1e8c42
refactor: removed v2 client and migrate helper functions to utils
guptadev21 Sep 29, 2025
6c6445f
refactor: update client imports and adjust project listing logic
guptadev21 Sep 29, 2025
747c1b4
refactor: update disk operations to use new utility functions and imp…
guptadev21 Sep 29, 2025
6a301bc
refactor: migrate to new SDK client and update deployment handling logic
guptadev21 Sep 29, 2025
229bd5e
refactor: update package handling to use new SDK client methods and i…
guptadev21 Sep 29, 2025
b908952
refactor: update client imports and method calls to align with new SD…
guptadev21 Sep 29, 2025
828ce44
refactor: update organization update calls to use 'body' parameter an…
guptadev21 Sep 29, 2025
d9930e2
refactor: update network and secret handling to use new SDK client me…
guptadev21 Sep 30, 2025
f71c93f
refactor: refactor code with sdk v2
guptadev21 Sep 30, 2025
5ab4d0a
chore: remove unnecessary blank line in CHANGELOG.md
guptadev21 Oct 8, 2025
6f703fa
refactor: update rapyuta-io-sdk-v2 dependency to use specific git rev…
guptadev21 Oct 9, 2025
adaf7fa
refactor: update device inspection logic to use dictionary conversion…
guptadev21 Oct 9, 2025
8a0c8c8
fix: update AppImage paths and versions for consistency in build script
guptadev21 Oct 9, 2025
c3fb231
chore: remove unused import of Device client in inspect.py
guptadev21 Oct 9, 2025
c12294a
fix: update rio.desktop file references to match Python version 3.13.7
guptadev21 Oct 9, 2025
abbb7bf
fix: made checks for project name
guptadev21 Oct 10, 2025
9cd8c6e
fix: update AppRun path for Python 3.13 in build script
guptadev21 Oct 13, 2025
0f89c23
fix: improve project and user group listing by implementing paginatio…
guptadev21 Oct 14, 2025
4962c5d
refactor: update client method names for consistency and clarity acro…
guptadev21 Oct 14, 2025
f697e05
fix: add scripts directory to .gitignore to prevent tracking of scrip…
guptadev21 Oct 14, 2025
abaa66f
chore: uv sync upgrade
guptadev21 Oct 14, 2025
dd7157d
fix: update model_dump calls to exclude_none and by_alias for improve…
guptadev21 Oct 27, 2025
08deb75
fix: enhance deployment log streaming and improve project status checks
guptadev21 Oct 29, 2025
8f48ccf
chore: update
guptadev21 Oct 30, 2025
ed9db5b
fix: update user group retrieval to use organizationGUID directly
guptadev21 Oct 30, 2025
56e9835
chore: update
guptadev21 Oct 30, 2025
2db509a
fix: update rapyuta-io-sdk-v2 source reference to latest commit
guptadev21 Oct 31, 2025
832bb61
chore: update
guptadev21 Oct 31, 2025
3e2a8bf
chore: update
guptadev21 Oct 31, 2025
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ Thumbs.db
.vscode/

.egg-info/
ignore*
ignore*
scripts/*
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# [9.5.0](https://github.com/rapyuta-robotics/rapyuta-io-cli/compare/v9.4.0...v9.5.0) (2024-12-11)


### Features

* **apply:** add support for ansible filters in Jinja2 ([#394](https://github.com/rapyuta-robotics/rapyuta-io-cli/issues/394)) ([d590490](https://github.com/rapyuta-robotics/rapyuta-io-cli/commit/d59049091011d88ec715f302701e425218ba4d9c)), closes [AB#39151](https://github.com/AB/issues/39151)
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ dependencies = [
"waiting>=1.4.1",
"yaspin==2.5.0",
"ansible-core>=2.13.13",
"rapyuta-io-sdk-v2@git+https://github.com/rapyuta-robotics/rapyuta-io-sdk-v2.git@feat/manifest-validation",
]

[tool.uv]
Expand All @@ -65,6 +66,9 @@ dev-dependencies = [
"furo",
]

[tool.uv.sources]
rapyuta-io-sdk-v2 = { git = "https://github.com/rapyuta-robotics/rapyuta-io-sdk-v2.git", rev = "feat/manifest-validation" }

[project.scripts]
rio = "riocli.bootstrap:safe_cli"

Expand Down
2 changes: 0 additions & 2 deletions riocli/apply/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from riocli.deployment.model import Deployment
from riocli.device.model import Device
from riocli.disk.model import Disk
from riocli.managedservice.model import ManagedService
from riocli.model import Model
from riocli.network.model import Network
from riocli.organization.model import Organization
Expand All @@ -44,7 +43,6 @@
"deployment": Deployment,
"device": Device,
"disk": Disk,
"managedservice": ManagedService,
"network": Network,
"organization": Organization,
"package": Package,
Expand Down
5 changes: 2 additions & 3 deletions riocli/auth/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,13 @@ def login(
config.data["auth_token"] = get_token(email, password)

# Save if the file does not already exist
if not config.exists or not interactive:
config.save()
else:
if config.exists and interactive:
click.confirm(
f"{Symbols.WARNING} Config already exists. Do you want to override"
" the existing config?",
abort=True,
)
config.save()

if not interactive:
# When just the email and password are provided
Expand Down
17 changes: 10 additions & 7 deletions riocli/auth/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
from riocli.constants import Colors, Symbols
from riocli.utils.selector import show_selection
from riocli.utils.spinner import with_spinner
from riocli.v2client import Client as v2Client
from riocli.v2client.util import handle_server_errors
from rapyuta_io_sdk_v2 import Client as v2Client
from rapyuta_io_sdk_v2.utils import handle_server_errors, walk_pages
from riocli.exceptions import ProjectNotFound, OrganizationNotFound

TOKEN_LEVELS = {0: AuthTokenLevel.LOW, 1: AuthTokenLevel.MED, 2: AuthTokenLevel.HIGH}
Expand Down Expand Up @@ -108,7 +108,10 @@ def select_project(
else find_project_guid(client, project, organization=organization)
)

projects = client.list_projects(organization_guid=organization)
# Fetch all projects in the organization using walk_pages
projects = []
for page in walk_pages(client.list_projects, organizations=[organization], limit=100):
projects.extend(page)
if len(projects) == 0:
config.data["project_id"] = ""
config.data["project_name"] = ""
Expand Down Expand Up @@ -231,12 +234,12 @@ def find_project_guid(
client: v2Client, name: str, organization: str | None = None
) -> str:
projects = client.list_projects(
query={"name": name},
organization_guid=organization,
name=name,
organizations=[organization],
)

if projects and projects[0].metadata.name == name:
return projects[0].metadata.guid
if projects.items and projects.items[0].metadata.name == name:
return projects.items[0].metadata.guid

raise ProjectNotFound()

Expand Down
2 changes: 0 additions & 2 deletions riocli/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from riocli.device import device
from riocli.disk import disk
from riocli.hwil import hwildevice
from riocli.managedservice import managedservice
from riocli.network import network
from riocli.oauth2 import oauth2
from riocli.organization import organization
Expand Down Expand Up @@ -159,7 +158,6 @@ def update(silent: bool) -> None:
cli.add_command(disk)
cli.add_command(shell)
cli.add_command(deprecated_repl)
cli.add_command(managedservice)
cli.add_command(template)
cli.add_command(organization)
cli.add_command(vpn)
Expand Down
9 changes: 5 additions & 4 deletions riocli/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

from click import get_app_dir
from rapyuta_io import Client
from rapyuta_io_sdk_v2 import Client as v2Client
from rapyuta_io_sdk_v2 import Configuration as v2Config

from riocli.exceptions import (
LoggedOut,
Expand All @@ -29,7 +31,6 @@
HwilLoggedOut,
)
from riocli.hwilclient import Client as HwilClient
from riocli.v2client import Client as v2Client


class Configuration:
Expand Down Expand Up @@ -105,18 +106,18 @@ def new_v2_client(self: Configuration, with_project: bool = True) -> v2Client:
if "auth_token" not in self.data:
raise LoggedOut

if "environment" in self.data:
environment = self.data.get("environment", "ga")
if environment:
os.environ["RIO_CONFIG"] = self.filepath

token = self.data.get("auth_token", None)
project = self.data.get("project_id", None)
if with_project and project is None:
raise NoProjectSelected

if not with_project:
project = None

return v2Client(self, auth_token=token, project=project)
return v2Client(config=v2Config().from_file(self.filepath))

def new_hwil_client(self: Configuration) -> HwilClient:
if "hwil_auth_token" not in self.data:
Expand Down
7 changes: 5 additions & 2 deletions riocli/configtree/export_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ def export_keys(

try:
client = new_v2_client(with_project=(not with_org))
tree = client.get_config_tree(
tree_name=tree_name, rev_id=rev_id, include_data=True
tree = client.get_configtree(
name=tree_name,
revision=rev_id,
include_data=True,
with_project=(not with_org),
)
if not tree.get("head"):
raise Exception("Config tree does not have keys in the revision")
Expand Down
2 changes: 1 addition & 1 deletion riocli/configtree/import_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def import_keys(
},
}

client.set_revision_config_tree(tree_name, payload)
client.set_configtree_revision(name=tree_name, configtree=payload)
spinner.text = click.style(
"Config tree HEAD updated successfully.", fg=Colors.CYAN
)
Expand Down
2 changes: 1 addition & 1 deletion riocli/configtree/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def merge_revisions(
},
}

client.set_revision_config_tree(base_tree_name, payload)
client.set_configtree_revision(name=base_tree_name, configtree=payload)
spinner.text = click.style("Config tree merged successfully.", fg=Colors.CYAN)
spinner.green.ok(Symbols.SUCCESS)
except Exception as e:
Expand Down
49 changes: 22 additions & 27 deletions riocli/configtree/revision.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from riocli.config import get_config_from_context, new_v2_client
from riocli.config.config import Configuration
from riocli.configtree.util import (
MILESTONE_LABEL_KEY,
display_config_tree_keys,
get_revision_from_state,
save_revision,
Expand All @@ -34,7 +33,7 @@
from riocli.constants.symbols import Symbols
from riocli.utils.spinner import with_spinner
from riocli.utils.state import StateFile
from riocli.v2client import Client
from rapyuta_io_sdk_v2 import Client
from riocli.utils import AliasedGroup


Expand Down Expand Up @@ -76,9 +75,7 @@ def __init__(
self._rev_id = rev.rev_id
msg = f"{Symbols.INFO} Re-using revision {self._rev_id}."
else:
self._rev = self._client.initialize_config_tree_revision(
tree_name=self._tree_name
)
self._rev = self._client.create_revision(name=self._tree_name)
self._rev_id = self._rev.metadata.guid
msg = f"{Symbols.SUCCESS} Revision {self._rev_id} created successfully."
save_revision(
Expand Down Expand Up @@ -119,13 +116,20 @@ def store(
self._data[key] = data

def store_file(self: Revision, key: str, file_path: str) -> None:
self._client.store_file_in_revision(
tree_name=self._tree_name, rev_id=self._rev_id, key=key, file_path=file_path
with open(file_path, "rb") as f:
file_hash = md5()
chunk = f.read(8192)
while chunk:
file_hash.update(chunk)
chunk = f.read(8192)
f.seek(0)
self._client.put_key_in_revision(
tree_name=self._tree_name, revision_id=self._rev_id, key=key
)

def delete(self: Revision, key: str) -> None:
self._client.delete_key_in_revision(
tree_name=self._tree_name, rev_id=self._rev_id, key=key
tree_name=self._tree_name, revision_id=self._rev_id, key=key
)

def commit(self: Revision, msg: str | None = None, author: str | None = None) -> None:
Expand All @@ -135,22 +139,11 @@ def commit(self: Revision, msg: str | None = None, author: str | None = None) ->
if author is None:
author = self._get_author()

payload: dict[str, Any] = {
"kind": "ConfigTreeRevision",
"apiVersion": "api.rapyuta.io/v2",
"message": msg,
"author": author,
}

if self._milestone is not None:
payload["metadata"] = {
"labels": {
MILESTONE_LABEL_KEY: self._milestone,
}
}

self._client.commit_config_tree_revision(
tree_name=self._tree_name, rev_id=self._rev_id, payload=payload
self._client.commit_revision(
tree_name=self._tree_name,
revision_id=self._rev_id,
message=msg,
author=author,
)
if not self._explicit:
save_revision(
Expand All @@ -177,8 +170,8 @@ def __exit__(self: Revision, typ: type, val: Any, _: Any) -> None:
raise val

if self._data:
self._client.store_keys_in_revision(
tree_name=self._tree_name, rev_id=self._rev_id, payload=self._data
self._client.put_keys_in_revision(
name=self._tree_name, revision_id=self._rev_id, config_values=self._data
)

if self._commit and self._rev_id:
Expand Down Expand Up @@ -594,7 +587,9 @@ def list_revision_keys(

try:
client = new_v2_client(with_project=(not with_org))
tree = client.get_config_tree(tree_name=tree_name, rev_id=rev_id)
tree = client.get_configtree(
name=tree_name, revision=rev_id, with_project=(not with_org)
)

keys = tree.get("keys")
if not isinstance(keys, dict):
Expand Down
17 changes: 10 additions & 7 deletions riocli/configtree/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import click
from click_help_colors import HelpColorsCommand
from munch import munchify
from yaspin.core import Yaspin

from riocli.config import get_config_from_context, new_v2_client
Expand Down Expand Up @@ -69,7 +70,7 @@ def create_config_tree(
"name": tree_name,
},
}
config_tree = client.create_config_tree(payload)
config_tree = munchify(client.create_configtree(body=payload))
spinner.text = click.style(
f"Config tree {config_tree.metadata.name} created successfully.",
fg=Colors.GREEN,
Expand Down Expand Up @@ -110,7 +111,7 @@ def delete_config_tree(

try:
client = new_v2_client(with_project=(not with_org))
client.delete_config_tree(tree_name)
client.delete_configtree(tree_name)
spinner.text = click.style("Config tree deleted successfully.", fg=Colors.GREEN)
spinner.green.ok(Symbols.SUCCESS)
except Exception as e:
Expand Down Expand Up @@ -158,7 +159,7 @@ def clone_tree(

try:
client = new_v2_client(with_project=(not with_org))
tree = client.get_config_tree(tree_name=tree_name)
tree = munchify(client.get_configtree(tree_name=tree_name))
head = tree.get("head")

if head is not None:
Expand All @@ -174,7 +175,7 @@ def clone_tree(
# We always clone into the current project.
# Thus, we recreate the client with_project=True.
client = new_v2_client(with_project=True)
config_tree = client.create_config_tree(payload)
config_tree = munchify(client.create_configtree(payload))
spinner.text = click.style(
f"Config tree {config_tree.metadata.name} cloned successfully.",
fg=Colors.GREEN,
Expand Down Expand Up @@ -252,7 +253,7 @@ def set_tree_revision(

try:
client = new_v2_client(with_project=(not with_org))
client.set_revision_config_tree(tree_name, payload)
client.set_configtree_revision(name=tree_name, configtree=payload)
spinner.text = click.style(
"Config tree head updated successfully.", fg=Colors.GREEN
)
Expand Down Expand Up @@ -288,7 +289,8 @@ def list_config_trees(

try:
client = new_v2_client(with_project=(not with_org))
trees = client.list_config_trees()
result = client.list_configtrees()
trees = munchify(result.get("items", []))
if not isinstance(trees, Iterable):
raise Exception("List items are not iterable")

Expand Down Expand Up @@ -360,7 +362,8 @@ def list_tree_revisions(
"""
try:
client = new_v2_client(with_project=(not with_org))
revisions = client.list_config_tree_revisions(tree_name=tree_name)
result = client.list_revisions(tree_name=tree_name, committed=with_org)
revisions = munchify(result.get("items", []))
if not isinstance(revisions, Iterable):
raise Exception("List items are not iterable")

Expand Down
Loading
Loading