Metadata-Version: 2.4
Name: py-regiondo
Version: 0.1.0
Summary: Python client for the Regiondo Booking API (https://sandbox-api.regiondo.com/api.json). Install as `py-regiondo`, import as `regiondo`.
Author-email: E-Dway <info@e-dway.com>
Maintainer: Marco Montanari
License: MIT
Project-URL: Homepage, https://github.com/e-dway/py-regiondo
Project-URL: Source, https://github.com/e-dway/py-regiondo
Project-URL: Issues, https://github.com/e-dway/py-regiondo/issues
Project-URL: Changelog, https://github.com/e-dway/py-regiondo/releases
Project-URL: API Reference, https://sandbox-api.regiondo.com/api.json
Project-URL: Reference Client (PHP/JS), https://github.com/regiondo-dev/api
Keywords: regiondo,booking,tours,activities,api,client
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: responses>=0.23; extra == "dev"
Dynamic: license-file

# regiondo

[![ci](https://github.com/e-dway/py-regiondo/actions/workflows/ci.yml/badge.svg)](https://github.com/e-dway/py-regiondo/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/py-regiondo.svg)](https://pypi.org/project/py-regiondo/)
[![Python](https://img.shields.io/pypi/pyversions/py-regiondo.svg)](https://pypi.org/project/py-regiondo/)

A Python client for the [Regiondo Booking API](https://sandbox-api.regiondo.com/api.json).

Implements the request signing scheme used by the Regiondo PHP/JS sample
clients (HMAC-SHA256 over `timestamp + public_key + http_build_query(params)`),
plus typed namespaces for every endpoint in the v1 spec.

## Install

```bash
pip install py-regiondo
```

The distribution is `py-regiondo`, the import name is `regiondo`:

```python
from regiondo import RegiondoClient
```

From source:

```bash
pip install -e ".[dev]"
```

## Usage

```python
from regiondo import RegiondoClient

client = RegiondoClient(
    public_key="YOUR_PUBLIC_KEY",
    private_key="YOUR_PRIVATE_KEY",
    sandbox=True,                # talks to https://sandbox-api.regiondo.com/v1/
    accept_language="de-DE",
)

# Catalog
categories = client.categories.list()
product = client.products.get(12345)
products = client.products.list(limit=20, active_only="true")
slots = client.products.timeslots(product_id=12345)

# Checkout flow
hold = client.checkout.create_hold(
    item={"product_id": 12345, "variation_id": 1, "qty": 2},
    currency="EUR",
)
totals = client.checkout.totals(input_data={"items": [...]})
order = client.checkout.purchase(
    input_data={"items": [...], "customer": {...}, "payment": {...}},
    currency="EUR",
)

# Partner / supplier
sales = client.partner.sold_items_list(date_from="2026-01-01", date_to="2026-01-31")

# Validation
client.validate.submit(item={"ticket_code": "ABC-123"})
```

### Namespaces

| Attribute        | Endpoints                                                       |
| ---------------- | --------------------------------------------------------------- |
| `client.account`     | `/account/locale`, `/account/currency`                      |
| `client.categories`  | `/categories`, `/categories/{id}`                            |
| `client.checkout`    | hold / totals / purchase / cancel / permanent reservations  |
| `client.languages`   | `/languages`, `/languages/{id}`                              |
| `client.locations`   | `/locations`, `/locations/suggest`, `/locations/{id}`        |
| `client.partner`     | sold items, CRM customers, bookings                          |
| `client.products`    | listing, variations, timeslots, availabilities, widgets, …   |
| `client.reviews`     | `/reviews`                                                   |
| `client.supplier`    | sold items, CRM customers, bookings, resources               |
| `client.tags`        | `/tags`                                                      |
| `client.validate`    | `/validate/submit`                                           |

### Calling an arbitrary endpoint

```python
client.get("products/availabilities/42", date_from="2026-01-01")
client.post("checkout/cancel", params={"reference_ids": "1,2,3"})
client.put("checkout/hold", params={"reservation_code": "X", "reserve_minutes": 15})
client.delete("checkout/hold", reservation_code="X")
```

All four methods sign the request, send PHP-style `http_build_query` params, and
return the parsed JSON body. JSON bodies passed via `json=...` are **not**
included in the signature, matching the reference PHP implementation.

### Errors

Non-2xx responses raise:

| HTTP    | Exception                                  |
| ------- | ------------------------------------------ |
| 401/403 | `regiondo.AuthenticationError`             |
| 404     | `regiondo.NotFoundError`                   |
| 429     | `regiondo.RateLimitError`                  |
| Other 4xx | `regiondo.ValidationError`               |
| 5xx     | `regiondo.RegiondoAPIError` (base class)   |

All of them carry `.status_code`, `.payload` (parsed JSON body), and `.response`
(raw `requests.Response`).

## Tests

```bash
pip install -e ".[dev]"
pytest
```

The signing tests pin output against PHP 7.2's `http_build_query` (captured
live) so the wire format stays compatible with the upstream verifier.

## Releasing

Releases are published to PyPI automatically by the `publish` workflow when a
GitHub Release is created. Auth is via **PyPI Trusted Publishing (OIDC)** — no
API token secrets in the repo.

### One-time PyPI setup

1. Sign in at https://pypi.org/manage/account/publishing/.
2. Under *Add a new pending publisher* (works even before the project exists),
   fill in:
   * **PyPI project name**: `py-regiondo`
   * **Owner**: `e-dway`
   * **Repository name**: `py-regiondo`
   * **Workflow filename**: `publish.yml`
   * **Environment name**: `pypi`
3. Create a matching GitHub Environment named `pypi` under
   *Settings → Environments* (optionally add required reviewers as a manual
   approval gate). Repeat for `testpypi` if you want to dry-run there.

### Cutting a release

```bash
# 1. Bump the version in pyproject.toml
$EDITOR pyproject.toml          # version = "X.Y.Z"

# 2. Commit, tag, push
git commit -am "release: X.Y.Z"
git tag vX.Y.Z
git push origin main vX.Y.Z

# 3. Create the GitHub Release for tag vX.Y.Z
gh release create vX.Y.Z --generate-notes
```

The workflow verifies that the tag (minus the `v` prefix) matches the version
in `pyproject.toml` before building and uploading. Dry-run uploads to TestPyPI
are available via the workflow's *Run workflow* button (choose `testpypi`).

## Notes

* The sandbox URL is `https://sandbox-api.regiondo.com/v1/`; production is
  `https://api.regiondo.com/v1/`. There are also regional production hosts
  (e.g. `api.regiondo.de`); pass them via `base_url=`.
* Regiondo limits API usage to 50,000 requests / 24 h (2,083 / h, 157 / 5 min).
  Prefer webhooks where possible.
* `/checkout/avaialableassignees` is misspelled upstream; the wrapper
  `client.checkout.available_assignees()` uses the misspelled path on the wire.

