Metadata-Version: 2.4
Name: getstrait
Version: 0.1.0
Summary: Python SDK for the Strait hotel booking API — booking infrastructure for AI agents.
Project-URL: Homepage, https://getstrait.dev
Project-URL: Repository, https://github.com/getstrait/strait-python
Project-URL: Changelog, https://github.com/getstrait/strait-python/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/getstrait/strait-python/issues
Author-email: Strait <moussa.omar.salim@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,anthropic,booking,hotel,llm,mcp,openai
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# Strait Python SDK

Hotel booking for AI agents. Python client for the Strait API.

```bash
pip install getstrait
```

- Resolve a hotel name to a property ID
- Check availability and pricing
- Book with human-in-the-loop approval (or skip it for autonomous flows)
- Cancel confirmed bookings
- One-line tool adapters for Anthropic and OpenAI

Full API reference: [getstrait.dev](https://getstrait.dev)

---

## Auth

Pass `api_key=` or set `STRAIT_API_KEY`:

```python
from strait import Strait

strait = Strait(api_key="sk_live_...")       # explicit
strait = Strait()                            # picks up STRAIT_API_KEY
```

Override the base URL (staging, self-host) with `base_url=` or `STRAIT_BASE_URL`.

---

## Agent loop — Anthropic

Drop Strait into an Anthropic agent in three lines: get the tool definitions, run the model, and dispatch tool calls back through `execute()`.

```python
import anthropic
from strait import Strait

strait = Strait()
client = anthropic.Anthropic()

messages = [{"role": "user", "content": "Book me a night at Hotel Berlin on April 10."}]

while True:
    resp = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        tools=strait.tools.for_anthropic(),
        messages=messages,
    )
    if resp.stop_reason != "tool_use":
        break

    tool_results = []
    for block in resp.content:
        if block.type == "tool_use":
            result = strait.tools.execute(block.name, block.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": str(result),
            })
    messages += [
        {"role": "assistant", "content": resp.content},
        {"role": "user", "content": tool_results},
    ]
```

By default, `hotels_book` and `hotels_cancel_booking` return UI-render data so a human can approve. Pass `mode="auto"` in the tool input to skip approval.

---

## Agent loop — OpenAI

```python
from openai import OpenAI
from strait import Strait

strait = Strait()
openai = OpenAI()

resp = openai.chat.completions.create(
    model="gpt-4.1",
    tools=strait.tools.for_openai(),
    messages=[{"role": "user", "content": "Find me a hotel in Berlin for April 10-12."}],
)
```

Dispatch tool calls the same way: `strait.tools.execute(name, json.loads(args))`.

---

## Direct API

The SDK also exposes the raw resources if you'd rather call endpoints yourself:

```python
from strait import Strait

strait = Strait()

# 1. Resolve
match = strait.properties.resolve(name="Hotel Berlin", city="Berlin")
property_id = match.results[0].property_id

# 2. Availability
avail = strait.properties.availability(
    property_id=property_id,
    check_in="2026-04-10",
    check_out="2026-04-12",
    guests=2,
)
offer = avail.available_offers[0]

# 3. Book — auto mode (no human approval UI)
booking = strait.checkout.book(
    offer_id=offer.offer_id,
    guest_name="Jane Doe",
    guest_email="jane@example.com",
    mode="auto",
)
print(booking.confirmation_code)
```

### Human approval vs auto

`checkout.book()` returns either a `SessionResponse` or `ExecuteResponse` depending on `mode`:

| mode                 | returns             | side effects                                              |
|----------------------|---------------------|-----------------------------------------------------------|
| `"human_approval"` (default) | `SessionResponse`   | Creates a checkout session; UI renders `ui_render_data`.  |
| `"auto"`             | `ExecuteResponse`   | Creates session **and** executes the booking immediately. |

Use the session pattern when a human needs to see the price before charging — your frontend renders `session.ui_render_data` and confirms via your own UI flow. Use `"auto"` for unattended agents.

### Cancellation

```python
# Preview (returns UI render data; does not cancel)
details = strait.bookings.cancel(confirmation_code="RKCRQJDV")

# Confirm cancellation
result = strait.bookings.cancel(
    confirmation_code="RKCRQJDV",
    mode="auto",
    reason="plans changed",
)
```

---

## Errors

All errors subclass `StraitError`:

```python
from strait import (
    APIError,              # non-2xx response (base)
    AuthenticationError,   # 401
    NotFoundError,         # 404
    RateLimitError,        # 429
    ServerError,           # 5xx
)

try:
    strait.properties.availability(property_id="bad", check_in="...", check_out="...", guests=2)
except NotFoundError as e:
    print(e.status_code, e.body)
```

---

## Notes

- **Sync only for now.** An `AsyncStrait` client is on the roadmap — raise an issue if you need it sooner.
- **Python 3.10+.**
- Use as a context manager to close the HTTP pool deterministically:
  ```python
  with Strait() as strait:
      ...
  ```

---

## License

MIT.
