Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create model using a function signature #1391

Closed
antoniomdk opened this issue Apr 14, 2020 · 4 comments
Closed

Create model using a function signature #1391

antoniomdk opened this issue Apr 14, 2020 · 4 comments

Comments

@antoniomdk
Copy link

Feature Request

Hi everyone, first things first, thank you for this fantastic tool you're developing.

I think it would be interesting to create a model dynamically based on a function signature.
In my case, I have some kind of function runners: functions that receive a function and
call it adding decorators, etc. I've created the following snippet to create a model from
a function signature. If you're interested in this feature, I can create a PR for it.

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.4
            pydantic compiled: False
                 install path: /Users/antonio/Documents/TFG-AntonioMolner/env/lib/python3.7/site-packages/pydantic
               python version: 3.7.7 (default, Mar 10 2020, 15:43:33)  [Clang 11.0.0 (clang-1100.0.33.17)]
                     platform: Darwin-19.2.0-x86_64-i386-64bit
     optional deps. installed: []
import pydantic

def create_model_from_signature(func: Callable,
                                model_name: str,
                                base_model: Type[BaseModel] = BaseModel):
    args, _, varkw, defaults, kwonlyargs, kwonlydefaults, annotations = getfullargspec(func)
    defaults = defaults or []
    args = args or []

    non_default_args = len(args) - len(defaults)
    defaults = (...,) * non_default_args + defaults

    keyword_only_params = {param: kwonlydefaults.get(param, Any) for param in kwonlyargs}
    params = {param: (annotations.get(param, Any), default) for param, default in zip(args, defaults)}

    class Config:
        extra = 'allow'

    # Allow extra params if there is a **kwargs parameter in the function signature
    config = Config if varkw else None

    return create_model(
        model_name,
        **params,
        **keyword_only_params,
        __base__=base_model,
        __config__=config,
    )
...

Example

In[12] m = create_model_from_signature(open, 'MyModel', BaseModel)

In[13] m.__fields__

Out[14]: 
{'file': ModelField(name='file', type=Optional[Any], required=True),
 'mode': ModelField(name='mode', type=Optional[Any], required=False, default='r'),
 'buffering': ModelField(name='buffering', type=Optional[Any], required=False, default=-1),
 'encoding': ModelField(name='encoding', type=Optional[Any], required=False, default=None),
 'errors': ModelField(name='errors', type=Optional[Any], required=False, default=None),
 'newline': ModelField(name='newline', type=Optional[Any], required=False, default=None),
 'closefd': ModelField(name='closefd', type=Optional[Any], required=False, default=True),
 'opener': ModelField(name='opener', type=Optional[Any], required=False, default=None)}
@antoniomdk
Copy link
Author

I've realized there is a validate_arguments method, I'm closing this issue.

@danielbraun89
Copy link

validate_arguments serve a different use case. Personally I don't understand why not going forward with the original idea...

@marsninja
Copy link

This is a great idea @antoniomdk , though I agree with @danielbraun89 , I'm trying to build an automated function signature to base model to fastAPI request body and would need to extract the base model from function signatures. validate_arguments doesn't actually provide the base model it uses internally it appears, unless I've missed something.

@marsninja
Copy link

NVM, I just noticed:

https://github.com/samuelcolvin/pydantic/blob/5bc1fcfb92aace50f18bf4ddcc915ef23e1c7431/pydantic/decorator.py#L45

I can use this as the model, didn't see it in the documentation, LMK if putting in a PR in for the docs if useful.

JoshuaLeivers added a commit to JoshuaLeivers/pydantic that referenced this issue Sep 4, 2023
This model type uses a Pydantic model to validate function
arguments and return values, exposing functions to pass in and
retrieve arguments, and to call functions using the stored
arguments.

This is a feature that has been asked for previously in pydantic#1391
but which was possible through v1 methods which are not present
in v2.
JoshuaLeivers added a commit to JoshuaLeivers/pydantic that referenced this issue Sep 4, 2023
This model type uses a Pydantic model to validate function
arguments and return values, exposing functions to pass in and
retrieve arguments, and to call functions using the stored
arguments.

This is a feature that has been asked for previously in
pydantic#1391 but which was possible through v1 methods
which are not present in v2 and so that issue is already closed.
JoshuaLeivers added a commit to JoshuaLeivers/pydantic that referenced this issue Sep 4, 2023
This model type uses a Pydantic model to validate function
arguments and return values, exposing functions to pass in and
retrieve arguments, and to call functions using the stored
arguments.

This is a feature that has been asked for previously in
pydantic#1391 but which was possible through v1 methods
which are not present in v2 and so that issue is already closed.
JoshuaLeivers added a commit to JoshuaLeivers/pydantic that referenced this issue Sep 4, 2023
This model type uses a Pydantic model to validate function
arguments and return values, exposing functions to pass in and
retrieve arguments, and to call functions using the stored
arguments.

This is a feature that has been asked for previously in
pydantic#1391 but which was possible through v1 methods
which are not present in v2 and so that issue is already closed.
JoshuaLeivers added a commit to JoshuaLeivers/pydantic that referenced this issue Sep 21, 2023
This model type uses a Pydantic model to validate function
arguments and return values, exposing functions to pass in and
retrieve arguments, and to call functions using the stored
arguments.

This is a feature that has been asked for previously in
pydantic#1391 but which was possible through v1 methods
which are not present in v2 and so that issue is already closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants