Metadata-Version: 2.4
Name: parse-sdk
Version: 0.1.0
Summary: Dynamic-yet-typed Python SDK for Parse APIs
Project-URL: Homepage, https://parse.bot
Project-URL: Changelog, https://pypi.org/project/parse-sdk/#history
Author-email: Parse <team@parse.bot>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,api-client,codegen,parse,scraping,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: httpx>=0.27
Requires-Dist: tomli>=1.1.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: pyright>=1.1.408; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: tomli>=2; (python_version < '3.11') and extra == 'dev'
Description-Content-Type: text/markdown

# parse-sdk

Typed Python SDK tooling for [Parse](https://parse.bot) APIs.

`parse-sdk` is the shared **runtime + CLI**. It generates a project-local
`parse_apis` package — a real, installed, editable dependency — that holds the
typed client for every API your key can call. Your application code imports from
`parse_apis`; `parse-sdk` provides the runtime bases and errors those clients use.

## Quickstart

In a uv-managed project (`uv init` first if you don't have a `pyproject.toml`):

```bash
uv add parse-sdk            # installs the runtime + `parse` CLI into your project
uv run parse init           # prompts for your API key, then scaffolds + syncs parse_apis
```

Non-interactive (CI, agents, scripts): authenticate first with
`uv run parse login --api-key YOUR_KEY` (add `--base-url …` for a non-default
host), or export `PARSE_API_KEY` — then `uv run parse init` runs without prompts.

`parse init` is the one-time setup. It:

1. ensures credentials (prompts and stores to `~/.config/parse/credentials`, or run `parse login` first);
2. creates the committed `parse_apis` scaffold;
3. records `parse_apis` as an **editable path dependency** (and a `[tool.uv.sources]` entry);
4. appends a deny-by-default `.gitignore` block (commits the scaffold, ignores generated payload);
5. migrates — or safely refuses — any legacy flat `parse_apis/` layout;
6. runs the first `parse sync`.

Then use it:

```python
from parse_apis.reddit_com_api import Reddit   # generated, typed client (slugs look like <domain>_<tld>_api)
from parse_apis import RateLimitError          # runtime errors, re-exported

reddit = Reddit()                              # picks up `parse login` credentials
try:
    # Navigate from a constructible resource, with a bounded fetch:
    for post in reddit.subreddit("smallbusiness").search_posts(query="hiring", limit=10):
        print(post.title)
except RateLimitError:
    ...
```

(The exact methods are generated from *your* API's spec — `parse_apis/<slug>/README.md`
and `example.py` document each client's real surface.)

```bash
uv run python app.py        # run your app in the project environment
uv run parse sync           # later: refresh after you change APIs in Parse
```

## Running commands (`uv run` vs. activation)

`uv add parse-sdk` installs the `parse` console script into your project's `.venv`,
which isn't on your shell `PATH` by default. Two equivalent ways to reach it:

- **`uv run parse <cmd>`** — runs the venv's `parse` with no activation, auto-syncing first. (Recommended.)
- **`source .venv/bin/activate`** then `parse <cmd>` directly.

Prefer one of these over a global `uv tool install parse-sdk`: codegen must run with
the **same** pinned `parse-sdk` your project runs against (see *Versioning* below), and a
global copy can drift out of sync. Your end users running their *app* never invoke `parse` —
they just `import parse_apis`.

## On-disk layout

```text
parse_apis/
  pyproject.toml                 # committed: name="parse-apis", pinned parse-sdk==X
  src/parse_apis/
    __init__.py                  # committed scaffold — re-exports runtime errors
    py.typed                     # committed
    reddit/__init__.py           # generated (gitignored)
    _manifest.json               # generated (gitignored)
    AGENTS.md  CLAUDE.md         # generated cross-API index (gitignored)
```

Commit the three scaffold files; the generated payload is per-key (it reveals your API
inventory) and stays gitignored. `parse sync` builds the next payload in a staging tree,
self-tests it (secret scan, import-model, no-stale-docs), and promotes it with an atomic
directory swap — a failed sync never leaves broken or secret-bearing files in your project.

## Import model

- Application code imports generated clients from `parse_apis.<slug>`.
- Runtime errors/base types are re-exported from `parse_apis` (sourced from `parse_sdk`).
- Because `parse_apis` is an **installed** editable package, imports resolve from any
  directory — no `sys.path` or editor `extraPaths` tricks.
- Generated files are project-local and differ per Parse API key.

## Fresh clone & CI (post-publish)

```bash
uv sync                     # installs deps incl. the editable parse_apis scaffold
uv run parse sync           # regenerate the per-key payload
uv run pytest && uv run pyright   # pyright must run against the PROJECT env —
                                  # add both as dev deps (`uv add --dev pytest pyright`);
                                  # a bare/global `pyright` can't resolve parse_apis
```

The committed scaffold is a valid dependency target before any slugs exist, so `uv sync`
succeeds on a clean checkout.

## CLI

| Command | What it does |
| --- | --- |
| `parse login` | Save API key + base URL to local credentials. No project changes. |
| `parse init` | One-time: ensure creds, scaffold `parse_apis`, record deps + gitignore, first sync. |
| `parse sync` | Regenerate the typed payload into `parse_apis/src/parse_apis` (staged + atomic). |
| `parse clean` | Remove generated payload; keep the committed scaffold. |
| `parse list` | Print the APIs the current key can call (no generation). |
| `parse whoami` | Show the current key + base URL. |

Run `parse <cmd> --help` for full per-command help.

## Versioning

`parse_apis/pyproject.toml` pins the **exact** `parse-sdk` it was generated against — generated
code subclasses the runtime by name. After upgrading `parse-sdk`, **re-run `parse sync`** to
regenerate against the new runtime; `init`/`sync` restamp the pin.

## Env vars

| Var | Default | Notes |
| --- | --- | --- |
| `PARSE_API_KEY` | – | Auth for real requests (or use `parse login`). |
| `PARSE_API_BASE_URL` | `https://api.parse.bot` | Locally: `http://localhost:8001`. |

## Changelog

Release history is on the PyPI project page:
<https://pypi.org/project/parse-sdk/#history>.

## Security

To report a security issue, email **security@parse.bot** — please do not open
a public issue.

## License

[MIT](LICENSE) © 2026 Parse. The license covers the `parse-sdk` runtime,
codegen, and CLI; use of the Parse API/service is governed separately by
Parse's terms.
