Metadata-Version: 2.4
Name: periplus-python-sdk
Version: 0.9.0
Summary: Read-only Python client for the public Periplus query API
License-Expression: AGPL-3.0-only
Project-URL: Repository, https://github.com/elei-io/periplus
Project-URL: Issues, https://github.com/elei-io/periplus/issues
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: licensing/LICENSE
License-File: licensing/NOTICE
License-File: licensing/README.md
License-File: licensing/THIRD_PARTY_NOTICES.md
Requires-Dist: httpx>=0.28
Requires-Dist: pydantic<3,>=2.12
Requires-Dist: sqlalchemy<3,>=2.0
Provides-Extra: notebook
Requires-Dist: marimo[sql]>=0.24.1; extra == "notebook"
Dynamic: license-file

# Periplus Python SDK

SQL access to the ClickHouse corpus through the Periplus HTTP API.
Install from PyPI:

```sh
python -m pip install --upgrade periplus-python-sdk
```

```python
from periplus_sdk import Client

with Client("https://api.periplus.dev", api_key="ppl_…") as client:
    result = client.execute(
        "SELECT capture_id, url FROM public_v1.captures LIMIT ?", [10]
    )
    print(result.columns, result.rows)
```

Use `PERIPLUS_API_URL` to omit the URL argument and `PERIPLUS_API_KEY` to
supply your personal organization API key. A key with `organization:sql:exec`
is required. Database usernames/passwords and anonymous access are not supported.
Use HTTPS outside loopback development. Connect directly to the API origin,
not the public marketing site.

Version 0.9.0 requires personal API keys instead of database credentials. Create
a key in the app's Settings → API keys with `organization:sql:exec` permission.
For local development, install `./clients/periplus-python-sdk` from the repository
root and connect to `http://localhost:8000`.

`AsyncClient` accepts the same options. `prepare` explains a SELECT; `execute`
returns typed columns/rows for read-only queries. `schema()` returns
visible tables, column types/descriptions and helper documentation. All SQL uses
`POST /api/v1/sql`; schema discovery uses `GET /api/v1/schema`. ClickHouse enforces
permissions. The SDK never retries automatically, including failed queries.

Public HTML joins use `parse_id` and `node_index`; `document_id` identifies exact
raw bytes. Public shorthand uses the `public_v1` schema.

For notebook/SQLAlchemy integration:

```python
from periplus_sdk import sql_api
from sqlalchemy import text

engine = sql_api.create_engine(base_url="http://localhost:8000", api_key="ppl_…")
with engine.connect() as connection:
    print(connection.execute(text("SELECT url FROM public_v1.captures LIMIT 5")).all())
engine.dispose()
```

Marimo discovers accessible tables and views through the schema endpoint. Column
reflection uses `SELECT * ... LIMIT 0` to retrieve native types without reading
corpus rows; no `SHOW`, `DESCRIBE`, or system-table access is required.

The DB-API connection advertises the ClickHouse dialect and converts native
nullable integer, decimal, date and datetime types. Nested types retain JSON wire
values. Writes are not exposed through the query API. There are no client
transactions; each statement is independent.
Streaming cursors expose incomplete/truncated results explicitly; configure
`allow_partial` only when partial results suit the application.

See [the public schema](../../docs/SCHEMA.md) and [query boundary](../../docs/QUERY.md).
