quarkpan


Namequarkpan JSON
Version 1.0.1 PyPI version JSON
download
home_pageNone
Summary夸克网盘 Python 客户端和命令行工具
upload_time2025-08-22 15:44:44
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords quark pan cloud storage cli api client 网盘
VCS
bugtrack_url
requirements httpx typer rich pydantic qrcode tqdm pytest pytest-asyncio
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # QuarkPan - 夸克网盘 Python 客户端

[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://www.python.org)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Version](https://img.shields.io/badge/Version-1.0.0-brightgreen.svg)](https://github.com/lich0821/QuarkPan)

一个功能完整的夸克网盘 Python API 客户端和命令行工具,支持文件管理、上传下载、分享转存等核心功能。提供简洁的 Python API 接口和强大的命令行工具,满足自动化脚本和日常使用需求。

## ✨ 主要功能

### 🔐 登录认证
- **API 二维码登录**: 通过官方 API 获取二维码,手机扫码安全登录
- **手动 Cookie 登录**: 支持手动输入 Cookie 的备用登录方式  
- **自动登录状态检查**: 智能检测登录状态,避免重复认证
- **安全 Cookie 管理**: 加密存储登录凭证,支持自动刷新

### 📁 文件管理
- **文件夹浏览**: 递归浏览文件夹,支持分页和路径导航
- **文件搜索**: 全盘关键词搜索,支持文件名和内容匹配
- **文件操作**: 创建、删除、重命名、移动文件和文件夹
- **批量操作**: 支持批量选择和处理多个文件
- **存储信息**: 实时查看网盘容量使用情况

### 📤 上传下载  
- **文件上传**: 支持单文件和文件夹上传,自动处理大文件分片
- **下载链接**: 获取文件直接下载地址,支持外部下载工具
- **进度显示**: 实时显示上传下载进度和速度
- **断点续传**: 支持大文件的断点续传功能

### 🔗 分享功能
- **创建分享**: 为文件 / 文件夹创建分享链接,支持密码和有效期设置
- **分享管理**: 查看、编辑、删除自己的分享记录
- **分享转存**: 将他人分享的资源一键转存到自己网盘
- **链接解析**: 智能识别和解析各种格式的分享链接

### 🖥️ 命令行工具
- **交互式界面**: 提供类似文件管理器的交互式命令行界面  
- **丰富命令集**: 涵盖所有网盘操作的完整命令集合
- **美观输出**: 使用 Rich 库提供彩色和格式化的终端输出
- **批量脚本**: 支持批量操作脚本和自动化任务

## 🚀 快速开始

### 安装

#### 方法一:从源码安装(推荐)
```bash
# 克隆项目
git clone https://github.com/lich0821/QuarkPan.git
cd QuarkPan

# 安装依赖
pip install -r requirements.txt

# 开发模式安装(可选)
pip install -e .
```

#### 方法二:直接使用
```bash
# 克隆后直接运行
git clone https://github.com/lich0821/QuarkPan.git
cd QuarkPan
pip install -r requirements.txt

# 三种运行方式任选其一:
# 1. 使用 Python 模块方式
python -m quark_client.cli --help

# 2. 直接运行 CLI 脚本
python cli.py --help

# 3. 安装后使用命令行工具(需要先运行 pip install -e .)
# quarkpan --help
```

### 快速体验

#### 1. 首次登录
```bash
# 启动交互式命令行工具(推荐新手使用)
python -m quark_client.cli interactive
# 或者
python cli.py interactive

# 直接进行二维码登录
python -m quark_client.cli auth login
# 或者
python cli.py auth login
```

#### 2. Python API 快速上手
```python
from quark_client import QuarkClient

# 创建客户端(首次使用会自动引导登录)
with QuarkClient() as client:
    # 检查登录状态
    if not client.is_logged_in():
        client.login()  # 自动打开二维码登录

    # 获取根目录文件列表
    files = client.list_files()
    print(f"找到 {len(files['data']['list'])} 个文件")

    # 搜索文件
    results = client.search_files("重要文档")

    # 获取存储信息
    storage = client.get_storage_info()
    print(f"已使用: {storage['data']['used'] / (1024**3):.2f} GB")
```

## 📖 详细使用说明

### Python API 使用

#### 基础文件操作
```python
from quark_client import QuarkClient

with QuarkClient() as client:
    # 文件列表获取
    files = client.list_files(folder_id="0", page=1, size=50)

    # 创建文件夹
    result = client.files.create_folder("新文件夹", parent_id="0")

    # 删除文件(支持批量)
    result = client.files.delete_files(["file_id_1", "file_id_2"])

    # 重命名文件
    result = client.files.rename_file("file_id", "新名称")

    # 移动文件(支持批量)
    result = client.files.move_files(["file_id"], "target_folder_id")

    # 搜索文件
    results = client.search_files("关键词", size=20)
```

#### 上传下载操作
```python
# 上传文件
result = client.upload.upload_file("本地文件.txt", parent_folder_id="0")

# 获取下载链接  
download_info = client.download.get_download_url("file_id")
download_url = download_info['download_url']

# 获取存储信息
storage = client.get_storage_info()
total_gb = storage['data']['total'] / (1024**3)
used_gb = storage['data']['used'] / (1024**3)
```

#### 分享管理
```python
# 创建分享链接
share = client.shares.create_share(
    file_ids=["file_id_1", "file_id_2"],
    title="我的分享",
    expire_days=7,
    password="1234"
)

# 获取我的分享列表
my_shares = client.shares.get_my_shares(page=1, size=20)

# 转存他人分享的文件
result = client.shares.save_shared_files(
    share_url="https://pan.quark.cn/s/abc123",
    password="1234",
    target_folder_id="0"
)

# 解析分享链接
share_id, password = client.shares.parse_share_url(
    "https://pan.quark.cn/s/abc123 密码: 1234"
)
```

### 命令行使用

> **说明**: 以下所有命令都提供两种运行方式:
> - `python -m quark_client.cli <command>` (模块方式)
> - `python cli.py <command>` (脚本方式)  
> - `quarkpan <command>` (安装后,需要先运行 `pip install -e .`)

#### 交互式模式(推荐新用户)
```bash  
# 启动交互式界面
python -m quark_client.cli interactive
# 或
python cli.py interactive

# 交互式界面提供类似文件管理器的体验:
# - 使用方向键浏览文件和文件夹
# - 按 Enter 进入文件夹或执行操作
# - 按 Tab 查看可用操作
# - 按 q 退出当前界面
```

#### 认证管理
```bash
# API 二维码登录(推荐)
python -m quark_client.cli auth login

# 手动 Cookie 登录
python -m quark_client.cli auth login --method simple

# 查看登录状态
python -m quark_client.cli auth status

# 登出账户
python -m quark_client.cli auth logout
```

#### 基础文件操作  
```bash
# 查看当前目录文件列表
python -m quark_client.cli ls

# 查看指定文件夹(使用文件夹 ID)
python -m quark_client.cli ls --folder-id FOLDER_ID

# 进入文件夹(切换当前工作目录)
python -m quark_client.cli cd 文件夹名称

# 返回上级目录
python -m quark_client.cli cd ..

# 创建文件夹
python -m quark_client.cli mkdir "新文件夹"

# 重命名文件/文件夹  
python -m quark_client.cli rename FILE_ID "新名称"

# 删除文件/文件夹
python -m quark_client.cli rm FILE_ID

# 移动文件到指定文件夹
python -m quark_client.cli mv FILE_ID FOLDER_ID

# 查看文件详细信息
python -m quark_client.cli info FILE_ID
```

#### 搜索功能
```bash
# 全盘搜索文件
python -m quark_client.cli search "关键词"

# 限制搜索结果数量
python -m quark_client.cli search "关键词" --limit 10

# 搜索特定文件类型
python -m quark_client.cli search "报告" --file-type pdf
```

#### 上传下载
```bash
# 上传文件到当前文件夹
python -m quark_client.cli upload "本地文件.txt"

# 上传到指定文件夹
python -m quark_client.cli upload "本地文件.txt" --folder-id FOLDER_ID

# 获取文件下载链接
python -m quark_client.cli download get FILE_ID

# 下载文件到本地
python -m quark_client.cli download FILE_ID --output "本地路径.txt"
```

#### 分享管理
```bash
# 创建文件分享
python -m quark_client.cli share create FILE_ID --title "分享标题" --password 1234

# 查看我的分享列表
python -m quark_client.cli share list

# 转存他人分享
python -m quark_client.cli share save "https://pan.quark.cn/s/abc123" --password 1234
```

## 🔐 登录认证详解

### API 二维码登录(推荐)

```bash
python -m quark_client.cli auth login
# 或
python cli.py auth login
```

**工作流程:**
1. 程序调用夸克官方 API 获取登录 token
2. 生成二维码并保存到 `config/qr_code.png`  
3. 在终端显示 ASCII 二维码
4. 使用夸克 APP 扫码确认登录
5. 自动获取并保存登录 Cookie
6. 验证登录状态并保存用户信息

**优点:**
- 安全可靠,使用官方 API
- 无需手动操作浏览器
- 自动化程度高

### 手动 Cookie 登录

```bash  
python -m quark_client.cli auth login --method simple
# 或
python cli.py auth login --method simple
```

**使用场景:**
- API 登录失败时的备用方案
- 已有有效 Cookie 需要快速导入
- 批量部署或脚本化场景

**操作步骤:**
1. 程序提供详细的 Cookie 获取指引
2. 用户手动从浏览器复制 Cookie
3. 粘贴到程序提示界面
4. 程序验证并保存 Cookie

### 登录状态管理

```bash
# 检查当前登录状态
python -m quark_client.cli auth status

# 查看用户信息
python -m quark_client.cli auth info  

# 刷新登录状态
python -m quark_client.cli auth refresh

# 退出登录
python -m quark_client.cli auth logout
```

**Cookie 安全说明:**
- Cookie 文件存储在 `config/cookies.json`
- 支持基础加密存储(可选)
- 自动检测 Cookie 过期并提醒重新登录
- 支持多账户 Cookie 管理(计划功能)

## 📚 API 使用说明

### 文件管理

```python
# 获取文件列表
files = client.list_files(folder_id="0", page=1, size=50)

# 创建文件夹
result = client.create_folder("新文件夹", parent_id="0")

# 删除文件
result = client.delete_files(["file_id_1", "file_id_2"])

# 重命名文件
result = client.rename_file("file_id", "新名称")

# 搜索文件
results = client.search_files("关键词")

# 上传文件
result = client.upload_file("本地文件.txt", parent_folder_id="0")

# 获取下载链接
download_url = client.get_download_url("file_id")
```

### 分享管理

```python
# 创建分享链接
share = client.create_share(
    file_ids=["file_id_1", "file_id_2"],
    title="我的分享",
    expire_days=7,
    password="1234"
)

# 解析分享链接
share_id, password = client.parse_share_url(
    "https://pan.quark.cn/s/abc123 密码: 1234"
)

# 转存分享文件
result = client.save_shared_files(
    share_url="https://pan.quark.cn/s/abc123",
    target_folder_id="0"
)

# 获取我的分享列表
shares = client.get_my_shares()
```

## 📁 项目结构

```
QuarkPan/
├── quark_client/             # 主要代码包
│   ├── __init__.py           # 包入口和导出定义
│   ├── client.py             # 主客户端类
│   ├── config.py             # 配置管理
│   ├── exceptions.py         # 异常定义
│   ├── auth/                 # 认证模块
│   │   ├── __init__.py  
│   │   ├── login.py         # 统一登录管理
│   │   ├── api_login.py     # API 二维码登录
│   │   └── simple_login.py  # 手动 Cookie 登录
│   ├── core/                # 核心 API 客户端
│   │   ├── __init__.py  
│   │   └── api_client.py    # HTTP 客户端和 API 封装
│   ├── services/            # 业务服务层
│   │   ├── __init__.py  
│   │   ├── file_service.py        # 文件管理服务
│   │   ├── file_upload_service.py # 文件上传服务
│   │   ├── file_download_service.py # 文件下载服务
│   │   ├── share_service.py       # 分享管理服务
│   │   └── name_resolver.py       # 文件名解析器
│   ├── cli/                 # 命令行界面
│   │   ├── __init__.py  
│   │   ├── __main__.py      # 模块入口 (python -m quark_client.cli)
│   │   ├── main.py          # CLI 主程序
│   │   ├── interactive.py   # 交互式界面
│   │   ├── utils.py         # CLI 工具函数
│   │   └── commands/        # 命令模块
│   │       ├── __init__.py
│   │       ├── auth.py            # 认证命令
│   │       ├── basic_fileops.py   # 基础文件操作
│   │       ├── download.py        # 下载命令
│   │       ├── move_commands.py   # 移动操作命令
│   │       ├── search.py          # 搜索命令
│   │       └── share_commands.py  # 分享命令
│   └── utils/               # 工具模块
│       ├── __init__.py  
│       ├── logger.py        # 日志工具
│       └── qr_code.py       # 二维码工具
├── examples/                # 使用示例
│   ├── basic_usage.py       # 基础功能演示
│   ├── file_operations_demo.py # 文件操作演示
│   ├── file_browser_demo.py # 文件浏览器演示
│   └── share_save_demo.py   # 分享转存演示
├── config/                  # 配置文件目录
│   ├── cookies.json         # 登录 Cookie 存储
│   ├── login_result.json    # 登录结果缓存
│   ├── qr_code.png          # 二维码图片
│   └── user_info.json       # 用户信息缓存
├── cli.py                   # CLI 直接入口脚本
├── setup.py                 # 安装配置
├── requirements.txt         # 依赖列表
├── LICENSE                  # 开源协议
└── README.md                # 项目说明
```

## 🧪 运行示例

项目提供了多个示例文件,帮助你快速了解各种功能的使用方法:

### 基础使用示例
```bash  
# 演示基本功能:登录、获取文件列表、搜索、存储信息
python examples/basic_usage.py
```

**功能演示:**
- ✅ 自动登录认证
- 📁 获取根目录文件列表(显示前 5 个)
- 💾 查看存储容量信息  
- 🔍 全盘文件搜索演示
- 🔗 获取个人分享列表

### 文件操作演示  
```bash
# 完整的文件管理操作流程演示
python examples/file_operations_demo.py
```

**功能演示:**
- 📂 浏览和列出文件夹内容
- ➕ 创建测试文件夹和子文件夹
- ✏️ 重命名文件和文件夹
- 📦 移动文件到不同文件夹
- 🗑️ 删除文件和清理测试数据
- 🔍 多关键词搜索演示

### 文件浏览器演示
```bash
# 交互式文件浏览器体验
python examples/file_browser_demo.py  
```

**功能演示:**
- 🖥️ 类似系统文件管理器的界面
- ⬆️⬇️ 方向键导航文件列表
- 📁 双击进入文件夹
- 📋 查看文件详细信息
- 🔄 实时刷新文件列表

### 分享转存演示
```bash
# 分享链接创建和转存功能
python examples/share_save_demo.py
```

**功能演示:**
- 🔗 创建文件分享链接(带密码和有效期)
- 📋 管理个人分享列表  
- 💾 转存他人分享的资源
- 🔍 分享链接格式解析
- 📊 分享文件详情查看

### 组合使用示例

你也可以组合使用多个示例来体验完整工作流:

```bash
# 完整体验流程
python examples/basic_usage.py          # 1. 首先体验基础功能
python examples/file_operations_demo.py # 2. 然后体验文件操作
python examples/share_save_demo.py      # 3. 最后体验分享功能
```

**注意事项:**
- 🔑 首次运行需要完成登录认证
- ⚠️ 某些操作会创建测试数据,程序会自动清理
- 📱 需要手机安装夸克 APP 用于扫码登录
- 🌐 需要稳定的网络连接

## 📦 依赖说明

### 核心依赖
- **httpx** (>=0.24.0): 现代化 HTTP 客户端,支持异步请求
- **pydantic** (>=2.0.0): 数据验证和类型注解
- **typer** (>=0.9.0): 现代化命令行界面框架
- **rich** (>=13.0.0): 美化终端输出和交互

### 二维码支持  
- **qrcode** (>=7.4.0): 二维码生成和终端ASCII显示

### 用户体验
- **tqdm** (>=4.65.0): 进度条显示

### 开发和测试
- **pytest** (>=7.0.0): 测试框架
- **pytest-asyncio** (>=0.21.0): 异步测试支持

### 依赖安装
```bash
# 安装所有依赖
pip install -r requirements.txt

# 仅安装核心依赖(最小化安装)  
pip install httpx typer rich pydantic

# 开发环境安装(包含测试工具)
pip install -r requirements.txt pytest pytest-asyncio
```

### 系统要求
- **Python**: 3.8 或更高版本
- **操作系统**: Windows/macOS/Linux
- **内存**: 建议 512MB 以上可用内存
- **网络**: 需要稳定的互联网连接
- **终端**: 支持 UTF-8 编码的终端(推荐)

## ⚠️ 注意事项与免责声明

### 使用须知
1. **首次使用**: 需要通过扫码或手动方式完成登录认证
2. **配置文件**: 登录信息保存在 `config/cookies.json`,请妥善保管
3. **网络环境**: 建议在稳定的网络环境下使用,避免上传 / 下载中断
4. **账号安全**: 请使用官方夸克 APP 进行扫码登录,确保账号安全
5. **功能限制**: 部分功能受夸克网盘官方 API 限制,可能会有调用频率限制

### 技术限制
- **大文件处理**: 超大文件的上传下载可能需要较长时间
- **并发限制**: 为避免触发反爬限制,默认限制并发请求数量
- **API 变更**: 夸克网盘官方 API 可能随时变更,导致部分功能暂时不可用
- **登录有效期**: Cookie 有效期有限,过期后需要重新登录

### 免责声明
1. **仅供学习**: 本项目仅用于学习和个人使用,不得用于商业用途
2. **使用风险**: 用户使用本工具所产生的任何风险和责任由用户自行承担
3. **服务条款**: 使用时请遵守夸克网盘的官方服务条款和用户协议
4. **数据安全**: 请勿使用本工具处理敏感或重要数据,作者不承担数据损失责任
5. **法律合规**: 用户应确保使用行为符合当地法律法规要求

### 故障排除
- **登录失败**: 尝试清除 `config/cookies.json` 后重新登录
- **API 错误**: 检查网络连接,或等待片刻后重试
- **二维码不显示**: 检查终端是否支持图片显示,或查看 `config/qr_code.png`
- **上传 / 下载中断**: 检查文件路径和网络连接状态
- **命令行乱码**: 确保终端支持 UTF-8 编码

### 获取帮助
- **GitHub Issues**: [提交问题报告](https://github.com/lich0821/QuarkPan/issues)
- **示例代码**: 参考 `examples/` 目录下的示例文件
- **微信群**: 发送 `WCF` 进群交流
<center>

![公众号搜索【漩智】加入社区](QrCode.jpg)
</center>

### 贡献指南
欢迎提交 Issue 和 Pull Request!在贡献代码前,请:
1. 阅读项目的代码风格规范
2. 确保新功能有对应的测试用例
3. 更新相关文档和示例代码
4. 遵循 MIT 开源协议

## 📄 许可协议

本项目采用 [MIT License](LICENSE) 开源协议。

---
⭐ 如果这个项目对你有帮助,请给个 Star 支持一下!

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "quarkpan",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "QuarkPan Team <tequant.ai@gmail.com>",
    "keywords": "quark, pan, cloud, storage, cli, api, client, \u7f51\u76d8",
    "author": null,
    "author_email": "QuarkPan Team <tequant.ai@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/89/be/50129257dde6aedb567b10c85bcc5bc2324cd5ae50f663466e4516d4c698/quarkpan-1.0.1.tar.gz",
    "platform": null,
    "description": "# QuarkPan - \u5938\u514b\u7f51\u76d8 Python \u5ba2\u6237\u7aef\n\n[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://www.python.org)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Version](https://img.shields.io/badge/Version-1.0.0-brightgreen.svg)](https://github.com/lich0821/QuarkPan)\n\n\u4e00\u4e2a\u529f\u80fd\u5b8c\u6574\u7684\u5938\u514b\u7f51\u76d8 Python API \u5ba2\u6237\u7aef\u548c\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u652f\u6301\u6587\u4ef6\u7ba1\u7406\u3001\u4e0a\u4f20\u4e0b\u8f7d\u3001\u5206\u4eab\u8f6c\u5b58\u7b49\u6838\u5fc3\u529f\u80fd\u3002\u63d0\u4f9b\u7b80\u6d01\u7684 Python API \u63a5\u53e3\u548c\u5f3a\u5927\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u6ee1\u8db3\u81ea\u52a8\u5316\u811a\u672c\u548c\u65e5\u5e38\u4f7f\u7528\u9700\u6c42\u3002\n\n## \u2728 \u4e3b\u8981\u529f\u80fd\n\n### \ud83d\udd10 \u767b\u5f55\u8ba4\u8bc1\n- **API \u4e8c\u7ef4\u7801\u767b\u5f55**: \u901a\u8fc7\u5b98\u65b9 API \u83b7\u53d6\u4e8c\u7ef4\u7801\uff0c\u624b\u673a\u626b\u7801\u5b89\u5168\u767b\u5f55\n- **\u624b\u52a8 Cookie \u767b\u5f55**: \u652f\u6301\u624b\u52a8\u8f93\u5165 Cookie \u7684\u5907\u7528\u767b\u5f55\u65b9\u5f0f  \n- **\u81ea\u52a8\u767b\u5f55\u72b6\u6001\u68c0\u67e5**: \u667a\u80fd\u68c0\u6d4b\u767b\u5f55\u72b6\u6001\uff0c\u907f\u514d\u91cd\u590d\u8ba4\u8bc1\n- **\u5b89\u5168 Cookie \u7ba1\u7406**: \u52a0\u5bc6\u5b58\u50a8\u767b\u5f55\u51ed\u8bc1\uff0c\u652f\u6301\u81ea\u52a8\u5237\u65b0\n\n### \ud83d\udcc1 \u6587\u4ef6\u7ba1\u7406\n- **\u6587\u4ef6\u5939\u6d4f\u89c8**: \u9012\u5f52\u6d4f\u89c8\u6587\u4ef6\u5939\uff0c\u652f\u6301\u5206\u9875\u548c\u8def\u5f84\u5bfc\u822a\n- **\u6587\u4ef6\u641c\u7d22**: \u5168\u76d8\u5173\u952e\u8bcd\u641c\u7d22\uff0c\u652f\u6301\u6587\u4ef6\u540d\u548c\u5185\u5bb9\u5339\u914d\n- **\u6587\u4ef6\u64cd\u4f5c**: \u521b\u5efa\u3001\u5220\u9664\u3001\u91cd\u547d\u540d\u3001\u79fb\u52a8\u6587\u4ef6\u548c\u6587\u4ef6\u5939\n- **\u6279\u91cf\u64cd\u4f5c**: \u652f\u6301\u6279\u91cf\u9009\u62e9\u548c\u5904\u7406\u591a\u4e2a\u6587\u4ef6\n- **\u5b58\u50a8\u4fe1\u606f**: \u5b9e\u65f6\u67e5\u770b\u7f51\u76d8\u5bb9\u91cf\u4f7f\u7528\u60c5\u51b5\n\n### \ud83d\udce4 \u4e0a\u4f20\u4e0b\u8f7d  \n- **\u6587\u4ef6\u4e0a\u4f20**: \u652f\u6301\u5355\u6587\u4ef6\u548c\u6587\u4ef6\u5939\u4e0a\u4f20\uff0c\u81ea\u52a8\u5904\u7406\u5927\u6587\u4ef6\u5206\u7247\n- **\u4e0b\u8f7d\u94fe\u63a5**: \u83b7\u53d6\u6587\u4ef6\u76f4\u63a5\u4e0b\u8f7d\u5730\u5740\uff0c\u652f\u6301\u5916\u90e8\u4e0b\u8f7d\u5de5\u5177\n- **\u8fdb\u5ea6\u663e\u793a**: \u5b9e\u65f6\u663e\u793a\u4e0a\u4f20\u4e0b\u8f7d\u8fdb\u5ea6\u548c\u901f\u5ea6\n- **\u65ad\u70b9\u7eed\u4f20**: \u652f\u6301\u5927\u6587\u4ef6\u7684\u65ad\u70b9\u7eed\u4f20\u529f\u80fd\n\n### \ud83d\udd17 \u5206\u4eab\u529f\u80fd\n- **\u521b\u5efa\u5206\u4eab**: \u4e3a\u6587\u4ef6 / \u6587\u4ef6\u5939\u521b\u5efa\u5206\u4eab\u94fe\u63a5\uff0c\u652f\u6301\u5bc6\u7801\u548c\u6709\u6548\u671f\u8bbe\u7f6e\n- **\u5206\u4eab\u7ba1\u7406**: \u67e5\u770b\u3001\u7f16\u8f91\u3001\u5220\u9664\u81ea\u5df1\u7684\u5206\u4eab\u8bb0\u5f55\n- **\u5206\u4eab\u8f6c\u5b58**: \u5c06\u4ed6\u4eba\u5206\u4eab\u7684\u8d44\u6e90\u4e00\u952e\u8f6c\u5b58\u5230\u81ea\u5df1\u7f51\u76d8\n- **\u94fe\u63a5\u89e3\u6790**: \u667a\u80fd\u8bc6\u522b\u548c\u89e3\u6790\u5404\u79cd\u683c\u5f0f\u7684\u5206\u4eab\u94fe\u63a5\n\n### \ud83d\udda5\ufe0f \u547d\u4ee4\u884c\u5de5\u5177\n- **\u4ea4\u4e92\u5f0f\u754c\u9762**: \u63d0\u4f9b\u7c7b\u4f3c\u6587\u4ef6\u7ba1\u7406\u5668\u7684\u4ea4\u4e92\u5f0f\u547d\u4ee4\u884c\u754c\u9762  \n- **\u4e30\u5bcc\u547d\u4ee4\u96c6**: \u6db5\u76d6\u6240\u6709\u7f51\u76d8\u64cd\u4f5c\u7684\u5b8c\u6574\u547d\u4ee4\u96c6\u5408\n- **\u7f8e\u89c2\u8f93\u51fa**: \u4f7f\u7528 Rich \u5e93\u63d0\u4f9b\u5f69\u8272\u548c\u683c\u5f0f\u5316\u7684\u7ec8\u7aef\u8f93\u51fa\n- **\u6279\u91cf\u811a\u672c**: \u652f\u6301\u6279\u91cf\u64cd\u4f5c\u811a\u672c\u548c\u81ea\u52a8\u5316\u4efb\u52a1\n\n## \ud83d\ude80 \u5feb\u901f\u5f00\u59cb\n\n### \u5b89\u88c5\n\n#### \u65b9\u6cd5\u4e00\uff1a\u4ece\u6e90\u7801\u5b89\u88c5\uff08\u63a8\u8350\uff09\n```bash\n# \u514b\u9686\u9879\u76ee\ngit clone https://github.com/lich0821/QuarkPan.git\ncd QuarkPan\n\n# \u5b89\u88c5\u4f9d\u8d56\npip install -r requirements.txt\n\n# \u5f00\u53d1\u6a21\u5f0f\u5b89\u88c5\uff08\u53ef\u9009\uff09\npip install -e .\n```\n\n#### \u65b9\u6cd5\u4e8c\uff1a\u76f4\u63a5\u4f7f\u7528\n```bash\n# \u514b\u9686\u540e\u76f4\u63a5\u8fd0\u884c\ngit clone https://github.com/lich0821/QuarkPan.git\ncd QuarkPan\npip install -r requirements.txt\n\n# \u4e09\u79cd\u8fd0\u884c\u65b9\u5f0f\u4efb\u9009\u5176\u4e00\uff1a\n# 1. \u4f7f\u7528 Python \u6a21\u5757\u65b9\u5f0f\npython -m quark_client.cli --help\n\n# 2. \u76f4\u63a5\u8fd0\u884c CLI \u811a\u672c\npython cli.py --help\n\n# 3. \u5b89\u88c5\u540e\u4f7f\u7528\u547d\u4ee4\u884c\u5de5\u5177\uff08\u9700\u8981\u5148\u8fd0\u884c pip install -e .\uff09\n# quarkpan --help\n```\n\n### \u5feb\u901f\u4f53\u9a8c\n\n#### 1. \u9996\u6b21\u767b\u5f55\n```bash\n# \u542f\u52a8\u4ea4\u4e92\u5f0f\u547d\u4ee4\u884c\u5de5\u5177\uff08\u63a8\u8350\u65b0\u624b\u4f7f\u7528\uff09\npython -m quark_client.cli interactive\n# \u6216\u8005\npython cli.py interactive\n\n# \u76f4\u63a5\u8fdb\u884c\u4e8c\u7ef4\u7801\u767b\u5f55\npython -m quark_client.cli auth login\n# \u6216\u8005\npython cli.py auth login\n```\n\n#### 2. Python API \u5feb\u901f\u4e0a\u624b\n```python\nfrom quark_client import QuarkClient\n\n# \u521b\u5efa\u5ba2\u6237\u7aef\uff08\u9996\u6b21\u4f7f\u7528\u4f1a\u81ea\u52a8\u5f15\u5bfc\u767b\u5f55\uff09\nwith QuarkClient() as client:\n    # \u68c0\u67e5\u767b\u5f55\u72b6\u6001\n    if not client.is_logged_in():\n        client.login()  # \u81ea\u52a8\u6253\u5f00\u4e8c\u7ef4\u7801\u767b\u5f55\n\n    # \u83b7\u53d6\u6839\u76ee\u5f55\u6587\u4ef6\u5217\u8868\n    files = client.list_files()\n    print(f\"\u627e\u5230 {len(files['data']['list'])} \u4e2a\u6587\u4ef6\")\n\n    # \u641c\u7d22\u6587\u4ef6\n    results = client.search_files(\"\u91cd\u8981\u6587\u6863\")\n\n    # \u83b7\u53d6\u5b58\u50a8\u4fe1\u606f\n    storage = client.get_storage_info()\n    print(f\"\u5df2\u4f7f\u7528: {storage['data']['used'] / (1024**3):.2f} GB\")\n```\n\n## \ud83d\udcd6 \u8be6\u7ec6\u4f7f\u7528\u8bf4\u660e\n\n### Python API \u4f7f\u7528\n\n#### \u57fa\u7840\u6587\u4ef6\u64cd\u4f5c\n```python\nfrom quark_client import QuarkClient\n\nwith QuarkClient() as client:\n    # \u6587\u4ef6\u5217\u8868\u83b7\u53d6\n    files = client.list_files(folder_id=\"0\", page=1, size=50)\n\n    # \u521b\u5efa\u6587\u4ef6\u5939\n    result = client.files.create_folder(\"\u65b0\u6587\u4ef6\u5939\", parent_id=\"0\")\n\n    # \u5220\u9664\u6587\u4ef6\uff08\u652f\u6301\u6279\u91cf\uff09\n    result = client.files.delete_files([\"file_id_1\", \"file_id_2\"])\n\n    # \u91cd\u547d\u540d\u6587\u4ef6\n    result = client.files.rename_file(\"file_id\", \"\u65b0\u540d\u79f0\")\n\n    # \u79fb\u52a8\u6587\u4ef6\uff08\u652f\u6301\u6279\u91cf\uff09\n    result = client.files.move_files([\"file_id\"], \"target_folder_id\")\n\n    # \u641c\u7d22\u6587\u4ef6\n    results = client.search_files(\"\u5173\u952e\u8bcd\", size=20)\n```\n\n#### \u4e0a\u4f20\u4e0b\u8f7d\u64cd\u4f5c\n```python\n# \u4e0a\u4f20\u6587\u4ef6\nresult = client.upload.upload_file(\"\u672c\u5730\u6587\u4ef6.txt\", parent_folder_id=\"0\")\n\n# \u83b7\u53d6\u4e0b\u8f7d\u94fe\u63a5  \ndownload_info = client.download.get_download_url(\"file_id\")\ndownload_url = download_info['download_url']\n\n# \u83b7\u53d6\u5b58\u50a8\u4fe1\u606f\nstorage = client.get_storage_info()\ntotal_gb = storage['data']['total'] / (1024**3)\nused_gb = storage['data']['used'] / (1024**3)\n```\n\n#### \u5206\u4eab\u7ba1\u7406\n```python\n# \u521b\u5efa\u5206\u4eab\u94fe\u63a5\nshare = client.shares.create_share(\n    file_ids=[\"file_id_1\", \"file_id_2\"],\n    title=\"\u6211\u7684\u5206\u4eab\",\n    expire_days=7,\n    password=\"1234\"\n)\n\n# \u83b7\u53d6\u6211\u7684\u5206\u4eab\u5217\u8868\nmy_shares = client.shares.get_my_shares(page=1, size=20)\n\n# \u8f6c\u5b58\u4ed6\u4eba\u5206\u4eab\u7684\u6587\u4ef6\nresult = client.shares.save_shared_files(\n    share_url=\"https://pan.quark.cn/s/abc123\",\n    password=\"1234\",\n    target_folder_id=\"0\"\n)\n\n# \u89e3\u6790\u5206\u4eab\u94fe\u63a5\nshare_id, password = client.shares.parse_share_url(\n    \"https://pan.quark.cn/s/abc123 \u5bc6\u7801: 1234\"\n)\n```\n\n### \u547d\u4ee4\u884c\u4f7f\u7528\n\n> **\u8bf4\u660e**: \u4ee5\u4e0b\u6240\u6709\u547d\u4ee4\u90fd\u63d0\u4f9b\u4e24\u79cd\u8fd0\u884c\u65b9\u5f0f\uff1a\n> - `python -m quark_client.cli <command>` \uff08\u6a21\u5757\u65b9\u5f0f\uff09\n> - `python cli.py <command>` \uff08\u811a\u672c\u65b9\u5f0f\uff09  \n> - `quarkpan <command>` \uff08\u5b89\u88c5\u540e\uff0c\u9700\u8981\u5148\u8fd0\u884c `pip install -e .`\uff09\n\n#### \u4ea4\u4e92\u5f0f\u6a21\u5f0f\uff08\u63a8\u8350\u65b0\u7528\u6237\uff09\n```bash  \n# \u542f\u52a8\u4ea4\u4e92\u5f0f\u754c\u9762\npython -m quark_client.cli interactive\n# \u6216\npython cli.py interactive\n\n# \u4ea4\u4e92\u5f0f\u754c\u9762\u63d0\u4f9b\u7c7b\u4f3c\u6587\u4ef6\u7ba1\u7406\u5668\u7684\u4f53\u9a8c\uff1a\n# - \u4f7f\u7528\u65b9\u5411\u952e\u6d4f\u89c8\u6587\u4ef6\u548c\u6587\u4ef6\u5939\n# - \u6309 Enter \u8fdb\u5165\u6587\u4ef6\u5939\u6216\u6267\u884c\u64cd\u4f5c\n# - \u6309 Tab \u67e5\u770b\u53ef\u7528\u64cd\u4f5c\n# - \u6309 q \u9000\u51fa\u5f53\u524d\u754c\u9762\n```\n\n#### \u8ba4\u8bc1\u7ba1\u7406\n```bash\n# API \u4e8c\u7ef4\u7801\u767b\u5f55\uff08\u63a8\u8350\uff09\npython -m quark_client.cli auth login\n\n# \u624b\u52a8 Cookie \u767b\u5f55\npython -m quark_client.cli auth login --method simple\n\n# \u67e5\u770b\u767b\u5f55\u72b6\u6001\npython -m quark_client.cli auth status\n\n# \u767b\u51fa\u8d26\u6237\npython -m quark_client.cli auth logout\n```\n\n#### \u57fa\u7840\u6587\u4ef6\u64cd\u4f5c  \n```bash\n# \u67e5\u770b\u5f53\u524d\u76ee\u5f55\u6587\u4ef6\u5217\u8868\npython -m quark_client.cli ls\n\n# \u67e5\u770b\u6307\u5b9a\u6587\u4ef6\u5939\uff08\u4f7f\u7528\u6587\u4ef6\u5939 ID\uff09\npython -m quark_client.cli ls --folder-id FOLDER_ID\n\n# \u8fdb\u5165\u6587\u4ef6\u5939\uff08\u5207\u6362\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\uff09\npython -m quark_client.cli cd \u6587\u4ef6\u5939\u540d\u79f0\n\n# \u8fd4\u56de\u4e0a\u7ea7\u76ee\u5f55\npython -m quark_client.cli cd ..\n\n# \u521b\u5efa\u6587\u4ef6\u5939\npython -m quark_client.cli mkdir \"\u65b0\u6587\u4ef6\u5939\"\n\n# \u91cd\u547d\u540d\u6587\u4ef6/\u6587\u4ef6\u5939  \npython -m quark_client.cli rename FILE_ID \"\u65b0\u540d\u79f0\"\n\n# \u5220\u9664\u6587\u4ef6/\u6587\u4ef6\u5939\npython -m quark_client.cli rm FILE_ID\n\n# \u79fb\u52a8\u6587\u4ef6\u5230\u6307\u5b9a\u6587\u4ef6\u5939\npython -m quark_client.cli mv FILE_ID FOLDER_ID\n\n# \u67e5\u770b\u6587\u4ef6\u8be6\u7ec6\u4fe1\u606f\npython -m quark_client.cli info FILE_ID\n```\n\n#### \u641c\u7d22\u529f\u80fd\n```bash\n# \u5168\u76d8\u641c\u7d22\u6587\u4ef6\npython -m quark_client.cli search \"\u5173\u952e\u8bcd\"\n\n# \u9650\u5236\u641c\u7d22\u7ed3\u679c\u6570\u91cf\npython -m quark_client.cli search \"\u5173\u952e\u8bcd\" --limit 10\n\n# \u641c\u7d22\u7279\u5b9a\u6587\u4ef6\u7c7b\u578b\npython -m quark_client.cli search \"\u62a5\u544a\" --file-type pdf\n```\n\n#### \u4e0a\u4f20\u4e0b\u8f7d\n```bash\n# \u4e0a\u4f20\u6587\u4ef6\u5230\u5f53\u524d\u6587\u4ef6\u5939\npython -m quark_client.cli upload \"\u672c\u5730\u6587\u4ef6.txt\"\n\n# \u4e0a\u4f20\u5230\u6307\u5b9a\u6587\u4ef6\u5939\npython -m quark_client.cli upload \"\u672c\u5730\u6587\u4ef6.txt\" --folder-id FOLDER_ID\n\n# \u83b7\u53d6\u6587\u4ef6\u4e0b\u8f7d\u94fe\u63a5\npython -m quark_client.cli download get FILE_ID\n\n# \u4e0b\u8f7d\u6587\u4ef6\u5230\u672c\u5730\npython -m quark_client.cli download FILE_ID --output \"\u672c\u5730\u8def\u5f84.txt\"\n```\n\n#### \u5206\u4eab\u7ba1\u7406\n```bash\n# \u521b\u5efa\u6587\u4ef6\u5206\u4eab\npython -m quark_client.cli share create FILE_ID --title \"\u5206\u4eab\u6807\u9898\" --password 1234\n\n# \u67e5\u770b\u6211\u7684\u5206\u4eab\u5217\u8868\npython -m quark_client.cli share list\n\n# \u8f6c\u5b58\u4ed6\u4eba\u5206\u4eab\npython -m quark_client.cli share save \"https://pan.quark.cn/s/abc123\" --password 1234\n```\n\n## \ud83d\udd10 \u767b\u5f55\u8ba4\u8bc1\u8be6\u89e3\n\n### API \u4e8c\u7ef4\u7801\u767b\u5f55\uff08\u63a8\u8350\uff09\n\n```bash\npython -m quark_client.cli auth login\n# \u6216\npython cli.py auth login\n```\n\n**\u5de5\u4f5c\u6d41\u7a0b\uff1a**\n1. \u7a0b\u5e8f\u8c03\u7528\u5938\u514b\u5b98\u65b9 API \u83b7\u53d6\u767b\u5f55 token\n2. \u751f\u6210\u4e8c\u7ef4\u7801\u5e76\u4fdd\u5b58\u5230 `config/qr_code.png`  \n3. \u5728\u7ec8\u7aef\u663e\u793a ASCII \u4e8c\u7ef4\u7801\n4. \u4f7f\u7528\u5938\u514b APP \u626b\u7801\u786e\u8ba4\u767b\u5f55\n5. \u81ea\u52a8\u83b7\u53d6\u5e76\u4fdd\u5b58\u767b\u5f55 Cookie\n6. \u9a8c\u8bc1\u767b\u5f55\u72b6\u6001\u5e76\u4fdd\u5b58\u7528\u6237\u4fe1\u606f\n\n**\u4f18\u70b9\uff1a**\n- \u5b89\u5168\u53ef\u9760\uff0c\u4f7f\u7528\u5b98\u65b9 API\n- \u65e0\u9700\u624b\u52a8\u64cd\u4f5c\u6d4f\u89c8\u5668\n- \u81ea\u52a8\u5316\u7a0b\u5ea6\u9ad8\n\n### \u624b\u52a8 Cookie \u767b\u5f55\n\n```bash  \npython -m quark_client.cli auth login --method simple\n# \u6216\npython cli.py auth login --method simple\n```\n\n**\u4f7f\u7528\u573a\u666f\uff1a**\n- API \u767b\u5f55\u5931\u8d25\u65f6\u7684\u5907\u7528\u65b9\u6848\n- \u5df2\u6709\u6709\u6548 Cookie \u9700\u8981\u5feb\u901f\u5bfc\u5165\n- \u6279\u91cf\u90e8\u7f72\u6216\u811a\u672c\u5316\u573a\u666f\n\n**\u64cd\u4f5c\u6b65\u9aa4\uff1a**\n1. \u7a0b\u5e8f\u63d0\u4f9b\u8be6\u7ec6\u7684 Cookie \u83b7\u53d6\u6307\u5f15\n2. \u7528\u6237\u624b\u52a8\u4ece\u6d4f\u89c8\u5668\u590d\u5236 Cookie\n3. \u7c98\u8d34\u5230\u7a0b\u5e8f\u63d0\u793a\u754c\u9762\n4. \u7a0b\u5e8f\u9a8c\u8bc1\u5e76\u4fdd\u5b58 Cookie\n\n### \u767b\u5f55\u72b6\u6001\u7ba1\u7406\n\n```bash\n# \u68c0\u67e5\u5f53\u524d\u767b\u5f55\u72b6\u6001\npython -m quark_client.cli auth status\n\n# \u67e5\u770b\u7528\u6237\u4fe1\u606f\npython -m quark_client.cli auth info  \n\n# \u5237\u65b0\u767b\u5f55\u72b6\u6001\npython -m quark_client.cli auth refresh\n\n# \u9000\u51fa\u767b\u5f55\npython -m quark_client.cli auth logout\n```\n\n**Cookie \u5b89\u5168\u8bf4\u660e\uff1a**\n- Cookie \u6587\u4ef6\u5b58\u50a8\u5728 `config/cookies.json`\n- \u652f\u6301\u57fa\u7840\u52a0\u5bc6\u5b58\u50a8\uff08\u53ef\u9009\uff09\n- \u81ea\u52a8\u68c0\u6d4b Cookie \u8fc7\u671f\u5e76\u63d0\u9192\u91cd\u65b0\u767b\u5f55\n- \u652f\u6301\u591a\u8d26\u6237 Cookie \u7ba1\u7406\uff08\u8ba1\u5212\u529f\u80fd\uff09\n\n## \ud83d\udcda API \u4f7f\u7528\u8bf4\u660e\n\n### \u6587\u4ef6\u7ba1\u7406\n\n```python\n# \u83b7\u53d6\u6587\u4ef6\u5217\u8868\nfiles = client.list_files(folder_id=\"0\", page=1, size=50)\n\n# \u521b\u5efa\u6587\u4ef6\u5939\nresult = client.create_folder(\"\u65b0\u6587\u4ef6\u5939\", parent_id=\"0\")\n\n# \u5220\u9664\u6587\u4ef6\nresult = client.delete_files([\"file_id_1\", \"file_id_2\"])\n\n# \u91cd\u547d\u540d\u6587\u4ef6\nresult = client.rename_file(\"file_id\", \"\u65b0\u540d\u79f0\")\n\n# \u641c\u7d22\u6587\u4ef6\nresults = client.search_files(\"\u5173\u952e\u8bcd\")\n\n# \u4e0a\u4f20\u6587\u4ef6\nresult = client.upload_file(\"\u672c\u5730\u6587\u4ef6.txt\", parent_folder_id=\"0\")\n\n# \u83b7\u53d6\u4e0b\u8f7d\u94fe\u63a5\ndownload_url = client.get_download_url(\"file_id\")\n```\n\n### \u5206\u4eab\u7ba1\u7406\n\n```python\n# \u521b\u5efa\u5206\u4eab\u94fe\u63a5\nshare = client.create_share(\n    file_ids=[\"file_id_1\", \"file_id_2\"],\n    title=\"\u6211\u7684\u5206\u4eab\",\n    expire_days=7,\n    password=\"1234\"\n)\n\n# \u89e3\u6790\u5206\u4eab\u94fe\u63a5\nshare_id, password = client.parse_share_url(\n    \"https://pan.quark.cn/s/abc123 \u5bc6\u7801: 1234\"\n)\n\n# \u8f6c\u5b58\u5206\u4eab\u6587\u4ef6\nresult = client.save_shared_files(\n    share_url=\"https://pan.quark.cn/s/abc123\",\n    target_folder_id=\"0\"\n)\n\n# \u83b7\u53d6\u6211\u7684\u5206\u4eab\u5217\u8868\nshares = client.get_my_shares()\n```\n\n## \ud83d\udcc1 \u9879\u76ee\u7ed3\u6784\n\n```\nQuarkPan/\n\u251c\u2500\u2500 quark_client/             # \u4e3b\u8981\u4ee3\u7801\u5305\n\u2502   \u251c\u2500\u2500 __init__.py           # \u5305\u5165\u53e3\u548c\u5bfc\u51fa\u5b9a\u4e49\n\u2502   \u251c\u2500\u2500 client.py             # \u4e3b\u5ba2\u6237\u7aef\u7c7b\n\u2502   \u251c\u2500\u2500 config.py             # \u914d\u7f6e\u7ba1\u7406\n\u2502   \u251c\u2500\u2500 exceptions.py         # \u5f02\u5e38\u5b9a\u4e49\n\u2502   \u251c\u2500\u2500 auth/                 # \u8ba4\u8bc1\u6a21\u5757\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py  \n\u2502   \u2502   \u251c\u2500\u2500 login.py         # \u7edf\u4e00\u767b\u5f55\u7ba1\u7406\n\u2502   \u2502   \u251c\u2500\u2500 api_login.py     # API \u4e8c\u7ef4\u7801\u767b\u5f55\n\u2502   \u2502   \u2514\u2500\u2500 simple_login.py  # \u624b\u52a8 Cookie \u767b\u5f55\n\u2502   \u251c\u2500\u2500 core/                # \u6838\u5fc3 API \u5ba2\u6237\u7aef\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py  \n\u2502   \u2502   \u2514\u2500\u2500 api_client.py    # HTTP \u5ba2\u6237\u7aef\u548c API \u5c01\u88c5\n\u2502   \u251c\u2500\u2500 services/            # \u4e1a\u52a1\u670d\u52a1\u5c42\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py  \n\u2502   \u2502   \u251c\u2500\u2500 file_service.py        # \u6587\u4ef6\u7ba1\u7406\u670d\u52a1\n\u2502   \u2502   \u251c\u2500\u2500 file_upload_service.py # \u6587\u4ef6\u4e0a\u4f20\u670d\u52a1\n\u2502   \u2502   \u251c\u2500\u2500 file_download_service.py # \u6587\u4ef6\u4e0b\u8f7d\u670d\u52a1\n\u2502   \u2502   \u251c\u2500\u2500 share_service.py       # \u5206\u4eab\u7ba1\u7406\u670d\u52a1\n\u2502   \u2502   \u2514\u2500\u2500 name_resolver.py       # \u6587\u4ef6\u540d\u89e3\u6790\u5668\n\u2502   \u251c\u2500\u2500 cli/                 # \u547d\u4ee4\u884c\u754c\u9762\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py  \n\u2502   \u2502   \u251c\u2500\u2500 __main__.py      # \u6a21\u5757\u5165\u53e3 (python -m quark_client.cli)\n\u2502   \u2502   \u251c\u2500\u2500 main.py          # CLI \u4e3b\u7a0b\u5e8f\n\u2502   \u2502   \u251c\u2500\u2500 interactive.py   # \u4ea4\u4e92\u5f0f\u754c\u9762\n\u2502   \u2502   \u251c\u2500\u2500 utils.py         # CLI \u5de5\u5177\u51fd\u6570\n\u2502   \u2502   \u2514\u2500\u2500 commands/        # \u547d\u4ee4\u6a21\u5757\n\u2502   \u2502       \u251c\u2500\u2500 __init__.py\n\u2502   \u2502       \u251c\u2500\u2500 auth.py            # \u8ba4\u8bc1\u547d\u4ee4\n\u2502   \u2502       \u251c\u2500\u2500 basic_fileops.py   # \u57fa\u7840\u6587\u4ef6\u64cd\u4f5c\n\u2502   \u2502       \u251c\u2500\u2500 download.py        # \u4e0b\u8f7d\u547d\u4ee4\n\u2502   \u2502       \u251c\u2500\u2500 move_commands.py   # \u79fb\u52a8\u64cd\u4f5c\u547d\u4ee4\n\u2502   \u2502       \u251c\u2500\u2500 search.py          # \u641c\u7d22\u547d\u4ee4\n\u2502   \u2502       \u2514\u2500\u2500 share_commands.py  # \u5206\u4eab\u547d\u4ee4\n\u2502   \u2514\u2500\u2500 utils/               # \u5de5\u5177\u6a21\u5757\n\u2502       \u251c\u2500\u2500 __init__.py  \n\u2502       \u251c\u2500\u2500 logger.py        # \u65e5\u5fd7\u5de5\u5177\n\u2502       \u2514\u2500\u2500 qr_code.py       # \u4e8c\u7ef4\u7801\u5de5\u5177\n\u251c\u2500\u2500 examples/                # \u4f7f\u7528\u793a\u4f8b\n\u2502   \u251c\u2500\u2500 basic_usage.py       # \u57fa\u7840\u529f\u80fd\u6f14\u793a\n\u2502   \u251c\u2500\u2500 file_operations_demo.py # \u6587\u4ef6\u64cd\u4f5c\u6f14\u793a\n\u2502   \u251c\u2500\u2500 file_browser_demo.py # \u6587\u4ef6\u6d4f\u89c8\u5668\u6f14\u793a\n\u2502   \u2514\u2500\u2500 share_save_demo.py   # \u5206\u4eab\u8f6c\u5b58\u6f14\u793a\n\u251c\u2500\u2500 config/                  # \u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\n\u2502   \u251c\u2500\u2500 cookies.json         # \u767b\u5f55 Cookie \u5b58\u50a8\n\u2502   \u251c\u2500\u2500 login_result.json    # \u767b\u5f55\u7ed3\u679c\u7f13\u5b58\n\u2502   \u251c\u2500\u2500 qr_code.png          # \u4e8c\u7ef4\u7801\u56fe\u7247\n\u2502   \u2514\u2500\u2500 user_info.json       # \u7528\u6237\u4fe1\u606f\u7f13\u5b58\n\u251c\u2500\u2500 cli.py                   # CLI \u76f4\u63a5\u5165\u53e3\u811a\u672c\n\u251c\u2500\u2500 setup.py                 # \u5b89\u88c5\u914d\u7f6e\n\u251c\u2500\u2500 requirements.txt         # \u4f9d\u8d56\u5217\u8868\n\u251c\u2500\u2500 LICENSE                  # \u5f00\u6e90\u534f\u8bae\n\u2514\u2500\u2500 README.md                # \u9879\u76ee\u8bf4\u660e\n```\n\n## \ud83e\uddea \u8fd0\u884c\u793a\u4f8b\n\n\u9879\u76ee\u63d0\u4f9b\u4e86\u591a\u4e2a\u793a\u4f8b\u6587\u4ef6\uff0c\u5e2e\u52a9\u4f60\u5feb\u901f\u4e86\u89e3\u5404\u79cd\u529f\u80fd\u7684\u4f7f\u7528\u65b9\u6cd5\uff1a\n\n### \u57fa\u7840\u4f7f\u7528\u793a\u4f8b\n```bash  \n# \u6f14\u793a\u57fa\u672c\u529f\u80fd\uff1a\u767b\u5f55\u3001\u83b7\u53d6\u6587\u4ef6\u5217\u8868\u3001\u641c\u7d22\u3001\u5b58\u50a8\u4fe1\u606f\npython examples/basic_usage.py\n```\n\n**\u529f\u80fd\u6f14\u793a\uff1a**\n- \u2705 \u81ea\u52a8\u767b\u5f55\u8ba4\u8bc1\n- \ud83d\udcc1 \u83b7\u53d6\u6839\u76ee\u5f55\u6587\u4ef6\u5217\u8868\uff08\u663e\u793a\u524d 5 \u4e2a\uff09\n- \ud83d\udcbe \u67e5\u770b\u5b58\u50a8\u5bb9\u91cf\u4fe1\u606f  \n- \ud83d\udd0d \u5168\u76d8\u6587\u4ef6\u641c\u7d22\u6f14\u793a\n- \ud83d\udd17 \u83b7\u53d6\u4e2a\u4eba\u5206\u4eab\u5217\u8868\n\n### \u6587\u4ef6\u64cd\u4f5c\u6f14\u793a  \n```bash\n# \u5b8c\u6574\u7684\u6587\u4ef6\u7ba1\u7406\u64cd\u4f5c\u6d41\u7a0b\u6f14\u793a\npython examples/file_operations_demo.py\n```\n\n**\u529f\u80fd\u6f14\u793a\uff1a**\n- \ud83d\udcc2 \u6d4f\u89c8\u548c\u5217\u51fa\u6587\u4ef6\u5939\u5185\u5bb9\n- \u2795 \u521b\u5efa\u6d4b\u8bd5\u6587\u4ef6\u5939\u548c\u5b50\u6587\u4ef6\u5939\n- \u270f\ufe0f \u91cd\u547d\u540d\u6587\u4ef6\u548c\u6587\u4ef6\u5939\n- \ud83d\udce6 \u79fb\u52a8\u6587\u4ef6\u5230\u4e0d\u540c\u6587\u4ef6\u5939\n- \ud83d\uddd1\ufe0f \u5220\u9664\u6587\u4ef6\u548c\u6e05\u7406\u6d4b\u8bd5\u6570\u636e\n- \ud83d\udd0d \u591a\u5173\u952e\u8bcd\u641c\u7d22\u6f14\u793a\n\n### \u6587\u4ef6\u6d4f\u89c8\u5668\u6f14\u793a\n```bash\n# \u4ea4\u4e92\u5f0f\u6587\u4ef6\u6d4f\u89c8\u5668\u4f53\u9a8c\npython examples/file_browser_demo.py  \n```\n\n**\u529f\u80fd\u6f14\u793a\uff1a**\n- \ud83d\udda5\ufe0f \u7c7b\u4f3c\u7cfb\u7edf\u6587\u4ef6\u7ba1\u7406\u5668\u7684\u754c\u9762\n- \u2b06\ufe0f\u2b07\ufe0f \u65b9\u5411\u952e\u5bfc\u822a\u6587\u4ef6\u5217\u8868\n- \ud83d\udcc1 \u53cc\u51fb\u8fdb\u5165\u6587\u4ef6\u5939\n- \ud83d\udccb \u67e5\u770b\u6587\u4ef6\u8be6\u7ec6\u4fe1\u606f\n- \ud83d\udd04 \u5b9e\u65f6\u5237\u65b0\u6587\u4ef6\u5217\u8868\n\n### \u5206\u4eab\u8f6c\u5b58\u6f14\u793a\n```bash\n# \u5206\u4eab\u94fe\u63a5\u521b\u5efa\u548c\u8f6c\u5b58\u529f\u80fd\npython examples/share_save_demo.py\n```\n\n**\u529f\u80fd\u6f14\u793a\uff1a**\n- \ud83d\udd17 \u521b\u5efa\u6587\u4ef6\u5206\u4eab\u94fe\u63a5\uff08\u5e26\u5bc6\u7801\u548c\u6709\u6548\u671f\uff09\n- \ud83d\udccb \u7ba1\u7406\u4e2a\u4eba\u5206\u4eab\u5217\u8868  \n- \ud83d\udcbe \u8f6c\u5b58\u4ed6\u4eba\u5206\u4eab\u7684\u8d44\u6e90\n- \ud83d\udd0d \u5206\u4eab\u94fe\u63a5\u683c\u5f0f\u89e3\u6790\n- \ud83d\udcca \u5206\u4eab\u6587\u4ef6\u8be6\u60c5\u67e5\u770b\n\n### \u7ec4\u5408\u4f7f\u7528\u793a\u4f8b\n\n\u4f60\u4e5f\u53ef\u4ee5\u7ec4\u5408\u4f7f\u7528\u591a\u4e2a\u793a\u4f8b\u6765\u4f53\u9a8c\u5b8c\u6574\u5de5\u4f5c\u6d41\uff1a\n\n```bash\n# \u5b8c\u6574\u4f53\u9a8c\u6d41\u7a0b\npython examples/basic_usage.py          # 1. \u9996\u5148\u4f53\u9a8c\u57fa\u7840\u529f\u80fd\npython examples/file_operations_demo.py # 2. \u7136\u540e\u4f53\u9a8c\u6587\u4ef6\u64cd\u4f5c\npython examples/share_save_demo.py      # 3. \u6700\u540e\u4f53\u9a8c\u5206\u4eab\u529f\u80fd\n```\n\n**\u6ce8\u610f\u4e8b\u9879\uff1a**\n- \ud83d\udd11 \u9996\u6b21\u8fd0\u884c\u9700\u8981\u5b8c\u6210\u767b\u5f55\u8ba4\u8bc1\n- \u26a0\ufe0f \u67d0\u4e9b\u64cd\u4f5c\u4f1a\u521b\u5efa\u6d4b\u8bd5\u6570\u636e\uff0c\u7a0b\u5e8f\u4f1a\u81ea\u52a8\u6e05\u7406\n- \ud83d\udcf1 \u9700\u8981\u624b\u673a\u5b89\u88c5\u5938\u514b APP \u7528\u4e8e\u626b\u7801\u767b\u5f55\n- \ud83c\udf10 \u9700\u8981\u7a33\u5b9a\u7684\u7f51\u7edc\u8fde\u63a5\n\n## \ud83d\udce6 \u4f9d\u8d56\u8bf4\u660e\n\n### \u6838\u5fc3\u4f9d\u8d56\n- **httpx** (>=0.24.0): \u73b0\u4ee3\u5316 HTTP \u5ba2\u6237\u7aef\uff0c\u652f\u6301\u5f02\u6b65\u8bf7\u6c42\n- **pydantic** (>=2.0.0): \u6570\u636e\u9a8c\u8bc1\u548c\u7c7b\u578b\u6ce8\u89e3\n- **typer** (>=0.9.0): \u73b0\u4ee3\u5316\u547d\u4ee4\u884c\u754c\u9762\u6846\u67b6\n- **rich** (>=13.0.0): \u7f8e\u5316\u7ec8\u7aef\u8f93\u51fa\u548c\u4ea4\u4e92\n\n### \u4e8c\u7ef4\u7801\u652f\u6301  \n- **qrcode** (>=7.4.0): \u4e8c\u7ef4\u7801\u751f\u6210\u548c\u7ec8\u7aefASCII\u663e\u793a\n\n### \u7528\u6237\u4f53\u9a8c\n- **tqdm** (>=4.65.0): \u8fdb\u5ea6\u6761\u663e\u793a\n\n### \u5f00\u53d1\u548c\u6d4b\u8bd5\n- **pytest** (>=7.0.0): \u6d4b\u8bd5\u6846\u67b6\n- **pytest-asyncio** (>=0.21.0): \u5f02\u6b65\u6d4b\u8bd5\u652f\u6301\n\n### \u4f9d\u8d56\u5b89\u88c5\n```bash\n# \u5b89\u88c5\u6240\u6709\u4f9d\u8d56\npip install -r requirements.txt\n\n# \u4ec5\u5b89\u88c5\u6838\u5fc3\u4f9d\u8d56\uff08\u6700\u5c0f\u5316\u5b89\u88c5\uff09  \npip install httpx typer rich pydantic\n\n# \u5f00\u53d1\u73af\u5883\u5b89\u88c5\uff08\u5305\u542b\u6d4b\u8bd5\u5de5\u5177\uff09\npip install -r requirements.txt pytest pytest-asyncio\n```\n\n### \u7cfb\u7edf\u8981\u6c42\n- **Python**: 3.8 \u6216\u66f4\u9ad8\u7248\u672c\n- **\u64cd\u4f5c\u7cfb\u7edf**: Windows/macOS/Linux\n- **\u5185\u5b58**: \u5efa\u8bae 512MB \u4ee5\u4e0a\u53ef\u7528\u5185\u5b58\n- **\u7f51\u7edc**: \u9700\u8981\u7a33\u5b9a\u7684\u4e92\u8054\u7f51\u8fde\u63a5\n- **\u7ec8\u7aef**: \u652f\u6301 UTF-8 \u7f16\u7801\u7684\u7ec8\u7aef\uff08\u63a8\u8350\uff09\n\n## \u26a0\ufe0f \u6ce8\u610f\u4e8b\u9879\u4e0e\u514d\u8d23\u58f0\u660e\n\n### \u4f7f\u7528\u987b\u77e5\n1. **\u9996\u6b21\u4f7f\u7528**: \u9700\u8981\u901a\u8fc7\u626b\u7801\u6216\u624b\u52a8\u65b9\u5f0f\u5b8c\u6210\u767b\u5f55\u8ba4\u8bc1\n2. **\u914d\u7f6e\u6587\u4ef6**: \u767b\u5f55\u4fe1\u606f\u4fdd\u5b58\u5728 `config/cookies.json`\uff0c\u8bf7\u59a5\u5584\u4fdd\u7ba1\n3. **\u7f51\u7edc\u73af\u5883**: \u5efa\u8bae\u5728\u7a33\u5b9a\u7684\u7f51\u7edc\u73af\u5883\u4e0b\u4f7f\u7528\uff0c\u907f\u514d\u4e0a\u4f20 / \u4e0b\u8f7d\u4e2d\u65ad\n4. **\u8d26\u53f7\u5b89\u5168**: \u8bf7\u4f7f\u7528\u5b98\u65b9\u5938\u514b APP \u8fdb\u884c\u626b\u7801\u767b\u5f55\uff0c\u786e\u4fdd\u8d26\u53f7\u5b89\u5168\n5. **\u529f\u80fd\u9650\u5236**: \u90e8\u5206\u529f\u80fd\u53d7\u5938\u514b\u7f51\u76d8\u5b98\u65b9 API \u9650\u5236\uff0c\u53ef\u80fd\u4f1a\u6709\u8c03\u7528\u9891\u7387\u9650\u5236\n\n### \u6280\u672f\u9650\u5236\n- **\u5927\u6587\u4ef6\u5904\u7406**: \u8d85\u5927\u6587\u4ef6\u7684\u4e0a\u4f20\u4e0b\u8f7d\u53ef\u80fd\u9700\u8981\u8f83\u957f\u65f6\u95f4\n- **\u5e76\u53d1\u9650\u5236**: \u4e3a\u907f\u514d\u89e6\u53d1\u53cd\u722c\u9650\u5236\uff0c\u9ed8\u8ba4\u9650\u5236\u5e76\u53d1\u8bf7\u6c42\u6570\u91cf\n- **API \u53d8\u66f4**: \u5938\u514b\u7f51\u76d8\u5b98\u65b9 API \u53ef\u80fd\u968f\u65f6\u53d8\u66f4\uff0c\u5bfc\u81f4\u90e8\u5206\u529f\u80fd\u6682\u65f6\u4e0d\u53ef\u7528\n- **\u767b\u5f55\u6709\u6548\u671f**: Cookie \u6709\u6548\u671f\u6709\u9650\uff0c\u8fc7\u671f\u540e\u9700\u8981\u91cd\u65b0\u767b\u5f55\n\n### \u514d\u8d23\u58f0\u660e\n1. **\u4ec5\u4f9b\u5b66\u4e60**: \u672c\u9879\u76ee\u4ec5\u7528\u4e8e\u5b66\u4e60\u548c\u4e2a\u4eba\u4f7f\u7528\uff0c\u4e0d\u5f97\u7528\u4e8e\u5546\u4e1a\u7528\u9014\n2. **\u4f7f\u7528\u98ce\u9669**: \u7528\u6237\u4f7f\u7528\u672c\u5de5\u5177\u6240\u4ea7\u751f\u7684\u4efb\u4f55\u98ce\u9669\u548c\u8d23\u4efb\u7531\u7528\u6237\u81ea\u884c\u627f\u62c5\n3. **\u670d\u52a1\u6761\u6b3e**: \u4f7f\u7528\u65f6\u8bf7\u9075\u5b88\u5938\u514b\u7f51\u76d8\u7684\u5b98\u65b9\u670d\u52a1\u6761\u6b3e\u548c\u7528\u6237\u534f\u8bae\n4. **\u6570\u636e\u5b89\u5168**: \u8bf7\u52ff\u4f7f\u7528\u672c\u5de5\u5177\u5904\u7406\u654f\u611f\u6216\u91cd\u8981\u6570\u636e\uff0c\u4f5c\u8005\u4e0d\u627f\u62c5\u6570\u636e\u635f\u5931\u8d23\u4efb\n5. **\u6cd5\u5f8b\u5408\u89c4**: \u7528\u6237\u5e94\u786e\u4fdd\u4f7f\u7528\u884c\u4e3a\u7b26\u5408\u5f53\u5730\u6cd5\u5f8b\u6cd5\u89c4\u8981\u6c42\n\n### \u6545\u969c\u6392\u9664\n- **\u767b\u5f55\u5931\u8d25**: \u5c1d\u8bd5\u6e05\u9664 `config/cookies.json` \u540e\u91cd\u65b0\u767b\u5f55\n- **API \u9519\u8bef**: \u68c0\u67e5\u7f51\u7edc\u8fde\u63a5\uff0c\u6216\u7b49\u5f85\u7247\u523b\u540e\u91cd\u8bd5\n- **\u4e8c\u7ef4\u7801\u4e0d\u663e\u793a**: \u68c0\u67e5\u7ec8\u7aef\u662f\u5426\u652f\u6301\u56fe\u7247\u663e\u793a\uff0c\u6216\u67e5\u770b `config/qr_code.png`\n- **\u4e0a\u4f20 / \u4e0b\u8f7d\u4e2d\u65ad**: \u68c0\u67e5\u6587\u4ef6\u8def\u5f84\u548c\u7f51\u7edc\u8fde\u63a5\u72b6\u6001\n- **\u547d\u4ee4\u884c\u4e71\u7801**: \u786e\u4fdd\u7ec8\u7aef\u652f\u6301 UTF-8 \u7f16\u7801\n\n### \u83b7\u53d6\u5e2e\u52a9\n- **GitHub Issues**: [\u63d0\u4ea4\u95ee\u9898\u62a5\u544a](https://github.com/lich0821/QuarkPan/issues)\n- **\u793a\u4f8b\u4ee3\u7801**: \u53c2\u8003 `examples/` \u76ee\u5f55\u4e0b\u7684\u793a\u4f8b\u6587\u4ef6\n- **\u5fae\u4fe1\u7fa4**: \u53d1\u9001 `WCF` \u8fdb\u7fa4\u4ea4\u6d41\n<center>\n\n![\u516c\u4f17\u53f7\u641c\u7d22\u3010\u6f29\u667a\u3011\u52a0\u5165\u793e\u533a](QrCode.jpg)\n</center>\n\n### \u8d21\u732e\u6307\u5357\n\u6b22\u8fce\u63d0\u4ea4 Issue \u548c Pull Request\uff01\u5728\u8d21\u732e\u4ee3\u7801\u524d\uff0c\u8bf7\uff1a\n1. \u9605\u8bfb\u9879\u76ee\u7684\u4ee3\u7801\u98ce\u683c\u89c4\u8303\n2. \u786e\u4fdd\u65b0\u529f\u80fd\u6709\u5bf9\u5e94\u7684\u6d4b\u8bd5\u7528\u4f8b\n3. \u66f4\u65b0\u76f8\u5173\u6587\u6863\u548c\u793a\u4f8b\u4ee3\u7801\n4. \u9075\u5faa MIT \u5f00\u6e90\u534f\u8bae\n\n## \ud83d\udcc4 \u8bb8\u53ef\u534f\u8bae\n\n\u672c\u9879\u76ee\u91c7\u7528 [MIT License](LICENSE) \u5f00\u6e90\u534f\u8bae\u3002\n\n---\n\u2b50 \u5982\u679c\u8fd9\u4e2a\u9879\u76ee\u5bf9\u4f60\u6709\u5e2e\u52a9\uff0c\u8bf7\u7ed9\u4e2a Star \u652f\u6301\u4e00\u4e0b\uff01\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "\u5938\u514b\u7f51\u76d8 Python \u5ba2\u6237\u7aef\u548c\u547d\u4ee4\u884c\u5de5\u5177",
    "version": "1.0.1",
    "project_urls": {
        "Bug Reports": "https://github.com/lich0821/QuarkPan/issues",
        "Changelog": "https://github.com/lich0821/QuarkPan/releases",
        "Documentation": "https://github.com/lich0821/QuarkPan/blob/main/docs/",
        "Homepage": "https://github.com/lich0821/QuarkPan",
        "Source": "https://github.com/lich0821/QuarkPan"
    },
    "split_keywords": [
        "quark",
        " pan",
        " cloud",
        " storage",
        " cli",
        " api",
        " client",
        " \u7f51\u76d8"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2cff315a8b8590dd5b8da43f7a47d247dd0211d361db357917b1f18e5de6bb58",
                "md5": "1888ff2fd3eff5694eaf180164639a2a",
                "sha256": "72263e873426455a428f3566b1311d20f219c52b1a693f3a874eb7d384f29819"
            },
            "downloads": -1,
            "filename": "quarkpan-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1888ff2fd3eff5694eaf180164639a2a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 81726,
            "upload_time": "2025-08-22T15:44:42",
            "upload_time_iso_8601": "2025-08-22T15:44:42.716443Z",
            "url": "https://files.pythonhosted.org/packages/2c/ff/315a8b8590dd5b8da43f7a47d247dd0211d361db357917b1f18e5de6bb58/quarkpan-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "89be50129257dde6aedb567b10c85bcc5bc2324cd5ae50f663466e4516d4c698",
                "md5": "0c1f2ab7ace6e339ca95466231f833bc",
                "sha256": "04df146af79fceedec5c9c59a4016ec14d0e793d59f430aa88091e57862d69c0"
            },
            "downloads": -1,
            "filename": "quarkpan-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "0c1f2ab7ace6e339ca95466231f833bc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 72030,
            "upload_time": "2025-08-22T15:44:44",
            "upload_time_iso_8601": "2025-08-22T15:44:44.760439Z",
            "url": "https://files.pythonhosted.org/packages/89/be/50129257dde6aedb567b10c85bcc5bc2324cd5ae50f663466e4516d4c698/quarkpan-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-22 15:44:44",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "lich0821",
    "github_project": "QuarkPan",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "httpx",
            "specs": [
                [
                    ">=",
                    "0.24.0"
                ]
            ]
        },
        {
            "name": "typer",
            "specs": [
                [
                    ">=",
                    "0.9.0"
                ]
            ]
        },
        {
            "name": "rich",
            "specs": [
                [
                    ">=",
                    "13.0.0"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    ">=",
                    "2.0.0"
                ]
            ]
        },
        {
            "name": "qrcode",
            "specs": [
                [
                    ">=",
                    "7.4.0"
                ]
            ]
        },
        {
            "name": "tqdm",
            "specs": [
                [
                    ">=",
                    "4.65.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    ">=",
                    "7.0.0"
                ]
            ]
        },
        {
            "name": "pytest-asyncio",
            "specs": [
                [
                    ">=",
                    "0.21.0"
                ]
            ]
        }
    ],
    "lcname": "quarkpan"
}
        
Elapsed time: 1.82553s