def test_mapping_with_types():
    def func(username) -> Mapping[str, int]:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert schema["patternProperties"] == {".*": {"type": "number"}}
def test_response_named_tuple():
    class User(NamedTuple):
        username: str
        password: str
        is_admin: bool = False

    def func(username) -> User:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert schema["properties"] == {
        "username": {
            "type": "string"
        },
        "password": {
            "type": "string"
        },
        "is_admin": {
            "type": "boolean",
            "default": False
        },
    }
    assert set(schema["required"]) == {"username", "password"}
    assert schema["additionalProperties"] == False
Beispiel #3
0
def test_uuid():
    def func(username) -> UUID:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "string"
    assert "pattern" not in schema
Beispiel #4
0
def api_to_schema(api: "lightbus.Api") -> dict:
    """Produce a lightbus schema for the given API"""
    schema = {"rpcs": {}, "events": {}}

    if isinstance(api, type):
        raise InvalidApiForSchemaCreation(
            "An attempt was made to derive an API schema from a type/class, rather than "
            "from an instance of an API. This is probably because you are passing an API "
            "class to api_to_schema(), rather than an instance of the API class."
        )

    for member_name, member in inspect.getmembers(api):
        if member_name.startswith("_"):
            # Don't create schema from private methods
            continue
        if hasattr(Api, member_name):
            # Don't create schema for methods defined on Api class
            continue

        if inspect.ismethod(member):
            schema["rpcs"][member_name] = {
                "parameters": make_rpc_parameter_schema(api.meta.name, member_name, method=member),
                "response": make_response_schema(api.meta.name, member_name, method=member),
            }
        elif isinstance(member, Event):
            schema["events"][member_name] = {
                "parameters": make_event_parameter_schema(api.meta.name, member_name, event=member)
            }

    return schema
Beispiel #5
0
def test_time():
    def func(username) -> time:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "string"
    assert schema["format"] == "time"
Beispiel #6
0
def test_response_typed_tuple():
    def func(username) -> Tuple[str, int, bool]:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "array"
    assert schema["items"] == [{"type": "string"}, {"type": "integer"}, {"type": "boolean"}]
Beispiel #7
0
def test_mapping_with_types():
    def func(username) -> Mapping[str, int]:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert schema["additionalProperties"] == {"type": "integer"}
Beispiel #8
0
def test_set_builtin():
    def func(username) -> Set:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "array"
    assert "items" not in schema
Beispiel #9
0
def test_set_type_with_hints():
    def func(username) -> Set[int]:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "array"
    assert schema["items"] == {"type": "integer"}
Beispiel #10
0
def test_decimal():
    def func(username) -> Decimal:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "string"
    assert schema["pattern"]
Beispiel #11
0
def test_mapping_without_types():
    def func(username) -> Mapping:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert "patternProperties" not in schema
    assert "required" not in schema
Beispiel #12
0
def test_enum_string():
    TestEnum = Enum("ExampleEnum", {"Foo": "foo", "Bar": "bar"})

    def func(username) -> TestEnum:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "string"
    assert set(schema["enum"]) == {"foo", "bar"}
Beispiel #13
0
def test_enum_number():
    TestEnum = Enum("ExampleEnum", {"Foo": 1, "Bar": 2})

    def func(username) -> TestEnum:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "integer"
    assert set(schema["enum"]) == {1, 2}
Beispiel #14
0
def test_unknown_type():
    class UnknownThing:
        pass

    def func(username) -> UnknownThing:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema
Beispiel #15
0
def test_enum_empty():
    TestEnum = Enum("ExampleEnum", {})

    def func(username) -> TestEnum:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema
    assert "enum" not in schema
Beispiel #16
0
def test_object_with_to_bus():
    class CustomClassToBus:
        def __to_bus__(self) -> float:
            pass

    def func(username) -> CustomClassToBus:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "number"
Beispiel #17
0
def test_response_wrapped():
    def func() -> int:
        pass

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        pass

    schema = make_response_schema("api_name", "rpc_name", wrapper)
    assert schema["type"] == "integer"
Beispiel #18
0
def test_enum_unknown_value_types():
    class UnknownThing:
        pass

    TestEnum = Enum("ExampleEnum", {"Foo": UnknownThing, "Bar": UnknownThing})

    def func(username) -> TestEnum:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema
    assert "enum" not in schema
Beispiel #19
0
def test_object_with_property():
    class User:
        username: str

        @property
        def my_prop(self):
            pass

    def func(username) -> User:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert schema["properties"]["my_prop"] == {}
Beispiel #20
0
def test_object_with_method():
    class User:
        username: str

        def my_func(self):
            pass

    def func(username) -> User:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "object"
    assert schema["properties"] == {"username": {"type": "string"}}
    assert set(schema["required"]) == {"username"}
    assert schema["additionalProperties"] == False
Beispiel #21
0
def test_ellipsis():
    def func(username) -> ...:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema
Beispiel #22
0
def test_response_no_types():
    def func(username):
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema
Beispiel #23
0
def test_response_null():
    def func(username) -> None:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "null"
Beispiel #24
0
def test_response_bool():
    def func(username) -> bool:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert schema["type"] == "boolean"
Beispiel #25
0
def test_any():
    def func(username) -> Any:
        pass

    schema = make_response_schema("api_name", "rpc_name", func)
    assert "type" not in schema