question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[REQ] Python Improved Model Template

See original GitHub issue

Is your feature request related to a problem? Please describe.

When using an IDE e.g. PyCharm with SDKs generated using the openapi-generator in Python. The docstring in the “init” method for any models is next to useless. All it says by default is

"""{modelName} - a model defined in OpenAPI". """

There is therefore little value in the type hints and docstring when developing using an IDE.

In addition there is no way to easily tell the difference between the required and optional parameters outside of looking at the setters and if they have a None check.

Describe the solution you’d like

It would be great to have a docstring with the parameter descriptions and types which helps with using the SDK.

For example (a snippet from our LUSID Python SDK):

"""
       ConfigurationRecipeSnippet - a model defined in OpenAPI

       :param aggregation_options: 
       :type aggregation_options: lusid.AggregationOptions
       :param model_rules:  The set of model rules that are available. There may be multiple rules for Vendors, but only one per model-instrument pair.  Which of these preference sets is used depends upon the model choice selection if specified, or failing that the global default model specification  in the options.
       :type model_rules: list[lusid.VendorModelRule]
       :param pricing_options: 
       :type pricing_options: lusid.PricingOptions
       :param market_rules:  The set of rules that define how to resolve particular use cases. These can be relatively general or specific in nature.  Nominally any number are possible and will be processed in order where applicable. However, there is evidently a potential  for increased computational cost where many rules must be applied to resolve data. Ensuring that portfolios are structured in  such a way as to reduce the number of rules required is therefore sensible.
       :type market_rules: list[lusid.MarketDataKeyRule]
       :param market_options: 
       :type market_options: lusid.MarketOptions
       :param recipe: 
       :type recipe: lusid.ConfigurationRecipe

       """  # noqa: E501

Would come from the following template:

        """
        {{classname}} - a model defined in OpenAPI

        {{#vars}}
        :param {{name}}: {{#description}} {{{description}}}{{/description}}{{#required}} (required){{/required}}{{#optional}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/optional}}
        :type {{name}}: {{^complexType}}{{dataType}}{{/complexType}}{{#complexType}}{{^isContainer}}{{packageName}}.{{complexType}}{{/isContainer}}{{#isListContainer}}list[{{packageName}}.{{complexType}}]{{/isListContainer}}{{#isMapContainer}}dict[str, {{packageName}}.{{complexType}}]{{/isMapContainer}}{{/complexType}}
        {{/vars}}

        """  # noqa: E501

It would also be great to have a required_map which notes down which attributes are required and optional.

E.g:

    required_map = {
        'aggregation_options': 'optional',
        'model_rules': 'optional',
        'pricing_options': 'optional',
        'market_rules': 'optional',
        'market_options': 'optional',
        'recipe': 'optional'
    }

Which would come from the following in the template:

    required_map = {
{{#vars}}
        '{{name}}': '{{^required}}optional{{/required}}{{#required}}required{{/required}}'{{#hasMore}},{{/hasMore}}
{{/vars}}
    }

Describe alternatives you’ve considered

We were able to solve both these issues with a custom template. I think the custom template we created is generic enough to be used as the default model template and want to see if we should merge it in.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
phemmercommented, Jan 9, 2021

After trying to generate a python model for a new project using the 4.3.1 generator, and finding it to be less than good, I tried using the 5.0.0 generator only to find it’s drastically worse.

With the 4.3.1 generator __init__ at least had arguments for the optional parameters. The 5.0.0 doesn’t, instead relying on **kwargs.
As another major regression, in 4.3.1 all the properties were defined on the class (using accessor methods), allowing an IDE to discover them. In 5.0.0 they are no longer there.

So basically in 4.3.1, the IDE at least had some idea that these arguments & properties existed, even if it didn’t know the type. Now it has no clue.
While I don’t understand the reason for all this metaprogramming, it’s making it impossible to work with static code analysis.

If we’re going to continue with this metaprogramming design, can we at least generate stub files to address the issue?

0reactions
spacethercommented, Jan 11, 2022

Closing this issue because the python-experimental generator includes the requested model type hints in the model __new__ signature. These type hints show up in pycharm. One can see it working in the Pet model here: https://github.com/OpenAPITools/openapi-generator/blob/master/samples/openapi3/client/petstore/python-experimental/petstore_api/model/pet.py#L137

    def __new__(
        cls,
        *args: typing.Union[dict, frozendict, ],
        name: name,
        photoUrls: photoUrls,
        id: typing.Union[id, Unset] = unset,
        category: typing.Union['Category', Unset] = unset,
        tags: typing.Union[tags, Unset] = unset,
        status: typing.Union[status, Unset] = unset,
        _instantiation_metadata: typing.Optional[InstantiationMetadata] = None,
        **kwargs: typing.Type[Schema],
    ):
Read more comments on GitHub >

github_iconTop Results From Across the Web

Python Requests Tutorial With Examples (and Video)
In this tutorial, you will learn how to: Understand the structure of a request; Make GET and POST requests; Read and extract elements...
Read more >
Python's Requests Library (Guide)
In this tutorial on Python's "requests" library, you'll see some of the most useful features that requests has to offer as well as...
Read more >
PEP 8 – Style Guide for Python Code
The guidelines provided here are intended to improve the readability of ... var_four) # Further indentation required as indentation is not ...
Read more >
Render multiple templates in get_data(request) - Stack Overflow
#views.py from django.views.generic import DetailView from my_app.models import MyModel, MyModel2 class MyView(DetailView): ...
Read more >
How to send HTTP requests in Python? - Machine Learning Plus
A GET request is used to request data from a specific server. ... form data, multipart files, and parameters via simple Python libraries....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found