Onegov Form API

Core

class onegov.form.core.Form(*args, **kwargs)[source]

Extends wtforms.Form with useful methods and integrations needed in OneGov applications.

Fieldsets

This form supports fieldsets (which WTForms doesn’t recognize). To put fields into a fieldset, add a fieldset attribute to the field during class definition:

class MyForm(Form):
    first_name = StringField('First Name', fieldset='Name')
    last_name = StringField('Last Name', fieldset='Name')
    comment = StringField('Comment')

A form created like this will have two fieldsets, one visible fieldset with the legend set to ‘Name’ and one invisible fieldset containing ‘comment’.

Fieldsets with the same name are not automatically grouped together. Instead, fields are taken in the order they are defined and put into the same fieldset, if the previous fieldset has the same name.

That is to say, in this example, we get three fieldsets:

class MyForm(Form):
    a = StringField('A', fieldset='1')
    b = StringField('B', fieldset='2')
    c = StringField('C', fieldset='1')

The first fieldset has the label ‘1’ and it contains ‘a’. The second fieldset has the label ‘2’ and it contains ‘b’. The third fieldset has the label ‘3’ and it contains ‘c’.

This ensures that all fields are in either a visible or an invisible fieldset (see Fieldset.is_visible()).

Dependencies

This form also supports dependencies. So field b may depend on field a, if field a has a certain value, field b is shown on the form (with some javascript) and its validators are actually executed. If field a does not have the required value, field b is hidden with javascript and its validators are not executed.

The validators which are skipped are only the validators passed with the field, the validators on the field itself are still invoked (we can’t skip them). However, only if the optional field is not empty. That is we prevent invalid values no matter what, but we allow for empty values if the dependent field does not have the required value.

This sounds a lot more complicated than it is:

class MyForm(Form):

    option = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No'),
    ])
    only_if_no = StringField(
        label='Only Shown When No',
        validators=[InputRequired()],
        depends_on=('option', 'no')
    )

Pricing

Pricing is a way to attach prices to certain form fields. A total price is calcualted depending on the selections the user makes:

class MyForm(Form):

    ticket_insurance = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No')
    ], pricing={
        'yes': (10.0, 'CHF')
    })

    discount_code = TextField('Discount Code', pricing={
        'CAMPAIGN2017': (-5.0, 'CHF')
    })

Note that the pricing has no implicit meaning. This is simply a way to attach prices and to get the total through the prices() and total() calls. What you do with these prices is up to you.

classmethod clone()[source]

Creates an independent copy of the form class.

The fields of the so called class may be manipulated without affecting the original class.

process_fieldset()[source]

Processes the fieldset parameter on the fields, which puts fields into fieldsets.

In the process the fields are altered so that wtforms recognizes them again (that is, attributes only known to us are removed).

See Form for more information.

process_depends_on()[source]

Processes the depends_on parameter on the fields, which adds the ability to have fields depend on values of other fields.

Supported are dependencies to boolean fields and choices. Search the source code for depends_on for plenty of examples.

For checkboxes, note that the value is ‘y’ (string) or ‘!y’ for the inverse.

In the process the fields are altered so that wtforms recognizes them again (that is, attributes only known to us are removed).

See Form for more information.

process_pricing()[source]

Processes the pricing parameter on the fields, which adds the ability to have fields associated with a price.

See Form for more information.

render_display(field)[source]

Renders the given field for display (no input). May be overwritten by descendants to return different html, or to return None.

If None is returned, the field is not rendered.

is_visible_through_dependencies(field_id)[source]

Returns true if the given field id has visible because all of it’s parents are visible. A field is invisible if its dependency is not met.

is_hidden(field)[source]

True if the given field should be hidden. The effect of this is left to the application (it might not render the field, or add a class which hides the field).

hide(field)[source]

Marks the given field as hidden.

show(field)[source]

Marks the given field as visibile.

prices()[source]

Returns the prices of all selected items depending on the formdata.

total()[source]

Returns the total amount of all prices.

submitted(request)[source]

Returns true if the given request is a successful post request.

ignore_csrf_error()[source]

Removes the csrf error from the form if found, after validation.

Use this only if you know what you are doing (really, never).

property has_required_email_field

Returns True if the form has a required e-mail field.

property title_fields

Fields used to generate a title.

match_fields(include_classes=None, exclude_classes=None, required=None, limit=None)[source]

Returns field ids matching the given search criteria.

Include_classes

A list of field classes which should be included.

Excluded_classes

A list of field classes which should be excluded.

Required

True if required fields only, False if no required fields.

Limit

If > 0, limits the number of returned elements.

All parameters may be set to None disable matching it to anything.

is_required(field_id)[source]

Returns true if the given field_id is required.

get_useful_data(exclude={'csrf_token'})[source]

Returns the form data in a dictionary, by default excluding data that should not be stored in the db backend.

populate_obj(obj, exclude=None, include=None)[source]

A reimplementation of wtforms populate_obj function with the addage of optional include/exclude filters.

If neither exclude nor include is passed, the function works like it does in wtforms. Otherwise fields are considered which are included but not excluded.

process(*args, **kwargs)[source]

Calls process_obj() if process() was called with the obj keyword argument.

This saves an extra check in many cases where we want to extend the process function, but only if an obj has been provided.

process_obj(obj)[source]

Called by process() if an object was passed.

Do not use this function directly. To process an object, you should call form.process(obj=obj) instead.

delete_field(fieldname)[source]

Removes the given field from the form and all the fieldsets.

validate()[source]

Adds support for ‘ensurances’ to the form. An ensurance is a method which is called during validation when all the fields have been populated. Therefore it is a good place to validate against multiple fields.

All methods which start with ensure_ are ensurances. If and only if an ensurance returns False it is considered to have failed. In this case the validate method returns False as well. If None or ‘’ or any other falsy value is returned, no error is assumed! This avoids having to return an extra True at the end of each ensurance.

When one ensurance fails, the others are still run. Also, there’s no error display mechanism. Showing an error is left to the ensurance itself. It can do so by adding messages to the various error lists of the form or by showing an alert through the request.

property ensurances

Returns the ensurances that need to be checked when validating.

This property may be overridden if only a subset of all ensurances should actually be enforced.

class onegov.form.core.Fieldset(label, fields)[source]

Defines a fieldset with a list of fields.

property non_empty_fields

Returns only the fields which are not empty.

class onegov.form.core.FieldDependency(*kwargs)[source]

Defines a dependency to a field. The given field(s) must have the given choice for this dependency to be fulfilled.

It’s possible to depend on NOT the given value by preceeding it with a ‘!’:

FieldDependency(‘field_1’, ‘!choice_1’)

To depend on more than one field, add the field_id’s and choices to the constructor:

FieldDependency(‘field_1’, ‘choice_1’) FieldDependency(‘field_1’, ‘choice_1’, ‘field_2’, ‘choice_2’)

class onegov.form.core.Pricing(rules)[source]

Defines pricing on a field, returning the correct price for the field depending on its rule.

onegov.form.core.merge_forms(*forms)[source]

Takes a list of forms and merges them.

In doing so, a new class is created which inherits from all the forms in the default method resolution order. So the first class will override fields in the second class and so on.

So this method is basically the same as:

class Merged(*forms):

pass

With one crucial difference, the order of the fields is as follows:

First, the fields from the first form are rendered, then the fields from the second form and so on. This is not the case if you merge the forms by simple class inheritance, as each form has it’s own internal field order, which when merged leads to unexpected results.

onegov.form.core.enforce_order(form_class, fields_in_order)[source]

Takes a list of fields used in a form_class and enforces the order of those fields.

If not all fields in the form are given, the resulting order is undefined.

onegov.form.core.move_fields(form_class, fields, after)[source]

Reorders the given fields (given by name) by inserting them directly after the given field.

If after is None, the fields are moved to the end.

Models

class onegov.form.models.FormDefinition(**kwargs)[source]

Defines a form stored in the database.

name

the name of the form (key, part of the url)

title

the title of the form

definition

the form as parsable string

group

the group to which this resource belongs to (may be any kind of string)

order

The normalized title for sorting

checksum

the checksum of the definition, forms and submissions with matching checksums are guaranteed to have the exact same definition

type

the type of the form, this can be used to create custom polymorphic subclasses. See http://docs.sqlalchemy.org/en/improve_toc/orm/extensions/declarative/inheritance.html.

submissions

link between forms and submissions

registration_windows

link between forms and registration windows

current_registration_window

the currently active registration window

this sorts the registration windows by the smaller k-nearest neighbour result of both start and end in relation to the current date

the result is the nearest date range in relation to today: * during an active registration window, it’s that active window * outside of active windows, it’s last window half way until

the next window starts

this could of course be done more conventionally, but this is cooler 😅

lead = None

lead text describing the form

text = None

content associated with the form

payment_method

payment options (‘manual’ for out of band payments without cc, ‘free’ for both manual and cc payments, ‘cc’ for forced cc payments)

property form_class

Parses the form definition and returns a form class.

class onegov.form.models.FormSubmission(**kwargs)[source]

Defines a submitted form in the database.

id

id of the form submission

name

name of the form this submission belongs to

title

the title of the submission, generated from the submitted fields NULL for submissions which are not complete

definition

the source code of the form at the moment of submission. This is stored alongside the submission as the original form may change later. We want to keep the old form around just in case.

received

the exact time this submissions was changed from ‘pending’ to ‘complete’

checksum

the checksum of the definition, forms and submissions with matching checksums are guaranteed to have the exact same definition

meta

metadata about this submission

data

the submission data

state

the state of the submission

spots

the number of spots this submission wants to claim (only relevant if there’s a registration window)

claimed

the number of spots this submission has actually received None => the decision if spots should be given is still open 0 => the decision was negative, no spots were given 1-x => the decision was positive, at least some spots were given

registration_window_id

the registration window linked with this submission

payment_method

payment options -> copied from the dfinition at the moment of submission. This is stored alongside the submission as the original form setting may change later.

property payable_reference

A string which identifies this payable in payment lists. Do not join any values here as it can lead to an explosion of executed queries!

By default we use the table name plus a hash derived from the primary key values of the table. This ensures that we do not accidentally leak secrets.

In practice, this reference should be customised for each payable.

property form_class

Parses the form definition and returns a form class.

property form_obj

Returns a form instance containing the submission data.

process_payment(price, provider=None, token=None)[source]

Takes a request, optionally with the provider and the token by the provider that can be used to charge the credit card and creates a payment record if necessary.

Returns True or a payment object if the payment was processed successfully. That is, if there is a payment or if there is no payment required the method returns truthy.

claim(spots=None)[source]

Claimes the given number of spots (defaults to the requested number of spots).

disclaim(spots=None)[source]

Disclaims the given number of spots (defaults to all spots that were claimed so far).

class onegov.form.models.PendingFormSubmission(**kwargs)[source]
class onegov.form.models.CompleteFormSubmission(**kwargs)[source]
class onegov.form.models.FormFile(**kwargs)[source]
class onegov.form.models.FormRegistrationWindow(**kwargs)[source]

Defines a registration window during which a form definition may be used to create submissions.

Submissions created thusly are attached to the currently active registration window.

Registration windows may not overlap.

id

the public id of the registraiton window

name

the name of the form to which this registration window belongs

enabled

true if the registration window is enabled

start

the start date of the window

end

the end date of the window

timezone

the timezone of the window

limit

the number of spots (None => unlimited)

overflow

enable an overflow of submissions

submissions

submissions linked to this

disassociate()[source]

Disassociates all records linked to this window.

property claimed_spots

Returns the number of actually claimed spots.

property requested_spots

Returns the number of requested spots.

When the claim has not been made yet, spots are counted as requested. When the claim has been partially made, the difference is counted as requested. If the claim has been fully made, the result is 0. If the claim has been relinquished, the result is 0.

property next_submission

Returns the submission next in line. In other words, the next submission in order of first come, first serve.

Collection

class onegov.form.collection.FormCollection(session)[source]

Manages a collection of forms and form-submissions.

get_definitions_with_submission_count()[source]

Returns all form definitions and the number of submissions belonging to those definitions, in a single query.

The number of submissions is stored on the form definition under the submissions_count attribute.

Only submissions which are ‘complete’ are considered.

class onegov.form.collection.FormDefinitionCollection(session)[source]

Manages a collection of forms.

add(title, definition, type=None, meta=None, content=None, name=None, payment_method='manual')[source]

Add the given form to the database.

delete(name, with_submissions=False)[source]

Delete the given form. Only possible if there are no submissions associated with it, or if with_submissions is True.

Note that pending submissions are removed automatically, only complete submissions have a bearing on with_submissions.

by_name(name)[source]

Returns the given form by name or None.

class onegov.form.collection.FormSubmissionCollection(session, name=None)[source]

Manages a collection of submissions.

add(name, form, state, id=None, payment_method=None, meta=None, email=None, spots=None)[source]

Takes a filled-out form instance and stores the submission in the database. The form instance is expected to have a _source parameter, which contains the source used to build the form (as only forms with this source may be stored).

This method expects the name of the form definition stored in the database. Use add_external() to add a submissions whose definition is not stored in the form_definitions table.

add_external(form, state, id=None, payment_method=None, meta=None, email=None)[source]

Takes a filled-out form instance and stores the submission in the database. The form instance is expected to have a _source parameter, which contains the source used to build the form (as only forms with this source may be stored).

In contrast to add(), this method is meant for submissions whose definition is not stored in the form_definitions table.

complete_submission(submission)[source]

Changes the state to ‘complete’, if the data is valid.

update(submission, form, exclude=None)[source]

Takes a submission and a form and updates the submission data as well as the files stored in a spearate table.

remove_old_pending_submissions(older_than, include_external=False)[source]

Removes all pending submissions older than the given date. The date is expected to be in UTC!

by_name(name)[source]

Return all submissions for the given form-name.

by_id(id, state=None, current_only=False)[source]

Return the submission by id.

State

Only if the submission matches the given state.

Current_only

Only if the submission is not older than one hour.

delete(submission)[source]

Deletes the given submission and all the files belonging to it.

Display

Contains renderers to display form fields.

onegov.form.display.render_field(field)

Renders the given field with the correct renderer.

Fields

class onegov.form.fields.MultiCheckboxField(*args, **kwargs)[source]
class onegov.form.fields.OrderedMultiCheckboxField(*args, **kwargs)[source]
class onegov.form.fields.UploadField(label=None, validators=None, filters=(), description='', id=None, default=None, widget=None, render_kw=None, _form=None, _name=None, _prefix='', _translations=None, _meta=None)[source]

A custom file field that turns the uploaded file into a compressed base64 string together with the filename, size and mimetype.

process_formdata(valuelist)[source]

Process data received over the wire from a form.

This will be called during form construction with data supplied through the formdata argument.

Parameters

valuelist – A list of strings to process.

class onegov.form.fields.UploadFileWithORMSupport(*args, **kwargs)[source]

Extends the upload field with onegov.file support.

populate_obj(obj, name)[source]

Populates obj.<name> with the field’s data.

Note

This is a destructive operation. If obj.<name> already exists, it will be overridden. Use with caution.

process_data(value)[source]

Process the Python data applied to this field and store the result.

This will be called during form construction by the form’s kwargs or obj argument.

Parameters

value – The python object containing the value to process.

class onegov.form.fields.HtmlField(*args, **kwargs)[source]

A textfield with html with integrated sanitation.

pre_validate(form)[source]

Override if you need field-level validation. Runs before any other validators.

Parameters

form – The form the field belongs to.

class onegov.form.fields.TagsField(label=None, validators=None, filters=(), description='', id=None, default=None, widget=None, render_kw=None, _form=None, _name=None, _prefix='', _translations=None, _meta=None)[source]

A tags field for use in conjunction with this library:

https://github.com/developit/tags-input

process_formdata(valuelist)[source]

Process data received over the wire from a form.

This will be called during form construction with data supplied through the formdata argument.

Parameters

valuelist – A list of strings to process.

process_data(value)[source]

Process the Python data applied to this field and store the result.

This will be called during form construction by the form’s kwargs or obj argument.

Parameters

value – The python object containing the value to process.

class onegov.form.fields.IconField(label=None, validators=None, filters=(), description='', id=None, default=None, widget=None, render_kw=None, _form=None, _name=None, _prefix='', _translations=None, _meta=None)[source]

Selects an icon out of a number of icons.

class onegov.form.fields.PhoneNumberField(*args, **kwargs)[source]

A string field with support for phone numbers.

class onegov.form.fields.ChosenSelectField(label=None, validators=None, coerce=<class 'str'>, choices=None, **kwargs)[source]

A select field with chosen.js support.

class onegov.form.fields.ChosenSelectMultipleField(label=None, validators=None, coerce=<class 'str'>, choices=None, **kwargs)[source]

A multiple select field with chosen.js support.

class onegov.form.fields.PreviewField(*args, **kwargs)[source]
populate_obj(obj, name)[source]

Populates obj.<name> with the field’s data.

Note

This is a destructive operation. If obj.<name> already exists, it will be overridden. Use with caution.

class onegov.form.fields.TimezoneDateTimeField(*args, **kwargs)[source]

A datetime field data returns the date with the given timezone and expects dateime values with a timezone.

Used together with onegov.core.orm.types.UTCDateTime.

process_data(value)[source]

Process the Python data applied to this field and store the result.

This will be called during form construction by the form’s kwargs or obj argument.

Parameters

value – The python object containing the value to process.

process_formdata(valuelist)[source]

Process data received over the wire from a form.

This will be called during form construction with data supplied through the formdata argument.

Parameters

valuelist – A list of strings to process.

Widgets

class onegov.form.widgets.OrderedListWidget(html_tag='ul', prefix_label=True)[source]

Extends the default list widget with automated ordering using the translated text of each element.

class onegov.form.widgets.MultiCheckboxWidget(*args, **kwargs)[source]

The default list widget with the label behind the checkbox.

class onegov.form.widgets.OrderedMultiCheckboxWidget(*args, **kwargs)[source]

The sorted list widget with the label behind the checkbox.

class onegov.form.widgets.CoordinateWidget(input_type=None)[source]

Widget containing the coordinates for the onegov.form.fields.CoordinateField class.

Basically a text input with a class. Meant to be enhanced on the browser using javascript.

class onegov.form.widgets.UploadWidget(multiple=False)[source]

An upload widget for the onegov.form.fields.UploadField class, which supports keeping, removing and replacing already uploaded files.

This is necessary as file inputs are read-only on the client and it’s therefore rather easy for users to lose their input otherwise (e.g. a form with a file is rejected because of some mistake - the file disappears once the response is rendered on the client).

image_source(field)[source]

Returns the image source url if the field points to an image and if it can be done (it looks like it’s possible, but I’m not super sure this is always possible).

class onegov.form.widgets.TagsWidget(input_type=None)[source]
class onegov.form.widgets.IconWidget(input_type=None)[source]
class onegov.form.widgets.ChosenSelectWidget(multiple=False)[source]
class onegov.form.widgets.PreviewWidget[source]

A widget that displays the html of a specific view whenver there’s a change in other fields. JavaScript is used to facilitate this.

Validators

class onegov.form.validators.Stdnum(format)[source]

Validates a string using any python-stdnum format.

See https://github.com/arthurdejong/python-stdnum.

class onegov.form.validators.FileSizeLimit(max_bytes)[source]

Makes sure an uploaded file is not bigger than the given number of bytes.

Expects an onegov.form.fields.UploadField instance.

class onegov.form.validators.WhitelistedMimeType(whitelist=None)[source]

Makes sure an uploaded file is in a whitelist of allowed mimetypes.

Expects an onegov.form.fields.UploadField instance.

class onegov.form.validators.ExpectedExtensions(extensions)[source]

Makes sure an uploaded file has one of the expected extensions. Since extensions are not something we can count on we look up the mimetype of the extension and use that to check.

Expects an onegov.form.fields.UploadField instance.

Usage:

ExpectedFileType('*')  # no check, really
ExpectedFileType('pdf')  # makes sure the given file is a pdf
class onegov.form.validators.ValidFormDefinition(require_email_field=True, reserved_fields=None, require_title_fields=False)[source]

Makes sure the given text is a valid onegov.form definition.

class onegov.form.validators.StrictOptional(strip_whitespace=True)[source]

A copy of wtform’s Optional validator, but with a more strict approach to optional validation checking.

See https://github.com/wtforms/wtforms/issues/350

class onegov.form.validators.ValidPhoneNumber(country='CH')[source]

Makes sure the given input is valid phone number.

Expects an wtforms.StringField instance.

class onegov.form.validators.UniqueColumnValue(table)[source]

Test if the given table does not already have a value in the column (identified by the field name).

If the form provides a model with such an attribute, we allow this value, too.

Usage:

username = StringField(validators=[UniqueColumnValue(User)])
class onegov.form.validators.InputRequiredIf(field_name, field_data, message=None, **kwargs)[source]

Validator which makes a field required if another field is set and has the given value.

Parser

onegov.form includes it’s own markdownish form syntax, inspired by https://github.com/maleldil/wmd

The goal of this syntax is to enable the creation of forms through the web, without having to use javascript, html or python code.

Also, just like Markdown, we want this syntax to be readable by humans.

How it works

Internally, the form syntax is converted into a YAML file, which is in turn parsed and turned into a WTForms class. We decided to go for the intermediate YAML file because it’s easy to define a Syntax which correctly supports indentation. Our pyparsing approach was flimsy at best.

Parser Errors

There’s currently no sophisticated error check. It’s possible that the parser misunderstand something you defined without warning. So be careful to check that what you wanted was actually what you got.

Syntax

Fields

Every field is identified by a label, an optional ‘required’ indicator and a field definition. The Label can be any kind of text, not including * and =. The * indicates that a field is required. The = separates the identifier from the definition.

A required field starts like this:

My required field * =

An optional field starts like this:

My optional field =

Following the identifier is the field definition. For example, this defines a textfield:

My textfield = ___

All possible fields are documented further below.

Fieldsets

Fields are grouped into fieldsets. The fieldset of a field is the fieldset that was last defined:

# Fieldset 1
I belong to Fieldset 1 = ___

# Fieldset 2
I belong to Fieldset 2 = ___

If no fieldset is defined, the fields don’t belong to a fieldset. To stop putting fields in a fieldset, define an empty fieldeset:

# Fieldset 1
I belong to Fieldset 1 = ___

# ...
I don't belong to a Fieldset = ___

Available Fields

Textfield

A textfield consists of exactly three underscores:

I'm a textfield = ___

If the textfield is limited in length, the length can be given:

I'm a limited textfield = ___[50]

The length of such textfields is validated.

Additionally, textfields may use regexes to validate their contents:

I'm a numbers-only textfield = ___/^[0-9]+$

You can combine the length with a regex, though you probably don’t want to:

I'm a length-limited numbers-only textfield = ___[4]/^[0-9]+$

This could be simplified as follows:

I’m a length-limited numbers-only textfield = ___/^[0-9]{0,4}$

Note that you don’t need to specify the beginning (^) and the end ($) of the string, but not doing so might result in unexpected results. For example, while ‘123abc’ is invalid for ___/^[0-9]+$, it is perfectly valid for ___/[0-9]+. The latter only demands that the text starts with a number, not that it only consists of numbers!

Textarea

A textarea has no limit and consists of exactly three dots:

I'm a textarea = ...

Optionally, the number of rows can be passed to the field. This changes the way the textarea looks, not the way it acts:

I'm a textarea with 10 rows = ...[10]
Password

A password field consists of exactly three stars:

I'm a password = ***
E-Mail

An e-mail field consists of exactly three @:

I'm an e-mail field = @@@
URL

An url field consists of the http/https prefix:

I'm an url field = http://
I'm the exact same = https://

Whether or not you enter http or https has no bearing on the validation.

Date

A date (without time) is defined by this exact string: YYYY.MM.DD:

I'm a date field = YYYY.MM.DD

Note that this doesn’t mean that the date format can be influenced.

Datetime

A date (with time) is defined by this exact string: YYYY.MM.DD HH:MM:

I'm a datetime field = YYYY.MM.DD HH:MM

Again, this doesn’t mean that the datetime format can be influenced.

Time

A Time is defined by this exact string: HH:MM:

I'm a time field = HH:MM

One more time, this doesn’t mean that the datetime format can be influenced.

Numbers

There are two types of number fields. An integer and a float field:

I'm an integer field = 0..99
I'm an integer field of a different range = -100..100

I'm a float field = 0.00..99.00
I'm an float field of a different range = -100.00..100.00
Code

To write code in a certain syntax, use the following:

Description = <markdown>

Currently, only markdown is supported.

Files

A file upload is defined like this:

I'm a file upload field = *.*

This particular example would allow any file. To allow only certain files do something like this:

I'm a image filed = *.png|*.jpg|*.gif
I'm a document = *.doc
I'm any document = *.doc|*.pdf

The files are checked against their file extension. Onegov.form also checks that uploaded files have the mimetype they claim to have and it won’t accept obviously dangerous uploads like binaries (unless you really want to).

Standard Numbers

onegov.form uses python-stdnum to offer a wide range of standard formats that are guaranteed to be validated.

To use, simply use a #, followed by the stdnum format to use:

I'm a valid IBAN (or empty) = # iban
I'm a valid IBAN (required) * = # iban

The format string after the # must be importable from stdnum. In other words, this must work, if you are using ch.ssn (to use an example):

$ python
>>> from stdnum.ch import ssn

This is a bit of an advanced feature and since it delegates most work to an external library there’s no guarantee that a format once used may be reused in the future.

Still, the library should be somewhat stable and the benefit is huge.

To see the available format, have a look at the docs: http://arthurdejong.org/python-stdnum/doc/1.1/index.html#available-formats

Radio Buttons

Radio button fields consist of x radio buttons, out of which one may be preselected. Radio buttons need to be indented on the lines after the definition:

Gender =
    ( ) Female
    ( ) Male
    (x) I don't want to say

Radio buttons also have the ability to define optional form parts. Those parts are only shown if a question was answered a certain way.

Form parts are properly nested if they lign up with the label above them.

For example:

Delivery Method =
    ( ) Pickup
        Pickup Time * = ___
    (x) Address
        Street * = ___
        Town * = ___

Here, the street and the town only need to be provided, if the delivery method is ‘Address’. If the user selects a different option, the fields are not shown and they will not be required.

On the other hand, if ‘Pickup’ is selected, the ‘Pickup Time’ needs to be filled out and the address options are hidden.

This kind of nesting may continue ad infinitum. Meaning you can nest radio buttons as deeply as you like. Note however, that this is discouraged and that your users will not be too happy if you present them with a deeply nested form.

More than one level of nesting is a clear indicator that your form is too complex.

Checkboxes

Checkboxes work exactly like radio buttons, just that you can select multiple fields:

Extras =
    [x] Phone insurance
    [ ] Phone case
    [x] Extra battery

Just like radiobuttons, checkboxes may be nested to created dependencies:

Additional toppings =
    [ ] Salami
    [ ] Olives
    [ ] Other
        Description = ___
Pricing Information

Radio buttons and checkboxes may be priced. For example, the following order form can be modeled:

Node Size =
    ( ) Small (20 USD)
    (x) Medium (30 USD)
    ( ) Large (40 USD)

Extras =
    [x] Second IP Address (20 CHF)
    [x] Backup (20 CHF)

The additional pricing metadata can be used to provide simple order forms. As in any other form, dependencies are taken into account.

class onegov.form.parser.core.CustomLoader(stream)[source]

Extends the default yaml loader with customized constructors.

class onegov.form.parser.core.constructor(tag)[source]

Adds decorated functions to as constructors to the CustomLoader.

class onegov.form.parser.core.Fieldset(label, fields=None)[source]

Represents a parsed fieldset.

class onegov.form.parser.core.Choice(key, label, selected=False, fields=None)[source]

Represents a parsed choice.

Note: Choices may have child-fields which are meant to be shown to the user if the given choice was selected.

class onegov.form.parser.core.Field(label, required, parent=None, fieldset=None, **kwargs)[source]

Represents a parsed field.

class onegov.form.parser.core.PasswordField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.EmailField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.UrlField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.DateField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.DatetimeField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.TimeField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.TextField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.TextAreaField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.CodeField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.StdnumField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.IntegerRangeField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.DecimalRangeField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.FileinputField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.RadioField(label, required, parent=None, fieldset=None, **kwargs)[source]
class onegov.form.parser.core.CheckboxField(label, required, parent=None, fieldset=None, **kwargs)[source]
onegov.form.parser.core.parse_formcode(formcode)[source]

Takes the given formcode and returns an intermediate representation that can be used to generate forms or do other things.

onegov.form.parser.core.parse_field_block(field_block, field_classes, used_ids, fieldset, parent=None)[source]

Takes the given parsed field block and yields the fields from it

onegov.form.parser.core.match(expr, text)[source]

Returns true if the given parser expression matches the given text.

onegov.form.parser.core.try_parse(expr, text)[source]

Returns the result of the given parser expression and text, or None.

onegov.form.parser.core.prepare(text)[source]

Takes the raw form source and prepares it for the translation into yaml.

onegov.form.parser.core.ensure_a_fieldset(lines)[source]

Makes sure that the given lines all belong to a fieldset. That means adding an empty fieldset before all lines, if none is found first.

onegov.form.parser.core.translate_to_yaml(text)[source]

Takes the given form text and constructs an easier to parse yaml string.

onegov.form.parser.grammar.text_without(characters)[source]

Returns all printable text without the given characters.

onegov.form.parser.grammar.matches(character)[source]

Returns true if the given character matches the token.

onegov.form.parser.grammar.literal(text)[source]

” Returns the given value, ignoring the tokens alltogether.

onegov.form.parser.grammar.as_int(tokens)[source]

Converts the token to int if possible.

onegov.form.parser.grammar.as_joined_string(tokens)[source]

Joins the given tokens into a single string.

onegov.form.parser.grammar.as_decimal(tokens)[source]

Converts the token to decimal if possible.

onegov.form.parser.grammar.as_uppercase(tokens)[source]

Converts the token to uppercase if possible.

onegov.form.parser.grammar.as_integer_range(tokens)[source]

Converts the token to an integer range if possible.

onegov.form.parser.grammar.as_decimal_range(tokens)[source]

Converts the token to a decimal range if possible.

onegov.form.parser.grammar.as_regex(tokens)[source]

Converts the token to a working regex if possible.

onegov.form.parser.grammar.unwrap(tokens)[source]

Unwraps grouped tokens.

onegov.form.parser.grammar.tag(**tags)[source]

Takes the given tags and applies them to the token.

onegov.form.parser.grammar.with_whitespace_inside(expr)[source]

Returns an expression that allows for whitespace inside, but not outside the expression.

onegov.form.parser.grammar.enclosed_in(expr, characters)[source]

Wraps the given expression in the given characters.

onegov.form.parser.grammar.number_enclosed_in(characters)[source]

Wraps numers in the given characters, making sure the result is an int.

onegov.form.parser.grammar.choices_enclosed_in(characters, choices)[source]

Wraps the given choices in the given characters, making sure only valid choices are possible.

onegov.form.parser.grammar.mark_enclosed_in(characters)[source]

Returns a mark (x) inclosed in the given characters. For example, mark_enclosed_in('[]') creates an expression that accepts any of these and sets the result of the ‘x’ value to True, the others to False:

[x]
[ ]
onegov.form.parser.grammar.textfield()[source]

Returns a textfield parser.

Example:

____[50]

The number defines the maximum length.

Additionally, a regex may be specified to validate the field:

___/[0-9]{4}
onegov.form.parser.grammar.textarea()[source]

Returns a textarea parser.

Example:

...[5]

The number defines the number of rows.

onegov.form.parser.grammar.code()[source]

Returns a code textfield with a specified syntax.

Currently only markdown is supported.

Example:

<markdown>
onegov.form.parser.grammar.password()[source]

Returns a password field parser.

Example:

***
onegov.form.parser.grammar.email()[source]

Returns an email field parser.

Example:

@@@
onegov.form.parser.grammar.url()[source]

Returns an url field parser.

Example:

http://
https://
onegov.form.parser.grammar.date()[source]

Returns a date parser.

Example:

YYYY.MM.DD
onegov.form.parser.grammar.datetime()[source]

Returns a datetime parser.

Example:

YYYY.MM.DD HH:MM
onegov.form.parser.grammar.time()[source]

Returns a time parser.

Example:

HH:MM
onegov.form.parser.grammar.stdnum()[source]

Returns an stdnum parser.

Example:

# iban
onegov.form.parser.grammar.fileinput()[source]

Returns a fileinput parser.

For all kindes of files::

.

For specific files:

.pdf|.doc

onegov.form.parser.grammar.decimal()[source]

Returns a decimal parser.

Decimal point is ‘.’.

For example:

0.00 123 11.1 -10.0

onegov.form.parser.grammar.range_field(value_expression, parse_action, type)[source]

Generic range field parser.

onegov.form.parser.grammar.integer_range_field()[source]

Returns an integer range parser.

onegov.form.parser.grammar.decimal_range_field()[source]

Returns a decimal range parser.

onegov.form.parser.grammar.currency()[source]

Returns a currency parser.

For example:

chf USD Cny

onegov.form.parser.grammar.marker_box(characters)[source]

Returns a marker box:

Example:

(x) Male
[x] Female
{x} What?
onegov.form.parser.grammar.radio()[source]

Returns a radio parser:

Example::

(x) Male ( ) Female

onegov.form.parser.grammar.checkbox()[source]

Returns a checkbox parser:

Example::

[x] Male [ ] Female

onegov.form.parser.grammar.fieldset_title()[source]

A fieldset title parser. Fieldset titles are just like headings in markdown:

# My header

It’s possible to have an empty fieldset title (to disable a fieldset):

# …

onegov.form.parser.grammar.field_identifier()[source]

Returns a field identifier parser:

Example:

My field *

Errors

exception onegov.form.errors.FormError[source]
exception onegov.form.errors.DuplicateLabelError(label)[source]
exception onegov.form.errors.InvalidMimeType[source]
exception onegov.form.errors.UnableToComplete[source]
exception onegov.form.errors.InvalidFormSyntax(line)[source]