diff --git a/asynction/mock_server.py b/asynction/mock_server.py index 65ad245..d1bf827 100644 --- a/asynction/mock_server.py +++ b/asynction/mock_server.py @@ -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 @@ -138,7 +139,7 @@ def __init__( @classmethod def from_spec( cls, - spec_path: Path, + spec_path: Union[Path, AsyncApiSpec], validation: bool = True, server_name: Optional[str] = None, docs: bool = True, @@ -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 pre loaded AsyncApiSpec object. :param validation: When set to ``False``, message payloads, channel bindings and ack callbacks are NOT validated. Defaults to ``True``. diff --git a/asynction/server.py b/asynction/server.py index e9d4c96..e0ab9a9 100644 --- a/asynction/server.py +++ b/asynction/server.py @@ -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 @@ -113,7 +114,7 @@ def init_app(self, app: Optional[Flask], **kwargs) -> None: @classmethod def from_spec( cls, - spec_path: Path, + spec_path: Union[Path, AsyncApiSpec], validation: bool = True, server_name: Optional[str] = None, docs: bool = True, @@ -124,7 +125,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 pre loaded AsyncApiSpec object. :param validation: When set to ``False``, message payloads, channel bindings and ack callbacks are NOT validated. Defaults to ``True``. @@ -155,7 +157,11 @@ def from_spec( ) """ - spec = load_spec(spec_path=spec_path) + if isinstance(spec_path, AsyncApiSpec): + spec = spec_path + else: + spec = load_spec(spec_path=spec_path) + server_security: Sequence[SecurityRequirement] = [] if ( server_name is not None diff --git a/tests/unit/test_mock_server.py b/tests/unit/test_mock_server.py index bfafcb9..603c78f 100644 --- a/tests/unit/test_mock_server.py +++ b/tests/unit/test_mock_server.py @@ -29,6 +29,7 @@ from asynction.mock_server import task_scheduler from asynction.server import AsynctionSocketIO from asynction.server import _noop_handler +from asynction.server import load_spec from asynction.types import GLOBAL_NAMESPACE from asynction.types import AsyncApiSpec from asynction.types import Channel @@ -140,6 +141,13 @@ 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): + spec = load_spec(fixture_paths.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, diff --git a/tests/unit/test_server.py b/tests/unit/test_server.py index a419aa7..964174b 100644 --- a/tests/unit/test_server.py +++ b/tests/unit/test_server.py @@ -50,6 +50,12 @@ def test_asynction_socketio_from_spec(fixture_paths: FixturePaths): assert isinstance(asio, AsynctionSocketIO) +def test_asynction_socketio_from_spec_object(fixture_paths: FixturePaths): + spec = load_spec(fixture_paths.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, ):