API

admin

Utilities for the admin site.

class FieldFilterCountsDb(request, params, model, model_admin)[source]

Filter by field and show counts for admin site.

Counts are calculated by the database.

class FieldFilterCountsMemory(request, params, model, model_admin)[source]

Filter by field and show counts for admin site.

Counts are calculated in memory.

allianceauth

Utilities related to Alliance Auth.

get_redis_client() Redis[source]

Return configured redis client used for Django caching in Alliance Auth.

is_night_mode(request) bool[source]

Returns True if the current user session is in night mode, else False

notify_admins(message: str, title: str, level: str = 'info') None[source]

Send notification to all admins.

Parameters:
  • message – Message text

  • title – Message title

  • level – Notification level of the message.

notify_admins_throttled(message_id: str, message: str, title: str, level: str = 'info', timeout: int | None = None)[source]

Send notification to all admins, but limits the frequency for sending messages with the same message ID, e.g. to once per day.

If this function is called during a timeout the notification will simply be ignored.

Parameters:
  • message_id – ID representing this message

  • message – Message text

  • title – Message title

  • level – Notification level of the message.

  • timeout – Time between each notification, e.g. 86400 = once per day. When not provided uses system default, which is 86400 and can also be set via this Django setting: APP_UTILS_NOTIFY_THROTTLED_TIMEOUT

notify_throttled(message_id: str, user: User, title: str, message: str, level: str = 'info', timeout: int | None = None)[source]

Send notification to user, but limits the frequency for sending messages with the same message ID, e.g. to once per day.

If this function is called during a timeout the notification will simply be ignored.

Parameters:
  • message_id – ID representing this message

  • title – Message title

  • message – Message text

  • level – Notification level of the message.

  • timeout – Time between each notification, e.g. 86400 = once per day. When not provided uses system default, which is 86400 and can also be set via this Django setting: APP_UTILS_NOTIFY_THROTTLED_TIMEOUT

app_settings

Django settings related utilities.

clean_setting(name: str, default_value: Any, min_value: int | None = None, max_value: int | None = None, required_type: type | None = None, choices: list | None = None) Any[source]

Clean a setting from Django settings.

Will use default_value if setting is not defined. Will use minimum or maximum value if respective boundary is exceeded.

Parameters:
  • default_value (otherwise derived from) – value to use if setting is not defined

  • min_value – minimum allowed value (0 assumed for int)

  • max_value – maximum value value

  • required_type – Mandatory if default_value is None,

  • default_value

Returns:

cleaned value for setting

This function is designed to be used in a dedicated module like app_settings.py as layer between the actual settings and all other modules. app_settings.py will import and clean all settings and all other modules are supposed to import the settings it.

Example for app_settings:

from app_utils.app_settings import clean_setting

EXAMPLE_SETTING = clean_setting("EXAMPLE_SETTING", 10)

caching

Utilities for caching objects and querysets.

class ObjectCacheMixin[source]

A mixin which adds a simple object cache to a Django manager.

clear_cache(pk: int)[source]

Clear cache for a potentially cached object.

This will also clear cached variants with select_related (if any).

Parameters:

pk – Primary key for object to fetch

get_cached(pk, timeout: int | None = None, select_related: str | None = None) Any[source]

Return the requested object either from DB or from cache.

Can be disabled globally through the setting APP_UTILS_OBJECT_CACHE_DISABLED.

Parameters:
  • pk – Primary key for object to fetch

  • timeout – Timeout in seconds for cache

  • select_related – select_related query to be applied (if any)

Returns:

model instance if found

Exceptions:

Model.DoesNotExist if object can not be found

Example:

# adding the Mixin to the model manager
class MyModelManager(ObjectCacheMixin, models.Manager):
    pass

# using the cache method
obj = MyModel.objects.get_cached(pk=42, timeout=3600)
cached_queryset(queryset: QuerySet, key: str, timeout: int) Any[source]

caches the given queryset

Parameters:
  • queryset – the query set to cache

  • key – key to be used to reference this cache

  • timeout – Timeout in seconds for cache

Returns:

query set

Example

queryset = cached_queryset(
    MyModel.objects.filter(name__contains="dummy"),
    key="my_cache_key",
    timeout=3600
)

database

Database related functionality.

class TableSizeMixin[source]

Add a table size functionality to a Django Manager.

db_table_size() int[source]

Calculate the database table size in bytes.

This method works for MySQL/MariaDB databases only.

datetime

Utilities related to date and time.

datetime_round_hour(my_dt: datetime) datetime[source]

Rounds given datetime object to nearest hour

dt_eveformat(my_dt: datetime) str[source]

converts a datetime to a string in eve format e.g. 2019-06-25T19:04:44

ldap_time_2_datetime(ldap_dt: int) datetime[source]

converts ldap time to datetime.datetime

ldap_timedelta_2_timedelta(ldap_td: int) timedelta[source]

converts a ldap time delta into a datetime.timedelta

timeuntil_str(duration: timedelta, show_seconds=True) str[source]

return the duration as nicely formatted string. Or empty string if duration is negative.

Format: [[[999y] [99m]] 99d] 99h 99m 99s

django

Extending the Django utilities.

admin_boolean_icon_html(value) str | None[source]

Variation of the admin boolean type, which returns the HTML for creating the usual True and False icons. But returns None for None, instead of the question mark.

app_labels() set[source]

returns set of all current app labels

users_with_permission(permission: Permission, include_superusers=True) QuerySet[source]

returns queryset of users that have the given Django permission

Parameters:
  • permission – required permission

  • include_superusers – whether superusers are included in the returned list

esi

Helpers for working with ESI.

exception EsiDailyDowntime[source]

ESI is offline due to daily downtime.

__init__()[source]
exception EsiErrorLimitExceeded(retry_in: float = 60)[source]

ESI error limit exceeded error.

__init__(retry_in: float = 60) None[source]
property retry_in: float

Time until next error window in seconds.

exception EsiOffline[source]

ESI is offline error.

__init__()[source]
class EsiStatus(is_online: bool, error_limit_remain: int | None = None, error_limit_reset: int | None = None, is_daily_downtime: bool = False)[source]

Current status of ESI (immutable).

__init__(is_online: bool, error_limit_remain: int | None = None, error_limit_reset: int | None = None, is_daily_downtime: bool = False) None[source]
property error_limit_remain: int | None

Amount of remaining errors in current window.

property error_limit_reset: int | None

Seconds until current error window resets.

error_limit_reset_w_jitter(max_jitter: int | None = None) int[source]

Calc seconds to retry in order to reach next error window incl. jitter.

property is_daily_downtime: bool

True if status was created during daily downtime time frame.

property is_error_limit_exceeded: bool

True when remain is below the threshold, else False.

Will also return False if remain/reset are not defined

property is_ok: bool

True if ESI is online and below error limit, else False.

property is_online: bool

True if ESI is online, else False.

raise_for_status()[source]

Raise an exception if ESI if offline or the error limit is exceeded.

exception EsiStatusException(message)[source]

EsiStatus base exception.

__init__(message)[source]
fetch_esi_status(ignore_daily_downtime: bool = False) EsiStatus[source]

Determine the current ESI status.

Parameters:

ignore_daily_downtime – When True will always make a request to ESI even during the daily downtime

retry_task_if_esi_is_down(self)[source]

Retry current celery task if ESI is not online or error threshold is exceeded.

This function has to be called from inside a celery task!

Parameters:

self – Current celery task from @shared_task(bind=True)

esi_testing

Tools for building unit tests with django-esi.

class BravadoOperationStub(data, headers: dict | None = None, also_return_response: bool = False, status_code=200, reason='OK')[source]

Stub to simulate the operation object return from bravado via django-esi.

class RequestConfig(also_return_response)[source]

A request config for a BravadoOperationStub.

__init__(also_return_response)[source]
__init__(data, headers: dict | None = None, also_return_response: bool = False, status_code=200, reason='OK')[source]
result(**kwargs)[source]

Execute operation and return result.

results(**kwargs)[source]

Execute operation and return results incl. paging.

class BravadoResponseStub(status_code, reason='', text='', headers=None, raw_bytes=None)[source]

Stub for IncomingResponse in bravado, e.g. for HTTPError exceptions.

__init__(status_code, reason='', text='', headers=None, raw_bytes=None) None[source]
class EsiClientStub(testdata: dict | None, endpoints: List[EsiEndpoint], http_error: Any = False)[source]

Stub for replacing a django-esi client in tests.

Parameters:
  • testdata – data to be returned from Endpoint

  • endpoints – List of defined endpoints

  • http_error – Set True to generate a http 500 error exception or set to a http error code to generate a specific http exception

__init__(testdata: dict | None, endpoints: List[EsiEndpoint], http_error: Any = False) None[source]
classmethod create_from_endpoints(endpoints: List[EsiEndpoint], **kwargs)[source]

Create stub from endpoints.

replace_endpoints(new_endpoints: List[EsiEndpoint]) EsiClientStub[source]

Replace given endpoint.

Parameters:

new_endpoint – List of new endpoints

Raises:

ValueError – When trying to replace an non existing endpoint

Returns:

New stub instance with replaced endpoints

class EsiEndpoint(category: str, method: str, primary_key: str | Tuple[str, str] | None = None, needs_token: bool = False, data: dict | list | str | None = None, http_error_code: int | None = None, side_effect: Callable | Exception | None = None)[source]

Class for defining ESI endpoints used in tests with the ESI client stub.

Parameters:
  • category – name of ESI category

  • method – name of ESI method

  • primary_key – name of primary key (e.g. corporation_id) or tuple of 2 keys

  • needs_token – Wether the method requires a token

  • data – Data to be returned from this endpoint

  • http_error_code – When provided will raise an HTTP exception with this code

  • side_effect – A side effect to be triggered. Can be an exception of a function.

  • raised. (Exceptions will be) –

  • endpoint (Functions will be called with the args of the) –

  • "data". (and it's result returned instead of) –

  • function (Return the object SIDE_EFFECT_DEFAULT in the) –

  • data. (to return the endpoints normal) –

__init__(category: str, method: str, primary_key: str | Tuple[str, str] | None = None, needs_token: bool = False, data: dict | list | str | None = None, http_error_code: int | None = None, side_effect: Callable | Exception | None = None) None
property requires_testdata: bool

True if this endpoint requires testdata to be provide as well.

When an endpoint is only partially defined, one need to also provide testdata when creating a stub.

SIDE_EFFECT_DEFAULT = <object object>

Special object that can be returned from side_effect functions to indicate that the normal data should be returned (instead of the result of the side_effect function)

build_http_error(http_code: int, text: str | None = None) HTTPError[source]

Build a HTTP exception for django-esi from given http code.

helpers

General purpose helpers.

class AttrDict(*args, **kwargs)[source]

Enhanced dict that allows property access to its keys.

Example:

>> my_dict = AttrDict({"color": "red", "size": "medium"})
>> my_dict["color"]
"red"
>> my_dict.color
"red"
__init__(*args, **kwargs)[source]
chunks(lst, size)[source]

Yield successive sized chunks from lst.

default_if_none(value, default)[source]

Return default if value is None.

humanize_number(value, magnitude: str | None = None, precision: int = 1) str[source]

Return the value in humanized format, e.g. 1234 becomes 1.2k

Parameters:
  • magnitude – fix the magnitude to format the number, e.g. “b”

  • precision – number of digits to round for

random_string(char_count: int) str[source]

returns a random string of given length

swagger_spec_path() str[source]

returns the path to the current esi swagger spec file

throttle(func: Callable, context_id: str, timeout: int | None) Any[source]

Call a function, but limit repeated calls with a timeout, e.g. once per day.

When a repeated call falls within the timeout the call will simply be ignored.

Parameters:
  • func – the function to be called

  • context_id – a string representing the context for applying the throttle, e.g. a combination of feature name and user ID

  • timeout – timeout in seconds between each repeated call of the function

Returns:

Return cached value of called function func

json

JSON related utilities.

class JSONDateTimeDecoder(*args, **kwargs)[source]

Decoder for the standard json library to decode JSON into datetime. To be used together with JSONDateTimeEncoder.

Example

message = json.loads(message_json, cls=JSONDateTimeDecoder)
__init__(*args, **kwargs) None[source]
class JSONDateTimeEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Encoder for the standard json library to encode datetime into JSON. To be used together with JSONDateTimeDecoder.

Works with naive and aware datetimes, but only with UTC timezone.

Example

message_json = json.dumps(message, cls=JSONDateTimeEncoder)

logging

Utilities for enhancing logging.

Utilities for logging.

class LoggerAddTag(my_logger, prefix)[source]

adds a custom prefix to the given logger

Example

import logging
from app_utils.logging import LoggerAddTag

logger = LoggerAddTag(logging.getLogger(__name__), __package__)
__init__(my_logger, prefix)[source]
make_logger_prefix(tag: str)[source]

creates a function to add logger prefixes, which returns tag when used empty

messages

Improvement of the Django message class.

class messages_plus[source]

Improvement of default Django messages with implicit HTML support.

classmethod debug(request: HttpRequest, message: str, *args, **kwargs) None[source]

Send a debug message with HTML support. Use with safe strings only!

classmethod error(request: HttpRequest, message: str, *args, **kwargs) None[source]

Send an error message with HTML support. Use with safe strings only!

classmethod info(request: HttpRequest, message: str, *args, **kwargs) None[source]

Send an info message with HTML support. Use with safe strings only!

classmethod success(request: HttpRequest, message: str, *args, **kwargs) None[source]

Send a success message with HTML support. Use with safe strings only!

classmethod warning(request: HttpRequest, message: str, *args, **kwargs) None[source]

Send a warning message with HTML support. Use with safe strings only!

scripts

Utilities and helpers for Python scripts.

start_django(max_hops=10, django_project_name='myauth', settings_module='myauth.settings.local', silent=False) None[source]

Start the current Django project.

This function encapsulates the boilerplate code needed to start the current Django project in a normal Python script.

It will also try to detect the path to the current Django project. If it can not be found, the function will exit with code 1.

Parameters:
  • max_hops (-) – Max number of hops up on the main path to check

  • django_project_name (-) – Name of the Django project

  • settings_module (-) – Qualified name of the settings module in the Django project

  • silent (-) – When True will not produce any output

Here is an example how to use this function in a script:

from app_utils.scripts import start_django

start_django()

def main():
    # put Django imports here
    ...

if __name__ == "__main__":
    main()

‘’’

testing

Utilities for making it easier to write tests.

class NoSocketsTestCase(methodName='runTest')[source]

Variation of Django’s TestCase class that prevents any network use.

Example

class TestMyStuff(NoSocketsTestCase):
    def test_should_do_what_i_need(self):
        ...
static guard(*args, **kwargs)[source]
Meta_private:

classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

classmethod tearDownClass()[source]

Hook method for deconstructing the class fixture after running all tests in the class.

exception SocketAccessError[source]

Error raised when a test script accesses the network

add_character_to_user(user: User, character: allianceauth.eveonline.models.EveCharacter, is_main: bool = False, scopes: List[str] | None = None, disconnect_signals: bool = False) allianceauth.authentication.models.CharacterOwnership[source]

Generates a token for the given Eve character and makes the given user it’s owner

Parameters:
  • user – New character owner

  • character – Character to add

  • is_main – Will set character as the users’s main when True

  • scopes – List of scopes for the token

  • disconnect_signals – Will disconnect signals temporarily when True

add_character_to_user_2(user: User, character_id, character_name, corporation_id, corporation_name, alliance_id=None, alliance_name=None, disconnect_signals=False) allianceauth.eveonline.models.EveCharacter[source]

Creates a new EVE character and makes the given user the owner

add_new_token(user: User, character: allianceauth.eveonline.models.EveCharacter, scopes: List[str] | None = None, owner_hash: str | None = None) Token[source]

Generate a new token for a user based on a character.

create_authgroup(states: Iterable[allianceauth.authentication.models.State] | None = None, **kwargs) Group[source]

Create Group object with additional Auth related properties for tests.

create_eve_character(character_id: int, character_name: str, **kwargs) allianceauth.eveonline.models.EveCharacter[source]

Create an EveCharacter object for tests.

create_fake_user(character_id: int, character_name: str, corporation_id: int | None = None, corporation_name: str | None = None, corporation_ticker: str | None = None, alliance_id: int | None = None, alliance_name: str | None = None, permissions: List[str] | None = None) User[source]

Create a fake user incl. main character and (optional) permissions.

Will use default corporation and alliance if not set.

create_state(priority: int, permissions: Iterable[str] | None = None, member_characters: Iterable[allianceauth.eveonline.models.EveCharacter] | None = None, member_corporations: Iterable[allianceauth.eveonline.models.EveCorporationInfo] | None = None, member_alliances: Iterable[allianceauth.eveonline.models.EveAllianceInfo] | None = None, member_factions: Iterable[allianceauth.eveonline.models.EveFactionInfo] | None = None, **kwargs) allianceauth.authentication.models.State[source]

Create a State object for tests.

create_user_from_evecharacter(character_id: int, permissions: List[str] | None = None, scopes: List[str] | None = None) Tuple[User, allianceauth.authentication.models.CharacterOwnership][source]

Create new allianceauth user from EveCharacter object.

Parameters:
  • character_id – ID of eve character

  • permissions – list of permission names, e.g. “my_app.my_permission”

  • scopes – list of scope names

generate_invalid_pk(MyModel: Any) int[source]

return an invalid PK for the given Django model

json_response_to_dict(response: JsonResponse, key='id') dict[source]

Convert JSON response into dict by given key.

json_response_to_python(response: JsonResponse) Any[source]

Convert JSON response into Python object.

multi_assert_in(items: Iterable, container: Iterable) bool[source]

Return True if all items are in container.

multi_assert_not_in(items: Iterable, container: Iterable) bool[source]

Return True if none of the item is in container.

next_number(key=None) int[source]

Generate consecutive numbers. Optionally numbers are generates for given key.

queryset_pks(queryset) set[source]

shortcut that returns the pks of the given queryset as set. Useful for comparing test results.

response_text(response: HttpResponse) str[source]

Return content of a HTTP response as string.

set_test_logger(logger_name: str, name: str) object[source]

set logger for current test module

Parameters:
  • logger – current logger object

  • name – name of current module, e.g. __file__

Returns:

amended logger

testdata_factories

This module provides factories for generating test objects from Django and AA Models.

Important: You need to add the dependency factory_boy to your test environment.

class BaseMetaFactory(class_name, bases, attrs)[source]
class EveAllianceInfoFactory(*args, **kwargs)[source]

Generate an EveAllianceInfo object.

class EveCharacterFactory(*args, **kwargs)[source]

Generate an EveCharacter object.

class EveCorporationInfoFactory(*args, **kwargs)[source]

Generate an EveCorporationInfo object.

class UserFactory(*args, **kwargs)[source]

Generate a User object.

Parameters:

permissions – List of permission names (optional), e.g. ["moonmining.basic_access"]

class UserMainFactory(*args, **kwargs)[source]

Generate a User object with main character.

Parameters:
  • main_character__character – EveCharacter object to be used as main (optional)

  • main_character__scopes – List of ESI scope names (optional), e.g. ["esi-characters.read_contacts.v1"]

testrunners

Custom test runners for Django.

class TimedTestRunner(pattern=None, top_level=None, verbosity=1, interactive=True, failfast=False, keepdb=False, reverse=False, debug_mode=False, debug_sql=False, parallel=0, tags=None, exclude_tags=None, test_name_patterns=None, pdb=False, buffer=False, enable_faulthandler=True, timing=False, shuffle=False, logger=None, **kwargs)[source]

Test runner which adds duration measurements to each tests (when verbose) and shows list of slowest tests at the end.

To use in tests define via the TEST_RUNNER setting or as --testrunner parameter for test, e.g.:

TEST_RUNNER = "app_utils.testrunners.TimedTestRunner"
python manage.py test -v 2 --testrunner app_utils.testrunners.TimedTestRunner
test_runner

alias of _TimedTextTestRunner

urls

Utilities related to URLs.

reverse_absolute(viewname: str, args: list | None = None) str[source]

Return absolute URL for a view name.

Similar to Django’s reverse(), but returns an absolute URL.

site_absolute_url() str[source]

Return absolute URL for this Alliance Auth site.

static_file_absolute_url(file_path: str) str[source]

Return absolute URL to a static file.

Parameters:

file_path – relative path to a static file

views

Utilities for supporting Django views.

class BootstrapStyle(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

A Bootstrap context style names, e.g. for labels

DANGER = 'danger'
DEFAULT = 'default'
INFO = 'info'
PRIMARY = 'primary'
SUCCESS = 'success'
WARNING = 'warning'
class HttpResponseNoContent(*args, **kwargs)[source]

Special HTTP response with no content, just headers.

The content operations are ignored.

__init__(*args, **kwargs)[source]
class JSONResponseMixin[source]

A mixin that can be used to render a JSON response for a class based view.

get_data(context)[source]

Return an object that will be serialized as JSON by json.dumps().

render_to_json_response(context, **response_kwargs)[source]

Return a JSON response, transforming ‘context’ to make the payload.

bootstrap_glyph_2_html(glyph_name, tooltip_text=None, color='initial') str[source]

Return HTML for a Bootstrap 3 glyph HTML. Can also have a tool tip and color.

bootstrap_glyph_html(glyph_name: str) str[source]

Return HTML for a Bootstrap 3 glyph.

bootstrap_icon_plus_name_html(icon_url, name, size: int = 32, avatar: bool = False, url: str | None = None, text: str | None = None) str[source]

Returns HTML to display an icon next to a name. Can also be a link.

DEPRECATED. To be replaced by bootstrap_icon_plus_text_html.

bootstrap_icon_plus_text_html(icon_url: str, text: str, size: int = 32, avatar: bool = False, url: str | None = None, suffix: str | None = None) str[source]

Return HTML for a widget consisting of an icon with a text or link:

<Icon> <Text/Link> [<Suffix>]

Adds the class icon-plus-text to all images to enable styling.

Parameters:
  • icon_url (-) – URL to an icon file, supported by <img>, e.g. GIF, PNG

  • text (-) – Text to be shown next to icon. Often a name.

  • size (-) – Size of the icon in pixel

  • avatar (-) – When enabled the icon will get Bootstrap 3 classes for avatars

  • url (-) – A provided URL will transform the text into a link

  • suffix (-) – Additional text to be shown after the main text. Will not be part of a link.

bootstrap_label_html(text: str, label: str = 'default') str[source]

Return HTML for a Bootstrap label.

Return HTML for a button with Bootstrap 3 glyphs.

Return HTML for a button with fontawesome symbols.

fontawesome_modal_button_html(modal_id: str, fa_code: str, ajax_url: str = '', tooltip: str = '', style=BootstrapStyle.DEFAULT) str[source]

Return HTML for a modal button with fontawesome symbols.

Parameters:
  • modal_id – DOM ID of modal to invoke

  • fa_code – fontawesome code, e.g. “fas fa-moon”

  • ajax_url – URL to invoke via AJAX for loading modal content

  • tooltip – text to appear as tooltip

  • style – Bootstrap context style for the button

humanize_value(value: float, precision: int = 2) str[source]

Return a value in a human readable and abbreviated form e.g. 1234678 -> 1.23m.

image_html(src: str, classes: List[str] | None = None, size: int | None = None) str[source]

Return HTML for an image with optional classes and size.

Return HTML for a link.

Parameters:
  • url (-) – URL

  • label (-) – Text describing the link

  • new_window (-) – When enabled the link will open a new window

  • classes (-) – Classes to be added to the a tag

no_wrap_html(text: str) str[source]

Add no-wrap HTML to text with Bootstrap 3.

yesno_str(value: bool) str[source]

Return yes/no for boolean as string and with localization.

yesnonone_str(value: bool | None) str[source]

Return yes/no/none for boolean as string and with localization.