Metadata-Version: 2.4
Name: djep-sdk
Version: 1.2.0
Summary: Official Python SDK for the DJ Event Planner (DJEP) REST API
Home-page: https://github.com/djeventplannerhub/djep-python-sdk
Author: DJ Event Planner
Author-email: support@djeventplanner.com
Keywords: djep dj event planner api sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: requires-python
Dynamic: summary

# DJEP Python SDK

Official Python SDK for the [DJ Event Planner (DJEP)](https://www.djeventplanner.com) REST API.

## Requirements

- Python 3.7 or later
- No external dependencies

## Installation

### Via pip

```bash
pip install djep-sdk
```

### Manual Installation

Download the SDK and place the `djep_sdk` folder in your project:

```python
from djep_sdk import Client
```

## Quick Start

```python
import os
from djep_sdk import Client

# Load your API key from environment variables (never hardcode keys)
djep = Client(api_key=os.environ['DJEP_API_KEY'], domain=os.environ['DJEP_DOMAIN'])

# Check API status
status = djep.status()
print(status['data']['api_version'])

# List upcoming events
events = djep.events.list(status='Booked', per_page=10)
for event in events['data']:
    print(f"{event['event_type']} on {event['event_date']}")
```

## Authentication

Your API key is generated in DJEP under **Setup > Integrations > API Key**.

**Important:** Never hardcode your API key in source files. Use environment variables.

```python
import os
from djep_sdk import Client

# Environment variable (recommended)
djep = Client(api_key=os.environ['DJEP_API_KEY'], domain=os.environ['DJEP_DOMAIN'])

# Or from a .env file (using python-dotenv)
from dotenv import load_dotenv
load_dotenv()
djep = Client(api_key=os.environ['DJEP_API_KEY'], domain=os.environ['DJEP_DOMAIN'])
```

## Usage

### Events

```python
# List events
events = djep.events.list(status='Booked', sort_by='event_date')

# Get a single event
event = djep.events.get(56789)

# Create an event (financials auto-calculated from package)
new_event = djep.events.create(
    clientid=12345,
    event_date='2026-09-15',
    event_type='Wedding',
    start_time='3:00 PM',
    end_time='11:00 PM',
    addons='501:2,502:1',
)
print(f"Total fee: {new_event['data']['financials']['total_fee']}")

# Update specific fields
djep.events.update(56789, {'status': 'Confirmed', 'guest_count': 200})

# Update and recalculate financials
djep.events.update(56789, {'pkg_idnumber': 14200}, recalculate=True)

# Delete an event (cascading)
djep.events.delete(56789)

# Event sub-data
payments = djep.events.payments(56789)
songs = djep.events.music_requests(56789)
planning = djep.events.planning(56789)
```

### Clients

```python
clients = djep.clients.list(per_page=25)
client = djep.clients.get(12345)

new_client = djep.clients.create(
    first_name='John',
    last_name='Smith',
    email='john@example.com',
)

djep.clients.update(12345, {'email': 'new@example.com'})
djep.clients.delete(12345)
```

### Venues, Employees, Packages, Addons, Contacts

```python
# All follow the same pattern
venues = djep.venues.list()
venue = djep.venues.get(789)

employees = djep.employees.list()
packages = djep.packages.list()
addons = djep.addons.list()
contacts = djep.contacts.list()
```

### Vendors

```python
vendors = djep.vendors.list()
vendor = djep.vendors.get(3456)

# Link a vendor to an event
djep.vendors.link_to_event(56789, 3456)
```

### Payments

```python
# List all payments company-wide
payments = djep.payments.list(per_page=50)

# Add a payment to an event
result = djep.payments.add_to_event(56789, 500.00, 'Credit Card',
    processing_fee=15,
    comments='Final payment',
)
print(f"Balance due: {result['data']['balance_due']}")
```

### Music Requests

```python
# Get requests for an event
songs = djep.music_requests.for_event(56789)

# Add a music request
djep.music_requests.add(56789, 'Queen', 'Bohemian Rhapsody', 'MPL')
djep.music_requests.add(56789, 'ABBA', 'Dancing Queen', 'DED', comments='For the bride')
```

### Booking Helpers

```python
# List available helpers
helpers = djep.booking_helpers.list()

# Run by unique_id (recommended)
result = djep.booking_helpers.run(56789, unique_id='book_event_1')
print(result['data']['log'])

# Or by position index
result = djep.booking_helpers.run(56789, bhid=0)
```

### Availability

```python
# Check a single date
avail = djep.availability.check('09/15/2026')
if avail['data']['available']:
    print(f"{avail['data']['employees']['available']} employees available")

# Check a date range (max 90 days)
date_range = djep.availability.range('09/01/2026', '09/30/2026')
for date in date_range['data']['dates']:
    status = 'Available' if date['available'] else 'Unavailable'
    print(f"{date['date']}: {status}")
```

### Settings

```python
rfi_settings = djep.settings.website_tools('request_info')
company = djep.settings.company()
fields = djep.settings.custom_fields()
```

### Expenses

```python
expenses = djep.expenses.list(per_page=25)
categories = djep.expenses.categories()
payees = djep.expenses.payees()
methods = djep.expenses.payment_methods()
```

### Other Resources

```python
rfi = djep.submissions.rfi()
quotes = djep.submissions.quotes()
contact_us = djep.submissions.contact_us()

closed_dates = djep.closed_dates.list()
equipment = djep.equipment.list()
systems = djep.systems.list()
```

### Create Submission (RFI)

Push leads from external sources into the DJ's submissions queue:

```python
# Wedding Wire lead
submission = djep.submissions.create(
    first_name='Sarah', last_name='Johnson',
    email='sarah@example.com', telephone='555-0123',
    event_date='2026-09-15', event_type='Wedding',
    guest_count=200, source='Wedding Wire',
    send_notification='true',
)
print(f"Submission ID: {submission['data']['req_idnumber']}")

# With custom questions and privacy consent
submission = djep.submissions.create(
    first_name='Emma', last_name='Wilson',
    email='emma@example.com',
    event_date='2027-06-20', event_type='Wedding',
    question_1='Yes, we need lighting', q1_mapto='custom_field1',
    privacy_policy_signed='true', source='Custom Website',
    send_notification='true',
)
```

### Convenience Endpoints

Quick actions without the `fields` parameter:

```python
# Quick status change â€” returns old and new status
result = djep.events.update_status(56789, 'Booked')
print(f"{result['data']['old_status']} â†’ {result['data']['new_status']}")

# Assign employee to position (1-15), with optional fee and role
djep.events.assign_employee(56789, 1, 48113, fee=500, role='Lead DJ')
djep.events.assign_employee(56789, 2, 48361, fee=350, role='MC')

# Unassign position 3
djep.events.assign_employee(56789, 3, 0)

# Update notes â€” pass any combination of note fields
djep.events.update_notes(56789,
    comments='AI Summary: Client wants 80s and 90s hits',
    next_action='Send playlist proposal',
    next_action_date='08/15/2026',
)
```

## Auto-Pagination

For resources with pagination, use `all()` to automatically iterate through every page:

```python
# Fetches all events across all pages
for event in djep.events.all(status='Booked'):
    print(event['event_date'])

# Works with any paginated resource
for client in djep.clients.all():
    print(f"{client['first_name']} {client['last_name']}")
```

## Error Handling

The SDK raises specific exceptions for different error types:

```python
from djep_sdk import (
    Client, DJEPError, AuthenticationError, NotFoundError,
    ValidationError, ForbiddenError, RateLimitError,
)

try:
    event = djep.events.get(99999)
except AuthenticationError as e:
    print(f'Invalid API key: {e}')
except NotFoundError as e:
    print(f'Not found: {e}')
except ForbiddenError as e:
    print(f'Forbidden: {e}')
except ValidationError as e:
    print(f'Validation error: {e}')
except RateLimitError as e:
    print(f'Rate limited: {e}')
except DJEPError as e:
    print(f'API error: {e}')
```

## Configuration Options

```python
djep = Client(
    api_key=os.environ['DJEP_API_KEY'],
    domain=os.environ['DJEP_DOMAIN'],
    timeout=60,  # Request timeout in seconds (default: 30)
)
```

## Security

- **Never** commit API keys to version control
- Store keys in environment variables or `.env` files (excluded from Git)
- Use the most restrictive API key for your use case
- API keys provide full access to the associated account â€” treat them like passwords

## API Documentation

Full API documentation is available at your DJEP instance:

```
https://yourdomain.com/api/api.asp?action=docs
```

## License

MIT
