Python SDK for XiaoShi AI Hub - Upload, download, and manage AI models and datasets with xpai-enc encryption support
Project description
Moha Hub Python SDK
Moha Hub Python SDK provides Python APIs and the moha CLI for working with Moha Hub repositories. It supports model, dataset, and Space repository management, upload/download workflows, token or username/password authentication, organization selection, and optional envelope encryption for large model files.
Features
- Python APIs similar to common Hub SDK patterns.
mohaCLI for authentication, repository management, branch management, upload, download, Space operations, and AI assistant workflows.- Token authentication and username/password authentication.
- Current organization selection through
moha organization useormoha org use. - ASCII table output for structured CLI command results.
- Single-file and snapshot downloads with include/exclude filters.
- File and folder uploads with optional encryption for large model files.
- Space creation, deploy, redeploy, status, and log streaming APIs.
- OpenAI-compatible AI assistant with function calling.
- Type hints for IDE support.
Installation
Moha SDK requires Python 3.10 or later.
pip install moha-hub
Install upload extras when you need upload support:
pip install "moha-hub[upload]"
Install a branch directly from GitHub:
pip install "git+https://github.com/poxiaoyun/moha-sdk.git@<branch-name>"
Install the local checkout for testing:
pip install -e ".[dev,upload]"
Verify the CLI entry point:
moha -h
Quick Start
CLI
# Show the compact default banner and usage.
moha
# Show full help.
moha -h
# Show basic or detailed debug information (place -v before the command).
moha -v
moha -v list model
moha -vvv download demo/my-model
# Log in with a token.
moha login https://rune.develop.xiaoshiai.cn --token your-token
# Log in interactively.
moha login https://rune.develop.xiaoshiai.cn
# Select an organization for unqualified repository IDs.
moha organization use demo
# List organizations. The current organization is marked with '*'.
moha org list
# Create and inspect repositories.
moha create model my-model --description "My model"
moha info model my-model
# Upload a folder or a single file.
moha upload my-model ./my_model
moha ul my-model ./my_model
moha upload my-model ./config.yaml configs/config.yaml
# Download a repository snapshot or selected files.
moha download my-model
moha dl my-model
moha download my-model config.yaml tokenizer.json
# Deploy and inspect a Space.
moha deploy demo/my-space
moha status demo/my-space
moha logs demo/my-space
moha logs demo/my-space -f -c web
The login endpoint must include a URL scheme:
moha login https://rune.develop.xiaoshiai.cn
Do not pass a bare host such as rune.develop.xiaoshiai.cn. After login succeeds,
the endpoint is saved in ~/.moha/config.json; all later CLI commands use that
saved endpoint, so --endpoint is not needed or accepted.
Debug output
Use counted -v flags before the command:
-vprints basic diagnostics: command, configured endpoint, authentication source, HTTP request/response summaries, and upload/download progress messages.-vvadds SDK debug context such as the current organization.-vvvadds detailed, redacted request metadata, response headers, runtime versions, and configuration paths.
Passwords, tokens, authorization headers, file contents, AI messages, and signed URL credentials are redacted. Raw third-party wire logging stays disabled.
Python API
from xiaoshiai_hub import moha_hub_download, snapshot_download
file_path = moha_hub_download(
repo_id="demo/my-model",
filename="config.yaml",
repo_type="models",
token="your-token",
)
print(f"Downloaded to: {file_path}")
repo_path = snapshot_download(
repo_id="demo/my-model",
repo_type="models",
allow_patterns=["*.yaml", "*.md"],
ignore_patterns=[".git*", "*.log"],
token="your-token",
)
print(f"Snapshot downloaded to: {repo_path}")
from xiaoshiai_hub import upload_file, upload_folder
upload_file(
path_file="./config.yaml",
path_in_repo="config.yaml",
repo_id="demo/my-model",
repo_type="models",
commit_message="Upload config file",
token="your-token",
)
upload_folder(
folder_path="./my_model",
repo_id="demo/my-model",
repo_type="models",
commit_message="Upload model files",
ignore_patterns=["*.log", ".git*"],
token="your-token",
)
HubClient
import sys
from xiaoshiai_hub import HubClient
client = HubClient(token="your-token")
repos = client.list_repositories(
repo_type="models",
scope="organization",
organization="demo",
)
for repo in repos:
print(f"{repo.organization}/{repo.name} - {repo.description}")
client.create_repository(
organization="demo",
repo_type="models",
repo_name="my-model",
description="My model",
visibility="internal",
metadata={
"license": ["apache-2.0"],
"frameworks": ["transformers"],
},
base_model=["demo/base-llama"],
relationship="finetune",
)
repo_info = client.get_repository_info("demo", "models", "my-model")
print(f"Repository: {repo_info.organization}/{repo_info.name}")
client.update_repository(
organization="demo",
repo_type="models",
repo_name="my-model",
description="Updated description",
)
refs = client.get_repository_refs("demo", "models", "my-model")
for ref in refs:
print(f"Branch: {ref.name} (commit: {ref.hash[:8]})")
Authentication
The SDK supports token authentication and username/password authentication.
Authentication precedence:
- CLI arguments
- Environment variables
- Locally saved token
Useful environment variables:
export MOHA_TOKEN="your-token"
export MOHA_USERNAME="your-username"
export MOHA_PASSWORD="your-password"
export MOHA_ORGANIZATION="demo"
After moha login <endpoint>, the token, endpoint, and username are stored
together in ~/.moha/config.json with user-only permissions. A persisted
current organization is kept in the same file. Existing ~/.moha/token.json
files remain readable for compatibility and are removed after the next
successful login. The MOHA_ENDPOINT environment variable remains available as
the default for direct Python SDK calls, but the CLI uses the endpoint saved by
login.
Organizations
Use organization or the org alias:
moha organization list
moha organization list --mine
moha organization use demo
moha org list
moha org use demo
organization list fetches all accessible organizations and renders them in a table. The current organization is marked with *.
Current organization precedence:
--organizationMOHA_ORGANIZATION- Local config saved by
moha organization use
Once selected, repository commands can omit the organization prefix:
moha organization use demo
moha create model my-model --description "My model"
moha upload my-model ./my_model
moha download my-model
CLI Commands
Top-level commands are grouped by function in moha -h.
| Group | Command | Description |
|---|---|---|
| Auth | login |
Log in and save token |
| Auth | logout |
Log out and delete saved token |
| Auth | whoami |
Show current login status |
| Organization | organization list / org l |
List organizations |
| Organization | organization use / org u |
Select current organization |
| Repository | list / l |
List repositories and images |
| Repository | create / c |
Create repositories and images |
| Repository | info / i |
Show repository and image information |
| Repository | update / u |
Update repositories and images |
| Repository | delete / del |
Delete repositories and images |
| Branch | refs |
List repository refs |
| Branch | branch-create / bc |
Create branch |
| Branch | branch-delete / bd |
Delete branch |
| Branch | branch-list / bl |
List branches |
| Transfer | upload / ul |
Upload a file or folder |
| Transfer | upload-file |
Upload one file |
| Transfer | download / dl |
Download a snapshot or selected files |
| Transfer | download-file |
Download one file |
| Space | deploy |
Deploy Space |
| Space | redeploy |
Redeploy Space |
| Space | status |
Show Space status |
| Space | logs |
Show Space logs |
| AI | ai |
Start the AI assistant |
| AI | ai-config |
Configure the AI assistant |
| Legacy | repo-list |
List repositories |
| Legacy | repo-create |
Create repository |
| Legacy | repo-info |
Show repository information |
| Legacy | repo-update |
Update repository |
| Legacy | repo-delete |
Delete repository |
| Legacy | space-deploy |
Deploy Space |
| Legacy | space-redeploy |
Redeploy Space |
| Legacy | space-status |
Show Space status |
Legacy command names remain available and are listed after the primary commands.
Structured CLI results use ASCII tables. Interactive prompts, errors, progress bars, and AI assistant natural-language responses remain plain terminal text.
Repository Commands
moha list shows resource-specific help. The list scope defaults to all.
moha create and moha info also use resource-specific subcommands.
moha update and moha delete use the same resource-specific structure.
Destructive commands prompt for --yes-i-really-mean-that; pass --force to skip the prompt.
Image list output includes the full repository path and tag count. Image info output includes supported architectures when tag metadata is available.
Model list output includes encryption type. Encrypted models show a lock emoji plus the encryption algorithm; unencrypted models show -.
Space list output includes emoji runtime status after the repository type column.
Space logs use the Space pod log WebSocket proxy. If a pod has multiple containers, pass --container / -c with the container name. Use --follow / -f to stream logs in real time.
Short resource aliases are also available: model / m, dataset / ds, image / img, and space / s.
moha list model
moha l m
moha list models --scope all
moha list dataset --scope create
moha list image --scope favorite
moha list space --scope organization --organization demo
moha list model --mine --organization demo
moha create model demo/my-model --description "My model" --visibility internal
moha c m demo/my-model --description "My model"
moha create dataset demo/my-dataset --description "My dataset"
moha create image demo/runtime --repo registry.example/demo/runtime --visibility internal
moha create space demo/my-space --description "My Space"
moha info model demo/my-model
moha i img demo/runtime
moha info image demo/runtime
moha update model demo/my-model --description "Updated description"
moha update image demo/runtime --description "Updated image"
moha delete model demo/my-model
moha del img demo/runtime --force
Branch Commands
moha refs demo/my-model
moha branch-list demo/my-model
moha bl demo/my-model
moha branch-create demo/my-model dev --from main
moha bc demo/my-model dev --from main
moha branch-delete demo/my-model dev
moha bd demo/my-model dev --force
Upload and Download
moha upload demo/my-model ./my_model
moha ul demo/my-model ./my_model
moha upload demo/my-model ./my_model artifacts
moha upload demo/my-model ./config.yaml configs/config.yaml
moha upload demo/my-model ./my_model \
--revision main \
--message "Upload model files" \
--ignore "*.log" \
--exclude ".git*"
moha upload demo/my-model ./model.safetensors \
--encrypt \
--encryption-password "your-secure-password"
moha download demo/my-model
moha dl demo/my-model
moha download demo/my-model config.yaml tokenizer.json
moha download demo/my-model --include "*.json" --exclude "*.log" --local-dir ./downloads
The legacy upload order is still accepted:
moha upload ./my_model demo/my-model
Encryption
Large model files can be encrypted during upload.
Supported algorithms:
| Algorithm | Description |
|---|---|
AES |
AES-256-CTR, default |
SM4 |
SM4-CTR |
Automatic encryption applies only when:
- File size is at least 5 MB.
- File extension is one of the supported model file extensions, such as
.safetensors,.bin,.pt,.pth, or.ckpt.
Small files and non-model files remain readable.
from xiaoshiai_hub import upload_file
upload_file(
path_file="./model.safetensors",
path_in_repo="model.safetensors",
repo_id="demo/my-model",
repo_type="models",
encryption_password="your-secure-password",
algorithm="AES",
token="your-token",
)
Spaces
from xiaoshiai_hub import HubClient
client = HubClient(token="your-token")
clusters = client.list_clusters("demo")
workspaces = client.list_cluster_workspaces("demo", clusters[0].id)
flavors = client.list_workspace_flavors("demo", clusters[0].id, workspaces[0].id)
products = client.list_products("demo")
client.create_space_repository(
organization="demo",
repo_name="my-gradio-app",
cluster=clusters[0].id,
namespace=workspaces[0].id,
product_id="gradio",
product_version="latest",
visibility="internal",
flavor=flavors[0].id if flavors else None,
env=[{"name": "MODEL_NAME", "value": "llama-7b"}],
description="My Gradio app",
)
client.deploy_space("demo", "my-gradio-app")
status = client.get_space_status("demo", "my-gradio-app")
print(f"Status: {status.phase}, healthy: {status.healthy}")
pods = client.list_space_pods("demo", "my-gradio-app")
pod_name = pods[0]["metadata"]["name"]
client.stream_space_logs(
"demo",
"my-gradio-app",
pod=pod_name,
container="web",
follow=True,
on_message=sys.stdout.write,
)
AI Assistant
Configure an OpenAI-compatible Chat Completion API:
moha ai-config
moha ai-config --api-base https://api.deepseek.com --api-key your-api-key --model deepseek-chat
moha ai-config --show
Or use environment variables:
export MOHA_AI_API_BASE="https://api.deepseek.com"
export MOHA_AI_API_KEY="your-api-key"
export MOHA_AI_MODEL="deepseek-chat"
Start interactive mode or run a one-shot prompt:
moha ai
moha ai --model deepseek-chat
moha ai --no-stream
moha ai --prompt "List model repositories I created."
The assistant can list and inspect repositories, create and update repositories, manage branches, inspect files, create or update text files, upload/download content, and inspect Space status. Destructive operations such as deleting repositories, branches, or files are not executed by the assistant; use the corresponding CLI command and confirm in the terminal.
Development
git clone https://github.com/poxiaoyun/moha-sdk.git
cd moha-sdk
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,upload]"
Run available checks:
python -m compileall xiaoshiai_hub tests
python -m pytest tests/test_regressions.py
API Reference
Top-level functions:
| Function | Description |
|---|---|
moha_hub_download() |
Download one file from a repository |
snapshot_download() |
Download a full repository snapshot |
upload_file() |
Upload one file to a repository |
upload_folder() |
Upload a folder to a repository |
login() |
Log in and save token |
save_token() / load_token() / delete_token() |
Authentication state in config.json |
save_endpoint() / load_endpoint() |
Endpoint in config.json |
save_current_organization() / load_current_organization() |
Current organization in config.json |
envelope_enc_file() |
Encrypt a file with envelope encryption |
HubClient methods:
| Method | Description |
|---|---|
list_organizations() |
List organizations |
get_organization() |
Get organization information |
list_repositories() |
List repositories |
list_images() |
List container images |
create_repository() |
Create repository |
create_image() |
Create container image |
get_repository_info() |
Get repository information |
update_repository() |
Update repository information |
get_image() |
Get container image information |
update_image() |
Update container image information |
delete_repository() |
Delete repository |
delete_image() |
Delete container image |
get_repository_refs() |
List repository refs |
get_default_branch() |
Get the default branch name |
create_branch() |
Create branch |
delete_branch() |
Delete branch |
get_repository_content() |
Browse repository content |
create_file() |
Create or update a repository file |
delete_file() |
Delete a repository file |
download_file() |
Download one file |
create_space_repository() |
Create Space repository |
deploy_space() |
Deploy Space |
redeploy_space() |
Redeploy Space |
get_space_status() |
Get Space status |
list_space_pods() |
List Space pods |
stream_space_logs() |
Stream Space logs |
list_clusters() |
List available clusters |
list_cluster_workspaces() |
List workspaces under a cluster |
list_workspace_flavors() |
List workspace flavors |
list_products() |
List product templates |
get_product() |
Get product details |
set_repository_encrypted() |
Set repository encryption flag |
cancel_repository_encrypted() |
Cancel repository encryption flag |
generate_data_key() |
Generate a data key through KMS |
Exception types:
| Exception | Description |
|---|---|
HubException |
Base exception for Hub errors |
RepositoryNotFoundError |
Repository was not found |
FileNotFoundError |
File was not found in a repository |
AuthenticationError |
Authentication failed |
HTTPError |
HTTP request failed |
UploadError |
Upload failed |
License
Apache License 2.0. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moha_hub-2.0.1.tar.gz.
File metadata
- Download URL: moha_hub-2.0.1.tar.gz
- Upload date:
- Size: 68.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53d3a6370a5784041033a2e5d8d9408db0887f9b2f4f02be4a1d53df24dc0302
|
|
| MD5 |
4265e6b5dadc14756d26cc2a783e49f0
|
|
| BLAKE2b-256 |
204920cdd4623cf690b7037ddc551b53855cb2a067fd1d046eded0ca6cc190d7
|
Provenance
The following attestation bundles were made for moha_hub-2.0.1.tar.gz:
Publisher:
publish.yml on poxiaoyun/moha-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moha_hub-2.0.1.tar.gz -
Subject digest:
53d3a6370a5784041033a2e5d8d9408db0887f9b2f4f02be4a1d53df24dc0302 - Sigstore transparency entry: 2232820537
- Sigstore integration time:
-
Permalink:
poxiaoyun/moha-sdk@0f551e7eca5cb392d759e70d155ad986ca933a5b -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/poxiaoyun
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0f551e7eca5cb392d759e70d155ad986ca933a5b -
Trigger Event:
release
-
Statement type:
File details
Details for the file moha_hub-2.0.1-py3-none-any.whl.
File metadata
- Download URL: moha_hub-2.0.1-py3-none-any.whl
- Upload date:
- Size: 71.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e78716301086b294a13c0ad83b14d104cd475bad43a9a613709b0345c1f0f97
|
|
| MD5 |
afd4c0ff9eb863908c437a0647c74355
|
|
| BLAKE2b-256 |
0df4032a6dc051a0d75983995cd65b7ad6207cc0af234b55da28c91c2ef402e0
|
Provenance
The following attestation bundles were made for moha_hub-2.0.1-py3-none-any.whl:
Publisher:
publish.yml on poxiaoyun/moha-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moha_hub-2.0.1-py3-none-any.whl -
Subject digest:
3e78716301086b294a13c0ad83b14d104cd475bad43a9a613709b0345c1f0f97 - Sigstore transparency entry: 2232821279
- Sigstore integration time:
-
Permalink:
poxiaoyun/moha-sdk@0f551e7eca5cb392d759e70d155ad986ca933a5b -
Branch / Tag:
refs/tags/v2.0.1 - Owner: https://github.com/poxiaoyun
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0f551e7eca5cb392d759e70d155ad986ca933a5b -
Trigger Event:
release
-
Statement type: