.. _blueprints: ========== Blueprints ========== Blueprints enable you to repeat the creation of Items or Sets in a consistent fashion. At it's core, a blueprint is just a `jsonschema `_ that you define, which you can then use to validate Items or Sets that you are adding to ``qalx``. Creating Blueprints ------------------- Create a blueprint using the `Blueprint` class and helper methods to add schema elements. Blueprint names are unique across an entire company. To create a blueprint for an item you can add various rules for data keys: .. code:: python from pyqalx import QalxSession, Blueprint qalx = QalxSession() dim_schema = Blueprint.item() dim_schema.add_data("width", {'type': 'number', 'minimum': 1}, required=True) dim_schema.add_data("height", {'type': 'number', 'minimum': 3, 'exclusiveMaximum': 100}, required=True) dim_bp = qalx.blueprint.add(name='DimsBlueprint', schema=dim_schema) You could also build the schema ahead of time and update the entire blueprint at once. The below example and the above example both give the same output and each have their own pros and cons to using them: .. code:: python from pyqalx import QalxSession, Blueprint qalx = QalxSession() dim_schema = Blueprint.item() schema = {'data': { 'type': 'object', 'properties': { 'width': {'type': 'number', 'minimum': 1 }, 'height': {'type': 'number', 'minimum': 3, 'exclusiveMaximum': 100 }, }, 'required': ['width', 'height'], } } dim_schema.add_schema(schema) dim_bp = qalx.blueprint.add(name='DimsBlueprint', schema=dim_schema) Using Blueprints ---------------- Blueprints can be used to validate that the data that you are trying to add to an Item or Set is valid. You can use a Blueprint during the add process by providing the name to the method. The below code would raise a `jsonschema.ValidationError` as the `DimsBlueprint` blueprint requires the `width` field on `data` to be at least 1 .. code:: python qalx = QalxSession() data = { 'width': 0.5 'height': 10 } qalx.item.add(data=data, blueprint_name='DimsBlueprint') The below code would create the item as usual as the data we are providing matches the schema defined in `DimsBlueprint` .. code:: python qalx = QalxSession() data = { 'width': 5 'height': 10 } qalx.item.add(data=data, blueprint_name='DimsBlueprint') For sets, it is possible to specify that certain item keys are specified and that each of the items conforms to a specific blueprint. Suppose that we want a set with a dimensions item and a material item. .. code:: python mat_schema = Blueprint.item() mat_schema.add_data("density", {'type': 'number'}, required=True) mat_schema.add_data("E", {'type': 'integer', 'multipleOf': 1e9}, required=True) mat_bp = qalx.blueprint.add(name='MatsBlueprint', schema=mat_schema) set_schema = Blueprint.set() set_schema.add_item("dimensions", dim_bp) set_schema.add_item("material", mat_bp) set_bp = qalx.blueprint.add(name='ASetBlueprint', schema=set_schema) Then, when we add items to a set we can ensure that the items are in the format we expect. .. code:: python d = qalx.item.add(data={'height': 30, 'width': 5}, blueprint_name='DimsBlueprint') m = qalx.item.add(data={'density': 1.4, 'E': 120e9}, blueprint_name='MatsBlueprint') s = qalx.set.add(items={"dimensions": d, "material": m}, blueprint_name='ASetBlueprint') Validating entities against blueprints -------------------------------------- Blueprints also provide the functionality to validate an entity locally, without making a save request to qalx. In this way, we can check for conformity with a blueprint schema if we require this check to be done for an entity without necessarily wishing to save the entity, at least at this point in time. The following example, demonstrates this functionality. Item ^^^^ .. code:: python d_no_bp = qalx.item.add(data={'height': 30, 'width': 5}) dim_bp.validate(d_no_bp) The validation in the code above works and no errors should be raised. In the same way, for items that are not structured according to a blueprint, a validation error will be raised. .. code:: python invalid_d = qalx.item.add(data={'a': 30, 'b': 5}) dim_bp.validate(invalid_d) The code above raises the following error: .. code-block:: ValidationError: 'width' is a required property Failed validating 'required' in schema['properties']['data']: {'properties': {'height': {'exclusiveMaximum': 100, 'minimum': 3, 'type': 'number'}, 'width': {'minimum': 1, 'type': 'number'}}, 'required': ['width', 'height'], 'type': 'object'} On instance['data']: {'a': 30, 'b': 5} Set ^^^ The same functionality is available for Set blueprints as well. .. code:: python d = qalx.item.add(data={'height': 30, 'width': 5}) valid_set = qalx.set.add(items={"dimensions": d}, blueprint_name="ASetBlueprint") # Make some changes to our valid set # Check that our set is still valid against the blueprint that we # obtained from earlier examples. set_bp.validate(valid_set) Data Schema Options ------------------- Datatypes ^^^^^^^^^ "``string``": "Hello World" "``number``": 1.23 "``integer``": 123 "``boolean``": true "``object``": {"foo":"bar", "baz":"Hello World"} "``array``": ["foo","bar", 5,"hello"] "``null``": None Features ^^^^^^^^ ``string`` + ``number`` + ``integer`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ enum: [...] format: date-time, email, hostname, ipv4, ipv6, uri ``string`` ~~~~~~~~~~ minLength, maxLength pattern: regexp ``number`` + ``integer`` ~~~~~~~~~~~~~~~~~~~~~~~~ minimum, maximum exclusiveMinimum, exclusiveMaximum multipleOf ``array`` ~~~~~~~~~ items minItems, maxItems uniqueItems: enforce uniqueness additionalItems: if true, validation always passes ``object`` ~~~~~~~~~~ properties minProperties, maxProperties patternProperties: regex base properties additionalProperties: if true, validation always passes required