Python SDK
Official Python SDK for the MonCréneau API, published on PyPI.
Installation
pip install moncreneau
Configuration
from moncreneau import Moncreneau
client = Moncreneau('YOUR_API_KEY')
With options:
from moncreneau import Moncreneau
client = Moncreneau(
'YOUR_API_KEY',
base_url='https://mc-prd.duckdns.org/api/v1',
timeout=30
)
With environment variables:
import os
from moncreneau import Moncreneau
client = Moncreneau(os.getenv('MONCRENEAU_API_KEY'))
List departments
from moncreneau import Moncreneau
client = Moncreneau('YOUR_API_KEY')
try:
departments = client.departments.list()
for dept in departments:
print(f"ID: {dept['id']} - {dept['name']}")
except Exception as e:
print(f"Error: {e}")
Create an appointment
from moncreneau import Moncreneau, MoncreneauError
client = Moncreneau('YOUR_API_KEY')
try:
appointment = client.appointments.create(
department_id=5,
date_time='2026-02-15T10:00:00',
name='Amadou Diallo'
)
print('✅ Appointment created!')
print(f"ID: {appointment['id']}")
print(f"QR Code: {appointment['qrCode']}")
print(f"Status: {appointment['status']}")
except MoncreneauError as e:
if e.code == 'INSUFFICIENT_CREDITS':
print(f'❌ Insufficient credits: {e.message}')
else:
print(f'❌ Error: {e.message}')
Check slot availability
The backend checks a single slot (date_time), not a date range.
from moncreneau import Moncreneau
client = Moncreneau('YOUR_API_KEY')
try:
availability = client.departments.get_availability('5', '2026-02-15T10:00:00')
if availability['available']:
print('✅ Slot available!')
print(f"Remaining slots: {availability['remainingSlots']}")
else:
print('❌ Slot unavailable')
print(f"Reason: {availability.get('unavailabilityReason')}")
except Exception as e:
print(f'Error: {e}')
Cancel an appointment
from moncreneau import Moncreneau
client = Moncreneau('YOUR_API_KEY')
try:
client.appointments.cancel('123')
print('✅ Appointment cancelled, 1 credit refunded')
except Exception as e:
print(f'❌ Error: {e}')
Django integration
# settings.py
MONCRENEAU_API_KEY = os.getenv('MONCRENEAU_API_KEY')
# services.py
from django.conf import settings
from moncreneau import Moncreneau
class MoncreneauService:
def __init__(self):
self.client = Moncreneau(settings.MONCRENEAU_API_KEY)
def create_appointment(self, department_id: int, date_time: str, name: str):
return self.client.appointments.create(
department_id=department_id,
date_time=date_time,
name=name
)
def list_departments(self):
return self.client.departments.list()
# Singleton
moncreneau_service = MoncreneauService()
# views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
import json
from moncreneau import MoncreneauError
from .services import moncreneau_service
@csrf_exempt
@require_http_methods(["POST"])
def create_appointment(request):
data = json.loads(request.body)
try:
appointment = moncreneau_service.create_appointment(
department_id=data['departmentId'],
date_time=data['dateTime'],
name=data['name']
)
return JsonResponse(appointment, status=201)
except MoncreneauError as e:
status = 402 if e.code == 'INSUFFICIENT_CREDITS' else e.status_code
return JsonResponse({'error': e.message}, status=status)
Error handling
There is only one error class, MoncreneauError — the business error code is available via .code:
from moncreneau import Moncreneau, MoncreneauError
client = Moncreneau('YOUR_API_KEY')
try:
appointment = client.appointments.create(
department_id=5,
date_time='2026-02-15T10:00:00',
name='Amadou Diallo'
)
except MoncreneauError as e:
if e.code == 'INSUFFICIENT_CREDITS':
print(f'Insufficient credits: {e.message}')
elif e.code == 'VALIDATION_ERROR':
print(f'Validation: {e.details}')
elif e.code == 'INVALID_API_KEY':
print('Invalid API key')
else:
print(f'Error {e.code} (HTTP {e.status_code}): {e.message}')
Webhook verification
verify_webhook_signature is a static method on the Moncreneau class, not an instance method:
# Flask
from flask import Flask, request, jsonify
from moncreneau import Moncreneau
import os
import json
app = Flask(__name__)
@app.route('/webhooks/moncreneau', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Moncreneau-Signature')
payload = request.get_data(as_text=True)
is_valid = Moncreneau.verify_webhook_signature(
payload,
signature,
os.getenv('WEBHOOK_SECRET')
)
if not is_valid:
return 'Invalid signature', 401
event = json.loads(payload)
print('Event:', request.headers.get('X-Moncreneau-Event'), event)
return jsonify({'received': True})
See Webhook Security for the signature format details.
Type hints
The SDK returns Dict[str, Any] (no dedicated typed objects) — return values behave like standard dictionaries (appointment['id'], not appointment.id).