[python-experimental] improves docs, add migration guide (#13210)

* Adds comments and migration readme section

* Samples regenerated

* Samples regenerated
This commit is contained in:
Justin Black 2022-08-17 14:27:02 -07:00 committed by GitHub
parent 9f3fac53c1
commit b1dec24ae8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 352 additions and 0 deletions

View File

@ -21,6 +21,70 @@ Python {{generatorLanguageVersion}}
v3.9 is needed so one can combine classmethod and property decorators to define
object schema properties as classes
## Migration from other generators like python and python-experimental
### Changes
1. This generator uses spec case for all (object) property names and parameter names.
- So if the spec has a property name like camelCase, it will use camelCase rather than camel_case
- So you will need to update how you input and read properties to use spec case
2. Endpoint parameters are stored in dictionaries to prevent collisions (explanation below)
- So you will need to update how you pass data in to endpoints
3. Endpoint responses now include the original response, the deserialized response body, and (todo)the deserialized headers
- So you will need to update your code to use response.body to access deserialized data
4. All validated data is instantiated in an instance that subclasses all validated Schema classes and Decimal/str/list/tuple/frozendict/NoneClass/BoolClass/bytes/io.FileIO
- This means that you can use isinstance to check if a payload validated against a schema class
- This means that no data will be of type None/True/False
- ingested None will subclass NoneClass
- ingested True will subclass BoolClass
- ingested False will subclass BoolClass
- So if you need to check is True/False/None, instead use instance.is_true()/.is_false()/.is_none()
5. All validated class instances are immutable except for ones based on io.File
- This is because if properties were changed after validation, that validation would no longer apply
- So no changing values or property values after a class has been instantiated
6. String + Number types with formats
- String type data is stored as a string and if you need to access types based on its format like date,
date-time, uuid, number etc then you will need to use accessor functions on the instance
- type string + format: See .as_date, .as_datetime, .as_decimal, .as_uuid
- type number + format: See .as_float, .as_int
- this was done because openapi/json-schema defines constraints. string data may be type string with no format
keyword in one schema, and include a format constraint in another schema
- So if you need to access a string format based type, use as_date/as_datetime/as_decimal/as_uuid/
- So if you need to access a number format based type, use as_int/as_float
### Object property spec case
This was done because when payloads are ingested, they can be validated against N number of schemas.
If the input signature used a different property name then that has mutated the payload.
So SchemaA and SchemaB must both see the camelCase spec named variable.
Also it is possible to send in two properties, named camelCase and camel_case in the same payload.
That use case should be support so spec case is used.
### Parameter spec case
Parameters can be included in different locations including:
- query
- path
- header
- cookie
Any of those parameters could use the same parameter names, so if every parameter
was included as an endpoint parameter in a function signature, they would collide.
For that reason, each of those inputs have been separated out into separate typed dictionaries:
- query_params
- path_params
- header_params
- cookie_params
So when updating your code, you will need to pass endpoint parameters in using those
dictionaries.
### Endpoint responses
Endpoint responses have been enriched to now include more information.
Any response reom an endpoint will now include the following properties:
response: urllib3.HTTPResponse
body: typing.Union[Unset, Schema]
headers: typing.Union[Unset, TODO]
Note: response header deserialization has not yet been added
## Installation & Usage
### pip install

View File

@ -41,6 +41,16 @@
{{#if nameInSnakeCase}}
locals()["{{{baseName}}}"] = {{name}}
del locals()['{{name}}']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
{{/if}}
{{/if}}
{{/unless}}

View File

@ -13,6 +13,70 @@ Python >=3.9
v3.9 is needed so one can combine classmethod and property decorators to define
object schema properties as classes
## Migration from other generators like python and python-experimental
### Changes
1. This generator uses spec case for all (object) property names and parameter names.
- So if the spec has a property name like camelCase, it will use camelCase rather than camel_case
- So you will need to update how you input and read properties to use spec case
2. Endpoint parameters are stored in dictionaries to prevent collisions (explanation below)
- So you will need to update how you pass data in to endpoints
3. Endpoint responses now include the original response, the deserialized response body, and (todo)the deserialized headers
- So you will need to update your code to use response.body to access deserialized data
4. All validated data is instantiated in an instance that subclasses all validated Schema classes and Decimal/str/list/tuple/frozendict/NoneClass/BoolClass/bytes/io.FileIO
- This means that you can use isinstance to check if a payload validated against a schema class
- This means that no data will be of type None/True/False
- ingested None will subclass NoneClass
- ingested True will subclass BoolClass
- ingested False will subclass BoolClass
- So if you need to check is True/False/None, instead use instance.is_true()/.is_false()/.is_none()
5. All validated class instances are immutable except for ones based on io.File
- This is because if properties were changed after validation, that validation would no longer apply
- So no changing values or property values after a class has been instantiated
6. String + Number types with formats
- String type data is stored as a string and if you need to access types based on its format like date,
date-time, uuid, number etc then you will need to use accessor functions on the instance
- type string + format: See .as_date, .as_datetime, .as_decimal, .as_uuid
- type number + format: See .as_float, .as_int
- this was done because openapi/json-schema defines constraints. string data may be type string with no format
keyword in one schema, and include a format constraint in another schema
- So if you need to access a string format based type, use as_date/as_datetime/as_decimal/as_uuid/
- So if you need to access a number format based type, use as_int/as_float
### Object property spec case
This was done because when payloads are ingested, they can be validated against N number of schemas.
If the input signature used a different property name then that has mutated the payload.
So SchemaA and SchemaB must both see the camelCase spec named variable.
Also it is possible to send in two properties, named camelCase and camel_case in the same payload.
That use case should be support so spec case is used.
### Parameter spec case
Parameters can be included in different locations including:
- query
- path
- header
- cookie
Any of those parameters could use the same parameter names, so if every parameter
was included as an endpoint parameter in a function signature, they would collide.
For that reason, each of those inputs have been separated out into separate typed dictionaries:
- query_params
- path_params
- header_params
- cookie_params
So when updating your code, you will need to pass endpoint parameters in using those
dictionaries.
### Endpoint responses
Endpoint responses have been enriched to now include more information.
Any response reom an endpoint will now include the following properties:
response: urllib3.HTTPResponse
body: typing.Union[Unset, Schema]
headers: typing.Union[Unset, TODO]
Note: response header deserialization has not yet been added
## Installation & Usage
### pip install

View File

@ -79,21 +79,81 @@ class PropertiesWithEscapedCharacters(
foobar = NumberSchema
locals()["foo\nbar"] = foobar
del locals()['foobar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
foobar = NumberSchema
locals()["foo\"bar"] = foobar
del locals()['foobar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
foo_bar = NumberSchema
locals()["foo\\bar"] = foo_bar
del locals()['foo_bar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
foobar = NumberSchema
locals()["foo\rbar"] = foobar
del locals()['foobar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
foobar = NumberSchema
locals()["foo\tbar"] = foobar
del locals()['foobar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
foobar = NumberSchema
locals()["foo\fbar"] = foobar
del locals()['foobar']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(
cls,

View File

@ -79,6 +79,16 @@ class PropertyNamedRefThatIsNotAReference(
ref = StrSchema
locals()["$ref"] = ref
del locals()['ref']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(
cls,

View File

@ -13,6 +13,70 @@ Python >=3.9
v3.9 is needed so one can combine classmethod and property decorators to define
object schema properties as classes
## Migration from other generators like python and python-experimental
### Changes
1. This generator uses spec case for all (object) property names and parameter names.
- So if the spec has a property name like camelCase, it will use camelCase rather than camel_case
- So you will need to update how you input and read properties to use spec case
2. Endpoint parameters are stored in dictionaries to prevent collisions (explanation below)
- So you will need to update how you pass data in to endpoints
3. Endpoint responses now include the original response, the deserialized response body, and (todo)the deserialized headers
- So you will need to update your code to use response.body to access deserialized data
4. All validated data is instantiated in an instance that subclasses all validated Schema classes and Decimal/str/list/tuple/frozendict/NoneClass/BoolClass/bytes/io.FileIO
- This means that you can use isinstance to check if a payload validated against a schema class
- This means that no data will be of type None/True/False
- ingested None will subclass NoneClass
- ingested True will subclass BoolClass
- ingested False will subclass BoolClass
- So if you need to check is True/False/None, instead use instance.is_true()/.is_false()/.is_none()
5. All validated class instances are immutable except for ones based on io.File
- This is because if properties were changed after validation, that validation would no longer apply
- So no changing values or property values after a class has been instantiated
6. String + Number types with formats
- String type data is stored as a string and if you need to access types based on its format like date,
date-time, uuid, number etc then you will need to use accessor functions on the instance
- type string + format: See .as_date, .as_datetime, .as_decimal, .as_uuid
- type number + format: See .as_float, .as_int
- this was done because openapi/json-schema defines constraints. string data may be type string with no format
keyword in one schema, and include a format constraint in another schema
- So if you need to access a string format based type, use as_date/as_datetime/as_decimal/as_uuid/
- So if you need to access a number format based type, use as_int/as_float
### Object property spec case
This was done because when payloads are ingested, they can be validated against N number of schemas.
If the input signature used a different property name then that has mutated the payload.
So SchemaA and SchemaB must both see the camelCase spec named variable.
Also it is possible to send in two properties, named camelCase and camel_case in the same payload.
That use case should be support so spec case is used.
### Parameter spec case
Parameters can be included in different locations including:
- query
- path
- header
- cookie
Any of those parameters could use the same parameter names, so if every parameter
was included as an endpoint parameter in a function signature, they would collide.
For that reason, each of those inputs have been separated out into separate typed dictionaries:
- query_params
- path_params
- header_params
- cookie_params
So when updating your code, you will need to pass endpoint parameters in using those
dictionaries.
### Endpoint responses
Endpoint responses have been enriched to now include more information.
Any response reom an endpoint will now include the following properties:
response: urllib3.HTTPResponse
body: typing.Union[Unset, Schema]
headers: typing.Union[Unset, TODO]
Note: response header deserialization has not yet been added
## Installation & Usage
### pip install

View File

@ -128,6 +128,16 @@ class FormatTest(
pass
locals()["float"] = _float
del locals()['_float']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
float32 = Float32Schema

View File

@ -82,6 +82,16 @@ class Model200Response(
_class = StrSchema
locals()["class"] = _class
del locals()['_class']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(
cls,

View File

@ -81,6 +81,16 @@ class ModelReturn(
_return = Int32Schema
locals()["return"] = _return
del locals()['_return']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(
cls,

View File

@ -86,6 +86,16 @@ class Name(
_property = StrSchema
locals()["property"] = _property
del locals()['_property']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(
cls,

View File

@ -84,12 +84,42 @@ class ObjectWithDifficultlyNamedProps(
special_property_name = Int64Schema
locals()["$special[property.name]"] = special_property_name
del locals()['special_property_name']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
_123_list = StrSchema
locals()["123-list"] = _123_list
del locals()['_123_list']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
_123_number = IntSchema
locals()["123Number"] = _123_number
del locals()['_123_number']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
def __new__(

View File

@ -122,6 +122,16 @@ class SchemaForRequestBodyApplicationXWwwFormUrlencoded(
pass
locals()["float"] = _float
del locals()['_float']
"""
NOTE:
openapi/json-schema allows properties to have invalid python names
The above local assignment allows the code to keep those invalid python names
This allows properties to have names like 'some-name', '1 bad name'
Properties with these names are omitted from the __new__ + _from_openapi_data signatures
- __new__ these properties can be passed in as **kwargs
- _from_openapi_data these are passed in in a dict in the first positional argument *arg
If the property is required and was not passed in, an exception will be thrown
"""
class double(