Metadata-Version: 2.4
Name: forktex-network
Version: 0.2.3
Summary: Standalone Python SDK for the ForkTex Network platform — identity, projects, tasks, worklogs, channels
License-Expression: AGPL-3.0-only
License-File: LICENSE
License-File: NOTICE
Keywords: forktex,network,sdk,collaboration,projects,tasks,worklogs
Author: FORKTEX
Author-email: info@forktex.com
Requires-Python: >=3.12
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Office/Business :: Groupware
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Provides-Extra: dev
Requires-Dist: build (>=1.2.2) ; extra == "dev"
Requires-Dist: httpx (>=0.27.0,<1.0.0)
Requires-Dist: pip-audit (>=2.7.3,<3.0.0) ; extra == "dev"
Requires-Dist: pydantic[email] (>=2.11.0,<3.0.0)
Requires-Dist: pyright (>=1.1.350) ; extra == "dev"
Requires-Dist: pytest (>=9.0.3,<10.0.0) ; extra == "dev"
Requires-Dist: pytest-asyncio (>=1.2.0,<2.0.0) ; extra == "dev"
Requires-Dist: respx (>=0.21.0,<1.0.0) ; extra == "dev"
Requires-Dist: ruff (>=0.8.0) ; extra == "dev"
Requires-Dist: twine (>=6.1.0) ; extra == "dev"
Project-URL: Homepage, https://forktex.com
Project-URL: Issues, https://github.com/forktex/network/issues
Project-URL: Repository, https://github.com/forktex/network
Description-Content-Type: text/markdown

# forktex-network

[![PyPI](https://img.shields.io/pypi/v/forktex-network.svg)](https://pypi.org/project/forktex-network/)
[![Python](https://img.shields.io/pypi/pyversions/forktex-network.svg)](https://pypi.org/project/forktex-network/)
[![License](https://img.shields.io/pypi/l/forktex-network.svg)](https://github.com/forktex/network/blob/master/sdk-py/LICENSE)

Standalone async Python SDK for the ForkTex Network platform.

`forktex-network` is the typed Python client for the Network operations platform — identity, multi-tenancy,
org and personal projects, tasks, work logs, and activity feeds. Every OpenAPI operation (~65 endpoints)
is exposed as a typed async method on `NetworkClient`, and every request/response schema is available as a
Pydantic model re-exported at the package root.

## Install

```bash
pip install forktex-network
```

**Requires Python 3.12+.** Tested on 3.12, 3.13, 3.14.

## Quick Start

### Human auth

```python
from forktex_network import NetworkClient

async with NetworkClient(base_url="https://network.forktex.com") as client:
    token = await client.login("user@example.com", "password")
    me = await client.identity_me()
    orgs = await client.tenancy_list_orgs()
```

### Service or agent auth

```python
from forktex_network import AuthType, NetworkClient

async with NetworkClient(
    base_url="https://network.forktex.com",
    api_key="ftx-...",
    auth_type=AuthType.SERVICE,
) as client:
    health = await client.health()

async with NetworkClient(
    base_url="https://network.forktex.com",
    api_key="ftx-...",
    auth_type=AuthType.AGENT,
    agent_id="forktex-automation",
) as client:
    feed = await client.feed_activity()
```

### Projects and tasks

```python
from forktex_network import NetworkClient, ProjectsSearchSpec, TasksPageSearchSpec, TaskCreate

async with NetworkClient(base_url="http://localhost:9000") as client:
    await client.login("user@example.com", "password")

    orgs = await client.tenancy_list_orgs()
    org_id = orgs[0].id

    projects = await client.projects_search_org(
        org_id=org_id,
        body=ProjectsSearchSpec(page=1, page_size=10),
    )
    first_project = projects.data[0]

    tasks = await client.tasks_search(
        project_id=first_project.id,
        body=TasksPageSearchSpec(page=1, page_size=20),
    )

    new_task = await client.tasks_create(
        body=TaskCreate(
            project_id=first_project.id,
            name="Write tests",
            status_id=1,
            priority_id=1,
        )
    )
```

## Method naming

Method names match the `operationId` of each OpenAPI operation, with the FastAPI-appended
`_api_<path>_<method>` tail stripped. A few examples:

| OpenAPI `operationId`                                 | Python method              |
|-------------------------------------------------------|----------------------------|
| `health_api_health_get`                               | `client.health()`          |
| `identity_me_api_identity_me_get`                     | `client.identity_me()`     |
| `tasks_search_api_tasks_project__project_id__search_page_post` | `client.tasks_search(...)` |
| `projects_search_org_api_projects_org__org_id__search_post`    | `client.projects_search_org(...)` |

A handful of convenience wrappers are added on top for common flows:

- `client.login(email, password)` — calls `identity_login` and captures the returned JWT.
- `client.register(email, password)` — calls `identity_register_account` and captures the JWT.
- `client.me()` — alias of `identity_me`.
- `client.close()` / `async with` — lifecycle.

## What's in the package

- `forktex_network.NetworkClient` — async client. Inherits ~65 generated methods from `_GeneratedOperations`
  plus the auth/session patch layer.
- `forktex_network.client.generated` — OpenAPI-derived Pydantic models, `_GeneratedOperations`,
  `SPEC_VERSION`, and `SPEC_HASH`.
- `forktex_network.auth` — `AuthType` and credential/header handling.

All generated models are re-exported at the top level:

```python
from forktex_network import (
    NetworkClient, NetworkAPIError, AuthType, Credentials,
    SPEC_VERSION, SPEC_HASH,
    HealthResponse, OrgRead, Task, TaskCreate, TaskDetail,
    ProjectsSearchSpec, TasksPageSearchSpec, WorkLogsSearchSpec,
    # ... every generated model
)
```

## MCP

The ForkTex Network backend also exposes an MCP (Model Context Protocol) surface at `/api/mcp`, mounted via
`fastapi-mcp`. It projects every FastAPI route as an MCP tool at runtime — no separate SDK path needed.
Agent hosts (Claude Desktop, Cursor, the Python/JS MCP clients, future ForkTex frontoffice/backoffice agents)
connect to `/api/mcp` directly. This SDK is not involved in the MCP transport; it remains the Python
programmatic client over REST.

Discoverability stub: `GET /api/mcp/info` returns protocol, version, endpoint, and spec link.

## Codegen

`make codegen` at the repo root does three things:

1. Exports the canonical `openapi.json` from the API.
2. Regenerates Python, JS, and TypeScript bundles into `api/codegen/build/`.
3. Distributes those bundles into `sdk-py/src/forktex_network/client/generated/`, `sdk-js/src/generated/`,
   and `client/src/api/`.

The TypeScript toolchain is pinned by `api/codegen/package.json` and `api/codegen/pnpm-lock.yaml`.

## Versioning

The SDK follows SemVer. Generated models include `SPEC_VERSION` and `SPEC_HASH` so consumers can inspect
which API schema was used for the current release.

## Repository

This SDK lives inside the `forktex/network` monorepo alongside the FastAPI API server, the Expo client, and
the JS SDK (`sdk-js/`, `@forktex/network`). The package is independently buildable and publishable.

## Development

The [`Makefile`](Makefile) is generated by `forktex fsd makefile sync` from [`forktex.json`](forktex.json) — do not hand-edit.

```bash
make help              # list every available target
make deps              # editable install with the dev group
make format            # ruff format
make lint              # ruff check
make test              # pytest tests/
make codegen-check     # verify the generated client imports cleanly
make build             # python3 -m build → dist/
make ci                # format-check + lint + license-check + audit + test + build
make clean             # remove caches and dist/
```

`make ci` is the single command that gates a publish: format-check, lint, dual-license header check, dependency CVE audit, full test suite, and `python -m build` + `twine check`.

### License headers

Every source file carries the AGPL-3.0 + Commercial dual-license SPDX header, applied idempotently via:

```bash
make license-check    # CI gate — fails if any source file is missing the header
make license-fix      # add or refresh headers across src/, tests/, scripts/
make license-strip    # remove headers (used before license-model changes)
```

## License

Dual-licensed — **AGPL-3.0-or-later** for open-source use, **commercial** for everything else (proprietary products, SaaS without source release, redistribution in closed-source form). See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE) for the full terms.

Commercial licensing inquiries: info@forktex.com.

The 1.0.0 release on PyPI was AGPLv3-only; from **0.2.3** onwards the package adds an explicit commercial-license carve-out (LicenseRef-ForkTex-Commercial) for proprietary use.

