evennia.web.api package

Submodules

evennia.web.api.filters module

FilterSets allow clients to specify querystrings that will determine the data that is retrieved in GET requests. By default, Django Rest Framework uses the ‘django-filter’ package as its backend. Django-filter also has a section in its documentation specifically regarding DRF integration.

https://django-filter.readthedocs.io/en/latest/guide/rest_framework.html

class evennia.web.api.filters.AccountDBFilterSet(data=None, queryset=None, *, request=None, prefix=None)[source]

Bases: evennia.web.api.filters.BaseTypeclassFilterSet

This adds filters for Account objects

class Meta[source]

Bases: object

fields = ['db_key', 'db_typeclass_path', 'db_tags__db_key', 'db_tags__db_category', 'username', 'db_is_connected', 'db_is_bot']
model

alias of evennia.accounts.models.AccountDB

_meta = <django_filters.filterset.FilterSetOptions object>
base_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'db_is_bot': <django_filters.rest_framework.filters.BooleanFilter object>, 'db_is_connected': <django_filters.rest_framework.filters.BooleanFilter object>, 'db_key': <django_filters.filters.CharFilter object>, 'db_tags__db_category': <django_filters.filters.CharFilter object>, 'db_tags__db_key': <django_filters.filters.CharFilter object>, 'db_typeclass_path': <django_filters.filters.CharFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>, 'username': <django_filters.filters.CharFilter object>}
declared_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
class evennia.web.api.filters.AliasFilter(field_name=None, lookup_expr='exact', *, label=None, method=None, distinct=False, exclude=False, **kwargs)[source]

Bases: evennia.web.api.filters.TagTypeFilter

A filter for objects by their aliases (tags with a tagtype of ‘alias’

tag_type = 'alias'
class evennia.web.api.filters.BaseTypeclassFilterSet(data=None, queryset=None, *, request=None, prefix=None)[source]

Bases: django_filters.rest_framework.filterset.FilterSet

A parent class with filters for aliases and permissions

_meta = <django_filters.filterset.FilterSetOptions object>
base_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
declared_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
static filter_name(queryset, name, value)[source]

Filters a queryset by aliases or the key of the typeclass :param queryset: The queryset being filtered :param name: The name of the field :param value: The value passed in from GET params

Returns

The filtered queryset

class evennia.web.api.filters.ObjectDBFilterSet(data=None, queryset=None, *, request=None, prefix=None)[source]

Bases: evennia.web.api.filters.BaseTypeclassFilterSet

This adds filters for ObjectDB instances - characters, rooms, exits, etc

class Meta[source]

Bases: object

fields = ['db_key', 'db_typeclass_path', 'db_tags__db_key', 'db_tags__db_category', 'db_location__db_key', 'db_home__db_key', 'db_location__id', 'db_home__id']
model

alias of evennia.objects.models.ObjectDB

_meta = <django_filters.filterset.FilterSetOptions object>
base_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'db_home__db_key': <django_filters.filters.CharFilter object>, 'db_home__id': <django_filters.filters.NumberFilter object>, 'db_key': <django_filters.filters.CharFilter object>, 'db_location__db_key': <django_filters.filters.CharFilter object>, 'db_location__id': <django_filters.filters.NumberFilter object>, 'db_tags__db_category': <django_filters.filters.CharFilter object>, 'db_tags__db_key': <django_filters.filters.CharFilter object>, 'db_typeclass_path': <django_filters.filters.CharFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
declared_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
class evennia.web.api.filters.PermissionFilter(field_name=None, lookup_expr='exact', *, label=None, method=None, distinct=False, exclude=False, **kwargs)[source]

Bases: evennia.web.api.filters.TagTypeFilter

A filter for objects by their permissions (tags with a tagtype of ‘permission’

tag_type = 'permission'
class evennia.web.api.filters.ScriptDBFilterSet(data=None, queryset=None, *, request=None, prefix=None)[source]

Bases: evennia.web.api.filters.BaseTypeclassFilterSet

This adds filters for Script objects

class Meta[source]

Bases: object

fields = ['db_key', 'db_typeclass_path', 'db_tags__db_key', 'db_tags__db_category', 'db_desc', 'db_obj__db_key', 'db_obj__id', 'db_account__id', 'db_account__username', 'db_is_active', 'db_persistent', 'db_interval']
model

alias of evennia.scripts.models.ScriptDB

_meta = <django_filters.filterset.FilterSetOptions object>
base_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'db_account__id': <django_filters.filters.NumberFilter object>, 'db_account__username': <django_filters.filters.CharFilter object>, 'db_desc': <django_filters.filters.CharFilter object>, 'db_interval': <django_filters.filters.NumberFilter object>, 'db_is_active': <django_filters.rest_framework.filters.BooleanFilter object>, 'db_key': <django_filters.filters.CharFilter object>, 'db_obj__db_key': <django_filters.filters.CharFilter object>, 'db_obj__id': <django_filters.filters.NumberFilter object>, 'db_persistent': <django_filters.rest_framework.filters.BooleanFilter object>, 'db_tags__db_category': <django_filters.filters.CharFilter object>, 'db_tags__db_key': <django_filters.filters.CharFilter object>, 'db_typeclass_path': <django_filters.filters.CharFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
declared_filters = {'alias': <evennia.web.api.filters.AliasFilter object>, 'name': <django_filters.filters.CharFilter object>, 'permission': <evennia.web.api.filters.PermissionFilter object>}
class evennia.web.api.filters.TagTypeFilter(field_name=None, lookup_expr='exact', *, label=None, method=None, distinct=False, exclude=False, **kwargs)[source]

Bases: django_filters.filters.CharFilter

This class lets you create different filters for tags of a specified db_tagtype.

filter(qs, value)[source]
tag_type = None
evennia.web.api.filters.get_tag_query(tag_type: Optional[str], key: str) → django.db.models.query_utils.Q[source]

Returns a Q object for searching by tag names for typeclasses :param tag_type: The type of tag (None, ‘alias’, etc) :type tag_type: str or None :param key: The name of the tag :type key: str

Returns

A Q object that for searching by this tag type and name

evennia.web.api.permissions module

class evennia.web.api.permissions.EvenniaPermission[source]

Bases: rest_framework.permissions.BasePermission

A Django Rest Framework permission class that allows us to use Evennia’s permission structure. Based on the action in a given view, we’ll check a corresponding Evennia access/lock check.

MINIMUM_CREATE_PERMISSION = 'builder'
MINIMUM_LIST_PERMISSION = 'builder'
static check_locks(obj, user, locks)[source]

Checks access for user for object with given locks :param obj: Object instance we’re checking :param user: User who we’re checking permissions :type user: Account :param locks: list of lockstrings :type locks: list

Returns

True if they have access, False if they don’t

Return type

bool

destroy_locks = ['delete']
has_object_permission(request, view, obj)[source]

Checks object-level permissions after has_permission

Parameters
  • request (Request) – The incoming request object.

  • view (View) – The django view we are checking permission for.

  • obj – Object we’re checking object-level permissions for

Returns

If permission is granted or not. If we return False here, a PermissionDenied error will be raised from the view.

Return type

bool

Notes

This method assumes that has_permission has already returned True. We check equivalent Evennia permissions in the request.user to determine if they can complete the action.

has_permission(request, view)[source]

Checks for permissions

Parameters
  • request (Request) – The incoming request object.

  • view (View) – The django view we are checking permission for.

Returns

If permission is granted or not. If we return False here, a PermissionDenied error will be raised from the view.

Return type

bool

Notes

This method is a check that always happens first. If there’s an object involved, such as with retrieve, update, or delete, then the has_object_permission method is called after this, assuming this returns True.

update_locks = ['control', 'edit']
view_locks = ['examine']

evennia.web.api.serializers module

Serializers in the Django Rest Framework are similar to Forms in normal django. They’re used for transmitting and validating data, both going to clients and coming to the server. However, where forms often contained presentation logic, such as specifying widgets to use for selection, serializers typically leave those decisions in the hands of clients, and are more focused on converting data from the server to JSON (serialization) for a response, and validating and converting JSON data sent from clients to our enpoints into python objects, often django model instances, that we can use (deserialization).

class evennia.web.api.serializers.AccountSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: evennia.web.api.serializers.TypeclassSerializerMixin, rest_framework.serializers.ModelSerializer

This uses the DefaultAccount object to have access to the sessions property

class Meta[source]

Bases: object

fields = ['username', 'session_ids', 'nicks', 'id', 'db_key', 'attributes', 'db_typeclass_path', 'aliases', 'tags', 'permissions']
model

alias of evennia.accounts.accounts.DefaultAccount

read_only_fields = ['id']
_declared_fields = {'aliases': SerializerMethodField(), 'attributes': SerializerMethodField(), 'db_key': CharField(required=False), 'nicks': SerializerMethodField(), 'permissions': SerializerMethodField(), 'session_ids': SerializerMethodField(), 'tags': SerializerMethodField()}
static get_session_ids(obj)[source]

Gets a list of session IDs connected to this Account :param obj: Account we’re grabbing sessions from :type obj: DefaultAccount

Returns

List of session IDs

class evennia.web.api.serializers.AttributeSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

fields = ['db_key', 'db_category', 'db_attrtype', 'value_display', 'db_value']
model

alias of evennia.typeclasses.attributes.Attribute

_declared_fields = {'db_value': CharField(required=False, write_only=True), 'value_display': SerializerMethodField(source='value')}
static get_value_display(obj: evennia.typeclasses.attributes.Attribute) → str[source]

Gets the string display of an Attribute’s value for serialization :param obj: Attribute being serialized

Returns

The Attribute’s value in string format

class evennia.web.api.serializers.ObjectDBSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: evennia.web.api.serializers.TypeclassSerializerMixin, rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

fields = ['db_location', 'db_home', 'contents', 'exits', 'nicks', 'id', 'db_key', 'attributes', 'db_typeclass_path', 'aliases', 'tags', 'permissions']
model

alias of evennia.objects.objects.DefaultObject

read_only_fields = ['id']
_declared_fields = {'aliases': SerializerMethodField(), 'attributes': SerializerMethodField(), 'contents': SerializerMethodField(), 'exits': SerializerMethodField(), 'nicks': SerializerMethodField(), 'permissions': SerializerMethodField(), 'tags': SerializerMethodField()}
static get_contents(obj)[source]

Gets non-exits for the object :param obj: Object being serialized

Returns

List of data from SimpleObjectDBSerializer

static get_exits(obj)[source]

Gets exits for the object :param obj: Object being serialized

Returns

List of data from SimpleObjectDBSerializer

class evennia.web.api.serializers.ScriptDBSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: evennia.web.api.serializers.TypeclassSerializerMixin, rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

fields = ['db_interval', 'db_persistent', 'db_start_delay', 'db_is_active', 'db_repeats', 'id', 'db_key', 'attributes', 'db_typeclass_path', 'aliases', 'tags', 'permissions']
model

alias of evennia.scripts.models.ScriptDB

read_only_fields = ['id']
_declared_fields = {'aliases': SerializerMethodField(), 'attributes': SerializerMethodField(), 'permissions': SerializerMethodField(), 'tags': SerializerMethodField()}
class evennia.web.api.serializers.SimpleObjectDBSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

fields = ['id', 'db_key']
model

alias of evennia.objects.objects.DefaultObject

_declared_fields = {}
class evennia.web.api.serializers.TagSerializer(instance=None, data=<class 'rest_framework.fields.empty'>, **kwargs)[source]

Bases: rest_framework.serializers.ModelSerializer

class Meta[source]

Bases: object

fields = ['db_key', 'db_category', 'db_data', 'db_tagtype']
model

alias of evennia.typeclasses.tags.Tag

_declared_fields = {}
class evennia.web.api.serializers.TypeclassSerializerMixin[source]

Bases: object

Mixin that contains types shared by typeclasses. A note about tags, aliases, and permissions. You might note that the methods and fields are defined here, but they’re included explicitly in each child class. What gives? It’s a DRF error: serializer method fields which are inherited do not resolve correctly in child classes, and as of this current version (3.11) you must have them in the child classes explicitly to avoid field errors. Similarly, the child classes must contain the attribute serializer explicitly to not have them render PK-related fields.

static get_aliases(obj)[source]

Serializes tags from the object’s Aliashandler :param obj: Typeclassed object being serialized

Returns

List of TagSerializer data

static get_attributes(obj)[source]

Serializes attributes from the object’s AttributeHandler :param obj: Typeclassed object being serialized

Returns

List of AttributeSerializer data

static get_nicks(obj)[source]

Serializes attributes from the object’s NicksHandler :param obj: Typeclassed object being serialized

Returns

List of AttributeSerializer data

static get_permissions(obj)[source]

Serializes tags from the object’s Permissionshandler :param obj: Typeclassed object being serialized

Returns

List of TagSerializer data

static get_tags(obj)[source]

Serializes tags from the object’s Tagshandler :param obj: Typeclassed object being serialized

Returns

List of TagSerializer data

shared_fields = ['id', 'db_key', 'attributes', 'db_typeclass_path', 'aliases', 'tags', 'permissions']

evennia.web.api.tests module

Tests for the REST API

class evennia.web.api.tests.TestEvenniaRESTApi(methodName='runTest')[source]

Bases: evennia.utils.test_resources.EvenniaTest

_overridden_settings = {'AUTH_USERNAME_VALIDATORS': [], 'REST_API_ENABLED': True, 'ROOT_URLCONF': 'evennia.web.api.tests'}
client_class

alias of rest_framework.test.APIClient

get_view_details(action)[source]

Helper function for generating list of named tuples

maxDiff = None
setUp()[source]

Sets up testing environment

tearDown()[source]

Hook method for deconstructing the test fixture after testing it.

test_create()[source]
test_delete()[source]
test_list()[source]
test_retrieve()[source]
test_set_attribute()[source]
test_update()[source]

evennia.web.api.urls module

The Django Rest Framework provides a way of generating urls for different views that implement standard CRUD operations in a quick way, using ‘routers’ and ‘viewsets’. A viewset implements standard CRUD actions and any custom actions that you want, and then a router will automatically generate URLs based on the actions that it detects for a viewset. For example, below we create a DefaultRouter. We then register ObjectDBViewSet, a viewset for CRUD operations for ObjectDB instances, to the ‘objects’ base endpoint. That will generate a number of URLs like the following: list objects: action: GET, url: /objects/, view name: object-list create object: action: POST, url: /objects/, view name: object-list retrieve object: action: GET, url: /objects/<:pk>, view name: object-detail update object: action: POST, url: /objects/<:pk>, view name: object-detail delete object: action: DELETE, url: /objects/<:pk>, view name: object-detail set attribute: action: POST, url: /objects/<:pk>/set-attribute, view name: object-set-attribute

evennia.web.api.views module

Views are the functions that are called by different url endpoints. The Django Rest Framework provides collections called ‘ViewSets’, which can generate a number of views for the common CRUD operations.

class evennia.web.api.views.AccountDBViewSet(**kwargs)[source]

Bases: evennia.web.api.views.TypeclassViewSetMixin, rest_framework.viewsets.ModelViewSet

Viewset for Account objects

basename = None
description = None
detail = None
filterset_class

alias of evennia.web.api.filters.AccountDBFilterSet

name = None
queryset = <QuerySet [Dummy(account#1)]>
serializer_class

alias of evennia.web.api.serializers.AccountSerializer

suffix = None
class evennia.web.api.views.CharacterViewSet(**kwargs)[source]

Bases: evennia.web.api.views.ObjectDBViewSet

This overrides the queryset to only retrieve Character objects based on your DefaultCharacter typeclass path.

basename = None
description = None
detail = None
name = None
queryset = <QuerySet []>
suffix = None
class evennia.web.api.views.ExitViewSet(**kwargs)[source]

Bases: evennia.web.api.views.ObjectDBViewSet

Viewset for Exit objects

basename = None
description = None
detail = None
name = None
queryset = <QuerySet []>
suffix = None
class evennia.web.api.views.ObjectDBViewSet(**kwargs)[source]

Bases: evennia.web.api.views.TypeclassViewSetMixin, rest_framework.viewsets.ModelViewSet

An example of a basic viewset for all ObjectDB instances. It declares the serializer to use for both retrieving and changing/creating/deleting instances. Serializers are similar to django forms, used for the transmitting of data (typically json).

basename = None
description = None
detail = None
filterset_class

alias of evennia.web.api.filters.ObjectDBFilterSet

name = None
queryset = <QuerySet []>
serializer_class

alias of evennia.web.api.serializers.ObjectDBSerializer

suffix = None
class evennia.web.api.views.RoomViewSet(**kwargs)[source]

Bases: evennia.web.api.views.ObjectDBViewSet

Viewset for Room objects

basename = None
description = None
detail = None
name = None
queryset = <QuerySet []>
suffix = None
class evennia.web.api.views.ScriptDBViewSet(**kwargs)[source]

Bases: evennia.web.api.views.TypeclassViewSetMixin, rest_framework.viewsets.ModelViewSet

Viewset for Script objects

basename = None
description = None
detail = None
filterset_class

alias of evennia.web.api.filters.ScriptDBFilterSet

name = None
queryset = <QuerySet []>
serializer_class

alias of evennia.web.api.serializers.ScriptDBSerializer

suffix = None
class evennia.web.api.views.TypeclassViewSetMixin[source]

Bases: object

This mixin adds some shared functionality to each viewset of a typeclass. They all use the same permission classes and filter backend. You can override any of these in your own viewsets.

filter_backends = [<class 'django_filters.rest_framework.backends.DjangoFilterBackend'>]
permission_classes = [<class 'evennia.web.api.permissions.EvenniaPermission'>]
set_attribute(request, pk=None)[source]

This is an example of a custom action added to a viewset. Based on the name of the method, it will create a default url_name (used for reversing) and url_path. The ‘pk’ argument is automatically passed to this action because it has a url path of the format <object type>/:pk/set-attribute. The get_object method is automatically set in the expected viewset classes that will inherit this, using the pk that’s passed along to retrieve the object.

This action will set an attribute if the db_value is defined, or remove it if no db_value is provided.