vulyk.models package

Submodules

vulyk.models.exc module

Module contains all exception classes could be raised during work with the DB.

exception vulyk.models.exc.TaskImportError[source]

Bases: Exception

exception vulyk.models.exc.TaskNotFoundError[source]

Bases: Exception

exception vulyk.models.exc.TaskPermissionError[source]

Bases: Exception

exception vulyk.models.exc.TaskSaveError[source]

Bases: Exception

exception vulyk.models.exc.TaskSkipError[source]

Bases: Exception

exception vulyk.models.exc.TaskValidationError[source]

Bases: Exception

exception vulyk.models.exc.WorkSessionLookUpError[source]

Bases: Exception

exception vulyk.models.exc.WorkSessionUpdateError[source]

Bases: Exception

vulyk.models.stats module

Module contains all models used to keep some metadata we could use to perform any kind of analysis.

class vulyk.models.stats.WorkSession(*args, **values)[source]

Bases: flask_mongoengine.Document

Class which represents a timespan during which user was working on the task Also it stores links to every entity involved.

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

activity

64-bit integer field. (Equivalent to IntField since the support to Python2 was dropped)

answer

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)
end_time

Datetime field.

Uses the python-dateutil library if available alternatively use time.strptime to parse the dates. Note: python-dateutil’s parser is fully featured and when installed you can utilise it to convert varying types of date formats into valid python datetime objects.

Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow)

Note: Microseconds are rounded to the nearest millisecond.

Pre UTC microsecond support is effectively broken. Use ComplexDateTimeField if you need accurate microsecond support.

classmethod get_total_user_time_approximate(user_id: bson.objectid.ObjectId)int[source]

Aggregated time spent doing tasks on all projects by certain user. As the source we use approximate values of start time and end time. Might be useful if no proper time accounting is done on frontend.

Parameters

user_id (ObjectId) – User ID

Returns

Total time (in seconds)

Return type

int

classmethod get_total_user_time_precise(user_id: bson.objectid.ObjectId)int[source]

Aggregated time spent doing tasks on all projects by certain user. As the source we use more precise value of activity field.

Parameters

user_id (ObjectId) – User ID

Returns

Total time (in seconds)

Return type

int

id

A field wrapper around MongoDB’s ObjectIds.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

start_time

Datetime field.

Uses the python-dateutil library if available alternatively use time.strptime to parse the dates. Note: python-dateutil’s parser is fully featured and when installed you can utilise it to convert varying types of date formats into valid python datetime objects.

Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow)

Note: Microseconds are rounded to the nearest millisecond.

Pre UTC microsecond support is effectively broken. Use ComplexDateTimeField if you need accurate microsecond support.

task

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)
task_type

A unicode string field.

user

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)

vulyk.models.task_types module

Module contains all models related to task type (plugin root) entity.

class vulyk.models.task_types.AbstractTaskType(settings: Dict[str, Any])[source]

Bases: object

The main entity in the application. Contains all the logic we need to handle task emission/accounting.

Could be overridden in plugins to fit your needs.

The simplest and most common scenario of being overridden is to have own

task type name and description to separate your tasks from any other.

CSS_ASSETS = []
JS_ASSETS = []
answer_model = None
property description

Explicit description of the plugin.

Returns

Plugin description.

Return type

str

export_reports(batch: str, closed: bool = True, qs=None)Generator[Dict[str, Any], None, None][source]

Exports results. IO is left out of scope here as well

Parameters
  • batch (str) – Certain batch to extract

  • closed (bool) – Specify if we need to export only closed tasks reports

  • qs (QuerySet) – Queryset, an optional argument. Default value is QS that exports all tasks with amount of answers > redundancy

Returns

Generator of lists of dicts with results

Return type

Generator[Dict[str, Any], None, None]

get_leaderboard(limit: int = 10)List[Dict][source]

Find users who contributed the most

Parameters

limit (int) – number of top users to return

Returns

List of dicts {user: user_obj, freq: count}

Return type

List[Dict]

get_leaders()List[Tuple[bson.objectid.ObjectId, int]][source]

Return sorted list of tuples (user_id, tasks_done)

Returns

list of tuples (user_id, tasks_done)

Return type

List[Tuple[ObjectId, int]]

get_next(user: vulyk.models.user.User)Dict[source]

Finds given user a new task and starts new WorkSession

Parameters

user (User) – an instance of User model

Returns

Prepared dictionary of model, or empty dictionary

Return type

Dict

helptext_template = ''
import_tasks(tasks: List[Dict], batch: Optional[AnyStr])None[source]

Imports tasks from an iterable over dicts io is left out of scope here.

Parameters
  • tasks (List[Dict]) – An iterable over dicts

  • batch (Optional[AnyStr]) – Batch ID (optional)

Raise

TaskImportError

property name

Human-readable name of the plugin.

Returns

Name of the task type.

Return type

str

on_task_done(user: vulyk.models.user.User, task_id: AnyStr, result: Dict[str, Any])None[source]

Saves user’s answers for a given task. Assumes that user is eligible for this kind of tasks.

Parameters
  • task_id (AnyStr) – Given task ID

  • user (User) – an instance of User model who provided an answer

  • result (Dict[str, Any]) – Task solving result

Raises

TaskSaveError - in case of general problems

Raises

TaskValidationError - in case of validation problems

record_activity(user_id: Union[AnyStr, bson.objectid.ObjectId], task_id: AnyStr, seconds: int)None[source]

Increases the counter of activity for current user in given task.

Parameters
  • user_id (Union[AnyStr, ObjectId]) – ID of user, who gets new task

  • task_id (AnyStr) – Current task

  • seconds (int) – User was active for

Raises

TaskSkipError, TaskNotFoundError

redundancy = 3
skip_task(task_id: AnyStr, user: vulyk.models.user.User)[source]

Marks given task as a skipped by a given user Assumes that user is eligible for this kind of tasks

Parameters
  • task_id (AnyStr) – Given task ID

  • user (User) – an instance of User model who provided an answer

Raises

TaskSkipError, TaskNotFoundError

task_model = None
property task_type_meta

Dict with task type metadata (freeform dict)

Returns

project specific metadata

Return type

Dict[str, Any]

template = ''
to_dict()Dict[str, Any][source]

Prepare simplified dict that contains basic info about the task type.

Returns

distilled dict with basic info

Return type

Dict[str, Any]

type_name = ''
property work_session_manager

Returns current instance of WorkSessionManager used in the task type.

Returns

Active WorkSessionManager instance.

Return type

WorkSessionManager

vulyk.models.tasks module

Module contains all models directly related to the main entity - tasks.

class vulyk.models.tasks.AbstractAnswer(*args, **values)[source]

Bases: flask_mongoengine.Document

This is AbstractTask model. You need to inherit it in your model

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

classmethod answers_numbers_by_tasks(task_ids: List[str])Dict[bson.objectid.ObjectId, int][source]

Groups answers, filtered by tasks they belong to, by user and count number of answers for every user.

Parameters

task_ids (List[str]) – List of tasks IDs

Returns

Map having user IDs as keys and answers numbers as values

Return type

Dict[ObjectId, int]

as_dict()Dict[str, Dict][source]

Converts the model-instance into a safe that will include also task and user.

Return type

Dict[str, Dict]

property corrections

Returns whole amount of actions/corrections given by user in this particular answer.

Returns

Count of corrections in this answer

Return type

int

created_at

Datetime field.

Uses the python-dateutil library if available alternatively use time.strptime to parse the dates. Note: python-dateutil’s parser is fully featured and when installed you can utilise it to convert varying types of date formats into valid python datetime objects.

Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow)

Note: Microseconds are rounded to the nearest millisecond.

Pre UTC microsecond support is effectively broken. Use ComplexDateTimeField if you need accurate microsecond support.

created_by

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)
id

A field wrapper around MongoDB’s ObjectIds.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

result

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

task

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)
task_type

A unicode string field.

class vulyk.models.tasks.AbstractTask(*args, **values)[source]

Bases: flask_mongoengine.Document

This is AbstractTask model. You need to inherit it in your model

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

as_dict()Dict[str, Any][source]

Converts the model-instance into a safe and lightweight dictionary.

Return type

Dict[str, Any]

batch

A reference to a document that will be automatically dereferenced on access (lazily).

Note this means you will get a database I/O access everytime you access this field. This is necessary because the field returns a Document which precise type can depend of the value of the _cls field present in the document in database. In short, using this type of field can lead to poor performances (especially if you access this field only to retrieve it pk field which is already known before dereference). To solve this you should consider using the LazyReferenceField.

Use the reverse_delete_rule to handle what should happen if the document the field is referencing is deleted. EmbeddedDocuments, DictFields and MapFields does not support reverse_delete_rule and an InvalidDocumentError will be raised if trying to set on one of these Document / Field types.

The options are:

  • DO_NOTHING (0) - don’t do anything (default).

  • NULLIFY (1) - Updates the reference to null.

  • CASCADE (2) - Deletes the documents associated with the reference.

  • DENY (3) - Prevent the deletion of the reference object.

  • PULL (4) - Pull the reference from a ListField of references

Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)

class Org(Document):
    owner = ReferenceField('User')

class User(Document):
    org = ReferenceField('Org', reverse_delete_rule=CASCADE)

User.register_delete_rule(Org, 'owner', DENY)
closed

Boolean field type.

id

A unicode string field.

classmethod ids_in_batch(batch: vulyk.models.tasks.Batch)List[str][source]

Collects IDs of all tasks that belong to certain batch.

Parameters

batch (Batch) – Batch instance

Returns

List of IDs

Return type

List[str]

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

task_data

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

task_type

A unicode string field.

users_count

32-bit integer field.

users_processed

A list field that wraps a standard field, allowing multiple instances of the field to be used as a list in the database.

If using with ReferenceFields see: many-to-many-with-listfields

Note

Required means it cannot be empty - as the default for ListFields is []

users_skipped

A list field that wraps a standard field, allowing multiple instances of the field to be used as a list in the database.

If using with ReferenceFields see: many-to-many-with-listfields

Note

Required means it cannot be empty - as the default for ListFields is []

class vulyk.models.tasks.Batch(*args, **values)[source]

Bases: flask_mongoengine.Document

Helper category to group tasks.

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

batch_meta

A dictionary field that wraps a standard Python dictionary. This is similar to an embedded document, but the structure is not defined.

Note

Required means it cannot be empty - as the default for DictFields is {}

closed

Boolean field type.

id

A unicode string field.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

classmethod task_done_in(batch_id: str)vulyk.models.tasks.BatchUpdateResult[source]

Increment needed values upon a task from the batch is done. In case if all tasks are finished – close the batch.

Parameters

batch_id (str) – Batch ID

Returns

Aggregate which represents complex effect of the method

Return type

BatchUpdateResult

task_type

A unicode string field.

tasks_count

32-bit integer field.

tasks_processed

32-bit integer field.

class vulyk.models.tasks.BatchUpdateResult(success, closed)

Bases: tuple

closed

Alias for field number 1

success

Alias for field number 0

vulyk.models.user module

Module contains all models related to member entity.

class vulyk.models.user.Anonymous[source]

Bases: flask_login.mixins.AnonymousUserMixin

name = 'Anonymous'
class vulyk.models.user.Group(*args, **values)[source]

Bases: flask_mongoengine.Document

Class was introduced to serve the permissions purpose

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

allowed_types

A list field that wraps a standard field, allowing multiple instances of the field to be used as a list in the database.

If using with ReferenceFields see: many-to-many-with-listfields

Note

Required means it cannot be empty - as the default for ListFields is []

description

A unicode string field.

id

A unicode string field.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

class vulyk.models.user.User(*args, **values)[source]

Bases: flask_mongoengine.Document, flask_login.mixins.UserMixin

Main model for member entity.

exception DoesNotExist

Bases: mongoengine.errors.DoesNotExist

exception MultipleObjectsReturned

Bases: mongoengine.errors.MultipleObjectsReturned

active

Boolean field type.

admin

Boolean field type.

as_dict()Dict[str, str][source]

Converts the model-instance into a safe dict that will include some basic info about member.

Returns

Reduced set of information about member.

Return type

Dict[str, str]

email

A unicode string field.

classmethod get_by_id(user_id: str)Optional[flask_mongoengine.Document][source]
Parameters

user_id (str) – Needed user ID

Returns

The user

Return type

Optional[User]

get_stats(task_type)Dict[str, int][source]

Returns member’s stats containing the number of tasks finished and the position in the global rank.

Parameters

task_type (vulyk.models.task_types.AbstractTaskType) – Task type instance.

Returns

Dictionary that contains total finished tasks count and the position in the global rank.

Return type

Dict[str, int]

groups

A list field that wraps a standard field, allowing multiple instances of the field to be used as a list in the database.

If using with ReferenceFields see: many-to-many-with-listfields

Note

Required means it cannot be empty - as the default for ListFields is []

id

A field wrapper around MongoDB’s ObjectIds.

is_active()bool[source]
is_admin()bool[source]
is_eligible_for(task_type: str)bool[source]

Check that user is authorized to work with this tasks type

Parameters

task_type (str) – Tasks type name

Returns

True if user is eligible

Return type

bool

Raises

AssertionError - if no task_type specified

last_login

Datetime field.

Uses the python-dateutil library if available alternatively use time.strptime to parse the dates. Note: python-dateutil’s parser is fully featured and when installed you can utilise it to convert varying types of date formats into valid python datetime objects.

Note: To default the field to the current datetime, use: DateTimeField(default=datetime.utcnow)

Note: Microseconds are rounded to the nearest millisecond.

Pre UTC microsecond support is effectively broken. Use ComplexDateTimeField if you need accurate microsecond support.

name

A unicode string field.

objects

The default QuerySet Manager.

Custom QuerySet Manager functions can extend this class and users can add extra queryset functionality. Any custom manager methods must accept a Document class as its first argument, and a QuerySet as its second argument.

The method function should return a QuerySet , probably the same one that was passed in, but modified in some way.

password

A unicode string field.

classmethod pre_save(sender: Type, document: flask_mongoengine.Document, **kwargs: Dict)flask_mongoengine.Document[source]

A signal handler which will put a new member into a default group if any hasn’t been assigned yet.

Parameters
  • sender (Type) – Type of signal emitter.

  • document (User) – New instance of User model.

  • kwargs (Dict) – Additional parameters

Returns

Modified User instance.

Return type

User

processed

32-bit integer field.

username

A unicode string field.

Module contents