Welcome to yawf’s documentation!

Contents:

yawf Package

yawf Package

class yawf.__init__.WorkflowChoices[source]

Bases: object

yawf.__init__.autodiscover()[source]
yawf.__init__.get_registered_workflows()
yawf.__init__.get_workflow(workflow_id)
yawf.__init__.get_workflow_by_instance(obj)[source]
yawf.__init__.get_workflow_display_name(id)[source]
yawf.__init__.get_workflow_name_map()[source]
yawf.__init__.register_workflow(workflow)[source]

actions Module

allowed Module

yawf.allowed.get_allowed(sender, obj)[source]

annotation Module

base Module

base_model Module

class yawf.base_model.WorkflowAwareModelBase[source]

Bases: object

get_clarified_instance()[source]
state_display()[source]
workflow
workflow_type_display()[source]

config Module

creation Module

dispatch Module

effects Module

class yawf.effects.SideEffect(message_id=None, states_from=None, states_to=None, message_group=None)[source]

Bases: object

Basic class to express side-effect actions.

SideEffect in yawf is a side-effect action that can be performed after certain changes in workflow.

User can treat effects as event handlers and put that handlers on any transition. To specify a transition, one can specify a list of states before transition, a list of states after transition and a list of message ids. Everything above is optional, so if you register a default side-effect without specify any of this variables, such side-effect will be called after each transition.

User can put any number of side-effects on each and every transition. In case of multiple effects matching specific transition each side-effect will be executed one by one.

Yawf executes side-effect after state transition, when yawf obtains new state (and possibly modified object).

Yawf passes keyword arguments to side-effect:
  • old_obj: the object before the state transition (before locking);

  • obj: the object after the state transition;

  • sender: message sender;

  • params: message arguments;

  • message_spec: message spec class (because we may want to distinguish

    between different messages in effects);

  • extra_context: extra context thas was passed to

    yawf.dispatch.dispatch();

  • handler_result: result of the state transition routine.

is_transactional = False
message_group = None
message_id = None
name
perform(**kwargs)[source]
set_performer(performer)[source]
states_from = None
states_to = None

exceptions Module

exception yawf.exceptions.ConcurrentRevisionUpdate[source]

Bases: yawf.exceptions.YawfException

code = 'concurrent_revision_update'
exception yawf.exceptions.CreateValidationError(validator)[source]

Bases: yawf.exceptions.MessageValidationError

code = 'create_validation_error'
exception yawf.exceptions.GroupPathEmptyError[source]

Bases: yawf.exceptions.YawfException

code = 'group_path_empty_error'
exception yawf.exceptions.IllegalStateError[source]

Bases: yawf.exceptions.YawfException

code = 'illegal_state_error'
exception yawf.exceptions.MessageIgnored[source]

Bases: yawf.exceptions.YawfException

code = 'message_ignored'
context
exception yawf.exceptions.MessageSpecNotRegisteredError[source]

Bases: yawf.exceptions.YawfException

code = 'message_spec_not_registered_error'
exception yawf.exceptions.MessageValidationError(validator)[source]

Bases: yawf.exceptions.YawfException

code = 'yawf_validation_error'
context
exception yawf.exceptions.NoAvailableMessagesError[source]

Bases: yawf.exceptions.YawfException

code = 'no_available_messages_error'
exception yawf.exceptions.OldStateInconsistenceError[source]

Bases: yawf.exceptions.YawfException

code = 'old_state_inconsistence_error'
exception yawf.exceptions.PermissionDeniedError[source]

Bases: yawf.exceptions.YawfException

code = 'permission_denied_error'
exception yawf.exceptions.ResourceNotFoundError[source]

Bases: yawf.exceptions.YawfException

code = 'resource_not_found_error'
exception yawf.exceptions.ResourcePermissionDeniedError[source]

Bases: yawf.exceptions.PermissionDeniedError

code = 'resource_permission_denied_error'
exception yawf.exceptions.UnhandledMessageError[source]

Bases: yawf.exceptions.YawfException

code = 'unhandled_message_error'
context
exception yawf.exceptions.WorkflowAlreadyRegisteredError[source]

Bases: yawf.exceptions.YawfException

code = 'workflow_already_registered_error'
exception yawf.exceptions.WorkflowNotLoadedError[source]

Bases: yawf.exceptions.YawfException

code = 'workflow_not_loaded_error'
exception yawf.exceptions.WrongHandlerResultError[source]

Bases: yawf.exceptions.YawfException

code = 'wrong_handler_result_error'
exception yawf.exceptions.YawfException[source]

Bases: coded_exceptions.CodedException

code = 'yawf_exception'

forms Module

yawf.forms.get_action_form_html(obj, sender)[source]
yawf.forms.get_create_form_html(workflow_type, sender=None)[source]
yawf.forms.get_object_as_html(obj, sender)[source]

graph Module

graph_views Module

handlers Module

class yawf.handlers.Handler(message_id=None, states_from=None, message_group=None, permission_checker=None)[source]

Bases: object

Basic class to express state transitions, both simple and extended.

Handler object is a callable. It gets a workflow object, message sender and arbitrary keyword arguments (passed with message) and must return new state id based on this information (it can return None and message will be ignored).

If handler returns a callable, then this callable applies as transaction on object (to change its extended state). The result of the latter callable represents a transition result. If callable returns generator, transition routine will iterate over it, collecting the yielded values. For more information about state transition, see yawf.state_transition module.

Transitioning callable can actually return anything besides generator. That is totally an application designer business.

copy_before_call = False
defer = True
message_group = None
message_id = None
perform(obj, sender, **kwargs)[source]
permission_checker = None
replace_if_exists = False
set_performer(handle_func)[source]
states_from = None
class yawf.handlers.SimpleStateTransition(*args, **kwargs)[source]

Bases: yawf.handlers.Handler

perform(obj, sender, **kwargs)[source]
state_to = None
class yawf.handlers.ComplexStateTransition(message_id=None, states_from=None, message_group=None, permission_checker=None)[source]

Bases: yawf.handlers.Handler

perform(obj, sender, **kwargs)[source]
transition(obj, sender, **kwargs)[source]
class yawf.handlers.EditHandler(message_id=None, states_from=None, message_group=None, permission_checker=None)[source]

Bases: yawf.handlers.ComplexStateTransition

field_names = None
post_hook(obj)[source]
transition(obj, sender, **kwargs)[source]
class yawf.handlers.SerializibleHandlerResult(**kwargs)[source]

Bases: object

get_serializible_value()[source]
type = None

library Module

models Module

permissions Module

class yawf.permissions.AndChecker(*checkers)[source]

Bases: yawf.permissions.BasePermissionChecker

class yawf.permissions.BasePermissionChecker(*checkers)[source]

Bases: object

add_checker(checker)[source]
fill_cache(obj, sender)[source]
get_atomical_checkers()[source]
perform_child_checker(checker, obj, sender, cache)[source]
yawf.permissions.C

alias of AndChecker

class yawf.permissions.NotChecker(checker)[source]

Bases: yawf.permissions.BasePermissionChecker

class yawf.permissions.OrChecker(*checkers)[source]

Bases: yawf.permissions.BasePermissionChecker

serialize_utils Module

signals Module

state_transition Module

utils Module

yawf.utils.chained_apply(callables_iterable)[source]
yawf.utils.common_cancel(obj, cancel_state='canceled', soft_delete_attr=None)[source]
yawf.utils.common_start(obj, state, soft_delete_attr=None)[source]
yawf.utils.filter_handler_result(result, cls_to_filter)[source]
yawf.utils.filter_side_effect_results(results, cls_to_filter)[source]
yawf.utils.make_common_cancel(cancel_state='canceled', soft_delete_attr=None)[source]
yawf.utils.make_common_start(state, soft_delete_attr=None)[source]
yawf.utils.make_common_updater(kwargs, field_names=None, post_hook=None)[source]
yawf.utils.maybe_list(a)[source]
yawf.utils.memoizible_property(getter)[source]
yawf.utils.metadefaultdict(fabric)[source]
yawf.utils.model_diff(instance1, instance2, full=False)[source]
yawf.utils.model_diff_fields(instance1, instance2)[source]
yawf.utils.optionally_edit(handler)[source]
yawf.utils.select_for_update(queryset)[source]

version Module

views Module

Subpackages

management Package

Subpackages
commands Package
graph_yawf_effects Module
graph_yawf_handlers Module

message_log Package

admin Module
models Module

messages Package

messages Package
allowed Module
class yawf.messages.allowed.AllowedWrapper(sender, obj, specs=None)[source]

Bases: object

yawf.messages.allowed.annotate_with_allowed_messages(sender, objects)[source]
yawf.messages.allowed.get_allowed_messages(sender, obj, cache=None)[source]
yawf.messages.allowed.get_allowed_messages_for_many(sender, objects)[source]
yawf.messages.allowed.get_message_specs(sender, obj)[source]
yawf.messages.allowed.get_message_specs_for_many(sender, objects)[source]
yawf.messages.allowed.is_valid_message(obj, message_id)[source]
common Module
class yawf.messages.common.BasicCancelMessage(**attrs)[source]

Bases: yawf.messages.spec.MessageSpec

id = 'cancel'
rank = 1000
verb = <django.utils.functional.__proxy__ object>
class yawf.messages.common.BasicDeleteMessage(**attrs)[source]

Bases: yawf.messages.spec.MessageSpec

id = 'delete'
rank = 1001
verb = <django.utils.functional.__proxy__ object>
class yawf.messages.common.BasicEditMessage(**attrs)[source]

Bases: yawf.messages.spec.MessageSpec

id = 'edit'
rank = 900
verb = <django.utils.functional.__proxy__ object>
class yawf.messages.common.BasicStartMessage(**attrs)[source]

Bases: yawf.messages.spec.MessageSpec

id = 'start_workflow'
verb = <django.utils.functional.__proxy__ object>
yawf.messages.common.message_spec_fabric(id, verb=None, rank=0, base_spec=<class 'yawf.messages.spec.MessageSpec'>, **attrs)[source]
spec Module
class yawf.messages.spec.EmptyValidator(*args, **kwargs)[source]

Bases: object

Class with django-form behaviour that filters out all incoming data, always becomes valid and returns empty dict as cleaned data.

cleaned_data
is_valid()[source]
class yawf.messages.spec.MessageSpec(**attrs)[source]

Bases: object

Specifies a message that can be passed to workflow.

Basic class for one of main entities. Message spec knows:

  • it’s unique ``id’‘;
  • how to represent spec for humans (using ``verb’’ in __unicode__);
  • how to validate parameters for this message (using ``validator_cls’‘);
  • priority (``rank’’ attribute).
dehydrate_params(obj, message)[source]

Method, that returns dehydrated message params for serialization.

id = None
id_grouper = '__'
is_grouped = False
params_wrapper(params)[source]

Wrapper used to wrap cleaned_data returned by validator_cls before passing it to handler.

With wrapper one has additional layer to transform structure of cleaned_data dict to make it more convenient to use.

For example, see yawf.messages.common.BasicEditMessage class.

rank = 0
validator_cls

alias of EmptyValidator

verb = None
submessage Module
class yawf.messages.submessage.RecursiveSubmessage(message_id, sender, params=None, raw_params=None)[source]

Bases: yawf.messages.submessage.Submessage

dispatch(parent_obj, parent_message)[source]
class yawf.messages.submessage.Submessage(obj, message_id, sender, params=None, need_lock_object=True, raw_params=None)[source]

Bases: object

as_message(parent)[source]
dispatch(parent_obj, parent_message)[source]
need_lock_object = True
transformation Module

resources Package

resources Package
allowed Module
yawf.resources.allowed.get_allowed_resources(sender, obj)[source]
yawf.resources.allowed.get_resource(obj, resource_id)[source]
base Module
class yawf.resources.base.WorkflowResource(handler, resource_id, permission_checker, description=None, slug=None)[source]

Bases: object

revision Package

revision Package
models Module
utils Module
Subpackages
migrations Package
0001_initial Module
0002_add_is_created_field Module

tests Package

tests Package
message_specs Module
class yawf.tests.message_specs.MessageSpecsTestCase(methodName='runTest')[source]

Bases: django.test.testcases.TestCase

test_fabric()[source]
test_grouping()[source]
test_repr()[source]
test_validator()[source]
test_without_id()[source]
permissions Module
class yawf.tests.permissions.PermissionsTestCase(methodName='runTest')[source]

Bases: django.test.testcases.TestCase

static call_count(func)[source]
setUp()[source]
test_atomics()[source]
test_cache()[source]

Call complex checker three times and check times that checker functions actually been called

test_checker_expressions()[source]
test_custom_sender()[source]
test_cyclic()[source]
test_fill_cache()[source]
test_inversion()[source]
test_inversion_invariance()[source]

Indices and tables