Code Reference

json_document.document

Document and fragment classes

class json_document.document.Document(value, schema=None)

Class representing a smart JSON document

A document is also a fragment that wraps the entire value. Is inherits all of its properties. There are two key differences: a document has no parent fragment and it holds the revision counter that is incremented on each modification of the document.

revision

Return the revision number of this document.

Each change increments this value by one. You should not really care about the count as sometimes the increments may be not what you expected. It is best to use this to spot difference (if your count is different than mine we’re different).

class json_document.document.DocumentFragment(document, parent, value, item=None, schema=None)

Wrapper around a fragment of a document.

Fragment may wrap a single item (such as None, bool, int, float, string) or to a container (such as list or dict). You can access the value pointed to with the value property.

Each fragment is linked to a parent fragment and the :attr:’document itself. When the parent fragment wraps a list or a dictionary then the index (or key) that this fragment was references as is stored in item. Sometimes this linkage becomes broken and a fragment is considered orphaned. Orphaned fragments still allow you to read the value they wrap but since they are no longer associated with any document you cannot set the value anymore.

Fragment is also optionally associated with a schema (typically the relevant part of the document schema). When schema is available you can validate() a fragment for correctness. If the schema designates a default_value you can revert_to_default() to discard the current value in favour of the one from the schema.

default_value

Get the default value.

Note: This method will raise SchemaError if the default is not defined in the schema

default_value_exists

Returns True if a default value exists for this fragment.

The default value can be accessed with default_value. You can also revert the current value to default by calling revert_to_default().

When there is no default value any attempt to use or access it will raise a SchemaError.

document

The document object (the topmost parent document fragment)

is_default

Check if this fragment points to a default value.

Note

A fragment that points to a value equal to the value of the default is not considered default. Only fragments that were not assigned a value previously are considered default.

is_orphaned

Check if a fragment is orphaned.

Orphaned fragments can occur in this scenario:

>>> doc = Document()
>>> doc["foo"] = "value"
>>> foo = doc["foo"]
>>> doc.value = {}
>>> foo.is_orphaned
True

That is, when the parent fragment value is overwritten.

item

The index of this fragment in the parent collection.

Item is named somewhat misleadingly. It is the name of the index that was used to access this fragment from the parent fragment. Typically this is the dictionary key name or list index.

parent

The parent fragment (if any)

The document root (typically a Document instance) has no parent. If the parent exist then fragment.parent[fragment.item] points back to the same value as fragment but wrapped in a different instance of DocumentFragment.

revert_to_default()

Discard current value and use defaults from the schema.

@raises TypeError: when default value does not exist Revert the value that this fragment points to to the default value.

schema

Schema associated with this fragment

Schema may be None

This is a read-only property. Schema is automatically provided when a sub-fragment is accessed on a parent fragment (all the way up to the document). To provide schema for your fragments make sure to include them in the properties or items. Alternatively you can provide additionalProperties that will act as a catch-all clause allowing you to define a schema for anything that was not explicitly matched by properties.

validate()

Validate the fragment value against the schema

value

Value being wrapped by this document fragment.

Getting reads the value (if not is_default) from the document or transparently returns the default values from the schema (if default_value_exists).

Setting a value instantiates default values in this or any parent fragment. That is, if the value of this fragment or any of the parent fragments is default (is_default returns True), then the default value is copied and used as the effective value instead.

When is_default is True setting any value (including the value of default_value) will overwrite the value so that is_default will return False. If you want to set the default value use revert_to_default() explicitly.

Setting a value that is different from the current value bumps the revision of the whole document.

class json_document.document.DocumentPersistence(document, storage, serializer=None)

Simple glue layer between document and storage:

document <-> serializer <-> storage

You can have any number of persistence instances associated with a single document.

load()

Load the document from the storage layer

save()

Save the document to the storage layer.

The document is only saved if the document was modified since it was last saved. The document revision is non-persistent property (so you cannot use it as a version control system) but as long as the document instance is alive you can optimize saving easily.

Exceptions

exception json_document.errors.DocumentError(document, msg)

Base class for all Document exceptions.

exception json_document.errors.DocumentSyntaxError(document, error)

Syntax error in document

exception json_document.errors.DocumentSchemaError(document, error)

Schema error in document

exception json_document.errors.OrphanedFragmentError(fragment)

Exception raised when an orphaned document fragment is being modified.

A fragment becomes orphaned if a saved reference no longer belongs to any document tree. This can happen when one reverts a document fragment to default value while still holding references do elements of that fragment.

exception json_document.errors.DocumentError(document, msg)

Base class for all Document exceptions.

exception json_document.errors.DocumentSchemaError(document, error)

Schema error in document

exception json_document.errors.DocumentSyntaxError(document, error)

Syntax error in document

exception json_document.errors.OrphanedFragmentError(fragment)

Exception raised when an orphaned document fragment is being modified.

A fragment becomes orphaned if a saved reference no longer belongs to any document tree. This can happen when one reverts a document fragment to default value while still holding references do elements of that fragment.

json_document.serializers

Document serializer classes

class json_document.serializers.JSON

JSON class encapsulates loading and saving JSON files using simplejson module. It handles ‘raw’ json without any of the additions specified in the Document class.

classmethod dump(stream, doc, human_readable=True, sort_keys=False)

Dump JSON to a stream-like object

Discussion:

If human_readable is True the serialized stream is meant to be read by humans, it will have newlines, proper indentation and spaces after commas and colons. This option is enabled by default.

If sort_keys is True then resulting JSON object will have sorted keys in all objects. This is useful for predictable format but is not recommended if you want to load-modify-save an existing document without altering it’s general structure. This option is not enabled by default.

Return value:

None

classmethod dumps(doc, human_readable=True, sort_keys=False)

Dump JSON to a string

Discussion:

If human_readable is True the serialized value is meant to be read by humans, it will have newlines, proper indentation and spaces after commas and colons. This option is enabled by default.

If sort_keys is True then resulting JSON object will have sorted keys in all objects. This is useful for predictable format but is not recommended if you want to load-modify-save an existing document without altering it’s general structure. This option is not enabled by default.

Return value:

JSON document as string

classmethod load(stream, retain_order=True)

Load a JSON document from the specified stream

Discussion:

The document is read from the stream and parsed as JSON text.

Return value:

The document loaded from the stream. If retain_order is True then the resulting objects are composed of ordered dictionaries. This mode is slightly slower and consumes more memory but allows one to save the document exactly as it was before (apart from whitespace differences).

Exceptions:
JSONDecodeError

When the text does not represent a correct JSON document.

classmethod loads(text, retain_order=True)

Same as load() but reads data from a string

exception json_document.serializers.JSONDecodeError(msg, doc, pos, end=None)[source]

Subclass of ValueError with the following additional properties:

msg: The unformatted error message doc: The JSON document being parsed pos: The start index of doc where parsing failed end: The end index of doc where parsing failed (may be None) lineno: The line corresponding to pos colno: The column corresponding to pos endlineno: The line corresponding to end (may be None) endcolno: The column corresponding to end (may be None)

json_document.storage

Storage classes (for storing serializer output)

class json_document.storage.FileStorage(pathname, ignore_missing=False)

File-based storage class.

This class is used in conjunction with DocumentPersistance to bind a Document to a file (via a serializer).

read()

Read all data from the file.

Data is transparently interpreted as UTF-8 encoded Unicode string. If ignore_missing is True and the file does not exist an empty string is returned instead.

write(data)

Write the specified data to the file

The data overwrites anything present in the file earlier. If data is an Unicode object it is automatically converted to UTF-8.

class json_document.storage.IStorage

Interface for storage classes

read()

Read all data from the storage

write(data)

Write data to the storage

json_document.bridge

Collection of decorator methods for accessing document fragments

You want to use those decorators if you are not interested in raw JSON or high-level DocumentFragments (which would require you to access each value via the .value property) but want to offer a pythonic API instead.

json_document.bridge.fragment(func)

Bridge to a document fragment.

The name of the fragment is identical to to the name of the decorated function. The function is never called, it is only used to obtain the docstring.

This is equivalent to:

@property
def foo(self):
    return self['foo']
json_document.bridge.readonly(func)

Read-only bridge to the value of a document fragment.

The name of the fragment is identical to to the name of the decorated function. The function is never called, it is only used to obtain the docstring.

This is equivalent to:

@property
def foo(self):
    return self['foo'].value
json_document.bridge.readwrite(func)

Read-write bridge to the value of a document fragment.

The name of the fragment is identical to to the name of the decorated function. The function is never called, it is only used to obtain the docstring.

This is equivalent to:

@property
def foo(self):
    return self['foo'].value

Followed by:

@foo.setter
def foo(self, new_value):
    return self['foo'] = new_value