Metadata-Version: 2.4
Name: ticketfairy
Version: 0.1.1
Summary: Python client for the Ticket Fairy API: public event listings, organiser events, sales and setup copies
Project-URL: Homepage, https://www.ticketfairy.com/developers
Project-URL: Documentation, https://www.ticketfairy.com/developers
Project-URL: Source, https://github.com/theticketfairy/ticketfairy-cli/tree/main/python
Project-URL: Issues, https://github.com/theticketfairy/ticketfairy-cli/issues
Project-URL: Changelog, https://github.com/theticketfairy/ticketfairy-cli/blob/main/python/CHANGELOG.md
Author-email: Ticket Fairy <support@theticketfairy.com>
License-Expression: MIT
License-File: LICENSE
Keywords: api,events,sdk,ticketfairy,ticketing,tickets
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# ticketfairy (Python)

The Python client for the [Ticket Fairy](https://www.ticketfairy.com) API. Use it to:

- read public event listings;
- create events for a brand you manage;
- read an event's sales;
- copy another event's setup into an event, as a background job you can follow.

It has no dependencies outside the Python standard library and needs Python 3.9 or later.

```sh
pip install ticketfairy
```

The same API is available from Node.js and the command line in the [`ticketfairy` npm package](https://www.npmjs.com/package/ticketfairy).

## Public event listings

The public listing needs no account.

```python
from ticketfairy import TicketFairy

tf = TicketFairy()

page = tf.events.list(country="GB", date_from="2026-11-01", size=50)
for event in page["events"]:
    print(event["displayName"], event["startDate"], event["url"])

# Every matching event, page after page:
for event in tf.events.iter(search="jazz", limit=200):
    print(event["displayName"])
```

`list` takes these filters:

| Filter | Meaning |
| --- | --- |
| `search` | Words to match against event names and descriptions |
| `country` | An ISO 3166-1 alpha-2 country code |
| `state` | A region, state or province |
| `date_from`, `date_to` | Dates as `YYYY-MM-DD` |
| `section_type` | The listing section to read |
| `timezone` | An IANA timezone for the date window |
| `sort` | `created_at`, `updated_at` or `start_date` |
| `order` | `asc` or `desc` |
| `brand_id` | Only events from this brand |
| `include` | The kinds of event to include |
| `size` | Events per page, up to 200 |

`iter` takes the same filters and follows `pagination.nextCursor` for you.

## Organiser API

The organiser API acts as you. To get a token:

1. Create a personal access token in your Ticket Fairy account settings.
2. Pass it to the client, or set it in the `TICKETFAIRY_TOKEN` environment variable.

The token can do what your roles allow, and nothing more.

```python
from ticketfairy import TicketFairy

org = TicketFairy(token="...")  # or set TICKETFAIRY_TOKEN

# Create a draft event for a brand where you are admin or owner.
event = org.events.create(
    brand_id=1234,
    attributes={"displayName": "Summer Festival 2027", "slug": "summer-festival-2027", "flagDraft": True},
)
print(event["id"])

# Tickets sold and revenue, by day and by ticket type and release.
sales = org.events.sales(event["id"])
```

`create` sends an `Idempotency-Key` with each request. If a network error happens, a retry cannot create a second event.

### Copy another event's setup

The copy runs in the background. `start` returns at once with the run. `wait` follows the run until it stops.

```python
run = org.setup_copy.start(new_event_id, source_event_id=last_year_event_id)
run = org.setup_copy.wait(new_event_id, run, timeout=600)

print(run["status"])  # done, partly_done or failed
for part in run["parts"]:
    print(part)
```

How a copy works:

- Both events must belong to the same brand.
- You need the owner, admin or producer role on both events.
- Forms need the owner or admin role.
- Leave out `parts` to copy everything, or name the parts you want.

`start` sends a `request_key`. Sending the same key and the same choice of parts again returns the same run, so a retried start does not copy twice.

## Errors

Every error is a `TicketFairyError`. Each error has these attributes:

- `status`: the HTTP status.
- `code`: a stable code, when the API sends one.
- `message`: the API's own explanation.
- `hint`: what to do next, when the API says.
- `body`: the response.

| Error | When |
| --- | --- |
| `AuthenticationError` | The token is missing, expired or revoked |
| `PermissionDeniedError` | Your role does not allow this |
| `NotFoundError` | No such event or run |
| `ValidationError` | A parameter or field is not valid; the message names it |
| `ConflictError` | A key was already used for something else, or a copy is already running |
| `RateLimitedError` | Too many requests; wait `retry_after` seconds |
| `ServerError` | Ticket Fairy could not complete the request |
| `NetworkError` | No response arrived |
| `SetupCopyTimeoutError` | `wait` gave up while the copy was still running; the copy carries on |

### When the client retries

Reads are retried after a rate limit, a server error or a network error. For a rate limit, the client first waits for the `Retry-After` time.

Writes are retried in the same cases only when the API can tell a repeat from a new request. That is the case for `create`, which sends an `Idempotency-Key`, and for `setup_copy.start`, which sends a `request_key`. A repeat sends the same key, so it returns the first attempt's result rather than doing the work twice.

When the retries run out, the error is raised. A `RateLimitedError` carries `retry_after`.

## API reference

The client follows these OpenAPI documents:

- [Public listing](https://www.ticketfairy.com/api/v1/openapi.json)
- [Organiser API](https://www.theticketfairy.com/api/openapi.json)

The developer guide is at [ticketfairy.com/developers](https://www.ticketfairy.com/developers).
