snail-orbit-client


Namesnail-orbit-client JSON
Version 0.5.1 PyPI version JSON
download
home_pageNone
SummaryType-safe Python client for Snail Orbit project management system with read operations and issue management
upload_time2025-08-22 00:38:13
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseNone
keywords api-client project-management snail-orbit task-tracking
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Snail Orbit Python Client Library

A modern, type-safe Python client for the Snail Orbit project management system. Focused on data access and read operations with comprehensive error handling and automatic schema validation.

## 🚀 Features

- **Dual Client Architecture**: Full-featured synchronous and asynchronous clients
- **Type Safety**: Complete type hints with Pydantic v2 models and mypy compatibility
- **Authentication**: Bearer token and JWT authentication support
- **Error Handling**: Comprehensive exception hierarchy with context
- **Pagination**: Automatic pagination with iterator pattern
- **Search & Filtering**: Advanced search and filtering capabilities

## 📦 Installation

```bash
# Using uv (recommended)
uv add snail-orbit-client

# Using pip
pip install snail-orbit-client
```

## 🔧 Quick Start

### Basic Usage

```python
from snail_orbit_client import SnailOrbitClient

# Initialize client
client = SnailOrbitClient(
    base_url="https://your-snail-orbit.example.com",
    token="your-api-token"
)

# Get user profile
profile = client.auth.get_profile()
print(f"Logged in as: {profile.name} ({profile.email})")

# List users with search
for user in client.users.list(search="john"):
    print(f"User: {user.name} ({user.email})")

# List projects with filtering
for project in client.projects.list(filter="is_active___eq:true"):
    print(f"Active project: {project.name}")

# List issues with query language
for issue in client.issues.list(q="priority:high and status:open"):
    print(f"Urgent issue: {issue.id_readable} - {issue.subject}")
    print(f"Time spent: {issue.hours_spent} hours")

# Get specific records
user = client.users.get("user-id")
project = client.projects.get("project-id")
specific_issue = client.issues.get("issue-id")

# Access custom fields
priority_field = specific_issue.fields.get('priority')
if priority_field:
    print(f"Priority: {priority_field.value}")
```

### Async Usage

```python
import asyncio
from snail_orbit_client import SnailOrbitAsyncClient

async def main():
    async with SnailOrbitAsyncClient(
        base_url="https://your-snail-orbit.example.com",
        token="your-api-token"
    ) as client:

        # Get user profile
        profile = await client.auth.get_profile()
        print(f"Logged in as: {profile.name} ({profile.email})")

        # List projects
        projects = []
        async for project in client.projects.list():
            projects.append(project)

        # Search issues
        urgent_issues = []
        async for issue in client.issues.list(q="priority:high and status:open"):
            urgent_issues.append(issue)

asyncio.run(main())
```

## 💪 Available Operations

### **Authentication**
- ✅ `auth.get_profile()` - Get current user profile

### **Users**
- ✅ `users.list(search=None, filter=None)` - List/search users
- ✅ `users.get(user_id)` - Get user by ID

### **Projects**
- ✅ `projects.list(search=None, filter=None)` - List/search projects
- ✅ `projects.get(project_id)` - Get project by ID

### **Issues**
- ✅ `issues.list(q=None, search=None)` - List/query issues
- ✅ `issues.get(issue_id)` - Get issue by ID
- ✅ `issues.get_by_readable_id(readable_id)` - Get issue by readable ID (e.g., "PRJ-123")
- ✅ `issues.create(issue_data)` - Create new issue
- ✅ `issues.update(issue_id, issue_data)` - Update issue
- ✅ `issues.delete(issue_id)` - Delete issue
- ✅ `issues.subscribe(issue_id)` - Subscribe to notifications
- ✅ `issues.unsubscribe(issue_id)` - Unsubscribe from notifications

### **Issue Comments**
- ✅ `issues.get_comments(issue_id)` - List comments for issue
- ✅ `issues.get_comment(issue_id, comment_id)` - Get specific comment
- ✅ `issues.create_comment(issue_id, comment_data)` - Create comment
- ✅ `issues.update_comment(issue_id, comment_id, comment_data)` - Update comment
- ✅ `issues.delete_comment(issue_id, comment_id)` - Delete comment

### **Issue Tags**
- ✅ `issues.add_tag(issue_id, tag_id)` - Add tag to issue
- ✅ `issues.remove_tag(issue_id, tag_id)` - Remove tag from issue

### **Custom Fields**
- ✅ `custom_fields.list_groups()` - List custom field groups
- ✅ `custom_fields.get_group(group_gid)` - Get custom field group
- ✅ `custom_fields.get_field(field_id)` - Get custom field

### **Activity Tracking**
- ✅ `activity.list(start, end, user_id=None)` - List activities by time range

## 🎯 Search & Filtering

### Users & Projects
Use `search` and `filter` parameters:

```python
# Text search
client.users.list(search="john doe")
client.projects.list(search="api project")

# Query language filtering
client.users.list(filter="is_active___eq:true and name___contains:developer")
client.projects.list(filter="created_at___gte:2024-01-01")

# Combined search and filter
client.users.list(search="john", filter="is_admin___eq:false")
```

### Issues
Use `q` (query language) and `search` parameters:

```python
# Query language (structured queries)
client.issues.list(q="priority:high and status:open")
client.issues.list(q="assignee:me and project:myproject")

# Text search
client.issues.list(search="database bug")

# Combined query and search
client.issues.list(q="status:open", search="authentication")
```

## 🔧 Advanced Configuration

```python
from snail_orbit_client import SnailOrbitClient, ClientConfig

config = ClientConfig(
    timeout=30.0,                    # Request timeout in seconds
    max_retries=3,                   # Maximum retry attempts
    retry_delay=1.0,                 # Base delay between retries
    user_agent="MyApp/1.0.0"         # Custom user agent
)

client = SnailOrbitClient(
    base_url="https://your-snail-orbit.example.com",
    token="your-token",
    config=config
)
```

### JWT Authentication

```python
# JWT signing with service credentials
# Requires backend configuration in API_SERVICE_TOKEN_KEYS
client = SnailOrbitClient(
    base_url="https://api.snail-orbit.com",
    token=("test", "test", "user-id")  # (kid, secret, user_id)
)
```


## 🏗️ Architecture

### **Pure API Client Design**
- **Direct API Access**: Models mirror API responses without abstraction
- **Generated Models**: Auto-synchronized with OpenAPI schema
- **Type-Safe**: Full mypy compatibility with strict type checking
- **Iterator Pattern**: Efficient pagination for large datasets

### **Resource Organization**
```python
client.auth            # Authentication and profile management
client.users           # User read operations
client.projects        # Project read operations
client.issues          # Issue management (full CRUD)
client.custom_fields   # Custom field read operations
client.activity        # Activity tracking and audit logs
```

## 🔒 Security & Reliability

- **Secure Token Handling**: Safe storage and transmission of credentials
- **JWT Signing**: Request-specific JWT with method/path hashing
- **Structured Exceptions**: Comprehensive error hierarchy with context
- **HTTP Status Mapping**: Specific exceptions for 401, 403, 404, 422, 429, 5xx
- **Retry Logic**: Exponential backoff with configurable limits
- **Schema Validation**: Automatic validation against API schema

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "snail-orbit-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "api-client, project-management, snail-orbit, task-tracking",
    "author": null,
    "author_email": "Snail Orbit Team <dev@snorbit.app>",
    "download_url": null,
    "platform": null,
    "description": "# Snail Orbit Python Client Library\n\nA modern, type-safe Python client for the Snail Orbit project management system. Focused on data access and read operations with comprehensive error handling and automatic schema validation.\n\n## \ud83d\ude80 Features\n\n- **Dual Client Architecture**: Full-featured synchronous and asynchronous clients\n- **Type Safety**: Complete type hints with Pydantic v2 models and mypy compatibility\n- **Authentication**: Bearer token and JWT authentication support\n- **Error Handling**: Comprehensive exception hierarchy with context\n- **Pagination**: Automatic pagination with iterator pattern\n- **Search & Filtering**: Advanced search and filtering capabilities\n\n## \ud83d\udce6 Installation\n\n```bash\n# Using uv (recommended)\nuv add snail-orbit-client\n\n# Using pip\npip install snail-orbit-client\n```\n\n## \ud83d\udd27 Quick Start\n\n### Basic Usage\n\n```python\nfrom snail_orbit_client import SnailOrbitClient\n\n# Initialize client\nclient = SnailOrbitClient(\n    base_url=\"https://your-snail-orbit.example.com\",\n    token=\"your-api-token\"\n)\n\n# Get user profile\nprofile = client.auth.get_profile()\nprint(f\"Logged in as: {profile.name} ({profile.email})\")\n\n# List users with search\nfor user in client.users.list(search=\"john\"):\n    print(f\"User: {user.name} ({user.email})\")\n\n# List projects with filtering\nfor project in client.projects.list(filter=\"is_active___eq:true\"):\n    print(f\"Active project: {project.name}\")\n\n# List issues with query language\nfor issue in client.issues.list(q=\"priority:high and status:open\"):\n    print(f\"Urgent issue: {issue.id_readable} - {issue.subject}\")\n    print(f\"Time spent: {issue.hours_spent} hours\")\n\n# Get specific records\nuser = client.users.get(\"user-id\")\nproject = client.projects.get(\"project-id\")\nspecific_issue = client.issues.get(\"issue-id\")\n\n# Access custom fields\npriority_field = specific_issue.fields.get('priority')\nif priority_field:\n    print(f\"Priority: {priority_field.value}\")\n```\n\n### Async Usage\n\n```python\nimport asyncio\nfrom snail_orbit_client import SnailOrbitAsyncClient\n\nasync def main():\n    async with SnailOrbitAsyncClient(\n        base_url=\"https://your-snail-orbit.example.com\",\n        token=\"your-api-token\"\n    ) as client:\n\n        # Get user profile\n        profile = await client.auth.get_profile()\n        print(f\"Logged in as: {profile.name} ({profile.email})\")\n\n        # List projects\n        projects = []\n        async for project in client.projects.list():\n            projects.append(project)\n\n        # Search issues\n        urgent_issues = []\n        async for issue in client.issues.list(q=\"priority:high and status:open\"):\n            urgent_issues.append(issue)\n\nasyncio.run(main())\n```\n\n## \ud83d\udcaa Available Operations\n\n### **Authentication**\n- \u2705 `auth.get_profile()` - Get current user profile\n\n### **Users**\n- \u2705 `users.list(search=None, filter=None)` - List/search users\n- \u2705 `users.get(user_id)` - Get user by ID\n\n### **Projects**\n- \u2705 `projects.list(search=None, filter=None)` - List/search projects\n- \u2705 `projects.get(project_id)` - Get project by ID\n\n### **Issues**\n- \u2705 `issues.list(q=None, search=None)` - List/query issues\n- \u2705 `issues.get(issue_id)` - Get issue by ID\n- \u2705 `issues.get_by_readable_id(readable_id)` - Get issue by readable ID (e.g., \"PRJ-123\")\n- \u2705 `issues.create(issue_data)` - Create new issue\n- \u2705 `issues.update(issue_id, issue_data)` - Update issue\n- \u2705 `issues.delete(issue_id)` - Delete issue\n- \u2705 `issues.subscribe(issue_id)` - Subscribe to notifications\n- \u2705 `issues.unsubscribe(issue_id)` - Unsubscribe from notifications\n\n### **Issue Comments**\n- \u2705 `issues.get_comments(issue_id)` - List comments for issue\n- \u2705 `issues.get_comment(issue_id, comment_id)` - Get specific comment\n- \u2705 `issues.create_comment(issue_id, comment_data)` - Create comment\n- \u2705 `issues.update_comment(issue_id, comment_id, comment_data)` - Update comment\n- \u2705 `issues.delete_comment(issue_id, comment_id)` - Delete comment\n\n### **Issue Tags**\n- \u2705 `issues.add_tag(issue_id, tag_id)` - Add tag to issue\n- \u2705 `issues.remove_tag(issue_id, tag_id)` - Remove tag from issue\n\n### **Custom Fields**\n- \u2705 `custom_fields.list_groups()` - List custom field groups\n- \u2705 `custom_fields.get_group(group_gid)` - Get custom field group\n- \u2705 `custom_fields.get_field(field_id)` - Get custom field\n\n### **Activity Tracking**\n- \u2705 `activity.list(start, end, user_id=None)` - List activities by time range\n\n## \ud83c\udfaf Search & Filtering\n\n### Users & Projects\nUse `search` and `filter` parameters:\n\n```python\n# Text search\nclient.users.list(search=\"john doe\")\nclient.projects.list(search=\"api project\")\n\n# Query language filtering\nclient.users.list(filter=\"is_active___eq:true and name___contains:developer\")\nclient.projects.list(filter=\"created_at___gte:2024-01-01\")\n\n# Combined search and filter\nclient.users.list(search=\"john\", filter=\"is_admin___eq:false\")\n```\n\n### Issues\nUse `q` (query language) and `search` parameters:\n\n```python\n# Query language (structured queries)\nclient.issues.list(q=\"priority:high and status:open\")\nclient.issues.list(q=\"assignee:me and project:myproject\")\n\n# Text search\nclient.issues.list(search=\"database bug\")\n\n# Combined query and search\nclient.issues.list(q=\"status:open\", search=\"authentication\")\n```\n\n## \ud83d\udd27 Advanced Configuration\n\n```python\nfrom snail_orbit_client import SnailOrbitClient, ClientConfig\n\nconfig = ClientConfig(\n    timeout=30.0,                    # Request timeout in seconds\n    max_retries=3,                   # Maximum retry attempts\n    retry_delay=1.0,                 # Base delay between retries\n    user_agent=\"MyApp/1.0.0\"         # Custom user agent\n)\n\nclient = SnailOrbitClient(\n    base_url=\"https://your-snail-orbit.example.com\",\n    token=\"your-token\",\n    config=config\n)\n```\n\n### JWT Authentication\n\n```python\n# JWT signing with service credentials\n# Requires backend configuration in API_SERVICE_TOKEN_KEYS\nclient = SnailOrbitClient(\n    base_url=\"https://api.snail-orbit.com\",\n    token=(\"test\", \"test\", \"user-id\")  # (kid, secret, user_id)\n)\n```\n\n\n## \ud83c\udfd7\ufe0f Architecture\n\n### **Pure API Client Design**\n- **Direct API Access**: Models mirror API responses without abstraction\n- **Generated Models**: Auto-synchronized with OpenAPI schema\n- **Type-Safe**: Full mypy compatibility with strict type checking\n- **Iterator Pattern**: Efficient pagination for large datasets\n\n### **Resource Organization**\n```python\nclient.auth            # Authentication and profile management\nclient.users           # User read operations\nclient.projects        # Project read operations\nclient.issues          # Issue management (full CRUD)\nclient.custom_fields   # Custom field read operations\nclient.activity        # Activity tracking and audit logs\n```\n\n## \ud83d\udd12 Security & Reliability\n\n- **Secure Token Handling**: Safe storage and transmission of credentials\n- **JWT Signing**: Request-specific JWT with method/path hashing\n- **Structured Exceptions**: Comprehensive error hierarchy with context\n- **HTTP Status Mapping**: Specific exceptions for 401, 403, 404, 422, 429, 5xx\n- **Retry Logic**: Exponential backoff with configurable limits\n- **Schema Validation**: Automatic validation against API schema\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Type-safe Python client for Snail Orbit project management system with read operations and issue management",
    "version": "0.5.1",
    "project_urls": null,
    "split_keywords": [
        "api-client",
        " project-management",
        " snail-orbit",
        " task-tracking"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fb62bfc4350302eaeea0d74a10c9141ffc2867c12c23a9562ae74904d4c9148f",
                "md5": "a1c71672c6fc2455a4401aeb8f23dfdd",
                "sha256": "564625b6f75483cb69c684a31464b5d04fad39a6e517abf353c5dbaf94fb1dcc"
            },
            "downloads": -1,
            "filename": "snail_orbit_client-0.5.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a1c71672c6fc2455a4401aeb8f23dfdd",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 47224,
            "upload_time": "2025-08-22T00:38:13",
            "upload_time_iso_8601": "2025-08-22T00:38:13.149233Z",
            "url": "https://files.pythonhosted.org/packages/fb/62/bfc4350302eaeea0d74a10c9141ffc2867c12c23a9562ae74904d4c9148f/snail_orbit_client-0.5.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-22 00:38:13",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "snail-orbit-client"
}
        
Elapsed time: 0.59175s