enchant-python-client


Nameenchant-python-client JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA client library for accessing Enchant REST API
upload_time2025-10-07 08:39:34
maintainerNone
docs_urlNone
authorAlfredo Ruiz
requires_python~=3.9
licenseMIT
keywords enchant api client helpdesk customer-support tickets
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # enchant-python-client

[![CI](https://github.com/0x0a1f-stacc/enchant-python-client/workflows/CI/badge.svg)](https://github.com/0x0a1f-stacc/enchant-python-client/actions)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Python client library for the [Enchant.com](https://www.enchant.com) REST API with support for both synchronous and asynchronous operations.

## ⚠️ Important Disclaimer

This is an **unofficial** Python client for the Enchant.com API.

- **Not affiliated with** Senvee Inc or Enchant.com
- **Not endorsed by** Senvee Inc or Enchant.com
- **Not maintained by** Senvee Inc or Enchant.com

This client was created based on publicly available [API documentation](https://dev.enchant.com/api/v1) and is provided as-is under the MIT License. Use at your own risk.

For official support, please contact Enchant at https://www.enchant.com

---

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage](#usage)
  - [Authentication](#authentication)
  - [Tickets](#tickets)
  - [Messages](#messages)
  - [Customers](#customers)
  - [Attachments](#attachments)
  - [Users](#users)
  - [Async Usage](#async-usage)
- [Advanced Usage](#advanced-usage)
- [API Coverage](#api-coverage)
- [Development](#development)
- [Contributing](#contributing)
- [License](#license)

## Features

- ✅ **Full API Coverage** - Supports all Enchant REST API v1 endpoints
- ✅ **Sync & Async** - Both synchronous and asynchronous request methods
- ✅ **Type Hints** - Full type annotations for better IDE support
- ✅ **Auto-generated** - Generated from OpenAPI 3.0 specification
- ✅ **Python 3.9+** - Modern Python support
- ✅ **Context Managers** - Proper resource cleanup with `with` statements
- ✅ **Flexible Auth** - Bearer token and HTTP Basic authentication
- ✅ **Customizable** - Built on httpx with extensive configuration options

## Installation

### Using pip

```bash
pip install enchant-python-client
```

### Using uv

```bash
uv add enchant-python-client
```

### From source

```bash
git clone https://github.com/0x0a1f-stacc/enchant-python-client.git
cd enchant-python-client
uv build --wheel
pip install dist/*.whl
```

## Quick Start

```python
from enchant_python_client import AuthenticatedClient
from enchant_python_client.api.tickets import list_tickets

# Create an authenticated client
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token"
)

# List all open tickets
with client as client:
    tickets = list_tickets.sync(client=client, state=["open"])
    for ticket in tickets:
        print(f"#{ticket.number}: {ticket.subject}")
```

## Usage

### Authentication

Get your API token from your Enchant account settings.

```python
from enchant_python_client import AuthenticatedClient

# Standard Bearer token authentication
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token"
)

# HTTP Basic Auth (token as username, any password)
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    prefix="",  # Empty prefix for Basic Auth
)
```

### Tickets

```python
from enchant_python_client.api.tickets import (
    list_tickets,
    get_ticket,
    create_ticket,
    update_ticket,
    add_labels_to_ticket,
)
from enchant_python_client.models import TicketUpdate

with client as client:
    # List tickets with filters
    open_tickets = list_tickets.sync(
        client=client,
        state=["open"],
        per_page=50,
        page=1
    )

    # Get a specific ticket with embedded data
    ticket = get_ticket.sync(
        client=client,
        ticket_id="abc123",
        embed=["customer", "messages", "labels"]
    )

    # Create a new ticket
    new_ticket_data = {
        "type": "email",
        "subject": "Need help with billing",
        "customer_id": "customer123",
        "inbox_id": "inbox456",
        "user_id": "user789"
    }
    new_ticket = create_ticket.sync(client=client, body=new_ticket_data)

    # Update a ticket
    update = TicketUpdate(state="closed", user_id="user789")
    updated = update_ticket.sync(
        client=client,
        ticket_id="abc123",
        body=update
    )

    # Add labels
    add_labels_to_ticket.sync(
        client=client,
        ticket_id="abc123",
        label_ids=["label1", "label2"]
    )
```

### Messages

```python
from enchant_python_client.api.messages import create_message
from enchant_python_client.models import (
    MessageCreateNote,
    MessageCreateOutboundReply,
)

with client as client:
    # Create an internal note
    note = MessageCreateNote(
        type="note",
        user_id="user123",
        body="Customer called to follow up",
        htmlized=False
    )
    message = create_message.sync(
        client=client,
        ticket_id="ticket123",
        body=note
    )

    # Send an outbound reply
    reply = MessageCreateOutboundReply(
        type="reply",
        direction="out",
        user_id="user123",
        to="customer@example.com",
        body="Thanks for contacting us! Here's the solution...",
        htmlized=False
    )
    message = create_message.sync(
        client=client,
        ticket_id="ticket123",
        body=reply
    )
```

### Customers

```python
from enchant_python_client.api.customers import (
    list_customers,
    get_customer,
    create_customer,
    update_customer,
)
from enchant_python_client.models import CustomerInput, ContactInput

with client as client:
    # List customers
    customers = list_customers.sync(client=client, per_page=100)

    # Get a specific customer
    customer = get_customer.sync(client=client, customer_id="cust123")

    # Create a customer
    new_customer = CustomerInput(
        first_name="John",
        last_name="Doe",
        contacts=[
            ContactInput(type="email", value="john@example.com"),
            ContactInput(type="phone", value="+1234567890")
        ]
    )
    customer = create_customer.sync(client=client, body=new_customer)

    # Update a customer
    update = CustomerInput(
        first_name="Jane",
        last_name="Doe"
    )
    updated = update_customer.sync(
        client=client,
        customer_id="cust123",
        body=update
    )
```

### Attachments

```python
from enchant_python_client.api.attachments import create_attachment, get_attachment
from enchant_python_client.models import AttachmentCreate
import base64

with client as client:
    # Upload an attachment
    with open("document.pdf", "rb") as f:
        file_data = base64.b64encode(f.read()).decode("utf-8")

    attachment = AttachmentCreate(
        name="document.pdf",
        type="application/pdf",
        data=file_data
    )
    created = create_attachment.sync(client=client, body=attachment)

    # Get attachment metadata
    attachment_info = get_attachment.sync(
        client=client,
        attachment_id=created.id
    )

    # Use attachment in a message
    note = MessageCreateNote(
        type="note",
        user_id="user123",
        body="Attached the requested document",
        htmlized=False,
        attachment_ids=[created.id]
    )
```

### Users

```python
from enchant_python_client.api.users import list_users

with client as client:
    # List all users in your help desk
    users = list_users.sync(client=client)
    for user in users:
        print(f"{user.first_name} {user.last_name} ({user.email})")
```

### Async Usage

All API methods have async equivalents:

```python
import asyncio
from enchant_python_client import AuthenticatedClient
from enchant_python_client.api.tickets import list_tickets, get_ticket

async def main():
    client = AuthenticatedClient(
        base_url="https://yoursite.enchant.com/api/v1",
        token="your-api-token"
    )

    async with client as client:
        # List tickets asynchronously
        tickets = await list_tickets.asyncio(
            client=client,
            state=["open"]
        )

        # Get detailed response with status code
        response = await get_ticket.asyncio_detailed(
            client=client,
            ticket_id="abc123"
        )
        print(f"Status: {response.status_code}")
        print(f"Ticket: {response.parsed}")

asyncio.run(main())
```

## Advanced Usage

### Custom HTTP Client Configuration

```python
from enchant_python_client import AuthenticatedClient

# Custom timeout
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    timeout=30.0  # 30 seconds
)

# Custom SSL verification
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    verify_ssl="/path/to/certificate.pem"
)

# Disable SSL verification (not recommended for production)
client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    verify_ssl=False
)
```

### Request/Response Hooks

```python
from enchant_python_client import AuthenticatedClient

def log_request(request):
    print(f"→ {request.method} {request.url}")

def log_response(response):
    print(f"← {response.status_code}")

client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    httpx_args={
        "event_hooks": {
            "request": [log_request],
            "response": [log_response]
        }
    }
)
```

### Pagination

```python
from enchant_python_client.api.tickets import list_tickets

with client as client:
    page = 1
    per_page = 100

    while True:
        tickets = list_tickets.sync(
            client=client,
            state=["open"],
            page=page,
            per_page=per_page
        )

        if not tickets:
            break

        for ticket in tickets:
            print(f"#{ticket.number}: {ticket.subject}")

        page += 1
```

### Error Handling

```python
from enchant_python_client import AuthenticatedClient
from enchant_python_client.api.tickets import get_ticket
from enchant_python_client.models import Error
import httpx

client = AuthenticatedClient(
    base_url="https://yoursite.enchant.com/api/v1",
    token="your-api-token",
    raise_on_unexpected_status=True
)

try:
    with client as client:
        response = get_ticket.sync_detailed(
            client=client,
            ticket_id="invalid-id"
        )

        if isinstance(response.parsed, Error):
            print(f"API Error: {response.parsed.message}")
        else:
            print(f"Ticket: {response.parsed.subject}")

except httpx.TimeoutException:
    print("Request timed out")
except Exception as e:
    print(f"Error: {e}")
```

## API Coverage

This client supports all Enchant REST API v1 endpoints:

| Resource | Endpoints |
|----------|-----------|
| **Tickets** | List, Get, Create, Update, Add Labels, Remove Labels |
| **Messages** | Create (Notes, Inbound Replies, Outbound Replies) |
| **Customers** | List, Get, Create, Update |
| **Contacts** | Create, Delete |
| **Attachments** | Create (Upload), Get |
| **Users** | List |

For detailed API documentation, see: https://dev.enchant.com/api/v1

## Development

This project uses [uv](https://github.com/astral-sh/uv) for dependency management.

```bash
# Clone the repository
git clone https://github.com/0x0a1f-stacc/enchant-python-client.git
cd enchant-python-client

# Install dependencies
uv sync

# Run linting
uv run ruff check enchant_python_client/
uv run ruff format enchant_python_client/

# Build distribution
uv build

# Regenerate client from OpenAPI spec
./scripts/regenerate.sh
```

### Project Structure

- `openapi.yaml` - OpenAPI 3.0 specification (source of truth)
- `enchant_python_client/` - Auto-generated client code
- `scripts/regenerate.sh` - Regenerate client from spec
- `CLAUDE.md` - AI coding assistant guidance
- `CONTRIBUTING.md` - Contribution guidelines

## Contributing

Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

### Reporting Issues

- [Bug Reports](.github/ISSUE_TEMPLATE/bug_report.md)
- [Feature Requests](.github/ISSUE_TEMPLATE/feature_request.md)

### Quick Contribution Guide

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Run linting: `uv run ruff check && uv run ruff format`
5. Update `CHANGELOG.md`
6. Commit your changes (`git commit -m 'Add amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

Copyright (c) 2025 Alfredo Ruiz

## Acknowledgments

- Generated using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client)
- Built with [httpx](https://www.python-encode.io/httpx/) and [attrs](https://www.attrs.org/)
- OpenAPI specification based on [Enchant API documentation](https://dev.enchant.com/api/v1)

## Links

- **Official Enchant Website**: https://www.enchant.com
- **Enchant API Documentation**: https://dev.enchant.com/api/v1
- **GitHub Repository**: https://github.com/0x0a1f-stacc/enchant-python-client
- **Issue Tracker**: https://github.com/0x0a1f-stacc/enchant-python-client/issues

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "enchant-python-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "~=3.9",
    "maintainer_email": null,
    "keywords": "enchant, api, client, helpdesk, customer-support, tickets",
    "author": "Alfredo Ruiz",
    "author_email": "Alfredo Ruiz <alfredo@globalvoice.mx>",
    "download_url": "https://files.pythonhosted.org/packages/16/3e/be5e67172c9423c79b4a92d79007d452eabbe7c78ba6ea153073fe7ab24f/enchant_python_client-1.0.0.tar.gz",
    "platform": null,
    "description": "# enchant-python-client\n\n[![CI](https://github.com/0x0a1f-stacc/enchant-python-client/workflows/CI/badge.svg)](https://github.com/0x0a1f-stacc/enchant-python-client/actions)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Python client library for the [Enchant.com](https://www.enchant.com) REST API with support for both synchronous and asynchronous operations.\n\n## \u26a0\ufe0f Important Disclaimer\n\nThis is an **unofficial** Python client for the Enchant.com API.\n\n- **Not affiliated with** Senvee Inc or Enchant.com\n- **Not endorsed by** Senvee Inc or Enchant.com\n- **Not maintained by** Senvee Inc or Enchant.com\n\nThis client was created based on publicly available [API documentation](https://dev.enchant.com/api/v1) and is provided as-is under the MIT License. Use at your own risk.\n\nFor official support, please contact Enchant at https://www.enchant.com\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n  - [Authentication](#authentication)\n  - [Tickets](#tickets)\n  - [Messages](#messages)\n  - [Customers](#customers)\n  - [Attachments](#attachments)\n  - [Users](#users)\n  - [Async Usage](#async-usage)\n- [Advanced Usage](#advanced-usage)\n- [API Coverage](#api-coverage)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Features\n\n- \u2705 **Full API Coverage** - Supports all Enchant REST API v1 endpoints\n- \u2705 **Sync & Async** - Both synchronous and asynchronous request methods\n- \u2705 **Type Hints** - Full type annotations for better IDE support\n- \u2705 **Auto-generated** - Generated from OpenAPI 3.0 specification\n- \u2705 **Python 3.9+** - Modern Python support\n- \u2705 **Context Managers** - Proper resource cleanup with `with` statements\n- \u2705 **Flexible Auth** - Bearer token and HTTP Basic authentication\n- \u2705 **Customizable** - Built on httpx with extensive configuration options\n\n## Installation\n\n### Using pip\n\n```bash\npip install enchant-python-client\n```\n\n### Using uv\n\n```bash\nuv add enchant-python-client\n```\n\n### From source\n\n```bash\ngit clone https://github.com/0x0a1f-stacc/enchant-python-client.git\ncd enchant-python-client\nuv build --wheel\npip install dist/*.whl\n```\n\n## Quick Start\n\n```python\nfrom enchant_python_client import AuthenticatedClient\nfrom enchant_python_client.api.tickets import list_tickets\n\n# Create an authenticated client\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\"\n)\n\n# List all open tickets\nwith client as client:\n    tickets = list_tickets.sync(client=client, state=[\"open\"])\n    for ticket in tickets:\n        print(f\"#{ticket.number}: {ticket.subject}\")\n```\n\n## Usage\n\n### Authentication\n\nGet your API token from your Enchant account settings.\n\n```python\nfrom enchant_python_client import AuthenticatedClient\n\n# Standard Bearer token authentication\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\"\n)\n\n# HTTP Basic Auth (token as username, any password)\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    prefix=\"\",  # Empty prefix for Basic Auth\n)\n```\n\n### Tickets\n\n```python\nfrom enchant_python_client.api.tickets import (\n    list_tickets,\n    get_ticket,\n    create_ticket,\n    update_ticket,\n    add_labels_to_ticket,\n)\nfrom enchant_python_client.models import TicketUpdate\n\nwith client as client:\n    # List tickets with filters\n    open_tickets = list_tickets.sync(\n        client=client,\n        state=[\"open\"],\n        per_page=50,\n        page=1\n    )\n\n    # Get a specific ticket with embedded data\n    ticket = get_ticket.sync(\n        client=client,\n        ticket_id=\"abc123\",\n        embed=[\"customer\", \"messages\", \"labels\"]\n    )\n\n    # Create a new ticket\n    new_ticket_data = {\n        \"type\": \"email\",\n        \"subject\": \"Need help with billing\",\n        \"customer_id\": \"customer123\",\n        \"inbox_id\": \"inbox456\",\n        \"user_id\": \"user789\"\n    }\n    new_ticket = create_ticket.sync(client=client, body=new_ticket_data)\n\n    # Update a ticket\n    update = TicketUpdate(state=\"closed\", user_id=\"user789\")\n    updated = update_ticket.sync(\n        client=client,\n        ticket_id=\"abc123\",\n        body=update\n    )\n\n    # Add labels\n    add_labels_to_ticket.sync(\n        client=client,\n        ticket_id=\"abc123\",\n        label_ids=[\"label1\", \"label2\"]\n    )\n```\n\n### Messages\n\n```python\nfrom enchant_python_client.api.messages import create_message\nfrom enchant_python_client.models import (\n    MessageCreateNote,\n    MessageCreateOutboundReply,\n)\n\nwith client as client:\n    # Create an internal note\n    note = MessageCreateNote(\n        type=\"note\",\n        user_id=\"user123\",\n        body=\"Customer called to follow up\",\n        htmlized=False\n    )\n    message = create_message.sync(\n        client=client,\n        ticket_id=\"ticket123\",\n        body=note\n    )\n\n    # Send an outbound reply\n    reply = MessageCreateOutboundReply(\n        type=\"reply\",\n        direction=\"out\",\n        user_id=\"user123\",\n        to=\"customer@example.com\",\n        body=\"Thanks for contacting us! Here's the solution...\",\n        htmlized=False\n    )\n    message = create_message.sync(\n        client=client,\n        ticket_id=\"ticket123\",\n        body=reply\n    )\n```\n\n### Customers\n\n```python\nfrom enchant_python_client.api.customers import (\n    list_customers,\n    get_customer,\n    create_customer,\n    update_customer,\n)\nfrom enchant_python_client.models import CustomerInput, ContactInput\n\nwith client as client:\n    # List customers\n    customers = list_customers.sync(client=client, per_page=100)\n\n    # Get a specific customer\n    customer = get_customer.sync(client=client, customer_id=\"cust123\")\n\n    # Create a customer\n    new_customer = CustomerInput(\n        first_name=\"John\",\n        last_name=\"Doe\",\n        contacts=[\n            ContactInput(type=\"email\", value=\"john@example.com\"),\n            ContactInput(type=\"phone\", value=\"+1234567890\")\n        ]\n    )\n    customer = create_customer.sync(client=client, body=new_customer)\n\n    # Update a customer\n    update = CustomerInput(\n        first_name=\"Jane\",\n        last_name=\"Doe\"\n    )\n    updated = update_customer.sync(\n        client=client,\n        customer_id=\"cust123\",\n        body=update\n    )\n```\n\n### Attachments\n\n```python\nfrom enchant_python_client.api.attachments import create_attachment, get_attachment\nfrom enchant_python_client.models import AttachmentCreate\nimport base64\n\nwith client as client:\n    # Upload an attachment\n    with open(\"document.pdf\", \"rb\") as f:\n        file_data = base64.b64encode(f.read()).decode(\"utf-8\")\n\n    attachment = AttachmentCreate(\n        name=\"document.pdf\",\n        type=\"application/pdf\",\n        data=file_data\n    )\n    created = create_attachment.sync(client=client, body=attachment)\n\n    # Get attachment metadata\n    attachment_info = get_attachment.sync(\n        client=client,\n        attachment_id=created.id\n    )\n\n    # Use attachment in a message\n    note = MessageCreateNote(\n        type=\"note\",\n        user_id=\"user123\",\n        body=\"Attached the requested document\",\n        htmlized=False,\n        attachment_ids=[created.id]\n    )\n```\n\n### Users\n\n```python\nfrom enchant_python_client.api.users import list_users\n\nwith client as client:\n    # List all users in your help desk\n    users = list_users.sync(client=client)\n    for user in users:\n        print(f\"{user.first_name} {user.last_name} ({user.email})\")\n```\n\n### Async Usage\n\nAll API methods have async equivalents:\n\n```python\nimport asyncio\nfrom enchant_python_client import AuthenticatedClient\nfrom enchant_python_client.api.tickets import list_tickets, get_ticket\n\nasync def main():\n    client = AuthenticatedClient(\n        base_url=\"https://yoursite.enchant.com/api/v1\",\n        token=\"your-api-token\"\n    )\n\n    async with client as client:\n        # List tickets asynchronously\n        tickets = await list_tickets.asyncio(\n            client=client,\n            state=[\"open\"]\n        )\n\n        # Get detailed response with status code\n        response = await get_ticket.asyncio_detailed(\n            client=client,\n            ticket_id=\"abc123\"\n        )\n        print(f\"Status: {response.status_code}\")\n        print(f\"Ticket: {response.parsed}\")\n\nasyncio.run(main())\n```\n\n## Advanced Usage\n\n### Custom HTTP Client Configuration\n\n```python\nfrom enchant_python_client import AuthenticatedClient\n\n# Custom timeout\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    timeout=30.0  # 30 seconds\n)\n\n# Custom SSL verification\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    verify_ssl=\"/path/to/certificate.pem\"\n)\n\n# Disable SSL verification (not recommended for production)\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    verify_ssl=False\n)\n```\n\n### Request/Response Hooks\n\n```python\nfrom enchant_python_client import AuthenticatedClient\n\ndef log_request(request):\n    print(f\"\u2192 {request.method} {request.url}\")\n\ndef log_response(response):\n    print(f\"\u2190 {response.status_code}\")\n\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    httpx_args={\n        \"event_hooks\": {\n            \"request\": [log_request],\n            \"response\": [log_response]\n        }\n    }\n)\n```\n\n### Pagination\n\n```python\nfrom enchant_python_client.api.tickets import list_tickets\n\nwith client as client:\n    page = 1\n    per_page = 100\n\n    while True:\n        tickets = list_tickets.sync(\n            client=client,\n            state=[\"open\"],\n            page=page,\n            per_page=per_page\n        )\n\n        if not tickets:\n            break\n\n        for ticket in tickets:\n            print(f\"#{ticket.number}: {ticket.subject}\")\n\n        page += 1\n```\n\n### Error Handling\n\n```python\nfrom enchant_python_client import AuthenticatedClient\nfrom enchant_python_client.api.tickets import get_ticket\nfrom enchant_python_client.models import Error\nimport httpx\n\nclient = AuthenticatedClient(\n    base_url=\"https://yoursite.enchant.com/api/v1\",\n    token=\"your-api-token\",\n    raise_on_unexpected_status=True\n)\n\ntry:\n    with client as client:\n        response = get_ticket.sync_detailed(\n            client=client,\n            ticket_id=\"invalid-id\"\n        )\n\n        if isinstance(response.parsed, Error):\n            print(f\"API Error: {response.parsed.message}\")\n        else:\n            print(f\"Ticket: {response.parsed.subject}\")\n\nexcept httpx.TimeoutException:\n    print(\"Request timed out\")\nexcept Exception as e:\n    print(f\"Error: {e}\")\n```\n\n## API Coverage\n\nThis client supports all Enchant REST API v1 endpoints:\n\n| Resource | Endpoints |\n|----------|-----------|\n| **Tickets** | List, Get, Create, Update, Add Labels, Remove Labels |\n| **Messages** | Create (Notes, Inbound Replies, Outbound Replies) |\n| **Customers** | List, Get, Create, Update |\n| **Contacts** | Create, Delete |\n| **Attachments** | Create (Upload), Get |\n| **Users** | List |\n\nFor detailed API documentation, see: https://dev.enchant.com/api/v1\n\n## Development\n\nThis project uses [uv](https://github.com/astral-sh/uv) for dependency management.\n\n```bash\n# Clone the repository\ngit clone https://github.com/0x0a1f-stacc/enchant-python-client.git\ncd enchant-python-client\n\n# Install dependencies\nuv sync\n\n# Run linting\nuv run ruff check enchant_python_client/\nuv run ruff format enchant_python_client/\n\n# Build distribution\nuv build\n\n# Regenerate client from OpenAPI spec\n./scripts/regenerate.sh\n```\n\n### Project Structure\n\n- `openapi.yaml` - OpenAPI 3.0 specification (source of truth)\n- `enchant_python_client/` - Auto-generated client code\n- `scripts/regenerate.sh` - Regenerate client from spec\n- `CLAUDE.md` - AI coding assistant guidance\n- `CONTRIBUTING.md` - Contribution guidelines\n\n## Contributing\n\nContributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n### Reporting Issues\n\n- [Bug Reports](.github/ISSUE_TEMPLATE/bug_report.md)\n- [Feature Requests](.github/ISSUE_TEMPLATE/feature_request.md)\n\n### Quick Contribution Guide\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Run linting: `uv run ruff check && uv run ruff format`\n5. Update `CHANGELOG.md`\n6. Commit your changes (`git commit -m 'Add amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\nCopyright (c) 2025 Alfredo Ruiz\n\n## Acknowledgments\n\n- Generated using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client)\n- Built with [httpx](https://www.python-encode.io/httpx/) and [attrs](https://www.attrs.org/)\n- OpenAPI specification based on [Enchant API documentation](https://dev.enchant.com/api/v1)\n\n## Links\n\n- **Official Enchant Website**: https://www.enchant.com\n- **Enchant API Documentation**: https://dev.enchant.com/api/v1\n- **GitHub Repository**: https://github.com/0x0a1f-stacc/enchant-python-client\n- **Issue Tracker**: https://github.com/0x0a1f-stacc/enchant-python-client/issues\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A client library for accessing Enchant REST API",
    "version": "1.0.0",
    "project_urls": {
        "Changelog": "https://github.com/0x0a1f-stacc/enchant-python-client/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/0x0a1f-stacc/enchant-python-client/blob/main/README.md",
        "Homepage": "https://github.com/0x0a1f-stacc/enchant-python-client",
        "Issues": "https://github.com/0x0a1f-stacc/enchant-python-client/issues",
        "Repository": "https://github.com/0x0a1f-stacc/enchant-python-client"
    },
    "split_keywords": [
        "enchant",
        " api",
        " client",
        " helpdesk",
        " customer-support",
        " tickets"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b13b82a5b0f9b0d3d2cd010648b2e5a3ca1350ebc802dcfad5f3b46da874ba86",
                "md5": "e98606ee55496dd9810da9fb02b68d61",
                "sha256": "9ed100079f82101fdfd474d2bff9be0974b07fb1fb2a89c272a98e09cc970612"
            },
            "downloads": -1,
            "filename": "enchant_python_client-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e98606ee55496dd9810da9fb02b68d61",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "~=3.9",
            "size": 68344,
            "upload_time": "2025-10-07T08:39:32",
            "upload_time_iso_8601": "2025-10-07T08:39:32.906227Z",
            "url": "https://files.pythonhosted.org/packages/b1/3b/82a5b0f9b0d3d2cd010648b2e5a3ca1350ebc802dcfad5f3b46da874ba86/enchant_python_client-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "163ebe5e67172c9423c79b4a92d79007d452eabbe7c78ba6ea153073fe7ab24f",
                "md5": "db132a71a4f8b6e6bab266608e844aeb",
                "sha256": "612cb9f875e9ba07f413f33c561b51af253dba3ae8783dfd0aebdb5347ea1a30"
            },
            "downloads": -1,
            "filename": "enchant_python_client-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "db132a71a4f8b6e6bab266608e844aeb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "~=3.9",
            "size": 26071,
            "upload_time": "2025-10-07T08:39:34",
            "upload_time_iso_8601": "2025-10-07T08:39:34.389503Z",
            "url": "https://files.pythonhosted.org/packages/16/3e/be5e67172c9423c79b4a92d79007d452eabbe7c78ba6ea153073fe7ab24f/enchant_python_client-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-07 08:39:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "0x0a1f-stacc",
    "github_project": "enchant-python-client",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "enchant-python-client"
}
        
Elapsed time: 1.60985s