Skip to content

Commit

Permalink
Moved json.paths functions into json.schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Collins committed Jul 19, 2020
1 parent 5fee550 commit 58d9318
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 94 deletions.
17 changes: 17 additions & 0 deletions src/labthings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,27 @@
from . import json

__all__ = [
"LabThing",
"create_app",
"Server",
"current_labthing",
"registered_extensions",
"registered_components",
"find_extension",
"find_component",
"StrictLock",
"CompositeLock",
"ClientEvent",
"current_task",
"current_task_stopped"
"update_task_progress"
"update_task_data"
"TaskKillException",
"extensions",
"views",
"fields",
"schema",
"semantics",
"json",
]

2 changes: 1 addition & 1 deletion src/labthings/apispec/apispec.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from apispec import APISpec
from ..json.paths import rule_to_path, rule_to_params
from ..json.schemas import rule_to_path, rule_to_params
from .utilities import convert_to_schema_or_json

from ..utilities import get_docstring, get_summary
Expand Down
78 changes: 0 additions & 78 deletions src/labthings/json/paths.py

This file was deleted.

76 changes: 75 additions & 1 deletion src/labthings/json/schemas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,80 @@
import werkzeug.routing
import re
from marshmallow import Schema, fields
from .marshmallow_jsonschema import JSONSchema
from collections.abc import Mapping
from .marshmallow_jsonschema import JSONSchema


PATH_RE = re.compile(r"<(?:[^:<>]+:)?([^<>]+)>")
# Conversion map of werkzeug rule converters to Javascript schema types
CONVERTER_MAPPING = {
werkzeug.routing.UnicodeConverter: ("string", None),
werkzeug.routing.IntegerConverter: ("integer", "int32"),
werkzeug.routing.FloatConverter: ("number", "float"),
}

DEFAULT_TYPE = ("string", None)


def rule_to_path(rule):
"""Convert a Flask rule into an JSON schema formatted URL path
Args:
rule: Flask rule object
Returns:
str: URL path
"""
return PATH_RE.sub(r"{\1}", rule.rule)


def rule_to_params(rule, overrides=None):
"""Convert a Flask rule into JSON schema URL parameters description
Args:
rule: Flask rule object
overrides (dict, optional): Optional dictionary to override params with
Returns:
dict: Dictionary of URL parameters
"""
overrides = overrides or {}
result = [
argument_to_param(argument, rule, overrides.get(argument, {}))
for argument in rule.arguments
]
for key in overrides.keys():
if overrides[key].get("in") in ("header", "query"):
overrides[key]["name"] = overrides[key].get("name", key)
result.append(overrides[key])
return result


def argument_to_param(argument, rule, override=None):
"""Convert a Flask rule into APISpec URL parameters description
Args:
argument (str): URL argument
rule: Flask rule object
override (dict, optional): Optional dictionary to override params with
Returns:
dict: Dictionary of URL parameter description
"""
param = {"in": "path", "name": argument, "required": True}
type_, format_ = CONVERTER_MAPPING.get(
# skipcq: PYL-W0212
type(rule._converters[argument]),
DEFAULT_TYPE,
)
param["schema"] = {}
param["schema"]["type"] = type_
if format_ is not None:
param["format"] = format_
if rule.defaults and argument in rule.defaults:
param["default"] = rule.defaults[argument]
param.update(override or {})
return param


def field_to_property(field):
Expand Down
5 changes: 0 additions & 5 deletions src/labthings/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@

__all__ = [
"Schema",
"FieldSchema",
"TaskSchema",
"ExtensionSchema",
"ActionSchema",
"build_action_schema",
"pre_load",
"pre_dump",
"validate",
Expand Down
3 changes: 1 addition & 2 deletions src/labthings/td.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from .views import View
from .event import Event
from .json.schemas import schema_to_json
from .json.paths import rule_to_params, rule_to_path
from .json.schemas import schema_to_json, rule_to_params, rule_to_path
from .find import current_labthing
from .utilities import get_docstring, snake_to_camel

Expand Down
14 changes: 7 additions & 7 deletions tests/test_json_paths.py → tests/test_json_schemas.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from labthings.json import paths
from labthings.json import schemas


def make_rule(app, path, **kwargs):
Expand All @@ -17,19 +17,19 @@ def make_param(in_location="path", **kwargs):

def test_rule_to_path(app):
rule = make_rule(app, "/path/<id>/")
assert paths.rule_to_path(rule) == "/path/{id}/"
assert schemas.rule_to_path(rule) == "/path/{id}/"


def test_rule_to_param(app):
rule = make_rule(app, "/path/<id>/")
assert paths.rule_to_params(rule) == [
assert schemas.rule_to_params(rule) == [
{"in": "path", "name": "id", "required": True, "schema": {"type": "string"}}
]


def test_rule_to_param_typed(app):
rule = make_rule(app, "/path/<int:id>/")
assert paths.rule_to_params(rule) == [
assert schemas.rule_to_params(rule) == [
{
"in": "path",
"name": "id",
Expand All @@ -42,7 +42,7 @@ def test_rule_to_param_typed(app):

def test_rule_to_param_typed_default(app):
rule = make_rule(app, "/path/<int:id>/", defaults={"id": 1})
assert paths.rule_to_params(rule) == [
assert schemas.rule_to_params(rule) == [
{
"in": "path",
"name": "id",
Expand All @@ -57,7 +57,7 @@ def test_rule_to_param_typed_default(app):
def test_rule_to_param_overrides(app):
rule = make_rule(app, "/path/<id>/")
overrides = {"override_key": {"in": "header", "name": "header_param"}}
assert paths.rule_to_params(rule, overrides=overrides) == [
assert schemas.rule_to_params(rule, overrides=overrides) == [
{"in": "path", "name": "id", "required": True, "schema": {"type": "string"}},
*overrides.values(),
]
Expand All @@ -66,6 +66,6 @@ def test_rule_to_param_overrides(app):
def test_rule_to_param_overrides_invalid(app):
rule = make_rule(app, "/path/<id>/")
overrides = {"override_key": {"in": "invalid", "name": "header_param"}}
assert paths.rule_to_params(rule, overrides=overrides) == [
assert schemas.rule_to_params(rule, overrides=overrides) == [
{"in": "path", "name": "id", "required": True, "schema": {"type": "string"}}
]

0 comments on commit 58d9318

Please sign in to comment.