Skip to main content

Type-safe Python client for Snail Orbit project management system with read operations and issue management

Project description

Snail Orbit Python Client

Type-safe Python client for the Snail Orbit project management API.

Installation

uv add snail-orbit-client
# or
pip install snail-orbit-client

Usage

Sync Client

from snail_orbit_client import SnailOrbitClient

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

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

# List issues
for issue in client.issues.list(q='priority:high and status:open'):
    print(f'{issue.id_readable}: {issue.subject}')

# Get specific issue
issue = client.issues.get('issue-id')

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

Async Client

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:
        profile = await client.auth.get_profile()

        async for issue in client.issues.list(q='status:open'):
            print(f'{issue.id_readable}: {issue.subject}')

asyncio.run(main())

API Resources

client.auth            # Authentication and profile
client.users           # User operations
client.projects        # Project operations
client.issues          # Issue CRUD operations
client.custom_fields   # Custom field definitions
client.activity        # Activity tracking

Issues

client.issues.list(q=None, search=None)           # List/query issues
client.issues.get(issue_id)                       # Get by ID
client.issues.get_by_readable_id(readable_id)     # Get by readable ID (e.g., 'PRJ-123')
client.issues.create(issue_data)                  # Create issue
client.issues.update(issue_id, issue_data)        # Update issue

# Comments
client.issues.get_comments(issue_id)
client.issues.create_comment(issue_id, comment_data)
client.issues.update_comment(issue_id, comment_id, comment_data)
client.issues.delete_comment(issue_id, comment_id)

# Tags
client.issues.add_tag(issue_id, tag_id)
client.issues.remove_tag(issue_id, tag_id)

# Attachments
client.issues.list_attachments(issue_id)                    # List attachments
client.issues.add_attachment(issue_id, attachment_input)    # Add attachment
client.issues.remove_attachment(issue_id, attachment_id)    # Remove attachment
client.issues.download_attachment(issue_id, attachment_id)  # Stream download
client.issues.upload_and_attach(issue_id, file)             # Upload and attach in one call

File Uploads

# Upload a file (loads into memory)
result = client.upload_file(b'content', filename='doc.pdf')
result = client.upload_file('/path/to/file.pdf')
result = client.upload_file(open('file.pdf', 'rb'))

# Streaming upload (memory-efficient for large files)
def read_chunks():
    with open('large_file.zip', 'rb') as f:
        while chunk := f.read(8192):
            yield chunk

result = client.stream_upload(read_chunks(), 'large_file.zip')

# Attach uploaded file to issue
from snail_orbit_client.models import IssueAttachmentInput
client.issues.add_attachment(issue_id, IssueAttachmentInput(id=result.id))

# Or use the convenience method
attachment = client.issues.upload_and_attach(issue_id, '/path/to/file.pdf')

Downloading Attachments

# Stream to file (memory-efficient)
with open('output.pdf', 'wb') as f:
    for chunk in client.issues.download_attachment(issue_id, attachment_id):
        f.write(chunk)

# Collect in memory (if you need bytes)
content = b''.join(client.issues.download_attachment(issue_id, attachment_id))

# Async streaming to file
async with aiofiles.open('output.pdf', 'wb') as f:
    async for chunk in client.issues.download_attachment(issue_id, attachment_id):
        await f.write(chunk)

Search and Filtering

# Issue query language
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')

# Users and projects use filter parameter
client.users.list(search='john', filter='is_active___eq:true')
client.projects.list(filter='created_at___gte:2024-01-01')

Configuration

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
)

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

JWT Authentication

# JWT signing with service credentials
client = SnailOrbitClient(
    base_url='https://api.snail-orbit.com',
    token=('key-id', 'secret', 'user-id')
)

Error Handling

from snail_orbit_client.exceptions import (
    SnailOrbitError,
    AuthenticationError,
    NotFoundError,
    ValidationError,
    RateLimitError,
)

try:
    issue = client.issues.get('invalid-id')
except NotFoundError:
    print('Issue not found')
except AuthenticationError:
    print('Authentication failed')
except ValidationError as e:
    print(f'Validation errors: {e.validation_errors}')
except RateLimitError as e:
    print(f'Rate limited, retry after {e.retry_after}s')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snail_orbit_client-0.13.2-py3-none-any.whl (40.7 kB view details)

Uploaded Python 3

File details

Details for the file snail_orbit_client-0.13.2-py3-none-any.whl.

File metadata

  • Download URL: snail_orbit_client-0.13.2-py3-none-any.whl
  • Upload date:
  • Size: 40.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for snail_orbit_client-0.13.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d1068257681eaa35c1339319895f02add666b16d7b980080303c68c9deced051
MD5 979cc99f35701af778b80cb057971429
BLAKE2b-256 4c95ce379d5746aaf60dfb25a8e9c21d2b86fda27e22ac3c7fa1c93c24e1ca17

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page