Metadata-Version: 2.4
Name: ithura
Version: 1.0.0
Summary: Official Python client for the Ithura API: tasks, sprints, projects, modules, wiki pages, and webhooks.
Project-URL: Homepage, https://ithura.com
Project-URL: Documentation, https://ithura.com/docs
Project-URL: Source, https://github.com/Aluchir/ithura-sdk-python
Project-URL: Issues, https://github.com/Aluchir/ithura-sdk-python/issues
Author: Ithura
License: MIT
License-File: LICENSE
Keywords: agile,api-client,issue-tracker,ithura,kanban,project-management,sdk,sprints,task-management
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Bug Tracking
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# ithura

[![PyPI](https://img.shields.io/pypi/v/ithura)](https://pypi.org/project/ithura/)
[![Python versions](https://img.shields.io/pypi/pyversions/ithura)](https://pypi.org/project/ithura/)
[![License](https://img.shields.io/pypi/l/ithura)](./LICENSE)

Official Python client for **[Ithura](https://ithura.com)**, a quiet project
management workspace for deliberate teams: tasks, sprints, wiki, whiteboards,
and intake.

## Install

```bash
pip install ithura
```

## Quick start

```python
from ithura import Ithura

client = Ithura(token="...")            # Settings > API tokens

workspace = client.workspace("acme")
projects = workspace.list_projects()

project = workspace.project(projects[0]["id"])

# Create a task
task = project.create_issue(name="Login times out on slow connections", priority="high")

# Move it into the current sprint
sprint = project.list_cycles()[0]
project.update_issue(task["id"], cycle_id=sprint["id"])

# Comment on it
project.add_comment(task["id"], "<p>Reproduced on staging.</p>")
```

Use it as a context manager to close the connection pool:

```python
with Ithura(token="...") as client:
    client.me()
```

## API

The client mirrors the [published OpenAPI spec](https://ithura.com/docs), so
each method maps to a documented endpoint.

```python
client.me()
client.list_workspaces()

ws = client.workspace("acme")
ws.get(); ws.members()
ws.list_projects()
ws.create_project(name="Web", identifier="WEB")
ws.list_pages(); ws.list_views()
ws.list_webhooks(); ws.create_webhook(url="https://example.com/hook")

p = ws.project(project_id)
p.get(); p.update(name="Web app"); p.delete()
p.states(); p.labels(); p.create_label(name="regression", color="#8a4f6d")

p.list_issues(priority="urgent", limit=20)
p.get_issue(task_id)
p.create_issue(name="...")
p.update_issue(task_id, state_id=state_id)
p.delete_issue(task_id)
p.list_comments(task_id)
p.add_comment(task_id, "<p>hi</p>")
p.issue_activities(task_id)

p.list_cycles(); p.create_cycle(name="Sprint 21")   # sprints
p.list_modules(); p.create_module(name="Billing")
p.list_boards(); p.list_intakes()
```

### Paging

`iter_issues()` walks a whole project without loading it all at once:

```python
for task in project.iter_issues(page_size=100, priority="high"):
    print(task["name"])
```

### Anything not covered

`request()` is the escape hatch, with auth and error handling applied:

```python
client.request("GET", "/workspaces/acme/projects/", params={"limit": 5})
```

### Errors

Non-2xx responses raise `IthuraError` with the status and parsed body:

```python
from ithura import IthuraError

try:
    project.get_issue("missing")
except IthuraError as err:
    if err.status == 404:
        ...
```

### Self-hosting

```python
Ithura(token="...", base_url="https://ithura.internal")
```

Pass your own `httpx.Client` for custom timeouts, proxies, or transports:

```python
import httpx
Ithura(token="...", client=httpx.Client(timeout=60.0))
```

## A note on naming

The HTTP API's noun for a work item is `issue`, and the product calls them
**tasks**. Method names follow the API so the mapping to the spec stays
obvious. The same applies to `cycle`, which the product calls a **sprint**.

## Links

- Ithura: <https://ithura.com>
- Documentation: <https://ithura.com/docs>
- JavaScript client: [`ithura` on npm](https://www.npmjs.com/package/ithura)
- MCP server for AI agents: [`ithura-mcp`](https://www.npmjs.com/package/ithura-mcp)

## License

MIT
