Skip to main content

Preston

CI codecov Python version Code style: black License

Preston is a Python library for accessing EVE Online's ESI API.

Installation

From pip:

pip install preston

Initialization

from preston import Preston

preston = Preston()

There are values that you can pass to __init__ as kwargs; those are detailed in the docstring for the class.

Usage

There are 3 main things that Preston does:

  1. Unauthenticated calls to ESI
  2. User authentication
  3. Authenticated calls to ESI for that user

For #1, all you need to do is initialize a Preston object and make the call:

preston = Preston(
    user_agent='some_user_agent'
)

data = preston.get_op('get_characters_character_id', character_id=91316135)
# ...

You should always include a good user_agent.

Additionally, a post_op method exists, that takes a dictionary (instead of **kwargs) and another parameter; the former is used like above, to satisfy the URL parameters, and the latter is sent to the ESI endpoint as the payload.

For #2, there are 2 methods that you'll need, get_authorize_url and authenticate, and several __init__ kwargs.

preston = Preston(
    user_agent='some_user_agent',
    client_id='something',
    client_secret='something',
    callback_url='something',
    scope='maybe_something',
)

You can find the last 4 values in your application on the EVE Dev site.

When you have a Preston instance constructed like this, you can make the call to get_authorize_url:

preston.get_authorize_url()
# https://login.eveonline.com/oauth/...

This is the URL that your user needs to visit and complete the flow. They'll be redirected to your app's callback URL, so you have to be monitoring that.

When you get their callback, take the code paramter from the URL and pass it to authenticate:

auth = preston.authenticate('their_code_here')

Finally for #3, having followed the steps above, you just make calls like previously, but you can do so to the authenticated-only endpoints. Make sure that if you're calling an endpoint that requires a specific scope, your app on EVE Devs has that scoped added and you've supplied it to the Preston initialization.

Resuming authentication

If your app uses scopes, it'll receive a refresh_token alongside the access_token. The access token, per usual, only lasts 20 minutes before it expires. In this situation, the refresh token can be used to get a new access token and a new refresh token. If your Preston instance has a refresh token, this will be done automatically when the access token expires.

If you want to store your current refresh token so you can fetch data with authorization later on again, you can do that with preston as following.

To get the current refresh token and keep getting informed when it changes, initialize Preston with a refresh token callback function. This function should look something like this:

def my_refresh_token_callback(preston: Preston):
    # To figure out which user called the callback, you can use the whoami() function.
    current_user_info = preston.whoami()
    character_id = current_user_info.get("character_id")
    scopes = current_user_info.get("scopes")
    
    # Now you probably want store the refresh token somewhere e.g. your db
    # Or something else persistent. In the simple case all users have the same scopes
    # and you are using a python shelve, you would do something like this:
    python_shelve[character_id] = preston.refresh_token

You can pass this function to Preston on initialization:

preston = Preston(
    ...,
    refresh_token_callback=my_refresh_token_callback
)

Now every time Preston needs to get new tokens, it will also call your function so you can stay up to date.

If you want to resume authentication, you can use the refresh token on initialization:

preston = Preston(
    ...,
    refresh_token='your_refresh_token_here'
)

Or you can get an authorized Preston instance from an unauthorized:

auth = preston.authenticate_from_token('your_refresh_token_here')

Error Handling

Preston usually retries network-related exceptions up to 4 times with exponential backoff (1, 2, 4, 8, ... seconds), and times out any single request after 6 seconds. This means that at most any single call can take 39 seconds. You can modify this behaviour with optional arguments:

preston = Preston(
    timeout="timeout_per_request_in_seconds",
    retrues="max_number_of_retries",
)

For non network related issues, Preston raises the Exceptions generated by requests immediately. You can find all possible errors here.

A simple error handling scheme might look something like this:

try:
    authed_preston = preston.authenticate_from_refresh(character.token)
except HTTPError as exp:
    # Some kind of error the user has to deal with e.g. no permissions, token revoked on website
    ...
except ConnectionError as exp:
    # Network issue. If it is a background task probably fine to log and skip, if there is a user tell him network is bad
    ...
    # in both cases The exception contains the full response e.g. you can
    print(exp.response.status_code)
    print(exp.response.text)
    # etc.

Developing

Building

Requirements

  • Git
  • uv
  • Python 3.8+

Steps

git clone https://github.com/Celeo/preston
cd preston
uv sync

Running tests

No coverage uv run pytest
Coverage printout uv run pytest --cov=preston
Coverage report uv run pytest --cov=preston --cov-report=html

License

Licensed under MIT (LICENSE).

Contributing

PRs are welcome. Please follow PEP8 (I'm lenient on E501) and use Google-style docstrings.

Metadata

Release files for preston 4.12.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for preston 4.12.1
File Size Uploaded Provenance Actions
preston-4.12.1.tar.gz 15.5 kB Without provenance Details for preston-4.12.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for preston 4.12.1
File Interpreter ABI Platform Actions
preston-4.12.1-py3-none-any.whl Python 3 none any Details for preston-4.12.1-py3-none-any.whl

Total release size: 27.4 kB

Release files / preston-4.12.1.tar.gz

Download URL preston-4.12.1.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
899305da8e5ced2a7b45d90885e645b2f656122fdcae8e5666f5b09eb0414fa8
BLAKE2b-256 checksum
How to use checksums
75f1313fb529c52f7696afda87c6c0c11f0e66e644ce99ea2c856762b03586d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.8

Release files / preston-4.12.1-py3-none-any.whl

Download URL preston-4.12.1-py3-none-any.whl
Size 11.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
58bb33c90b1eaaca8361c9e8ac533fc03858dac30c68cc928b92644d62302e22
BLAKE2b-256 checksum
How to use checksums
e4a09d179338ff1891a2cbbb151467225ddd1ce017a97d28a27a837532fca773
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.8

Security for preston 4.12.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page