1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 03:24:20 +00:00

✏️ Make commands coroutines

This commit is contained in:
Steffo 2020-12-07 19:26:32 +01:00
parent b8607edb56
commit eb90daa241
3 changed files with 24 additions and 12 deletions

View file

@ -40,11 +40,11 @@ def parameter_to_field(param: inspect.Parameter, **kwargs) -> Tuple[type, pydant
def signature_to_model(f: Callable, __config__: pydantic.BaseConfig = ModelConfig, **extra_params):
"""
Convert the signature of a function to a pydantic model.
Convert the signature of a async function to a pydantic model.
Arguments starting with ``_`` are ignored.
:param f: The function to use the signature of.
:param f: The async function to use the signature of.
:param __config__: The config the pydantic model should use.
:param extra_params: Extra parameters to be added to the model.
:return: The created pydantic model.

View file

@ -18,7 +18,8 @@ class EngineerRouter:
:param name: The name of the command (``start``, ``settings``, etc). If not specified, it will use the name
of the wrapped function.
:param f: The function that should be executed when the command is called. It must have a ``.model`` property.
:param f: The async function that should be executed when the command is called.
It must have a ``.model`` property.
.. seealso:: :meth:`.command`, :func:`.params.function_with_model`
"""
@ -33,13 +34,13 @@ class EngineerRouter:
.. code-block:: python
@command()
def ping():
async def ping():
print("Pong!")
.. code-block:: python
@command(name="ping")
def xyzzy():
async def xyzzy():
print("Pong!")
:param name: The name of the command (``start``, ``settings``, etc). If not specified, it will use the name
@ -61,7 +62,18 @@ class EngineerRouter:
return decorator
def call(self, __name: str, **kwargs):
async def call(self, __name: str, **kwargs) -> Any:
"""
Call the command with the specified name using the passed kwargs.
:param __name: The name of the function.
:param kwargs: Kwargs to pass to the desired function:
- Kwargs starting with ``__`` are never passed to the function.
- Kwargs starting with ``_`` are passed as they are.
- Other kwargs are validated by the function's :mod:`pydantic` model.
:return: The return value of the function.
:raises pydantic.ValidationError: If the kwargs do not pass the :mod:`pydantic` model validation.
"""
model_params = {}
extra_params = {}
for key, value in kwargs.items():
@ -74,7 +86,7 @@ class EngineerRouter:
# noinspection PyPep8Naming
Model: Type[pydantic.BaseModel] = f.model
model: pydantic.BaseModel = Model(**model_params)
return f(**model.dict(), **extra_params)
return await f(**model.dict(), **extra_params)
__all__ = (

View file

@ -6,14 +6,14 @@ import royalnet.engineer as re
@pytest.fixture
def a_random_function():
async def my_async_function():
def f(*, big_f: str, _hidden: int) -> str:
return big_f
return f
def test_parameter_to_field(a_random_function):
signature = inspect.signature(a_random_function)
def test_parameter_to_field(my_async_function):
signature = inspect.signature(my_async_function)
parameter = signature.parameters["big_f"]
t, fieldinfo = re.parameter_to_field(parameter)
assert isinstance(fieldinfo, pydantic.fields.FieldInfo)
@ -21,8 +21,8 @@ def test_parameter_to_field(a_random_function):
assert fieldinfo.title == parameter.name == "big_f"
def test_signature_to_model(a_random_function):
Model = re.signature_to_model(a_random_function)
def test_signature_to_model(my_async_function):
Model = re.signature_to_model(my_async_function)
assert callable(Model)
model = Model(big_f="banana")