Skip to content

Commit

Permalink
Allow pre loaded AsyncAPISpec in from_spec (#160)
Browse files Browse the repository at this point in the history
* Allow from_spec to accept an AsyncApiSpec object

* Fix doc comment indentation

* Convert from AsyncApiSpec to JsonMapping

* Handle review items
  • Loading branch information
alex-zywicki authored Jan 19, 2022
1 parent 71b3260 commit cb4b781
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
6 changes: 4 additions & 2 deletions asynction/mock_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from typing import MutableSequence
from typing import Optional
from typing import Sequence
from typing import Union

from faker import Faker
from faker.exceptions import UnsupportedFeature
Expand Down Expand Up @@ -138,7 +139,7 @@ def __init__(
@classmethod
def from_spec(
cls,
spec_path: Path,
spec_path: Union[Path, JSONMapping],
validation: bool = True,
server_name: Optional[str] = None,
docs: bool = True,
Expand All @@ -160,7 +161,8 @@ def from_spec(
* ``custom_formats_sample_size``
:param spec_path: The path where the AsyncAPI YAML specification is located.
:param spec_path: The path where the AsyncAPI YAML specification is located,
or a dictionary object of the AsyncAPI data structure
:param validation: When set to ``False``, message payloads, channel
bindings and ack callbacks are NOT validated.
Defaults to ``True``.
Expand Down
21 changes: 13 additions & 8 deletions asynction/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Any
from typing import Optional
from typing import Sequence
from typing import Union
from urllib.parse import urlparse

import jsonschema
Expand Down Expand Up @@ -67,13 +68,15 @@ def resolve_references(raw_spec: JSONMapping) -> JSONMapping:
return deep_resolve(raw_spec, resolver)


def load_spec(spec_path: Path) -> AsyncApiSpec:
with open(spec_path) as f:
serialized = f.read()
raw = yaml.safe_load(serialized)

raw_resolved = resolve_references(raw_spec=raw)
def load_spec(spec_path: Union[Path, JSONMapping]) -> AsyncApiSpec:
if isinstance(spec_path, Path):
with open(spec_path) as f:
serialized = f.read()
spec = yaml.safe_load(serialized)
else:
spec = spec_path

raw_resolved = resolve_references(spec)
return AsyncApiSpec.from_dict(raw_resolved)


Expand Down Expand Up @@ -113,7 +116,7 @@ def init_app(self, app: Optional[Flask], **kwargs) -> None:
@classmethod
def from_spec(
cls,
spec_path: Path,
spec_path: Union[Path, JSONMapping],
validation: bool = True,
server_name: Optional[str] = None,
docs: bool = True,
Expand All @@ -124,7 +127,8 @@ def from_spec(
"""Create a Flask-SocketIO server from an AsyncAPI spec.
This is the single entrypoint to the Asynction server API.
:param spec_path: The path where the AsyncAPI YAML specification is located.
:param spec_path: The path where the AsyncAPI YAML specification is located,
or a dictionary object of the AsyncAPI data structure
:param validation: When set to ``False``, message payloads, channel
bindings and ack callbacks are NOT validated.
Defaults to ``True``.
Expand Down Expand Up @@ -156,6 +160,7 @@ def from_spec(
"""
spec = load_spec(spec_path=spec_path)

server_security: Sequence[SecurityRequirement] = []
if (
server_name is not None
Expand Down
9 changes: 9 additions & 0 deletions tests/unit/test_mock_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import jsonschema
import pytest
import yaml
from faker import Faker
from flask.app import Flask
from flask_socketio import SocketIO
Expand Down Expand Up @@ -140,6 +141,14 @@ def test_mock_asynction_socketio_from_spec(fixture_paths: FixturePaths):
assert isinstance(mock_asio.faker, Faker)


def test_mock_asynction_socketio_from_spec_object(fixture_paths: FixturePaths):
with open(fixture_paths.simple, "r") as simple:
spec = yaml.safe_load(simple)
mock_asio = MockAsynctionSocketIO.from_spec(spec_path=spec)
assert isinstance(mock_asio, MockAsynctionSocketIO)
assert isinstance(mock_asio.faker, Faker)


def new_mock_asynction_socket_io(
spec: AsyncApiSpec,
app: Optional[Flask] = None,
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest import mock

import pytest
import yaml
from faker import Faker
from flask import Flask

Expand Down Expand Up @@ -50,6 +51,13 @@ def test_asynction_socketio_from_spec(fixture_paths: FixturePaths):
assert isinstance(asio, AsynctionSocketIO)


def test_asynction_socketio_from_spec_object(fixture_paths: FixturePaths):
with open(fixture_paths.simple, "r") as simple:
spec = yaml.safe_load(simple)
asio = AsynctionSocketIO.from_spec(spec_path=spec)
assert isinstance(asio, AsynctionSocketIO)


def test_asynction_socketio_from_spec_uses_spec_server_path_as_socketio_path(
fixture_paths: FixturePaths,
):
Expand Down

0 comments on commit cb4b781

Please sign in to comment.