Metadata-Version: 2.5
Name: mymarky
Version: 0.1.0
Summary: Typed Python client for the Marky REST API: create, schedule and publish posts, upload media, and verify webhooks.
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: attrs>=23.1
Requires-Dist: httpx<1,>=0.27
Description-Content-Type: text/markdown

# mymarky

Typed Python client for the Marky REST API. Python 3.11+.

```bash
pip install mymarky
```

```python
from mymarky import Marky, NotFoundError
from mymarky.generated.api.businesses import list_workspaces
from mymarky.generated.api.library import upload_media_from_url
from mymarky.generated.api.posts import create_post
from mymarky.generated.models import MediaUploadFromUrlRequest, PostCreateRequest

with Marky(api_key="mk_live_...") as marky:
    workspace = next(marky.paginate(list_workspaces.sync))
    media = upload_media_from_url.sync(
        client=marky.client,
        body=MediaUploadFromUrlRequest(workspace_id=workspace.id, url="https://example.com/photo.jpg"),
    )
    post = create_post.sync(
        workspace.id,
        client=marky.client,
        body=PostCreateRequest(caption="We're open late this Friday!", media_ids=[media.id]),
    )
```

Every operation lives in `mymarky.generated.api.<tag>.<operation>` with
`sync`, `sync_detailed`, `asyncio` and `asyncio_detailed` variants; pass
`client=marky.client`.

Workspace operations (`list_workspaces`, `get_workspace`, `create_workspace`,
`update_workspace`, `delete_workspace`) live in the `businesses` tag module.
Routes inside a workspace keep their `/api/businesses/{business_id}/...` path,
so their first argument is named `business_id`: pass the workspace ID.

- **Errors**: any non-2xx raises an `ApiError` subclass (`NotFoundError`,
  `RateLimitError`, ...). Branch on `err.code`, never on the message.
- **Retries**: 429s, and 5xx/network errors on requests that are safe to repeat.
  Create calls get an `Idempotency-Key` automatically, so a retry never makes a
  duplicate. Pass `idempotency_key=` to make your own retries safe too.
- **Unknown values**: enums are plain strings, so a new status or platform never
  breaks parsing; unknown fields land in `.additional_properties`.
- **Renamed "business" to "workspace"**: `list_businesses`, `get_business`,
  `create_business`, `update_business`, `delete_business` and the `business_id`
  field on media upload bodies still work but are deprecated; use the
  `*_workspace(s)` functions and `workspace_id`.
- **Webhooks**: `construct_event(raw_body, request.headers, secret)` checks the
  `X-Marky-Signature` HMAC over `"{X-Marky-Timestamp}." + raw body`, rejects
  deliveries older than 5 minutes (replays), and returns the event.
