Serializing Nettlesome Data
Nettlesome relies on Marshmallow for dumping and loading data (also known as “serializing and deserializing”). These methods will convert Nettlesome objects back and forth from a JSON format that can be easily transmitted over the web.
Loading JSON Data
When loading data from a JSON string or from a Python dictionary,
Nettlesome’s data schemas will apply some validation to check that the
data has the right fields, and then load a Nettlesome object such as a
Predicate
,
Statement
,
or Assertion
. Here’s an example of
creating a Predicate from a JSON string.
First, create a schema by making an instance of the schema class named for the type of object you want to create. (The syntax for making an instance of a class is the class name followed by a pair of parentheses.)
>>> from nettlesome.schemas import PredicateSchema
>>> schema = PredicateSchema()
If we were loading an object from a Python dictionary, we would use the
load()
method. But when we load from a JSON string, we use
loads()
. (The extra ‘s’ at the end means ‘string’.)
>>> json_string = """{"content": "$defendant stole ${victim}'s car","truth": false}"""
>>> predicate = schema.loads(json_string)
>>> predicate
Predicate(template='$defendant stole ${victim}'s car', truth=False)
>>> str(predicate)
"it was false that $defendant stole ${victim}'s car"
Note that Predicate
and Comparison
both share
the PredicateSchema
schema, because
Comparison is a subclass of Predicate.
>>> data = {"content": "the size of the farm was", "sign": ">", "expression": "20 acres"}
>>> comparison = schema.load(data)
>>> comparison
Comparison(template='the size of the farm was', truth=True, quantity_range=UnitRange(quantity="20 acre", sign=">", include_negatives=False))
>>> str(comparison)
'that the size of the farm was greater than 20 acre'
Generating Schema Documentation
Nettlesome can use the
apispec library to
automatically generate
OpenAPI documentation
of what fields need to be passed to a schema to create a Nettlesome
object. To use this feature, pass the Schema class you want to document
to the make_spec
function.
>>> from nettlesome import make_spec
>>> spec = make_spec(PredicateSchema)
>>> print(spec)
<apispec.core.APISpec object at 0x7fa4ad641a30>
To actually read the schema specification, either use the to_dict()
method to get the specification as a Python object or use the
to_yaml()
method to see it in the less cluttered YAML format.
>>> print(spec.to_yaml())\
components:
schemas:
Predicate:
properties:
content:
type: string
expression:
default: null
nullable: true
sign:
default: null
enum:
- ''
- '>='
- ==
- '!='
- <=
- <>
- '>'
- <
nullable: true
type: string
truth:
default: true
type: boolean
type: object
info:
description: Metadata tags designed for semantic comparisons
title: Nettlesome API Specification
version: 0.1.0
openapi: 3.0.2
paths: {}
Dumping Objects to JSON
When you’re ready to take data out of a Nettlesome object, you can
either use dump()
to convert it to a basic Python dictionary, or use
dumps()
to convert it directly to a JSON string. Here’s an example of
creating a Nettlesome Assertion
object using Python, but then converting
it to JSON.
>>> from nettlesome import Assertion, Statement, Entity
>>> fact = Statement(predicate="$suspect stole bread", terms=Entity(name="Valjean"))
>>> accusation = Assertion(statement=fact, authority=Entity(name="Javert"))
>>> print(accusation)
the assertion, by <Javert>, of the statement that <Valjean> stole bread
>>> from nettlesome.schemas import AssertionSchema
>>> schema = AssertionSchema()
>>> schema.dumps(accusation)
'{"generic": false, "statement": {"generic": false, "terms": [{"generic": true, "plural": false, "name": "Valjean", "type": "Entity"}], "absent": false, "predicate": {"content": "$suspect stole bread", "truth": true, "expression": null}}, "absent": false, "authority": {"generic": true, "plural": false, "name": "Javert"}}'