Django ESI
Django ESI is a Django app that provides a streamlined interface for interacting with the EVE Stable Interface (ESI), the official API for EVE Online. It facilitates dynamic client generation for public and private ESI endpoints, supports EVE Online Single Sign-On (SSO) for character authentication and token retrieval, and offers control over ESI endpoint versions. As of version 9.2.0, it is actively maintained by the Alliance Auth development team and builds upon the `aiopenapi3` library for OpenAPI 3 support.
Common errors
-
AttributeError("No tag/path filtering supplied to ESI Client.")cause The `ESIClientProvider` was instantiated without specifying `operations` or `tags` filters in a production environment (where `settings.DEBUG` is `False`). This is a safeguard against high memory usage.fixModify the `ESIClientProvider` instantiation to include `operations=['OperationName1', 'OperationName2']` or `tags=['Tag1', 'Tag2']` to load only the necessary ESI endpoints. Example: `esi = ESIClientProvider(..., tags=['Universe'])`. -
django.db.utils.IntegrityError: NOT NULL constraint failed: esi_token.refresh_token
cause This error typically occurs during the EVE SSO callback process when the `refresh_token` cannot be stored in the database. Common reasons include misconfigured SSO application settings (e.g., incorrect callback URL, missing scopes), or issues with `python manage.py migrate` for `esi` models.fixVerify that your EVE SSO application's callback URL matches `ESI_SSO_CALLBACK_URL` in your Django settings. Ensure all necessary scopes are registered with your SSO app. Run `python manage.py migrate` to ensure the `esi` database tables are correctly set up. -
ModuleNotFoundError: No module named 'esi'
cause The 'esi' app is not correctly added to `INSTALLED_APPS` in your Django project's settings, or the `django-esi` package is not installed in your active Python environment.fixFirst, ensure `pip install django-esi` was run. Then, add `'esi'` to your `INSTALLED_APPS` list in your Django `settings.py` file: `INSTALLED_APPS = [... 'esi', ...]`
Warnings
- breaking The OpenAPI client introduced in Django-ESI 8.x can consume significantly more memory due to in-memory Pydantic models. Failing to use `operations` or `tags` filters when instantiating `ESIClientProvider` without `DEBUG=True` will result in an `AttributeError`.
- gotcha The `compatibility_date` parameter for `ESIClientProvider` should be set to a date you genuinely tested your application against, not 'today'. This header dictates ESI's API behavior for your application.
- gotcha Django-ESI 8.x and later heavily rely on caching and E-Tags. Disabling this can lead to excessive ESI requests and higher memory usage for your application if not managed carefully.
- breaking EVE SSO and User-Agent settings are mandatory for `django-esi` to function correctly and adhere to CCP's developer guidelines.
Install
-
pip install django-esi
Imports
- ESIClientProvider
from esi.openapi_clients import ESIClientProvider
- token_required
from esi.decorators import token_required
Quickstart
import os
from django.conf import settings
# Minimal Django settings for standalone execution (in a real project, these would be in settings.py)
if not settings.configured:
settings.configure(
INSTALLED_APPS=['esi'],
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-dev'),
# Required for EVE SSO, even if not used in this specific public API example
ESI_SSO_CLIENT_ID=os.environ.get('ESI_SSO_CLIENT_ID', 'test-dummy'),
ESI_SSO_CLIENT_SECRET=os.environ.get('ESI_SSO_CLIENT_SECRET', 'test-dummy'),
ESI_SSO_CALLBACK_URL=os.environ.get('ESI_SSO_CALLBACK_URL', 'http://localhost:8000/sso/callback'),
ESI_USER_CONTACT_EMAIL=os.environ.get('ESI_USER_CONTACT_EMAIL', 'your_email@example.com'),
DEBUG=True # Useful for development, disables some client filters
)
from esi.openapi_clients import ESIClientProvider
# Instantiate the ESI client provider
# It's strongly recommended to re-use this client wherever possible (e.g., as a global or singleton).
# For best results, use a compatibility_date that you genuinely tested against.
# ua_appname should be PascalCase and ua_version semantic versioning.
# For development, you can set DEBUG=True in Django settings to temporarily bypass tag/operation filtering.
esi_client = ESIClientProvider(
compatibility_date="2024-07-23",
ua_appname="MyDjangoApp",
ua_version="0.1.0",
# Filtering is crucial for memory efficiency in production
# Example: operations=["GetAlliances"], tags=["Universe"]
tags=["Universe"]
)
# Example: Fetching a EVE Universe type (e.g., for 'Vexor')
try:
# Using the filtered client to access the Universe tag
type_id = 603
vexor_info = esi_client.client.Universe.GetUniverseTypesTypeId(type_id=type_id).results()
print(f"Fetched EVE Type (ID: {type_id}): {vexor_info.name}")
# Example of localized response
vexor_info_ko = esi_client.client.Universe.GetUniverseTypesTypeId(
type_id=type_id, Accept_Language='ko'
).results()
print(f"Fetched EVE Type in Korean (ID: {type_id}): {vexor_info_ko.name}")
except Exception as e:
print(f"An error occurred: {e}")