Metadata-Version: 2.4
Name: xiaoshiai-hub
Version: 1.2.3
Summary: Python SDK for XiaoShi AI Hub - Upload, download, and manage AI models and datasets with xpai-enc encryption support
Home-page: https://github.com/poxiaoyun/moha-sdk
Author: XiaoShi AI
Author-email: XiaoShi AI <support@xiaoshiai.cn>
Maintainer: XiaoShi AI Team
Maintainer-email: XiaoShi AI Team <support@xiaoshiai.cn>
License: Apache-2.0
Project-URL: Homepage, https://github.com/poxiaoyun/moha-sdk
Project-URL: Repository, https://github.com/poxiaoyun/moha-sdk
Project-URL: Issues, https://github.com/poxiaoyun/moha-sdk/issues
Keywords: xiaoshi,ai-hub,machine-learning,deep-learning,model-hub,dataset,encryption,xpai-enc,sdk,api-client,model-encryption
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.20.0
Requires-Dist: tqdm>=4.62.0
Requires-Dist: cryptography>=46.0.3
Provides-Extra: upload
Requires-Dist: gitpython>=3.1.0; extra == "upload"
Provides-Extra: encryption
Provides-Extra: dev
Requires-Dist: pytest>=6.0; extra == "dev"
Requires-Dist: pytest-cov>=2.0; extra == "dev"
Requires-Dist: pytest-mock>=3.6.0; extra == "dev"
Requires-Dist: black>=22.0; extra == "dev"
Requires-Dist: flake8>=4.0; extra == "dev"
Requires-Dist: mypy>=0.950; extra == "dev"
Requires-Dist: isort>=5.10.0; extra == "dev"
Requires-Dist: build>=0.8.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Requires-Dist: gitpython>=3.1.0; extra == "dev"
Provides-Extra: all
Requires-Dist: gitpython>=3.1.0; extra == "all"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: maintainer
Dynamic: requires-python

# XiaoShi AI Hub Python SDK

[![PyPI version](https://badge.fury.io/py/xiaoshiai-hub.svg)](https://badge.fury.io/py/xiaoshiai-hub)
[![Python Support](https://img.shields.io/pypi/pyversions/xiaoshiai-hub.svg)](https://pypi.org/project/xiaoshiai-hub/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

XiaoShi AI Hub Python SDK 是一个功能强大的 Python 库，用于与 XiaoShi AI Hub 平台进行交互。它提供了简单易用的 API 和命令行工具，支持模型、数据集和 Spaces 应用的上传、下载与管理，并支持大型模型文件的透明加密功能。


## ✨ 特性

- 🚀 **简单易用** - 类似 Hugging Face Hub 的 API 设计，上手即用
- 🖥️ **命令行工具** - 提供 `moha` CLI，无需编写代码即可上传下载
- 🤖 **AI 智能助手** - 通过自然语言管理仓库，支持 OpenAI 兼容 API（含 function calling）
- 📥 **下载功能** - 支持下载单个文件或整个仓库
- 📤 **上传功能** - 支持上传文件和文件夹到仓库
- 🔐 **智能加密** - 自动加密大型模型文件（≥5MB 的 .safetensors、.bin、.pt、.pth、.ckpt 文件）
- 🚀 **Spaces 支持** - 创建、发布、重新发布和管理 Space 应用
- 🎯 **模式匹配** - 支持使用 allow/ignore 模式过滤文件
- 📊 **进度显示** - 下载和上传时显示进度条
- 🔑 **多种认证** - 支持用户名/密码和 Token 认证
- 🌐 **环境变量配置** - 灵活的 Hub URL 配置
- 📝 **文件操作** - 通过 API 直接创建、更新和删除仓库中的文件
- 💾 **缓存支持** - 高效的文件缓存机制
- 🔍 **类型提示** - 完整的类型注解，IDE 友好
- ✅ **仓库验证** - 上传前自动检查仓库是否存在
- 🧬 **模型血缘** - 支持记录模型的基础模型和微调关系

## 📦 安装

### 基础安装

```bash
pip install xiaoshiai-hub
```



## 🚀 快速开始

### 命令行工具 (CLI)

安装后即可使用 `moha` 命令行工具：

```bash
# 查看帮助
moha --help

# 上传文件夹到仓库
moha upload ./my_model org/my-model --username your-username --password your-password

# 上传单个文件
moha upload-file ./config.yaml org/my-model --username your-username --password your-password

# 下载整个仓库
moha download org/my-model --username your-username --password your-password

# 下载单个文件
moha download-file org/my-model config.yaml --username your-username --password your-password
```

详细的 CLI 使用说明请参考 [命令行工具](#-命令行工具-cli) 章节。

### Python API

#### 下载单个文件

```python
from xiaoshiai_hub import moha_hub_download

# 下载单个文件
file_path = moha_hub_download(
    repo_id="demo/demo",
    filename="config.yaml",
    repo_type="models",  # 或 "datasets"、"spaces"
    username="your-username",
    password="your-password",
)
print(f"文件已下载到: {file_path}")
```

#### 下载整个仓库

```python
from xiaoshiai_hub import snapshot_download

# 下载整个仓库
repo_path = snapshot_download(
    repo_id="demo/demo",
    repo_type="models",
    username="your-username",
    password="your-password",
)
print(f"仓库已下载到: {repo_path}")
```

#### 使用过滤器下载

```python
from xiaoshiai_hub import snapshot_download

# 只下载 YAML 和 Markdown 文件
repo_path = snapshot_download(
    repo_id="demo/demo",
    allow_patterns=["*.yaml", "*.yml", "*.md"],
    ignore_patterns=[".git*", "*.log"],
    username="your-username",
    password="your-password",
)
```

#### 上传文件

```python
from xiaoshiai_hub import upload_file

# 上传单个文件
result = upload_file(
    path_file="./config.yaml",
    path_in_repo="config.yaml",
    repo_id="demo/my-model",
    repo_type="models",
    commit_message="Upload config file",
    username="your-username",
    password="your-password",
)
print(f"上传成功: {result}")
```

#### 上传文件夹

```python
from xiaoshiai_hub import upload_folder

# 上传整个文件夹
result = upload_folder(
    folder_path="./my_model",
    repo_id="demo/my-model",
    repo_type="models",
    commit_message="Upload model files",
    ignore_patterns=["*.log", ".git*"],  # 忽略这些文件
    username="your-username",
    password="your-password",
)
print(f"上传成功: {result}")
```

#### 加密上传

SDK 会自动加密大型模型文件（≥5MB 的 .safetensors、.bin、.pt、.pth、.ckpt 文件）：

```python
from xiaoshiai_hub import upload_file

# 上传文件，大型模型文件会自动加密
result = upload_file(
    path_file="./model.safetensors",  # 如果 ≥5MB，会自动加密
    path_in_repo="model.safetensors",
    repo_id="demo/my-model",
    repo_type="models",
    encryption_password="your-secure-password",  # 设置加密密码
    username="your-username",
    password="your-password",
)
```

#### 上传文件夹（自动加密大文件）

```python
from xiaoshiai_hub import upload_folder

# 上传文件夹，大型模型文件会自动加密
result = upload_folder(
    folder_path="./my_model",
    repo_id="demo/my-model",
    repo_type="models",
    encryption_password="your-secure-password",  # 大文件会自动加密
    ignore_patterns=["*.log", ".git*"],
    username="your-username",
    password="your-password",
)

```

#### 使用 HubClient API

```python
from xiaoshiai_hub import HubClient

# 创建客户端
client = HubClient(
    username="your-username",
    password="your-password",
)

# 列出仓库
repos = client.list_repositories(
    repo_type="models",
    scope="organization",       # "public"、"create"、"favorite"、"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="我的模型",
    visibility="internal",
    metadata={
        "license": ["apache-2.0"],
        "frameworks": ["transformers"],
    },
    base_model=["demo/base-llama"],           # 基础模型（可选）
    relationship="finetune",                   # adapter/finetune/quantized/merge/repackage（可选）
)

# 获取仓库信息
repo_info = client.get_repository_info("demo", "models", "my-model")
print(f"仓库名称: {repo_info.name}")
print(f"组织: {repo_info.organization}")
print(f"所有者: {repo_info.owner}")
print(f"可见性: {repo_info.visibility}")

# 更新仓库
client.update_repository(
    organization="demo",
    repo_type="models",
    repo_name="my-model",
    description="更新后的描述",
)

# 列出分支
refs = client.get_repository_refs("demo", "models", "my-model")
for ref in refs:
    print(f"分支: {ref.name} (commit: {ref.hash[:8]})")

# 创建分支（幂等操作，已存在则直接返回）
client.create_branch("demo", "models", "my-model", "dev", "main")

# 删除分支（幂等操作，不存在则直接返回）
client.delete_branch("demo", "models", "my-model", "dev")

# 浏览仓库内容
content = client.get_repository_content("demo", "models", "my-model", "main")
for entry in content.entries:
    print(f"{entry.type}: {entry.name} ({entry.size} bytes)")

# 创建/更新仓库中的文件（适用于小型文本文件）
client.create_file(
    organization="demo",
    repo_type="models",
    repo_name="my-model",
    branch="main",
    file_path="README.md",
    content="# My Model\n\n这是我的模型",
    message="Add README",
)

# 删除仓库中的文件
client.delete_file(
    organization="demo",
    repo_type="models",
    repo_name="my-model",
    branch="main",
    file_path="old_file.txt",
    message="Remove old file",
)

# 删除仓库
client.delete_repository("demo", "models", "my-model")
```

#### Spaces 应用管理

SDK 支持创建和管理 Spaces 应用，可以将 Gradio、Streamlit 或 Docker 应用部署到集群上。

```python
from xiaoshiai_hub import HubClient

client = HubClient(
    username="your-username",
    password="your-password",
)

# 查看可用集群
clusters = client.list_clusters("demo")
for c in clusters:
    print(f"集群: {c.name} (ID: {c.id}, 状态: {c.state})")

# 查看集群下的工作空间
workspaces = client.list_cluster_workspaces("demo", cluster_id="cluster-1")
for ws in workspaces:
    print(f"工作空间: {ws.name} (ID: {ws.id})")

# 查看工作空间下的规格（Flavor）
flavors = client.list_workspace_flavors("demo", cluster_id="cluster-1", workspace_id="ws-1")
for f in flavors:
    print(f"规格: {f.name} (ID: {f.id}, 类型: {f.type})")

# 查看可用产品模版
products = client.list_products("demo")
for p in products:
    versions = [v.version for v in p.versions]
    print(f"模版: {p.name} (ID: {p.id}, 版本: {versions})")

# 创建 Space 仓库
client.create_space_repository(
    organization="demo",
    repo_name="my-app",
    cluster="cluster-1",
    namespace="ws-1",
    product_id="gradio",
    product_version="1.0.0",
    visibility="internal",
    flavor="gpu-a100",                          # 可选：GPU 规格
    env=[{"name": "MODEL_NAME", "value": "llama-7b"}],  # 可选：环境变量
    description="我的 Gradio 应用",
)

# 发布 Space
client.deploy_space("demo", "my-app")

# 重新发布 Space
client.redeploy_space("demo", "my-app")

# 查看 Space 状态
status = client.get_space_status("demo", "my-app")
print(f"健康状态: {'健康' if status.healthy else '不健康'}")
print(f"阶段: {status.phase}")
if status.endpoints:
    for ep in status.endpoints:
        print(f"端点: {ep.name} ({ep.kind}) -> {ep.url}")
```

## 🔐 加密功能

SDK 提供了智能加密功能，支持 **AES** 和 **SM4** 两种加密算法对大型模型文件进行加密。

### 支持的加密算法

| 算法 | 说明 |
|------|------|
| `AES` | AES-256-CTR 模式，国际通用标准（默认） |
| `SM4` | SM4-CTR 模式，国密标准 |

### 自动加密规则

上传时，SDK 会自动加密符合以下条件的文件：

1. **文件大小** ≥ 5MB
2. **文件扩展名**为：`.safetensors`、`.bin`、`.pt`、`.pth`、`.ckpt`

小文件和其他类型的文件（如配置文件、README 等）不会被加密，保持可读性。

### 使用加密功能

```python
from xiaoshiai_hub import upload_folder

# 上传文件夹，使用 AES 加密（默认）
result = upload_folder(
    folder_path="./llama-7b",
    repo_id="demo/llama-7b",
    encryption_password="my-secure-password-123",
    username="your-username",
    password="your-password",
)

# 使用 SM4 国密算法加密
result = upload_folder(
    folder_path="./llama-7b",
    repo_id="demo/llama-7b",
    encryption_password="my-secure-password-123",
    algorithm="SM4",  # 使用 SM4 加密
    username="your-username",
    password="your-password",
)

# 文件夹中的大型模型文件（如 model.safetensors）会被自动加密
# 小文件（如 config.json、README.md）保持原样
```

### 临时目录管理

上传时可以指定临时目录用于存放加密文件：

```python
result = upload_folder(
    folder_path="./my_model",
    repo_id="demo/my-model",
    encryption_password="password",
    temp_dir="/tmp/encrypted_files",  # 指定临时目录
    username="your-username",
    password="your-password",
)
# 如果不指定 temp_dir，会自动创建临时目录并在上传后清理
```

## ⚙️ 配置

### 环境变量

```bash
# Hub 服务端点
export MOHA_ENDPOINT="https://your-hub-url.com"

# 认证信息（可选，避免每次输入）
export MOHA_USERNAME="your-username"
export MOHA_PASSWORD="your-password"
export MOHA_TOKEN="your-token"

# 加密密码（可选）
export MOHA_ENCRYPTION_PASSWORD="your-encryption-password"

# AI 助手配置（可选）
export MOHA_AI_API_BASE="https://api.deepseek.com"  # OpenAI 兼容 API 地址
export MOHA_AI_API_KEY="your-api-key"                # API 密钥
export MOHA_AI_MODEL="deepseek-chat"                  # 模型名称
```

## 🖥️ 命令行工具 (CLI)

SDK 提供了 `moha` 命令行工具，支持登录认证、仓库管理、分支管理、上传下载等操作。

### 基本用法

```bash
moha --help
```

### 登录认证

```bash
# 登录（交互式输入用户名和密码）
moha login

# 直接指定用户名和密码
moha login --username your-username --password your-password

# 查看当前登录状态
moha whoami

# 退出登录
moha logout
```

登录后，Token 会保存到 `~/.moha/token.json`，后续命令无需重复输入认证信息。

### 仓库管理

```bash
# 查询公开仓库
moha repo-list

# 查询我创建的仓库
moha repo-list --scope create

# 查询我收藏的仓库
moha repo-list --scope favorite

# 查询组织内的仓库
moha repo-list --scope organization --organization myorg

# 查询组织内我创建的仓库
moha repo-list --scope organization --organization myorg --mine

# 查询组织内的数据集仓库
moha repo-list --scope organization --organization myorg --repo-type datasets

# 查询 Spaces 应用
moha repo-list --scope organization --organization myorg --repo-type spaces

# 创建仓库
moha repo-create org/my-model \
    --description "我的模型" \
    --visibility internal \
    --license apache-2.0 \
    --tasks text-generation \
    --frameworks transformers

# 创建数据集仓库
moha repo-create org/my-dataset \
    --repo-type datasets \
    --description "我的数据集" \
    --visibility private

# 创建仓库并关联基础模型（模型血缘）
moha repo-create org/my-finetune \
    --description "基于 Llama 的微调模型" \
    --base-model org/llama-7b \
    --relationship finetune

# 查看仓库信息
moha repo-info org/my-model

# 更新仓库信息
moha repo-update org/my-model \
    --description "更新后的描述" \
    --tags production

# 删除仓库（需要确认）
moha repo-delete org/my-model

# 跳过确认直接删除
moha repo-delete org/my-model -y
```

### 分支管理

```bash
# 列出仓库的所有分支
moha branch-list org/my-model

# 创建分支（基于 main 分支）
moha branch-create org/my-model dev

# 创建分支（基于指定分支）
moha branch-create org/my-model feature --from dev

# 删除分支
moha branch-delete org/my-model dev

# 跳过确认直接删除
moha branch-delete org/my-model dev -y
```

### 上传文件夹

```bash
# 基本用法
moha upload ./my_model org/my-model

# 完整参数示例
moha upload ./my_model org/my-model \
    --repo-type models \
    --revision main \
    --message "Upload model files" \
    --ignore "*.log" \
    --ignore ".git*" \
    --username your-username \
    --password your-password

# 启用加密（默认使用 AES）
moha upload ./my_model org/my-model \
    --encrypt \
    --encryption-password "your-secret" \
    --username your-username \
    --password your-password

# 使用 SM4 国密算法加密
moha upload ./my_model org/my-model \
    --encrypt \
    --encryption-password "your-secret" \
    --algorithm SM4 \
    --username your-username \
    --password your-password
```

### 上传单个文件

```bash
# 基本用法（使用文件名作为仓库路径）
moha upload-file ./config.yaml org/my-model

# 指定仓库中的路径
moha upload-file ./config.yaml org/my-model \
    --path-in-repo configs/config.yaml

# 完整参数示例
moha upload-file ./model.safetensors org/my-model \
    --path-in-repo weights/model.safetensors \
    --repo-type models \
    --revision main \
    --message "Upload model weights" \
    --encrypt \
    --encryption-password "your-secret" \
    --username your-username \
    --password your-password
```

### 下载仓库

```bash
# 基本用法
moha download org/my-model

# 完整参数示例
moha download org/my-model \
    --local-dir ./downloaded_model \
    --repo-type models \
    --revision main \
    --include "*.safetensors" \
    --include "*.json" \
    --ignore "*.log" \
    --username your-username \
    --password your-password
```

### 下载单个文件

```bash
# 基本用法
moha download-file org/my-model config.yaml

# 完整参数示例
moha download-file org/my-model model.safetensors \
    --local-dir ./downloads \
    --repo-type models \
    --revision main \
    --username your-username \
    --password your-password
```

### Space 管理

```bash
# 发布 Space
moha space-deploy org/my-app

# 重新发布 Space
moha space-redeploy org/my-app

# 查看 Space 状态
moha space-status org/my-app
```

### CLI 命令列表

| 命令 | 说明 |
|------|------|
| `moha login` | 登录并保存 Token |
| `moha logout` | 退出登录并删除 Token |
| `moha whoami` | 查看当前登录状态 |
| `moha repo-list` | 列出仓库（支持按范围、组织过滤） |
| `moha repo-create` | 创建仓库 |
| `moha repo-update` | 更新仓库 |
| `moha repo-delete` | 删除仓库 |
| `moha repo-info` | 查看仓库信息 |
| `moha branch-create` | 创建分支 |
| `moha branch-delete` | 删除分支 |
| `moha branch-list` | 列出仓库的所有分支 |
| `moha upload` | 上传文件夹到仓库 |
| `moha upload-file` | 上传单个文件到仓库 |
| `moha download` | 下载整个仓库 |
| `moha download-file` | 从仓库下载单个文件 |
| `moha space-deploy` | 发布 Space 应用 |
| `moha space-redeploy` | 重新发布 Space 应用 |
| `moha space-status` | 查看 Space 应用状态 |
| `moha ai` | 启动 AI 智能助手 |
| `moha ai-config` | 配置 AI 助手（API 地址、密钥、模型） |

### CLI 参数说明

#### 通用参数

| 参数 | 说明 | 适用命令 |
|------|------|----------|
| `--repo-type, -t` | 仓库类型：`models`、`datasets` 或 `spaces`（默认：models） | 大部分命令 |
| `--base-url` | API 基础 URL（默认：环境变量 MOHA_ENDPOINT） | 所有 |
| `--token` | 认证令牌 | 所有 |
| `--username` | 用户名 | 所有 |
| `--password` | 密码 | 所有 |

#### 仓库列表参数

| 参数 | 说明 | 适用命令 |
|------|------|----------|
| `--scope, -s` | 查询范围：`public`、`create`、`favorite`、`organization`（默认：public） | repo-list |
| `--organization, -o` | 组织名称（scope=organization 时必需） | repo-list |
| `--mine, -m` | 仅显示我在该组织内创建的仓库 | repo-list |

#### 上传/下载参数

| 参数 | 说明 | 适用命令 |
|------|------|----------|
| `--revision, -r` | 分支/标签/提交（默认：main） | upload, download |
| `--message, -m` | 提交消息 | upload, upload-file |
| `--ignore, -i` | 忽略模式（可多次使用） | upload, download |
| `--include` | 包含模式（可多次使用） | download |
| `--encrypt, -e` | 启用加密 | upload, upload-file |
| `--encryption-password` | 加密密码 | upload, upload-file |
| `--algorithm, -a` | 加密算法：`AES` 或 `SM4`（默认：AES） | upload, upload-file |
| `--path-in-repo, -p` | 仓库中的文件路径 | upload-file |
| `--temp-dir` | 加密临时目录 | upload |
| `--local-dir, -o` | 本地保存目录 | download, download-file |
| `--quiet, -q` | 禁用进度条 | download, download-file |

#### 仓库管理参数

| 参数 | 说明 | 适用命令 |
|------|------|----------|
| `--description, -d` | 仓库描述 | repo-create, repo-update |
| `--visibility, -v` | 可见性：`public`、`internal`、`private` | repo-create, repo-update |
| `--license` | 许可证（可多次使用） | repo-create, repo-update |
| `--tasks` | 任务类型（可多次使用） | repo-create, repo-update |
| `--languages` | 语言（可多次使用） | repo-create, repo-update |
| `--tags` | 标签（可多次使用） | repo-create, repo-update |
| `--frameworks` | 框架（可多次使用） | repo-create, repo-update |
| `--base-model` | 基础模型（可多次使用） | repo-create, repo-update |
| `--relationship` | 与基础模型的关系 | repo-create, repo-update |
| `--yes, -y` | 跳过确认提示 | repo-delete, branch-delete |

#### 分支管理参数

| 参数 | 说明 | 适用命令 |
|------|------|----------|
| `--from, -f` | 基于哪个分支创建（默认：main） | branch-create |
| `--yes, -y` | 跳过确认提示 | branch-delete |

### 使用环境变量

可以通过环境变量设置认证信息，避免每次输入：

```bash
# 设置环境变量
export MOHA_USERNAME="your-username"
export MOHA_PASSWORD="your-password"
export MOHA_ENCRYPTION_PASSWORD="your-secret"

# 然后直接使用命令
moha upload ./my_model org/my-model --encrypt
moha download org/my-model
```

## 🤖 AI 智能助手

SDK 内置了 AI 智能助手，支持通过自然语言管理仓库、分支、文件等资源。助手基于 OpenAI 兼容的 Chat Completion API（含 function calling），支持 DeepSeek、OpenAI、通义千问等模型服务。

### 配置 AI 助手

首次使用前需要配置 API 信息：

```bash
# 交互式配置（推荐）
moha ai-config

# 直接指定参数
moha ai-config --api-base https://api.deepseek.com --api-key your-key --model deepseek-chat

# 查看当前配置
moha ai-config --show
```

也可以通过环境变量配置：

```bash
export MOHA_AI_API_BASE="https://api.deepseek.com"
export MOHA_AI_API_KEY="your-api-key"
export MOHA_AI_MODEL="deepseek-chat"
```

配置文件保存在 `~/.moha/ai_config.json`，权限为 600（仅当前用户可读写）。环境变量的优先级高于配置文件。

### 启动交互式助手

```bash
# 启动交互式聊天
moha ai

# 指定模型
moha ai --model gpt-4o

# 禁用流式输出
moha ai --no-stream
```

交互模式下支持：
- 输入 `exit` 或 `quit` 退出
- 输入 `clear` 清除对话历史
- 上下键浏览历史命令

### 单次指令模式

```bash
# 使用 --prompt 执行单条指令
moha ai --prompt "列出我创建的所有模型仓库"

moha ai --prompt "查看 myorg/my-model 仓库的详细信息"

moha ai --prompt "创建一个名为 myorg/new-model 的私有模型仓库"
```

### AI 助手能力

助手通过 function calling 可执行以下操作：

| 类别 | 支持的操作 |
|------|------------|
| **仓库管理** | 列出、查看、创建、更新、删除仓库 |
| **分支管理** | 列出、创建、删除分支 |
| **文件操作** | 浏览仓库目录、读取文件内容、创建/更新文件、删除文件 |
| **上传下载** | 下载仓库、上传本地目录到仓库 |
| **Space 管理** | 发布、重新发布、查看 Space 应用状态 |
| **本地文件** | 创建目录、创建文件、列出目录、读取文件 |

### 使用示例

```
你: 帮我看看 myorg 组织下有哪些模型仓库
助手: 找到 3 个仓库:
  myorg/llama-7b - Llama 2 7B 模型
  myorg/bert-base - BERT 基础模型
  myorg/gpt2-finetune - GPT-2 微调模型

你: 查看 myorg/llama-7b 的文件列表
助手: 路径 '/' 下的内容:
  [dir] configs/
  [file] config.json (1234 bytes)
  [file] model.safetensors (13421772800 bytes)
  [file] README.md (2048 bytes)

你: 把本地 ./my-model 目录上传到 myorg/new-model 仓库
助手: 目录上传成功: ./my-model -> myorg/new-model（分支: main）
```

### AI 助手 CLI 参数

| 参数 | 说明 |
|------|------|
| `--prompt, -p` | 直接执行单条指令（非交互模式） |
| `--api-base` | AI API 地址（或设置 MOHA_AI_API_BASE 环境变量） |
| `--api-key` | AI API 密钥（或设置 MOHA_AI_API_KEY 环境变量） |
| `--model, -m` | 模型名称（或设置 MOHA_AI_MODEL 环境变量） |
| `--no-stream` | 禁用流式输出（默认启用流式） |

## 📋 使用场景

### 场景 1: 上传开源模型到私有 Hub

```python
from xiaoshiai_hub import upload_folder

# 上传 Hugging Face 下载的模型到私有 Hub
result = upload_folder(
    folder_path="~/.cache/huggingface/hub/models--meta-llama--Llama-2-7b-hf",
    repo_id="myorg/llama-2-7b",
    repo_type="models",
    commit_message="Upload Llama 2 7B model",
    username="your-username",
    password="your-password",
)
```

### 场景 2: 加密上传敏感模型

```python
from xiaoshiai_hub import upload_folder

# 上传模型并加密大文件
result = upload_folder(
    folder_path="./proprietary-model",
    repo_id="myorg/proprietary-model",
    encryption_password="super-secret-password",  # 大文件自动加密
    ignore_patterns=["*.log", "checkpoints/"],
    username="your-username",
    password="your-password",
)
```

### 场景 3: 批量下载数据集

```python
from xiaoshiai_hub import snapshot_download

# 下载整个数据集
dataset_path = snapshot_download(
    repo_id="myorg/my-dataset",
    repo_type="datasets",
    allow_patterns=["*.parquet", "*.json"],  # 只下载数据文件
    ignore_patterns=["*.md"],  # 忽略文档
    username="your-username",
    password="your-password",
)
```

### 场景 4: 检查仓库是否存在

```python
from xiaoshiai_hub import HubClient
from xiaoshiai_hub.exceptions import RepositoryNotFoundError

client = HubClient(username="your-username", password="your-password")

try:
    repo_info = client.get_repository_info("myorg", "models", "my-model")
    print(f"仓库存在: {repo_info.name}")
except RepositoryNotFoundError:
    print("仓库不存在，请先创建")
```

### 场景 5: 部署 Space 应用

```python
from xiaoshiai_hub import HubClient

client = HubClient(username="your-username", password="your-password")

# 创建 Space 仓库并部署
client.create_space_repository(
    organization="myorg",
    repo_name="demo-app",
    cluster="cluster-1",
    namespace="ws-1",
    product_id="gradio",
    product_version="1.0.0",
    description="Demo Gradio App",
)

# 上传代码到 Space 仓库
from xiaoshiai_hub import upload_folder
upload_folder(
    folder_path="./my_app",
    repo_id="myorg/demo-app",
    repo_type="spaces",
    username="your-username",
    password="your-password",
)

# 发布 Space
client.deploy_space("myorg", "demo-app")

# 查看状态
status = client.get_space_status("myorg", "demo-app")
print(f"状态: {status.phase}, 健康: {status.healthy}")
```

### 场景 6: 管理模型血缘关系

```python
from xiaoshiai_hub import HubClient

client = HubClient(username="your-username", password="your-password")

# 创建微调模型仓库，关联基础模型
client.create_repository(
    organization="myorg",
    repo_type="models",
    repo_name="llama-7b-chat",
    description="基于 Llama 7B 的对话微调模型",
    base_model=["myorg/llama-7b"],
    relationship="finetune",       # adapter/finetune/quantized/merge/repackage
    metadata={
        "license": ["apache-2.0"],
        "frameworks": ["transformers"],
        "tasks": ["text-generation"],
    },
)
```


## ⚠️ 重要说明

### 仓库必须先创建

在上传文件或文件夹之前，必须先在 Hub 上创建仓库。SDK 会自动检查仓库是否存在：

```python
from xiaoshiai_hub import upload_file
from xiaoshiai_hub.exceptions import RepositoryNotFoundError

try:
    result = upload_file(
        path_file="./model.bin",
        path_in_repo="model.bin",
        repo_id="myorg/my-model",
        username="your-username",
        password="your-password",
    )
except RepositoryNotFoundError as e:
    print(f"错误: {e}")
    print("请先在 Hub 上创建仓库")
```

### 加密文件的大小和类型限制

只有满足以下条件的文件才会被加密：

1. **文件大小** ≥ 5MB
2. **文件扩展名**为：`.safetensors`、`.bin`、`.pt`、`.pth`、`.ckpt`

其他文件保持原样，不会被加密。

### 临时文件清理

使用 `encryption_password` 时，SDK 会创建临时目录存放加密文件。上传完成后会自动清理，但如果上传失败，可能需要手动清理临时目录。

## 🔧 开发

### 设置开发环境

```bash
# 克隆仓库
git clone https://github.com/poxiaoyun/moha-sdk.git
cd moha-sdk

# 创建虚拟环境
python -m venv venv
source venv/bin/activate  # Linux/macOS
# 或
venv\Scripts\activate  # Windows

# 安装开发依赖
pip install -e ".[dev]"
```

### 项目结构

```
xiaoshiai_hub/
├── __init__.py          # 包入口，公开 API
├── client.py            # HubClient 核心客户端
├── download.py          # 下载功能
├── upload.py            # 上传功能（需要 gitpython）
├── auth.py              # 认证管理（Token 存储/读取）
├── cli.py               # 命令行工具入口
├── ai.py                # AI 智能助手（function calling）
├── envelope_crypto.py   # 信封加密模块（AES/SM4）
├── types.py             # 数据类型定义
└── exceptions.py        # 异常类型定义
```

### 可选依赖

```bash
# 上传功能需要 GitPython
pip install xiaoshiai-hub[upload]

# 运行测试
pip install xiaoshiai-hub[test]

# 完整开发环境
pip install xiaoshiai-hub[dev]
```

## 📚 API 参考

### 顶层函数

| 函数 | 说明 |
|------|------|
| `moha_hub_download()` | 下载仓库中的单个文件 |
| `snapshot_download()` | 下载整个仓库（支持模式过滤） |
| `upload_file()` | 上传单个文件到仓库 |
| `upload_folder()` | 上传文件夹到仓库 |
| `login()` | 登录并保存 Token |
| `save_token()` / `load_token()` / `delete_token()` | Token 管理 |
| `envelope_enc_file()` | 使用信封加密模式加密文件 |

### HubClient 方法

| 方法 | 说明 |
|------|------|
| `list_repositories()` | 列出仓库（支持范围/组织过滤） |
| `create_repository()` | 创建仓库 |
| `get_repository_info()` | 获取仓库信息 |
| `update_repository()` | 更新仓库信息 |
| `delete_repository()` | 删除仓库 |
| `get_repository_refs()` | 获取仓库分支列表 |
| `get_default_branch()` | 获取默认分支名称 |
| `create_branch()` | 创建分支 |
| `delete_branch()` | 删除分支 |
| `get_repository_content()` | 浏览仓库目录内容 |
| `create_file()` | 在仓库中创建/更新文件 |
| `delete_file()` | 删除仓库中的文件 |
| `download_file()` | 下载单个文件 |
| `create_space_repository()` | 创建 Space 仓库 |
| `deploy_space()` | 发布 Space |
| `redeploy_space()` | 重新发布 Space |
| `get_space_status()` | 获取 Space 状态 |
| `list_clusters()` | 列出可用集群 |
| `list_cluster_workspaces()` | 列出集群下的工作空间 |
| `list_workspace_flavors()` | 列出工作空间下的规格 |
| `list_products()` | 列出可用产品模版 |
| `get_product()` | 获取产品详情 |
| `set_repository_encrypted()` | 设置仓库加密标记 |
| `cancel_repository_encrypted()` | 取消仓库加密标记 |
| `generate_data_key()` | 通过 KMS 生成数据密钥 |

### 异常类型

| 异常 | 说明 |
|------|------|
| `HubException` | 所有 Hub 相关异常的基类 |
| `RepositoryNotFoundError` | 仓库不存在 |
| `FileNotFoundError` | 仓库中的文件不存在 |
| `AuthenticationError` | 认证失败 |
| `HTTPError` | HTTP 请求错误（含 `status_code` 属性） |
| `UploadError` | 上传操作失败 |

### 数据类型

| 类型 | 说明 |
|------|------|
| `Repository` | 仓库信息（名称、组织、可见性、元数据等） |
| `Ref` | Git 引用（分支/标签名称、哈希、是否默认） |
| `GitContent` | 仓库内容（文件/目录，含 LFS 元数据） |
| `Commit` | Git 提交信息 |
| `SpaceMetadata` | Space 元数据（集群、命名空间、状态） |
| `SpaceEndpoint` | Space 端点信息（名称、URL、类型） |
| `Cluster` / `ClusterWorkspace` / `Flavor` | 集群/工作空间/规格信息 |
| `Product` / `ProductVersion` | 产品模版及版本信息 |

## 🤝 贡献

欢迎贡献！请随时提交 Issue 或 Pull Request。

### 贡献指南

1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 开启 Pull Request

## 📄 许可证

本项目采用 Apache 2.0 许可证 - 详见 [LICENSE](LICENSE) 文件

## 💬 支持

如有问题或需要帮助，请：

1. 查看文档和示例
2. 搜索或创建 [Issue](https://github.com/poxiaoyun/moha-sdk/issues)
3. 联系维护者
