Metadata-Version: 2.4
Name: yuque-sdk
Version: 0.1.0
Summary: A Python client library for Yuque OpenAPI
Project-URL: Homepage, https://github.com/yourusername/yuque-python
Project-URL: Repository, https://github.com/yourusername/yuque-python
Project-URL: Issues, https://github.com/yourusername/yuque-python/issues
Author-email: Your Name <your.email@example.com>
License: Apache-2.0
Keywords: api,client,collaboration,documentation,yuque
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: pyyaml>=6.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Requires-Dist: types-requests>=2.31.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == 'docs'
Requires-Dist: sphinx>=7.0.0; extra == 'docs'
Description-Content-Type: text/markdown

# Yuque Python SDK

[![PyPI Version](https://img.shields.io/pypi/v/yuque.svg)](https://pypi.org/project/yuque/)
[![Python Versions](https://img.shields.io/pypi/pythonversions/yuque.svg)](https://pypi.org/project/yuque/)
[![License](https://img.shields.io/pypi/l/yuque.svg)](https://opensource.org/licenses/Apache-2.0)

A modern, type-safe Python client library for the [Yuque OpenAPI](https://www.yuque.com/yuque/developer/api).

## Features

- **Modern Python**: Built with Python 3.10+ type hints and Pydantic v2
- **Async/Sync Support**: Both synchronous and asynchronous interfaces
- **Comprehensive Coverage**: Full support for all Yuque API endpoints
- **Type Safety**: Full type annotations with Pydantic models
- **Error Handling**: Detailed exception hierarchy for API errors
- **Pagination**: Automatic pagination handling for list endpoints

## Installation

```bash
# Using uv (recommended)
uv add yuque

# Using pip
pip install yuque
```

## Quick Start

### Synchronous Usage

```python
from yuque import YuqueClient

# Initialize the client with your API token
client = YuqueClient(token="your-api-token")

# Get current user
user = client.user.get_me()
print(f"Hello, {user.name}!")

# List your repositories
repos = client.repo.list()
for repo in repos:
    print(f"- {repo['name']} ({repo['slug']})")

# Get a specific document
doc = client.doc.get(doc_id=12345)
print(f"Document: {doc['title']}")
```

### Asynchronous Usage

```python
import asyncio
from yuque import YuqueClient

async def main():
    async with YuqueClient(token="your-api-token") as client:
        # Get current user
        user = await client.user.get_me_async()
        print(f"Hello, {user.name}!")

        # List repositories
        repos = await client.repo.list_async()
        for repo in repos:
            print(f"- {repo.name}")

asyncio.run(main())
```

### Using as Context Manager

```python
from yuque import YuqueClient

# Synchronous context manager
with YuqueClient(token="your-token") as client:
    user = client.user.get_me()
    print(user.name)

# Asynchronous context manager
import asyncio
async def async_example():
    async with YuqueClient(token="your-token") as client:
        user = await client.user.get_me_async()
        print(user.name)

asyncio.run(async_example())
```

## API Reference

### User API

```python
# Get current authenticated user
user = client.user.get_me()

# Get user by ID
user = client.user.get_by_id(user_id=123)

# Get groups for a user
groups = client.user.get_groups(user_id=123)
```

### Group API

```python
# Get group by login
group = client.group.get(login="my-group")

# List repositories in a group
repos = client.group.get_repos(login="my-group")

# List group members
members = client.group.get_members(login="my-group")

# Add a member to group
client.group.add_member(login="my-group", user_id=123, role=1)

# Update member role
client.group.update_member(login="my-group", user_id=123, role=0)

# Remove a member
client.group.remove_member(login="my-group", user_id=123)

# Get group statistics
stats = client.group.get_statistics(login="my-group")
```

### Repository (Book) API

```python
# Get repository by ID
repo = client.repo.get(book_id=123)

# Get repository by path
repo = client.repo.get_by_path(group_login="my-group", book_slug="my-repo")

# List all repositories
repos = client.repo.list()

# List user's repositories
repos = client.repo.get_user_repos(login="username")

# List group's repositories
repos = client.repo.get_group_repos(login="my-group")

# Get table of contents
toc = client.repo.get_toc(book_id=123)
toc = client.repo.get_toc_by_path(group_login="my-group", book_slug="my-repo")
```

### Document API

```python
# Get document by ID
doc = client.doc.get(doc_id=12345)

# List documents in a repository
docs = client.doc.get_by_repo(book_id=123)

# List documents by path
docs = client.doc.get_by_path(group_login="my-group", book_slug="my-repo")

# Create a document
doc = client.doc.create(
    book_id=123,
    title="My New Document",
    body="# Hello World\n\nThis is my new document.",
    format="markdown",
)

# Update a document
doc = client.doc.update(
    doc_id=12345,
    title="Updated Title",
    body="Updated content...",
)

# Delete a document
client.doc.delete(doc_id=12345)

# Get document version
version = client.doc.get_version(version_id=1)
```

### Search API

```python
# Search across Yuque
results = client.search.search(keyword="python", type="doc")
for result in results:
    print(f"- {result.title}: {result.url}")
```

## Error Handling

The library provides detailed exceptions for different API error scenarios:

```python
from yuque import YuqueClient
from yuque.exceptions import (
    YuqueError,
    AuthenticationError,
    PermissionDeniedError,
    NotFoundError,
    InvalidArgumentError,
    ValidationError,
    RateLimitError,
    ServerError,
    NetworkError,
)

try:
    client = YuqueClient(token="your-token")
    user = client.user.get_me()
except AuthenticationError:
    print("Invalid API token")
except PermissionDeniedError:
    print("You don't have permission")
except NotFoundError:
    print("Resource not found")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except YuqueError as e:
    print(f"API error: {e}")
```

## Configuration

```python
from yuque import YuqueClient

# Custom timeout
client = YuqueClient(token="your-token", timeout=60.0)

# Custom max retries
client = YuqueClient(token="your-token", max_retries=5)
```

## Getting Your API Token

1. Log in to [Yuque](https://www.yuque.com)
2. Go to [Developer Settings](https://www.yuque.com/yuque/developer/api)
3. Create a new Personal Access Token
4. Copy the token and use it in your application

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

## Links

- [Yuque OpenAPI Documentation](https://www.yuque.com/yuque/developer/api)
- [PyPI Package](https://pypi.org/project/yuque/)
- [Issue Tracker](https://github.com/yourusername/yuque-python/issues)
