Backend API manual¶
VST Utils framework consolidates such frameworks as Django, Django Rest Framework, drf-yasg and Celery. Below are descriptions of some features used in the development of projects based on vstutils.
Models¶
A model is the single, definitive source of truth about your data. It contains the essential fields and behaviors of the data you’re storing. Usually best practice is to avoid writing views and serializers manually, BModel provides plenty of Meta attributes to autogenerate serializers and views for almost any usecase.
Default Django model classes overrides in vstutils.models module.
-
class
vstutils.models.
BModel
(*args, **kwargs)[source]¶ Default model class that autogenerate model viewset, separate serializers for list() and retrieve(), filters, api endpoints and nested views.
- Examples:
from django.db import models from rest_framework.fields import ChoiceField from vstutils.models import BModel class Stage(BModel): name = models.CharField(max_length=256) order = models.IntegerField(default=0) class Meta: default_related_name = "stage" ordering = ('order', 'id',) # fields which would be showed on list. _list_fields = [ 'id', 'name', ] # fields which would be showed on detail view and creation. _detail_fields = [ 'id', 'name', 'order' ] # make order as choices from 0 to 9 _override_detail_fields = { 'order': ChoiceField((str(i) for i in range(10))) } class Task(BModel): name = models.CharField(max_length=256) stages = models.ManyToManyField(Stage) class Meta: # fields which would be showed. _list_fields = [ 'id', 'name', ] # create nested views from models _nested = { 'stage': { 'allow_append': False, 'model': Stage } }
In this case, you create models which could converted to simple view, where:
POST
/GET
to/api/version/task/
- creates new or get list of tasksPUT
/PATCH
/GET
/DELETE
to/api/version/task/:id/
- updates, retrieves or removes instance of taskPOST
/GET
to/api/version/task/:id/stage/
- creates new or get list of stages in taskPUT
/PATCH
/GET
/DELETE
to/api/version/task/:id/stage/:stage_id
- updates, retrieves or removes instance of stage in task.
To attach a view to an API just insert the following code in settings.py:
API[VST_API_VERSION][r'task'] = { 'model': 'your_application.models.Task' }
For primary access to generated view, just inherit from Task.generated_view property.
List of meta-attributes for generating a view:
_view_class
- list of additional view classes to inherit from, class or string to import with base class ViewSet. Constants are also supported:read_only
- to create a view only for viewing;list_only
- to create a view with list only;history
- to create a view only for viewing and deleting records.
Default is simple CRUD-view.
_serializer_class
- class of API serializer, use this attribute to specify parent class for autogenerated serializers. Default isvstutils.api.serializers.VSTSerializer
. Can take a string to import, serializer class ordjango.utils.functional.SimpleLazyObject
._serializer_class_name
- model name for OpenAPI definitions.This would be a model name in generated admin interface. Default is name of model class._list_fields
or_detail_fields
- list of fields which will be listed in entity view. Same as DRF serializers meta-attribute “fields”._override_list_fields
or_override_detail_fields
- mapping with names and field types that will be redeclared in serializer attributes(think of it as you are redeclaring fields in DRF ModelSerializer)._properties_groups
- dict with key as group name and value as list with fields. Allows to grouping fields on frontend in cases._view_field_name
- name of field which frontend should show as main view name._non_bulk_methods
- list of methods which must not used via bulk requests._extra_serializer_classes
- mapping with additional serializers in viewset. Example, custom serializer, which will compute smthg in action (mapping name). Value can be string for import. Important note: setting model attribute to None allows to use standard serializer generation mechanism and get fields from a list or detail serializer (set __inject_from__ serializer’s meta attribute to list or detail accordingly)._filterset_fields
- list/dict of filterset names for API-filtering. Default is list of fields in list view. When processing a list of fields, it checks for the presence of special field names and inherit additional parent classes. If the list containsid
, class will inherit fromvstutils.api.filters.DefaultIDFilter
. If the list containsname
, class will inherit fromvstutils.api.filters.DefaultNameFilter
. If both conditions are present, inheritance will be from all of the above classes. Possible values include list of fields to filter or dict where key is a field name and value is a Filter class. Dict extends attribute functionality and provide ability to override filter field class (None value disable overriding)._filter_backends
- list of vstutils.api.filter_backends.VSTFilterBackend classes. Values can be string for import._override_filter_backends
- boolean flag indicates that_filter_backends
override default viewset (otherwise appends). Default isFalse
._permission_classes
- list of DRF permission classes. Values can be string for import._override_permission_classes
- boolean flag indicates that_permission_classes
override default viewset (otherwise appends). Default isFalse
._copy_attrs
- list of model-instance attributes indicates that object is copiable with this attrs._nested
- key-value mapping with nested views (key - nested name, kwargs forvstutils.api.decorators.nested_view
decorator but supportsmodel
attribute as nested).model
can be string for import.
Note
Sometimes you may need to create an action on generated view. Use
vstutils.models.decorators.register_view_action
decorator with thedetail
argument to determine applicability to a list or detail entry. In this case, the decorated method will take an instance of the view object asself
attribute.Note
In some cases, inheriting models may require inheriting the Meta class from the base model. If the Meta is explicitly declared in the base class, then you can get it through the attribute OriginalMeta and use it for inheritance.
Note
Docstring of model will be reused for view descriptions. You can specify both a general description for all actions and specifically for each action using the following syntax:
General description for all actions. action_name: Description for this action. another_action: Description for another action.
If hidden is set to True, entry will be excluded from query in BQuerySet.
-
id
¶ Primary field for select and search in API.
-
class
vstutils.models.
Manager
(*args, **kwargs)[source]¶ Default VSTUtils manager. Used by BaseModel and BModel. Uses BQuerySet as base.
-
class
vstutils.models.queryset.
BQuerySet
(model=None, query=None, using=None, hints=None)[source]¶ Represent a lazy database lookup for a set of objects. Allows to override default iterable class by custom_iterable_class attribute (class with __iter__ method which returns generator of model objects) and default query class by custom_query_class attribute (class inherited from
django.db.models.sql.query.Query
).-
cleared
()[source]¶ Filter queryset for models with attribute ‘hidden’ and exclude all hidden objects.
-
get_paginator
(*args, **kwargs)[source]¶ Returns initialized object of
vstutils.utils.Paginator
over current instance’s QuerySet. All args and kwargs passthroughs to Paginator’s constructor.
-
-
class
vstutils.models.decorators.
register_view_action
(*args, **kwargs)[source]¶ Simple decorator for marking model methods as generated view actions. The decorated method becomes a method of generated view and self will be view object. See supported args in
vstutils.api.decorators.subaction()
Note
Often, the action does not transfer any parameters and requires only sending an empty query. To speed up development, we set the default serializer to
vstutils.api.serializers.EmptySerializer
.
Also you can use custom models without using database:¶
-
class
vstutils.custom_model.
FileModel
(*args, **kwargs)[source]¶ Simple custom model which load data from YAML-file. Path to the file stored in FileModel.file_path attribute.
- Examples:
Source file stored in /etc/authors.yaml with content:
- name: "Sergey Klyuykov" - name: "Michael Taran"
Correct usage will be:
from vstutils.custom_model import FileModel, CharField class Authors(FileModel): name = CharField(max_length=512) file_path = '/etc/authors.yaml'
-
class
vstutils.custom_model.
ListModel
(*args, **kwargs)[source]¶ Simple custom model which uses attribute ListModel.data with dicts of models data. Usefull when you have simple list of data.
- Examples:
from vstutils.custom_model import ListModel, CharField class Authors(ListModel): name = CharField(max_length=512) data = [ {"name": "Sergey Klyuykov"}, {"name": "Michael Taran"}, ]
-
data
= []¶ List with data dicts. Empty by default.
Web API¶
Web API is based on Django Rest Framework with some nested functions.
Fields¶
The Framework includes a list of convenient serializer fields. Some of them take effect only in generated admin interface.
Additional serializer fields for generating OpenAPI and GUI.
-
class
vstutils.api.fields.
AutoCompletionField
(*args, **kwargs)[source]¶ Field that provides autocompletion on frontend, using specified list of objects.
- Parameters
autocomplete (list,tuple,str) – Autocompletion reference. You can set simple list/tuple with values or set OpenApi schema definition name. For definition name GUI will find optimal link and will show values based on
autocomplete_property
andautocomplete_represent
arguments.autocomplete_property (str) – this argument indicates which attribute will be get from OpenApi schema definition model as value.
autocomplete_represent – this argument indicates which attribute will be get from OpenApi schema definition model as represent value.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
BinFileInStringField
(*args, **kwargs)[source]¶ Field extends
FileInStringField
, but work with binary(base64) files.Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
CommaMultiSelect
(*args, **kwargs)[source]¶ Field containing a list of values with specified separator(default: “,”). Gets list of values from another model or custom list. Provides autocompletion as
AutoCompletionField
, but with comma-lists. Suited for property-fields in model where main logic is already implemented or withCharField
.- Parameters
select (str,tuple,list) – OpenApi schema definition name or list with values.
select_separator (str) – separator of values. Default is comma.
select_property,select_represent – work as
autocomplete_property
andautocomplete_represent
. Default isname
.use_prefetch – prefetch values on frontend at list-view. Default is
False
.make_link – Show value as link to model. Default is
True
.dependence (dict) – Dictionary, where keys are name of field from the same model, and values are name of query filter .If at least one of the fields that we depend on is non nullable, required and set to null, autocompletion list will be empty and field will be disabled.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
DependEnumField
(*args, **kwargs)[source]¶ Field extends
DynamicJsonTypeField
but data won’t be transformed to json and would be given as is. Useful forproperty
in models or for actions.- Parameters
field (str) – field in model which value change will change type of current value.
types – key-value mapping where key is value of subscribed field and value is type (in OpenApi format) of current field.
choices (dict) – variants of choices for different subscribed field values. Uses mapping where key is value of subscribed field and value is list with values to choice.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
but without value modifications.
-
class
vstutils.api.fields.
DependFromFkField
(*args, **kwargs)[source]¶ Field extends
DynamicJsonTypeField
. Validates field data byfield_attribute
chosen in related model. By default, any value offield_attribute
validates asVSTCharField
. To override this behavior you should set dict-attribute in related model named{field_attribute value}_fields_mapping
where:key - string representation of value type which is received from related instance
field_attribute
.value -
rest_framework.Field
instance for validation.
- Parameters
field (str) – field in model which value change will change type of current value. Field must be
FkModelField
.field_attribute (str) – attribute of model related model instance with name of type.
Warning
field_attribute
in related model must berest_framework.ChoicesField
or GUI will show field as simple text.
-
class
vstutils.api.fields.
DynamicJsonTypeField
(*args, **kwargs)[source]¶ Field which type is based on another field. It converts value to internal string and represent field as json object.
- Parameters
field (str) – field in model which value change will change type of current value.
types – key-value mapping where key is value of subscribed field and value is type (in OpenApi format) of current field.
choices (dict) – variants of choices for different subscribed field values. Uses mapping where key is value of subscribed field and value is list with values to choice.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
but without value modifications.
-
class
vstutils.api.fields.
FileInStringField
(*args, **kwargs)[source]¶ Field extends
VSTCharField
and saves file’s content as string.Value must be text (not binary) and saves in model as is.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
FkField
(*args, **kwargs)[source]¶ Implementation of ForeignKeyField.You can specify which field of a related model will be stored in field(default: “id”), and which will represent field on frontend.
- Parameters
select (str) – OpenApi schema definition name.
autocomplete_property (str) – this argument indicates which attribute will be get from OpenApi schema definition model as value. Default is
id
.autocomplete_represent – this argument indicates which attribute will be get from OpenApi schema definition model as represent value. Default is
name
.use_prefetch (bool) – prefetch values on frontend at list-view. Default is
True
.make_link (bool) – Show value as link to model. Default is
True
.dependence (dict) – Dictionary, where keys are name of field from the same model, and keys are name of query filter. If at least one of the fields that we depend on is non nullable, required and set to null, autocompletion list will be empty and field will be disabled.
Note
Take effect only in GUI. In API it would behave as
rest_framework.IntegerField
.
-
class
vstutils.api.fields.
FkModelField
(*args, **kwargs)[source]¶ Extends
FkField
, but stores referred model class. This field is useful fordjango.db.models.ForeignKey
fields in model to set.- Parameters
select (vstutils.models.BModel,vstutils.api.serializers.VSTSerializer) – model class (based on
vstutils.models.BModel
) or serializer class which used in API and has path in OpenApi schema.autocomplete_property (str) – this argument indicates which attribute will be get from OpenApi schema definition model as value. Default is
id
.autocomplete_represent – this argument indicates which attribute will be get from OpenApi schema definition model as represent value. Default is
name
.use_prefetch – prefetch values on frontend at list-view. Default is
True
.make_link – Show value as link to model. Default is
True
.
Warning
Model class on call .to_internal_value get object from database. Be careful on mass save executions.
Warning
Permissions to model which is referred by this field, will not be checked. You should check it manually in signals or validators.
-
class
vstutils.api.fields.
HtmlField
(*args, **kwargs)[source]¶ Field contains html text and marked as format:html. The field does not validate whether its content is HTML.
Warning
Do not allow for users to modify this data because they can set some scripts to value and it would be vulnerability.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
MultipleNamedBinaryFileInJsonField
(*args, **kwargs)[source]¶ Extends
NamedBinaryFileInJsonField
but uses list of structures. Used for operating with multiple files.
-
class
vstutils.api.fields.
MultipleNamedBinaryImageInJsonField
(*args, **kwargs)[source]¶ Extends
MultipleNamedBinaryFileInJsonField
but uses list of structures. Used for operating with multiple images and works as list ofNamedBinaryImageInJsonField
.
-
class
vstutils.api.fields.
NamedBinaryFileInJsonField
(*args, **kwargs)[source]¶ Field that takes JSON with properties: * name - string - name of file; * mediaType - string - MIME type of file * content - base64 string - content of file.
This field is useful for saving binary files with their names in
django.db.models.CharField
ordjango.db.models.TextField
model fields. All manipulations with decoding and encoding binary content data executes on client. This imposes reasonable limits on file size.Note
Take effect only in GUI. In API it would behave as
VSTCharField
with structure of data.
-
class
vstutils.api.fields.
NamedBinaryImageInJsonField
(*args, **kwargs)[source]¶ Extends
NamedBinaryFileInJsonField
but in GUI has a different view which shows an image(if inputed binary image is valid).Validation of this field can be done withvstutils.api.validators.ImageValidator
.
-
class
vstutils.api.fields.
PasswordField
(*args, **kwargs)[source]¶ Extends CharField but in schema overload format to password. Used for making fields with asterisks instead of data in GUI.
-
class
vstutils.api.fields.
RatingField
(min_value=0, max_value=5, step=1, front_style='stars', **kwargs)[source]¶ Extends class ‘rest_framework.serializers.FloatField’. This field represents a rating form input on frontend. Grading limits can be specified with ‘min_value=’ and ‘max_value=’, defaults are 0 to 5.Minimal step between grades are specified in ‘step=’, default - 1.Frontend visual representation can be chosen with ‘front_style=’, available variants are listed in ‘self.valid_front_styles’.
for ‘slider’ front style, you can specify slider color, by passing valid color to ‘color=’. for ‘fa_icon’ front style, you can specify FontAwesome icon that would be used for displaying rating, by passing a valid FontAwesome icon code to ‘fa_class=’.
-
class
vstutils.api.fields.
RedirectCharField
(*args, **kwargs)[source]¶ Field for redirect by string. Often used in actions for redirect after execution.
Note
Take effect only in GUI. In API it would behave as
rest_framework.IntegerField
.
-
class
vstutils.api.fields.
RedirectIntegerField
(*args, **kwargs)[source]¶ Field for redirect by id. Often used in actions for redirect after execution.
Note
Take effect only in GUI. In API it would behave as
rest_framework.IntegerField
.
-
class
vstutils.api.fields.
RelatedListField
(related_name, fields, view_type='list', **kwargs)[source]¶ Extends class ‘vstutils.api.fields.VSTCharField’. With this field you can output reverse ForeignKey relation as a list of related instances. To use it, you need to specify ‘related_name’ kwarg(related_manager for reverse ForeignKey) and ‘fields’ kwarg(list or tuple of fields from related model, which needs to be included)
-
class
vstutils.api.fields.
SecretFileInString
(*args, **kwargs)[source]¶ Field extends
FileInStringField
, but hides it’s value in admin interface.Value must be text (not binary) and saves in model as is.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
-
class
vstutils.api.fields.
TextareaField
(*args, **kwargs)[source]¶ Field containing multiline string.
Note
Take effect only in GUI. In API it would behave as
VSTCharField
.
Validators¶
There is useful validation classes for fields.
-
class
vstutils.api.validators.
ImageBaseSizeValidator
(extensions=None, **kwargs)[source]¶ If you want you want to use this class for validating image width/height, you should rewrite self.orientation to (‘height’,) or (‘width’,) or (‘height’, ‘width’)
Raises rest_framework.exceptions.ValidationError: if not(min <= (height or width) <= max)
- Parameters
extensions (
typing.Union
[typing.Tuple
,typing.List
,None
]) –
-
class
vstutils.api.validators.
ImageHeightValidator
(extensions=None, **kwargs)[source]¶ Wrapper for _ImageBaseSizeValidator that validates only height
- Parameters
min_height – minimal height of an image being validated
max_height – maximal height of an image being validated
extensions (
typing.Union
[typing.Tuple
,typing.List
,None
]) –
-
class
vstutils.api.validators.
ImageOpenValidator
(extensions=None, **kwargs)[source]¶ Image validator that checks if image can be unpacked from b64 to PIL Image obj
Raises rest_framework.exceptions.ValidationError: in case PIL throws error when trying to open given file
- Parameters
extensions (
typing.Union
[typing.Tuple
,typing.List
,None
]) –
-
class
vstutils.api.validators.
ImageResolutionValidator
(extensions=None, **kwargs)[source]¶ Wrapper for _ImageBaseSizeValidator that validates both height and width
- Parameters
min_height – minimal height of an image being validated
max_height – maximal height of an image being validated
min_width – minimal width of an image being validated
max_width – maximal width of an image being validated
extensions (
typing.Union
[typing.Tuple
,typing.List
,None
]) –
-
class
vstutils.api.validators.
ImageValidator
(extensions=None, **kwargs)[source]¶ Base Image Validation class Validates image format Wont work if Pillow isn’t installed :type extensions:
typing.Union
[typing.Tuple
,typing.List
,None
] :param extensions: Tuple or List of file extensions, that should pass the validation Raises rest_framework.exceptions.ValidationError: in case file extension are not in the list-
property
has_pillow
¶ Check if Pillow is installed
-
property
-
class
vstutils.api.validators.
ImageWidthValidator
(extensions=None, **kwargs)[source]¶ Wrapper for _ImageBaseSizeValidator that validates only height
- Parameters
min_width – minimal width of an image being validated
max_width – maximal width of an image being validated
extensions (
typing.Union
[typing.Tuple
,typing.List
,None
]) –
-
class
vstutils.api.validators.
RegularExpressionValidator
(regexp=None)[source]¶ Class for regular expression based validation
- Raises
rest_framework.exceptions.ValidationError – in case value does not match regular expression
- Parameters
regexp (
typing.Optional
[typing.Pattern
]) –
-
class
vstutils.api.validators.
UrlQueryStringValidator
(regexp=None)[source]¶ Class for validation url query string, for example a=&b=1
- Parameters
regexp (
typing.Optional
[typing.Pattern
]) –
Serializers¶
Default serializer classes for web-api. Read more in Django REST Framework documentation for Serializers.
-
class
vstutils.api.serializers.
BaseSerializer
(*args, **kwargs)[source]¶ Default and simple serializer with default logic to work with objects. Read more in DRF documentation how to create Serializers and work with them.
-
class
vstutils.api.serializers.
EmptySerializer
(*args, **kwargs)[source]¶ Default serializer for empty responses. In generated GUI this means simple action button which will not show additional view before execution.
-
class
vstutils.api.serializers.
VSTSerializer
(*args, **kwargs)[source]¶ Default model serializer based on
rest_framework.serializers.ModelSerializer
. Read more in DRF documentation how to create Model Serializers.
Views¶
Default ViewSets for web-api.
-
class
vstutils.api.base.
CopyMixin
(**kwargs)[source]¶ Mixin for viewsets which adds copy endpoint to view.
-
copy
(request, **kwargs)[source]¶ Endpoint which copy instance with deps.
- Parameters
request (
rest_framework.request.Request
) –- Return type
-
copy_field_name
= 'name'¶ Name of field which will get a prefix.
-
copy_prefix
= 'copy-'¶ Value of prefix which will be added to new instance name.
List of related names which will be copied to new instance.
-
-
class
vstutils.api.base.
HistoryModelViewSet
(**kwargs)[source]¶ Default viewset like ReadOnlyModelViewSet but for historical data (allow to delete, but cannt create and update).
-
class
vstutils.api.base.
ModelViewSet
(**kwargs)[source]¶ A viewset that provides default create(), retrieve(), update(), partial_update(), destroy() and list() actions under model.
- Variables
model (vstutils.models.BModel) – DB model with data.
serializer_class (vstutils.api.serializers.VSTSerializer) – Serializer for view of Model data.
serializer_class_one (vstutils.api.serializers.VSTSerializer) – Serializer for view one instance of Model data.
serializer_class_[ACTION_NAME] (vstutils.api.serializers.VSTSerializer) – Serializer for view of any endpoint like .create.
- Examples:
from vstutils.api.base import ModelViewSet from . import serializers as sers class StageViewSet(ModelViewSet): # This is difference with DRF: # we use model instead of queryset model = sers.models.Stage # Serializer for list view (view for a list of Model instances serializer_class = sers.StageSerializer # Serializer for page view (view for one Model instance). # This property is not required, if its value is the same as `serializer_class`. serializer_class_one = sers.StageSerializer # Allowed to set decorator to custom endpoint like this: # serializer_class_create - for create method # serializer_class_copy - for detail endpoint `copy`. # etc...
-
class
vstutils.api.base.
ReadOnlyModelViewSet
(**kwargs)[source]¶ Default viewset like vstutils.api.base.ModelViewSet for readonly models.
-
class
vstutils.api.decorators.
nested_view
(name, arg=None, methods=None, *args, **kwargs)[source]¶ By default DRF does not support nested views. This decorator solves this problem.
You need two or more models with nested relationship (Many-to-Many or Many-to-One) and two viewsets. Decorator setups nested viewset to parent viesetclass and generate paths in API.
- Parameters
name (str) – – Name of nested path. Also used as default name for related queryset (see manager_name).
arg (str) – – Name of nested primary key field.
view (vstutils.api.base.ModelViewSet, vstutils.api.base.HistoryModelViewSet, vstutils.api.base.ReadOnlyModelViewSet) – – Nested viewset class.
allow_append (bool) – – Flag for allowing to append existed instances.
manager_name (str) – – Name of model-object attr which contains nested queryset.
methods (list) – – List of allowed methods to nested view endpoints.
subs (list,None) – – List of allowed subviews or actions to nested view endpoints.
Example:
from vstutils.api.decorators import nested_view from vstutils.api.base import ModelViewSet from . import serializers as sers class StageViewSet(ModelViewSet): model = sers.models.Stage serializer_class = sers.StageSerializer nested_view('stages', 'id', view=StageViewSet) class TaskViewSet(ModelViewSet): model = sers.models.Task serializer_class = sers.TaskSerializer
This code generates api paths:
/tasks/ - GET,POST
/tasks/{id}/ - GET,PUT,PATCH,DELETE
/tasks/{id}/stages/ - GET,POST
/tasks/{id}/stages/{stages_id}/ - GET,PUT,PATCH,DELETE
-
vstutils.api.decorators.
subaction
(*args, **kwargs)[source]¶ Decorator which wrap object method to subaction of viewset.
- Parameters
methods (list) – List of allowed HTTP-request methods. Default is
["post"]
.detail (bool) – Flag which signalizing that this method is over one instance.
serializer_class (vstutils.api.serializers.VSTSerializer) – Serializer for this action.
permission_classes – Tuple or list permission classes.
url_path (str) – API-path name for this action.
description (str) – Description for this action in OpenAPI.
multiaction (bool) – Allow to use this action in multiactions. Works only with
vstutils.api.serializers.EmptySerializer
as response.
Filtersets¶
For greater development convenience, the framework provides additional classes and functions for filtering elements by fields.
-
class
vstutils.api.filters.
DefaultIDFilter
(data=None, queryset=None, *, request=None, prefix=None)[source]¶ Basic filterset to search by id. Provides a search for multiple values separated by commas. Uses
extra_filter()
in fields.
-
class
vstutils.api.filters.
DefaultNameFilter
(data=None, queryset=None, *, request=None, prefix=None)[source]¶ Basic filterset to search by part of name. Uses LIKE DB condition by
name_filter()
.
-
class
vstutils.api.filters.
FkFilterHandler
(related_pk='id', related_name='name', pk_handler=<class 'int'>)[source]¶ Simple handler for filtering by relational fields.
- Parameters
related_pk (
str
) – Field name of related model’s primary key. Default is ‘id’.related_name (
str
) – Field name of related model’s charfield. Default is ‘name’.pk_handler (
typing.Callable
) – Changes handler for checking value before search. Sends “0” in handler falls. Default is ‘int()’.
- Example:
class CustomFilterSet(filters.FilterSet): author = CharFilter(method=vst_filters.FkFilterHandler(related_pk='pk', related_name='email'))
Where
author
is ForeignKey to User and you want to search by primary key and email.
-
vstutils.api.filters.
extra_filter
(queryset, field, value)[source]¶ Method for searching values in a comma-separated list.
- Parameters
queryset (django.db.models.query.QuerySet) – model queryset for filtration.
field (str) – field name in FilterSet. Also supports __not suffix.
value (str) – comma separated list of searching values.
- Returns
filtered queryset.
- Return type
-
vstutils.api.filters.
name_filter
(queryset, field, value)[source]¶ Method for searching by part of name. Uses LIKE DB condition or contains qs-expression.
- Parameters
queryset (django.db.models.query.QuerySet) – model queryset for filtration.
field (str) – field name in FilterSet. Also supports __not suffix.
value (str) – searching part of name.
- Returns
filtered queryset.
- Return type
Responses¶
DRF provides a standard set of variables whose names correspond to the human-readable name of the HTTP code. For convenience, we have dynamically wrapped this in a set of classes that have appropriate names and additionally provide the following capabilities:
String responses are wrapped in json like
{ "detail": "string response" }
.Keep attribute timings for further processing in middlewares.
Set status code from class name (e.g.
HTTP_200_OK
orResponse200
got code 200).
All classes inherit from:
Middlewares¶
By default, the Django assumes that the developer will develop itself Middleware class, but it is not always convenient. The vstutils library offers a convenient request handler class for elegant OOP development. Middlewares is needed to process incoming requests and sent responses before they reach the final destination.
-
class
vstutils.middleware.
BaseMiddleware
(get_response)[source]¶ Middleware base class for handling:
Incoming requests by
BaseMiddleware.request_handler()
;Outgoing response before any calling on server by
BaseMiddleware.get_response_handler()
;Outgoing responses by
BaseMiddleware.handler()
.
Middleware must be added to MIDDLEWARE list in settings.
- Example:
from vstutils.middleware import BaseMiddleware from django.http import HttpResponse class CustomMiddleware(BaseMiddleware): def request_handler(self, request): # Add header to request request.headers['User-Agent'] = 'Mozilla/5.0' return request def get_response_handler(self, request): if not request.user.is_stuff: # Return 403 HTTP status for non-stuff users. # This request never gets in any view. return HttpResponse( "Access denied!", content_type="text/plain", status_code=403 ) return super().get_response_handler(request) def handler(self, request, response): # Add header to response response['Custom-Header'] = 'Some value' return response
- Parameters
get_response (
typing.Callable
) –
-
get_response_handler
(request)[source]¶ Entrypoint for breaking or continuing request handling. This function should return django.http.HttpResponse object or result of parent class calling.
- Parameters
request (django.http.HttpRequest) – HTTP-request object which is wrapped from client request.
- Return type
-
handler
(request, response)[source]¶ The response handler. Here, all the magic of processing the response sent, insertion of headers to response, etc.
- Parameters
request (django.http.HttpRequest) – HTTP-request object.
response (django.http.HttpResponse) – HTTP-response object which will be sended to client.
- Returns
Handled response object.
- Return type
-
request_handler
(request)[source]¶ The request handler. Called before request will be handled by any view.
- Parameters
request (django.http.HttpRequest) – HTTP-request object which is wrapped from client request.
- Returns
Handled request object.
- Return type
Endpoint¶
Endpoint view has two purposes: bulk requests execution and providing openapi schema.
Endpoint url is /{API_URL}/endpoint/
, for example value with default settings is /api/endpoint/
.
API_URL
can be changed in settings.py
.
-
class
vstutils.api.endpoint.
EndpointViewSet
(**kwargs)[source]¶ Default API-endpoint viewset.
-
get
(request)[source]¶ Returns response with swagger ui or openapi json schema if ?format=openapi
- Parameters
request (
vstutils.api.endpoint.BulkRequestType
) –- Return type
django.http.response.HttpResponse
-
get_client
(request)[source]¶ Returns test client and guarantees that if bulk request comes authenticated than test client will be authenticated with the same user
- Parameters
request (
vstutils.api.endpoint.BulkRequestType
) –- Return type
vstutils.api.endpoint.BulkClient
-
get_serializer
(*args, **kwargs)[source]¶ Return the serializer instance that should be used for validating and deserializing input, and for serializing output.
- Return type
vstutils.api.endpoint.OperationSerializer
-
get_serializer_context
(context)[source]¶ Extra context provided to the serializer class.
- Return type
-
operate
(operation_data, context)[source]¶ Method used to handle one operation and return result of it
- Parameters
operation_data (
typing.Dict
) –context (
typing.Dict
) –
- Return type
-
post
(request)[source]¶ Execute transactional bulk request
- Parameters
request (
vstutils.api.endpoint.BulkRequestType
) –- Return type
-
put
(request, allow_fail=True)[source]¶ Execute non transaction bulk request
- Parameters
request (
vstutils.api.endpoint.BulkRequestType
) –- Return type
-
serializer_class
¶ One operation serializer class.
alias of
vstutils.api.endpoint.OperationSerializer
-
versioning_class
¶ alias of
rest_framework.versioning.QueryParameterVersioning
-
Bulk requests¶
Bulk request allows you send multiple request to api at once, it accepts json list of operations.
Method |
Transactional (all operations in one transaction) |
Synchronous (operations executed one by one in given order) |
---|---|---|
|
NO |
YES |
|
YES |
YES |
|
NO |
NO |
Parameters of one operation (* means that parameter is required):
method
* - http method of requestpath
* - path of request, can bestr
orlist
data
- data that needs to be sentquery
- query parameters asstr
headers
-dict
with headers which will be sent, names of headers must follow CGI specification (e.g.,CONTENT_TYPE
,GATEWAY_INTERFACE
,HTTP_*
).version
-str
with specified version of api, if not provided thenVST_API_VERSION
will be used
In any request parameter you can insert result value of previous operations
(<<{OPERATION_NUMBER}[path][to][value]>>
), for example:
[
{"method": "post", "path": "user", "data": {"name": "User 1"}),
{"method": "delete", "version": "v2", "path": ["user", "<<0[data][id]>>"]}
]
Result of bulk request is json list of objects for operation:
method
- http methodpath
- path of request, always strdata
- data that needs to be sentstatus
- response status code
Transactional bulk request returns 502 BAG GATEWAY
and make rollback if one of requests is failed.
Warning
If you send non-transactional bulk request, you will get 200
status and must
validate statuses on each operation responses.
Openapi schema¶
Request on GET /{API_URL}/endpoint/
returns Swagger UI.
Request on GET /{API_URL}/endpoint/?format=openapi
returns json openapi schema. Also you can specify required
version of schema using version
query parameter (e.g., GET /{API_URL}/endpoint/?format=openapi&version=v2
).
Applying hooks to the schema can also be helpful.
This functionality will help to change certain data in the schema before it will be sended to user.
In order to set some hooks, it is enough to specify in settings.py
the OPENAPI_HOOKS
which is an array with lines for importing functions.
Each function will take 2 named arguments:
request
- user request object.schema
- ordered dict with openapi schema.
Note
Sometimes hooks may raise an exception, and in order not to break the chain of data modification, such exceptions are handled. However, the changes made to the schema before the raised exception will be saved.
- Example hook:
def hook_add_username_to_guiname(request, schema): schema['info']['title'] = f"{request.username} - {schema['info']['title']}"
Testing Framework¶
VST Utils Framework includes a few helper in base testcase class and improve support for making API requests. That means if you want make bulk request to endpoint you dont need create and init test client, but just need to call:
endpoint_results = self.bulk([
# list of endpoint requests
])
Creating test case¶
After creating new project via vstutils
you can found test.py
module,
where you see testcase classes based on vstutils.tests.BaseTestCase
.
At the moment, we officially support two styles of writing tests:
through classic and simple query wrappers with run check and
through runtime optimized bulk queries with manual value checking.
Simple example with classic tests¶
For example, if you have api endpoint like /api/v1/project/
and model Project
you can write testcase like this:
from vstutils.tests import BaseTestCase
class ProjectTestCase(BaseTestCase):
def setUp(self):
super(ProjectTestCase, self).setUp()
# init demo project
self.initial_project = self.get_model_class('project.Test').objects.create(name="Test")
def tearDown(self)
super(ProjectTestCase, self).tearDown()
# remove it after test
self.initial_project.delete()
def test_project_endpoint(self):
# Test checks that api return valid values
self.list_test('/api/v1/project/', 1)
self.details_test(
["project", self.initial_project.id],
name=self.initial_project.name
)
# Try to create new projects and check list endpoint
test_data = [
{"name": f"TestProject{i}"}
for i in range(2)
]
id_list = self.mass_create("/api/v1/project/", test_data, 'name')
self.list_test('/api/v1/project/', 1 + len(id_list))
This simple example demonstrate functionality of default test case class. Default projects are initialized in such a way that for the fastest and most efficient result it is best to distribute testing of various entities into different classes. This example demonstrate classic style of testing, but you can use bulks in your test cases.
Bulk requests in tests¶
The bulk query system and its capabilities are very well suited for testing and executing valid queries. Returning to the previous example, it could be rewritten as follows:
from vstutils.tests import BaseTestCase
class ProjectTestCase(BaseTestCase):
def setUp(self):
super(ProjectTestCase, self).setUp()
# init demo project
self.initial_project = self.get_model_class('project.Test').objects.create(name="Test")
def tearDown(self)
super(ProjectTestCase, self).tearDown()
# remove it after test
self.initial_project.delete()
def test_project_endpoint(self):
test_data = [
{"name": f"TestProject{i}"}
for i in range(2)
]
bulk_data = [
{"method": "get", "path": ["project"]},
{"method": "get", "path": ["project", self.initial_project.id]}
]
bulk_data += [
{"method": "post", "path": ["project"], "data": i}
for i in test_data
]
bulk_data.append(
{"method": "get", "path": ["project"]}
)
results = self.bulk_transactional(bulk_data)
self.assertEqual(results[0]['status'], 200)
self.assertEqual(results[0]['data']['count'], 1)
self.assertEqual(results[1]['status'], 200)
self.assertEqual(results[1]['data']['name'], self.initial_project.name)
for pos, result in enumerate(results[2:-1]):
self.assertEqual(result['status'], 201)
self.assertEqual(result['data']['name'], test_data[pos]['name'])
self.assertEqual(results[-1]['status'], 200)
self.assertEqual(results[-1]['data']['count'], 1 + len(test_data))
In this case, you have more code rows, but your tests will be closer to GUI workflow,
because vstutils-projects uses /api/endpoint/
for requests.
Either way, bulk queries are much faster due to some optimizations,
so you can reduce testcase execution time.
Test case API¶
-
class
vstutils.tests.
BaseTestCase
(methodName='runTest')[source]¶ Main testcase class extends
django.test.TestCase
.-
assertCheckDict
(first, second, msg=None)[source]¶ Fail if the two fields in dicts are unequal as determined by the ‘==’ operator. Checks if first not contains or not equal field in second
- Parameters
first (
typing.Dict
) –second (
typing.Dict
) –msg (
typing.Optional
[str
]) –
-
assertCount
(iterable, count, msg=None)[source]¶ Call
len()
overiterable
and check equals withcount
.- Parameters
iterable (
typing.Sized
) – any iterable object which could be sended tolen()
.count (
int
) – expected result.msg (
typing.Optional
[typing.Any
]) – error message
-
assertRCode
(resp, code=200, *additional_info)[source]¶ Fail if response code is not equal. Message is response body.
- Parameters
resp (django.http.HttpResponse) – response object
code (int) – expected code
-
bulk
(data, code=200, **kwargs)[source]¶ Make non transactional bulk request and assert status code (default is 200)
- Parameters
data (
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]) – request datacode (
int
) – http status to assertkwargs – named arguments for
get_result()
- Return type
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
,typing.Dict
,typing.Sequence
[typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]]]- Returns
bulk response
-
bulk_transactional
(data, code=200, **kwargs)[source]¶ Make transactional bulk request and assert status code (default is 200)
- Parameters
data (
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]) – request datacode (
int
) – http status to assertkwargs – named arguments for
get_result()
- Return type
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
,typing.Dict
,typing.Sequence
[typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]]]- Returns
bulk response
-
details_test
(url, **kwargs)[source]¶ Test for get details of model. If you setup additional named arguments, the method check their equality with response data. Uses
get_result()
method.- Parameters
url – url to detail record. For example:
/api/v1/project/1/
(where1
is uniq id of project). You can useget_url()
for building url.kwargs – params that’s should be checked (key - field name, value - field value).
-
endpoint_call
(data=None, method='get', code=200, **kwargs)[source]¶ Make request to endpoint and assert response status code if specified (default is 200). Uses
get_result()
method for execution.- Parameters
data (
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
,None
]) – request datamethod (
str
) – http request methodcode (
int
) – http status to assert
- Return type
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
,typing.Dict
,typing.Sequence
[typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]]]- Returns
bulk response
-
get_count
(model, **kwargs)[source]¶ Simple wrapper over
get_model_filter()
which returns counter of items.- Parameters
model (str,django.db.models.Model) – string which contains model name (if attribute
model
is set to the testcase class), module import,app.ModelName
ordjango.db.models.Model
.kwargs – named arguments to
django.db.models.query.QuerySet.filter()
.
- Returns
number of instances in database.
- Return type
-
get_model_class
(model)[source]¶ Getting model class by string or return model arg.
- Parameters
model (str,django.db.models.Model) – string which contains model name (if attribute
model
is set to the testcase class), module import,app.ModelName
ordjango.db.models.Model
.- Returns
Model class.
- Return type
-
get_model_filter
(model, **kwargs)[source]¶ Simple wrapper over
get_model_class()
which returns filtered queryset from model.- Parameters
model (str,django.db.models.Model) – string which contains model name (if attribute
model
is set to the testcase class), module import,app.ModelName
ordjango.db.models.Model
.kwargs – named arguments to
django.db.models.query.QuerySet.filter()
.
- Return type
-
get_result
(rtype, url, code=None, *args, **kwargs)[source]¶ Execute and test response code on request with returning parsed result of request. The method uses the following procedure:
Test client authorization (with
user
which creates insetUp()
).Executing a request (sending args and kwargs to request method).
Parsing the result (converts json string to python-object).
Checking the http status code with
assertRCode()
(if you have not specified it, the code will be selected in accordance with the request method from the standard setstd_codes
).Logout client.
Return parsed result.
- Parameters
rtype – request type (methods from Client cls): get, post etc.
url – requested url string or tuple for
get_url()
. You can useget_url()
for url building or setup it as full string.code (
typing.Optional
[int
]) – expected return code from request.relogin – execute force login and logout on each call. Default is
True
.args – extra-args for Client class request method.
kwargs – extra-kwargs for Client class request method.
- Return type
typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
,typing.Dict
,typing.Sequence
[typing.Union
[typing.List
[typing.Dict
[str
,typing.Any
]],str
]]]- Returns
result of request.
-
get_url
(*items)[source]¶ Function for creating url path based on
VST_API_URL
andVST_API_VERSION
settings. Without arguments returns path to default version of api.- Return type
- Returns
string like
/api/v1/.../.../
where...
is args of function.
-
list_test
(url, count)[source]¶ Test for get list of models. Checks only list count. Uses
get_result()
method.- Parameters
url – url to abstract layer. For example:
/api/v1/project/
. You can useget_url()
for building url.count – count of objects in DB.
-
mass_create
(url, data, *fields, **kwargs)[source]¶ Mass creation objects in api-abstration. Uses
get_result()
method.- Parameters
url – url to abstract layer like argument in
get_result()
. For example:/api/v1/project/
.data – list with data to send on creation and feature checks.
kwargs – extra-kwargs for request method.
- Params fields
list of fields to check after creation.
- Returns
list of id from all resulted objects.
- Return type
Note
The method does not use endpoint requests. That mean if you want send some extra headers or data you can do it by additional kwargs.
-
models
= None¶ Attribute with default project models module.
-
classmethod
patch
(*args, **kwargs)[source]¶ Simple
unittest.mock.patch()
class-method wrapper.- Return type
typing.AbstractContextManager
[unittest.mock.Mock
]
-
std_codes
: Dict[str, int] = {'delete': 204, 'get': 200, 'patch': 200, 'post': 201}¶ Default http status codes for different http methods. Uses in
get_result()
-
class
user_as
(testcase, user)[source]¶ Context for execute bulk or something as user. The context manager overrides
self.user
in TestCase and revert this changes on exit.- Parameters
user (django.contrib.auth.models.AbstractUser) – new user object for execution.
-
Utils¶
This is some tested set of development utilities. Utilities include a collection of some code that will be useful in one way or another to develop the application. Most of the functions are used by vstutils itself.
-
class
vstutils.utils.
BaseEnum
(value)[source]¶ BaseEnum extends Enum class and used to create enum-like objects that can be used in django serializers or django models.
Example:
from vstutils.models import BModel class ItemCLasses(BaseEnum): FIRST='FIRST' SECOND='SECOND' THIRD='THIRD' class MyDjangoModel(BModel): item_class = models.CharField(max_length=1024, choices=ItemCLasses.to_choices()) @property def is_second(self): # Function check is item has second class of instance return ItemCLasses.SECOND.is_equal(self.item_class)
-
class
vstutils.utils.
BaseVstObject
[source]¶ Default mixin-class for custom objects which needed to get settings and cache.
-
class
vstutils.utils.
Executor
(stdout=- 1, stderr=- 2, **environ_variables)[source]¶ Command executor with realtime output write and line handling. By default and by design executor initialize string attribute
output
which will be modifyed by+=
operator with new lines byExecutor.write_output()
procedure. Override the method if you want change behavior.Executor class supports periodically (0.01 sec) handling process and execute some checks by overriding
Executor.working_handler()
procedure method. If you want disable this behavior override the method by None value or useUnhandledExecutor
.-
exception
CalledProcessError
(returncode, cmd, output=None, stderr=None)¶ Raised when run() is called with check=True and the process returns a non-zero exit status.
- Attributes:
cmd, returncode, stdout, stderr, output
-
property
stdout
¶ Alias for output attribute, to match stderr
-
working_handler
(proc)[source]¶ Additional handler for executions.
- Parameters
proc (
subprocess.Popen
) –- Return type
-
exception
-
class
vstutils.utils.
KVExchanger
(key, timeout=None)[source]¶ Class for transmit data using key-value fast (cache-like) storage between services. Uses same cache-backend as Lock.
-
class
vstutils.utils.
Lock
(id, payload=None, repeat=1, err_msg='', timeout=None)[source]¶ Lock class for multi-jobs workflow.
Note
Used django.core.cache lib and settings in settings.py
Have Lock.SCHEDULER and Lock.GLOBAL id
-
class
vstutils.utils.
ModelHandlers
(type_name, err_message=None)[source]¶ Handlers for some models like ‘INTEGRATIONS’ or ‘REPO_BACKENDS’. Based on
ObjectHandlers
but more specific for working with models. All handlers backends get by first argument model object.Attributes:
- Parameters
-
get_object
(name, obj)[source]¶ - Parameters
name (
str
) – – string name of backendname – str
obj (django.db.models.Model) – – model object
- Returns
backend object
- Return type
-
class
vstutils.utils.
ObjectHandlers
(type_name, err_message=None)[source]¶ Handlers wrapper for get objects from some settings structure.
- Example:
from vstutils.utils import ObjectHandlers ''' In `settings.py` you should write some structure: SOME_HANDLERS = { "one": { "BACKEND": "full.python.path.to.module.SomeClass" }, "two": { "BACKEND": "full.python.path.to.module.SomeAnotherClass", "OPTIONS": { "some_named_arg": "value" } } } ''' handlers = ObjectHandlers('SOME_HANDLERS') # Get class handler for 'one' one_backend_class = handlers['one'] # Get object of backend 'two' two_obj = handlers.get_object() # Get object of backend 'two' with overriding constructor named arg two_obj_overrided = handlers.get_object(some_named_arg='another_value')
- Parameters
type_name (
str
) –err_message (
typing.Optional
[str
]) –
-
class
vstutils.utils.
Paginator
(qs, chunk_size=None)[source]¶ Class for fragmenting the query for small queries.
-
class
vstutils.utils.
SecurePickling
(secure_key=None)[source]¶ Secured pickle wrapper by Vigenère cipher.
- Example:
from vstutils.utils import SecurePickling serializer = SecurePickling('password') # Init secret object a = {"key": "value"} # Serialize object with secret key pickled = serializer.dumps(a) # Deserialize object unpickled = serializer.loads(pickled) # Check, that object is correct assert a == unpickled
- Parameters
secure_key (
typing.Optional
[str
]) –
-
class
vstutils.utils.
URLHandlers
(type_name='GUI_VIEWS', *args, **kwargs)[source]¶ Object handler for GUI views. Uses GUI_VIEWS from settings.py. Based on
ObjectHandlers
but more specific to urlpatterns.- Example:
from vstutils.utils import URLHandlers # By default gets from `GUI_VIEWS` in `settings.py` urlpatterns = list(URLHandlers())
- Parameters
type_name (
str
) –
-
class
vstutils.utils.
UnhandledExecutor
(stdout=- 1, stderr=- 2, **environ_variables)[source]¶ Class based on
Executor
but disables working_handler.
-
class
vstutils.utils.
apply_decorators
(*decorators)[source]¶ Decorator which apply list of decorators on method or class.
- Example:
from vstutils.utils import apply_decorators def decorator_one(func): print(f"Decorated {func.__name__} by first decorator.") return func def decorator_two(func): print(f"Decorated {func.__name__} by second decorator.") return func @apply_decorators(decorator_one, decorator_two) def decorated_function(): # Function decorated by both decorators. print("Function call.")
-
class
vstutils.utils.
classproperty
(fget, fset=None)[source]¶ Decorator which makes class method as class property.
- Example:
from vstutils.utils import classproperty class SomeClass(metaclass=classproperty.meta): # Metaclass is needed for set attrs in class # instead of and not only object. some_value = None @classproperty def value(cls): return cls.some_value @value.setter def value(cls, new_value): cls.some_value = new_value
- Parameters
fget (
typing.Callable
) –fset (
typing.Optional
[typing.Callable
]) –
-
vstutils.utils.
deprecated
(func)[source]¶ This is a decorator which can be used to mark functions as deprecated. It will result in a warning being emitted when the function is used.
- Parameters
func (
typing.Callable
) –
-
vstutils.utils.
list_to_choices
(items_list, response_type=<class 'list'>)[source]¶ Method to create django model choices from flat list of values.
- Parameters
items_list (
typing.Iterable
) – list of flat values.response_type (
typing.Callable
) – casting type of returned mapping
- Return type
- Returns
list of tuples from items_list values
-
class
vstutils.utils.
model_lock_decorator
(**kwargs)[source]¶ Decorator for functions where ‘pk’ kwarg exist for lock by id.
Warning
On locked error raised
Lock.AcquireLockException
Method must have and called with
pk
named arg.
-
class
vstutils.utils.
raise_context_decorator_with_default
(*args, **kwargs)[source]¶ Context for exclude errors and return default value.
- Example:
from yaml import load from vstutils.utils import raise_context_decorator_with_default @raise_context_decorator_with_default(default={}) def get_host_data(yaml_path, host): with open(yaml_path, 'r') as fd: data = load(fd.read(), Loader=Loader) return data[host] # This decorator used when you must return some value even on error # In log you also can see traceback for error if it occur def clone_host_data(host): bs_data = get_host_data('inventories/aws/hosts.yml', 'build_server') ...
-
class
vstutils.utils.
redirect_stdany
(new_stream=<_io.StringIO object>, streams=None)[source]¶ Context for redirect any output to own stream.
Note
On context return stream object.
On exit return old streams
-
vstutils.utils.
send_template_email
(sync=False, **kwargs)[source]¶ Function executing sync or async email sending; according sync argument and settings variable “RPC_ENABLED”. You can use this function to send message, it sends message asynchronously or synchronously. If you don’t set settings for celery or don’t have celery it sends synchronously mail. If celery is installed and configured and sync argument of the function is set to False, it sends asynchronously email.
- Parameters
sync (
bool
) – argument for determining how send email, asynchronously or synchronouslysubject – mail subject.
email – list of strings or single string, with email addresses of recipients
template_name – relative path to template in templates directory, must include extension in file name.
context_data – dictionary with context for rendering message template.
-
vstutils.utils.
send_template_email_handler
(subject, email_from, email, template_name, context_data=None, **kwargs)[source]¶ Function for email sending. The function convert recipient to list and set context before sending if it possible.
- Parameters
subject (
str
) – mail subject.email_from (
str
) – sender that be setup in email.email (
typing.Union
[typing.List
,str
]) – list of strings or single string, with email addresses of recipientstemplate_name (
str
) – relative path to template in templates directory, must include extension in file name.context_data (
typing.Optional
[typing.Dict
]) – dictionary with context for rendering message template.kwargs – additional named arguments for send_mail
- Return type
- Returns
Number of emails sent.