Module reahl.component.modelinterface

Facilities to govern user input and output, as well as what access the current user has to model objects.

' Copyright 2018 Reahl Software Services (Pty) Ltd. All rights reserved.

@startuml
!include ./base.iuml

title Fields and Events 

note as N1
  A Field controls the attribute of a model object.
  A Field can have ValidationConstraints and AccessRights. 
  An Event is a kind of Field representing something the user can trigger.
  Events are made to do something by linking them to Actions.
  Actions wrap a python callable
  AccessRights are linked to an Action to determine whether a 
  Field is writeable and another to determine if it is readable.
end note


callable <<python>>
attribute <<python>>
Exception <<python>>

Event --up-|> Field
Event -- Action
Action --> callable : "function or object method"

Field --> attribute : domain_value
Field --> ModelObject : "bound to"
ModelObject -right-> attribute: "has attribute"
Field -right- "*" ValidationConstraint
Field --- AccessRights
AccessRights -left- Action : readable
AccessRights -left- Action : writable

ValidationConstraint --up-|> Exception


@enduml

Fields

FieldIndex

class reahl.component.modelinterface.FieldIndex(storage_object)

Used to define a set of Field instances applicable to an object. In order to declare a Field, merely assign an instance of Field to an attribute of the FieldIndex.

Programmers should not construct this class, a prepared instance of it will be passed to methods marked as @exposed. (See ExposedDecorator )

exposed

reahl.component.modelinterface.exposed

alias of reahl.component.modelinterface.ExposedDecorator

ExposedDecorator

class reahl.component.modelinterface.ExposedDecorator(*args)

This class has the alias “exposed”. Apply it as decorator to a method declaration to indicate that the method defines a number of Fields. The decorated method is passed an instance of FieldIndex to which each Field should be assigned. Each such Field is associated with an similarly named attribute on each instance of the current class.

Parameters

args – A list of names of Fields that will be defined by this method. This is used when accessing the resultant FieldIndex on a class, instead of on an instance.

Field

class reahl.component.modelinterface.Field(default=None, required=False, required_message=None, label=None, readable=None, writable=None, disallowed_message=None, min_length=None, max_length=None)

A Field represents something which can be input by a User.

A Field is responsible for transforming user input from a string into a Python object which that string represents. Different kinds of Fields marshall input to different kinds of Python object. This (base) class does no marshalling itself, the parsed Python object is just the input string as given. Subclasses override this behaviour.

A Field also manages the validation of such input, based on a list of individual instances of ValidationConstraint added to the Field.

The final parsed value of a Field is set as an attribute on a Python object to which the Field is bound.

Parameters
  • default – The default (parsed) value if no user input is given.

  • required – If True, indicates that input is always required for this Field.

  • required_message – See error_message of RequiredConstraint.

  • label – A text label by which to identify this Field to a user.

  • readable – A callable that takes one argument (this Field). It is executed to determine whether the current user is allowed to see this Field. Returns True if the user is allowed, else False.

  • writable – A callable that takes one argument (this Field). It is executed to determine whether the current user is allowed supply input for this Field. Returns True if the user is allowed, else False.

  • disallowed_message – An error message to be displayed when a user attempts to supply input to this Field when it is not writable for that user. (See error_message of ValidationConstraint.)

  • min_length – The minimum number of characters allowed in the user supplied input.

  • max_length – The maximum number of characters allowed in the user supplied input.

Changed in version 4.0: Added min_length and max_length kwargs.

entered_input_type

alias of builtins.str

property initial_value

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

property input_status

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

property validation_error

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

property user_input

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

property parsed_input

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

make_required(required_message)

Forces this Field to be required, using required_message as an error message.

as_required(required_message=None)

Returns a new Field which is exactly like this one, except that the new Field is required, using required_message.

make_optional()

Forces this Field to be optional (not required).

as_optional()

Returns a new Field which is exactly like this one, except that the new Field is optional.

without_validation_constraint(validation_constraint_class)
Returns a new Field which is exactly like this one, except that the new Field does not include

a ValidationConstraint of the class given as validation_constraint_class.

Changed in version 4.0: Changed name to be consistent with conventions for with_ methods.

with_validation_constraint(validation_constraint)
Returns a new Field which is exactly like this one, except that the new Field also includes

the ValidationConstraint given as validation_constraint.

Changed in version 4.0: Changed name to be consistent with conventions for with_ methods.

with_label(label)
Returns a new Field which is exactly like this one, except that its label is set to

the given text.

New in version 5.0.

with_discriminator(discriminator)

Returns a new Field which is exactly like this one, except that its name is mangled to include the given text as to prevent name clashes.

New in version 5.0.

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

from_input(unparsed_input, ignore_validation=False, ignore_access=False)

Sets the value of this Field from the given unparsed_input.

as_input()

Returns the value of this Field as a string.

add_validation_constraint(validation_constraint)

Adds the given validation_constraint to this Field. All ValidationConstraints added to the Field are used in order, to validate input supplied to the Field.

CurrentUser

class reahl.component.modelinterface.CurrentUser

A Field whose value is always set to the party of the account currently logged in.

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

EmailField

class reahl.component.modelinterface.EmailField(default=None, required=False, required_message=None, label=None, readable=None, writable=None)

A Field representing a valid email address. Its parsed value is the given string.

PasswordField

class reahl.component.modelinterface.PasswordField(default=None, required=False, required_message=None, label=None, writable=None, min_length=6, max_length=20)

A Field representing a password. Its parsed value is the given string, but the user is not allowed to see its current value.

BooleanField

class reahl.component.modelinterface.BooleanField(default=None, required=False, required_message=None, label=None, readable=None, writable=None, true_value=None, false_value=None)

A Field that can only have one of two parsed values: True or False. The string representation of each of these values are given in true_value or false_value, respectively. (These default to ‘on’ and ‘off’ initially.)

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

IntegerField

class reahl.component.modelinterface.IntegerField(default=None, required=False, required_message=None, label=None, readable=None, writable=None, min_value=None, max_value=None)

A Field that yields an integer.

Parameters
  • min_value – The minimum value allowed as valid input.

  • max_value – The maximum value allowed as valid input.

(For other arguments, see Field.)

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

DateField

class reahl.component.modelinterface.DateField(default=None, required=False, required_message=None, label=None, readable=None, writable=None, min_value=None, max_value=None)

A Field that can parse a Python Date from a given user input string. The input string need not conform to strict format – a DateField does its best to parse what is given. The names of months, days, etc that may be typed by a user are parsed according to the current language in use.

Parameters
  • min_value – The earliest value allowed as valid input.

  • max_value – The latest value allowed as valid input.

(For other arguments, see Field.)

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

Inputting predefined values

ChoiceField

class reahl.component.modelinterface.ChoiceField(grouped_choices, default=None, required=False, required_message=None, label=None, readable=None, writable=None)

A Field that only allows the value of one of the given Choice instances as input.

Parameters

grouped_choices – A list of Choice or ChoiceGroup instances from which a user should choose a single Choice.

(For other arguments, see Field.)

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

MultiChoiceField

class reahl.component.modelinterface.MultiChoiceField(grouped_choices, default=None, required=False, required_message=None, label=None, readable=None, writable=None)

A Field that allows a selection of values from the given Choice instances as input.

entered_input_type

alias of builtins.list

parse_input(unparsed_inputs)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_values)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

Choice

class reahl.component.modelinterface.Choice(value, field)

One possible Choice to be allowed as input for a ChoiceField.

Parameters
  • value – The Python value represented by this Choice.

  • field – A Field able to marshall the value of this Choice. The label of this Field is used as a string to represent this Choice to a user.

ChoiceGroup

class reahl.component.modelinterface.ChoiceGroup(label, choices)

Different Choice instances can be grouped together. User interface machinery can use this information for display purposes.

Parameters
  • label – A name for the group to display.

  • choices – The list of choices in this ChoiceGroup.

Inputting files

FileField

class reahl.component.modelinterface.FileField(allow_multiple=False, default=None, required=False, required_message=None, label=None, readable=None, writable=None, max_size_bytes=None, accept=None, max_files=None)

A Field that can accept one or more files as input.

Parameters
  • allow_multiple – Set to True to allow more than one file to be input at a time.

  • max_size_bytes – The maximim size of file allowed, in bytes.

  • accept – The accepted type of file, as specified via mime type.

  • max_files – Specifies the maximum number of files the user is allowed to input.

(For other arguments, see Field.)

parse_input(unparsed_value)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

UploadedFile

class reahl.component.modelinterface.UploadedFile(filename, contents, mime_type)

Represents a file that was input by a user. The contents of the file is represented as bytes, because knowing what the encoding is is a tricky issue. The user only sits in front of the browser and selects files on their filesystem and hits ‘upload’. Those files can be binary or text. If text, they may or may not be in the same encoding as their system’s preferred encoding. If binary, their browser may guess their content type correctly or may not, and if we go and decode them with i.e UTF-8, the system could break with UnicodeDecodeError on jpegs and the like.

Changed in version 3.0: UploadedFile is now constructed with the entire contents of the uploaded file instead of with a file-like object as in 2.1.

filename

The name of the file

mime_type

The mime type of the file

property size

The size of the UploadedFile contents.

open()

A contextmanager for reading the file contents (as bytes).

For example:

with uploaded_file.open() as contents:
    print(contents.read())

Constraints

ValidationConstraint

class reahl.component.modelinterface.ValidationConstraint(error_message=None)

A ValidationConstraint is responsible for checking that a given value is deemed valid input. Each ValidationConstraint only checks one aspect of the validity of a given Field. The ValidationConstraint first checks a string sent as user input, but can afterwards also validate the resultant Python object which was created based on such string input.

Parameters

error_message – The error message shat should be shown to a user if input failed this ValidationConstraint. This error_message is a string containing a PEP-292 template. Attributes of the ValidationConstraint can be referred to by name in variable references of this template string.

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

validate_parsed_value(parsed_value)

Override this method to provide the custom logic of how this ValidationConstraint should check the given Python object after it was created from initial input in string form. If validation fails, this method should raise self.

property parameters

Override this property to supply parameters for this ValidationConstraint. Parameters are used by user interface mechanics outside the scope of this module for implementation reasons.

property message

The message to display to a user if this ValidationConstraint is failed by some input.

property label

The textual label displayed to users for the Field to which this ValidationConstraint is linked.

property value

The current value which failed validation.

RemoteConstraint

class reahl.component.modelinterface.RemoteConstraint(error_message=None)

A ValidationConstraint which can only be executed on the server. Create a subclass of this class and override validate_input and validate_parsed_value.

Parameters

error_message – (See ValidationConstraint)

RequiredConstraint

class reahl.component.modelinterface.RequiredConstraint(dependency_expression='*', error_message=None)

The presence of this ValidationConstraint on a Field indicates that the Field is required.

Parameters
  • dependency_expression – RequiredConstraint is conditional upon this jquery selector expression matching more than 0 elements. By default this matches all elements, making the RequiredConstraint non-conditional.

  • error_message – (See ValidationConstraint)

Changed in version 5.0: Renamed selector_expression to dependency_expression.

property parameters

Override this property to supply parameters for this ValidationConstraint. Parameters are used by user interface mechanics outside the scope of this module for implementation reasons.

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

EqualToConstraint

class reahl.component.modelinterface.EqualToConstraint(other_field, error_message=None)

A ValidationConstraint that requires the value of its Field to be equal to the value input into other_field.

Parameters
  • other_field – The Field whose value must be equal to the Field to which this ValidationConstraint is attached.

  • error_message – (See ValidationConstraint)

GreaterThanConstraint

class reahl.component.modelinterface.GreaterThanConstraint(other_field, error_message=None)

A ValidationConstraint that requires the value of its Field to be greater than the value input into other_field (the > operator is used for the comparison).

Parameters

SmallerThanConstraint

class reahl.component.modelinterface.SmallerThanConstraint(other_field, error_message=None)

A ValidationConstraint that requires the value of its Field to be smaller than the value input into other_field (the < operator is used for the comparison).

Parameters

MinLengthConstraint

class reahl.component.modelinterface.MinLengthConstraint(min_length, error_message=None)

A ValidationConstraint that requires length of what the user typed to be at least min_length characters long.

Parameters
  • min_length – The minimum allowed length of the input.

  • error_message – (See ValidationConstraint)

property parameters

Override this property to supply parameters for this ValidationConstraint. Parameters are used by user interface mechanics outside the scope of this module for implementation reasons.

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

MaxLengthConstraint

class reahl.component.modelinterface.MaxLengthConstraint(max_length, error_message=None)

A ValidationConstraint that requires length of what the user typed to not be more than max_length characters long.

Parameters
  • max_length – The maximum allowed length of the input.

  • error_message – (See ValidationConstraint)

property parameters

Override this property to supply parameters for this ValidationConstraint. Parameters are used by user interface mechanics outside the scope of this module for implementation reasons.

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

PatternConstraint

class reahl.component.modelinterface.PatternConstraint(pattern, error_message=None)

A ValidationConstraint that requires unparsed input to match the supplied regex.

Parameters
property parameters

Override this property to supply parameters for this ValidationConstraint. Parameters are used by user interface mechanics outside the scope of this module for implementation reasons.

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

AllowedValuesConstraint

class reahl.component.modelinterface.AllowedValuesConstraint(allowed_values, error_message=None)

A PatternConstraint that only allows unparsed input equal to one of a list of allowed_values.

Parameters
  • allowed_values – A list containing the strings values to be allowed.

  • error_message – (See ValidationConstraint)

IntegerConstraint

class reahl.component.modelinterface.IntegerConstraint(error_message=None)

A PatternConstraint that only allows input that represent a valid integer.

Parameters

error_message – (See ValidationConstraint)

validate_input(unparsed_input)

Override this method to provide the custom logic of how this ValidationConstraint should check the given string for validity. If validation fails, this method should raise self.

MinValueConstraint

class reahl.component.modelinterface.MinValueConstraint(min_value, error_message=None)

A ValidationConstraint that requires its parsed input to be greater than or equal to a supplied min_value. (To do the comparison, the >= operator is used on the parsed value.)

Parameters
validate_parsed_value(parsed_value)

Override this method to provide the custom logic of how this ValidationConstraint should check the given Python object after it was created from initial input in string form. If validation fails, this method should raise self.

MaxValueConstraint

class reahl.component.modelinterface.MaxValueConstraint(max_value, error_message=None)

A ValidationConstraint that requires its parsed input to be smaller than or equal to a supplied max_value. (To do the comparison, the <= operator is used on the parsed value.)

Parameters
validate_parsed_value(parsed_value)

Override this method to provide the custom logic of how this ValidationConstraint should check the given Python object after it was created from initial input in string form. If validation fails, this method should raise self.

Events and Actions

Event

class reahl.component.modelinterface.Event(label=None, action=None, readable=None, writable=None, disallowed_message=None, **event_argument_fields)

An Event can be triggered by a user. When an Event occurs, the action of the Event is executed.

Parameters
  • label – (See Field)

  • action – The Action to execute when this Event occurs.

  • readable – (See Field)

  • writable – (See Field)

  • disallowed_message – (See Field)

  • event_argument_fields – Keyword arguments given in order to specify the names of the auirguments this Event should have. The value to each keyword argument is a Field governing input to that Event argument.

from_input(unparsed_input, ignore_validation=False, ignore_access=False)

Sets the value of this Field from the given unparsed_input.

with_arguments(**event_arguments)

Returns a new Event exactly like this one, but with argument values as given.

parse_input(unparsed_input)

Override this method on a subclass to specify how that subclass transforms the unparsed_input (a string) into a representative Python object.

unparse_input(parsed_value)

Override this method on a subclass to specify how that subclass transforms a given Python object (parsed_value) to a string that represents it to a user.

Action

class reahl.component.modelinterface.Action(declared_method, arg_names=[], kwarg_name_map={})

An Action which is supplied to an Event is executed when that Event occurs. Executing the Action means executing its declared_method.

Parameters
  • declared_method – The method to be called when executing this Action.

  • arg_names – A list of the names of Event arguments to send to declared_method as positional arguments (in the order listed).

  • kwarg_name_map – A dictionary specifying which keyword arguments to send to declared_method when called. The dictionary maps each name of an Event argument that needs to be sent to the name of the keyword argument as which it should be sent.

Allowed

class reahl.component.modelinterface.Allowed(allowed)

An Action that always returns the (boolean) value of allowed with which it was constructed.

Not

class reahl.component.modelinterface.Not(action)

An Action which returns the boolean inverse of the result of another action.

SecuredDeclaration

class reahl.component.modelinterface.SecuredDeclaration(read_check=None, write_check=None)

A decorator for marking a method as being @secured. Marking a method as @secured, causes a wrapper to be placed around the original method. The wrapper checks the access rights of the current user before each call to the method to ensure unauthorised users cannot call the wrapped method.

When such a @secured method is used as the declared_method of an Action, the Action derives its access constraints directly from the @secured method.

Parameters
  • read_check – A callable with signature matching that of the @secured method. It should return True to indicate that the current user may be aware of the method, else False. User interface machinery could use this info to determine what to show to a user, what to grey out, or what to hide completely, depending on who the current user is.

  • write_check – A callable with signature matching that of the @secured method. It should return True to indicate that the current user may execute the method, else False.