Skip to content

Commit 414319d

Browse files
author
Adam Gray
committed
Convert property and endpoint names to snake case in Python code
1 parent 5583d86 commit 414319d

File tree

18 files changed

+90
-36
lines changed

18 files changed

+90
-36
lines changed

openapi_python_client/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
from pathlib import Path
99
from typing import Any, Dict, Optional
1010

11+
import stringcase
1112
import httpx
1213
import yaml
1314
from jinja2 import Environment, PackageLoader
1415

16+
from openapi_python_client import utils
1517
from .openapi_parser import OpenAPI, import_string_from_reference
1618

1719
__version__ = version(__package__)
@@ -61,6 +63,8 @@ def _get_json(*, url: Optional[str], path: Optional[Path]) -> Dict[str, Any]:
6163

6264

6365
class _Project:
66+
TEMPLATE_FILTERS = {"snakecase": utils.snake_case}
67+
6468
def __init__(self, *, openapi: OpenAPI) -> None:
6569
self.openapi: OpenAPI = openapi
6670
self.env: Environment = Environment(loader=PackageLoader(__package__), trim_blocks=True, lstrip_blocks=True)
@@ -72,6 +76,8 @@ def __init__(self, *, openapi: OpenAPI) -> None:
7276
self.package_dir: Path = self.project_dir / self.package_name
7377
self.package_description = f"A client library for accessing {self.openapi.title}"
7478

79+
self.env.filters.update(self.TEMPLATE_FILTERS)
80+
7581
def build(self) -> None:
7682
""" Create the project from templates """
7783

openapi_python_client/openapi_parser/properties.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass, field
22
from typing import Any, ClassVar, Dict, List, Optional
33

4+
from openapi_python_client import utils
45
from .reference import Reference
56

67

@@ -15,6 +16,10 @@ class Property:
1516
constructor_template: ClassVar[Optional[str]] = None
1617
_type_string: ClassVar[str]
1718

19+
@property
20+
def python_name(self):
21+
return utils.snake_case(self.name)
22+
1823
def get_type_string(self) -> str:
1924
""" Get a string representation of type that should be used when declaring this property """
2025
if self.required:
@@ -201,7 +206,7 @@ def get_type_string(self) -> str:
201206

202207
def transform(self) -> str:
203208
""" Convert this into a JSONable value """
204-
return f"{self.name}.to_dict()"
209+
return f"{self.python_name}.to_dict()"
205210

206211

207212
@dataclass

openapi_python_client/openapi_parser/reference.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from dataclasses import dataclass
66
from typing import Dict
77

8-
import stringcase
8+
from .. import utils
99

1010
class_overrides: Dict[str, Reference] = {}
1111

@@ -21,9 +21,9 @@ class Reference:
2121
def from_ref(ref: str) -> Reference:
2222
""" Get a Reference from the openapi #/schemas/blahblah string """
2323
ref_value = ref.split("/")[-1]
24-
class_name = stringcase.pascalcase(ref_value)
24+
class_name = utils.pascal_case(ref_value)
2525

2626
if class_name in class_overrides:
2727
return class_overrides[class_name]
2828

29-
return Reference(class_name=class_name, module_name=stringcase.snakecase(ref_value),)
29+
return Reference(class_name=class_name, module_name=utils.snake_case(ref_value),)

openapi_python_client/templates/async_endpoint_module.pyi

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ from ..errors import ApiResponseError
1212
{% for endpoint in collection.endpoints %}
1313

1414

15-
async def {{ endpoint.name }}(
15+
async def {{ endpoint.name | snakecase }}(
1616
*,
1717
{# Proper client based on whether or not the endpoint requires authentication #}
1818
{% if endpoint.requires_security %}
@@ -42,7 +42,12 @@ async def {{ endpoint.name }}(
4242
{% endfor %}
4343
]:
4444
""" {{ endpoint.description }} """
45-
url = f"{client.base_url}{{ endpoint.path }}"
45+
url = "{}{{ endpoint.path }}".format(
46+
client.base_url
47+
{%- for parameter in endpoint.path_parameters -%}
48+
,{{parameter.name}}={{parameter.python_name}}
49+
{%- endfor -%}
50+
)
4651

4752
{% if endpoint.query_parameters %}
4853
params = {
@@ -54,8 +59,8 @@ async def {{ endpoint.name }}(
5459
}
5560
{% for parameter in endpoint.query_parameters %}
5661
{% if not parameter.required %}
57-
if {{ parameter.name }} is not None:
58-
params["{{ parameter.name }}"] = {{ parameter.transform() }}
62+
if {{ parameter.python_name }} is not None:
63+
params["{{ parameter.name }}"] = str({{ parameter.transform() }})
5964
{% endif %}
6065
{% endfor %}
6166
{% endif %}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{% if property.required %}
2-
{{ property.name }} = datetime.fromisoformat(d["{{ property.name }}"])
2+
{{ property.python_name }} = datetime.fromisoformat(d["{{ property.name }}"])
33
{% else %}
4-
{{ property.name }} = None
5-
if ({{ property.name }}_string := d.get("{{ property.name }}")) is not None:
6-
{{ property.name }} = datetime.fromisoformat(cast(str, {{ property.name }}_string))
4+
{{ property.python_name }} = None
5+
if ({{ property.python_name }}_string := d.get("{{ property.name }}")) is not None:
6+
{{ property.python_name }} = datetime.fromisoformat(cast(str, {{ property.python_name }}_string))
77
{% endif %}

openapi_python_client/templates/endpoint_module.pyi

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ from ..errors import ApiResponseError
1212
{% for endpoint in collection.endpoints %}
1313

1414

15-
def {{ endpoint.name }}(
15+
def {{ endpoint.name | snakecase }}(
1616
*,
1717
{# Proper client based on whether or not the endpoint requires authentication #}
1818
{% if endpoint.requires_security %}
@@ -42,7 +42,12 @@ def {{ endpoint.name }}(
4242
{% endfor %}
4343
]:
4444
""" {{ endpoint.description }} """
45-
url = f"{client.base_url}{{ endpoint.path }}"
45+
url = "{}{{ endpoint.path }}".format(
46+
client.base_url
47+
{%- for parameter in endpoint.path_parameters -%}
48+
,{{parameter.name}}={{parameter.python_name}}
49+
{%- endfor -%}
50+
)
4651

4752
{% if endpoint.query_parameters %}
4853
params = {
@@ -54,8 +59,8 @@ def {{ endpoint.name }}(
5459
}
5560
{% for parameter in endpoint.query_parameters %}
5661
{% if not parameter.required %}
57-
if {{ parameter.name }} is not None:
58-
params["{{ parameter.name }}"] = {{ parameter.transform() }}
62+
if {{ parameter.python_name }} is not None:
63+
params["{{ parameter.name }}"] = str({{ parameter.transform() }})
5964
{% endif %}
6065
{% endfor %}
6166
{% endif %}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
{{ property.name }} = []
2-
for {{ property.name }}_item in d.get("{{ property.name }}", []):
3-
{{ property.name }}.append({{ property.reference.class_name }}({{ property.name }}_item))
1+
{{ property.python_name }} = []
2+
for {{ property.python_name }}_item in d.get("{{ property.name }}", []):
3+
{{ property.python_name }}.append({{ property.reference.class_name }}({{ property.python_name }}_item))

openapi_python_client/templates/model.pyi

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ class {{ schema.reference.class_name }}:
2222
"{{ property.name }}": self.{{ property.transform() }},
2323
{% endfor %}
2424
{% for property in schema.optional_properties %}
25-
"{{ property.name }}": self.{{ property.transform() }} if self.{{ property.name }} is not None else None,
26-
{% endfor %}
25+
"{{ property.name }}": self.{{ property.transform() }} if self.{{property.python_name}} is not None else None,
26+
{% endfor %}
2727
}
2828

2929
@staticmethod
@@ -33,12 +33,12 @@ class {{ schema.reference.class_name }}:
3333
{% if property.constructor_template %}
3434
{% include property.constructor_template %}
3535
{% else %}
36-
{{ property.name }} = {{ property.constructor_from_dict("d") }}
36+
{{property.python_name}} = {{property.constructor_from_dict("d")}}
3737
{% endif %}
3838

3939
{% endfor %}
4040
return {{ schema.reference.class_name }}(
4141
{% for property in schema.required_properties + schema.optional_properties %}
42-
{{ property.name }}={{ property.name }},
42+
{{ property.python_name }}={{ property.python_name }},
4343
{% endfor %}
4444
)
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{% if property.required %}
2-
{{ property.name }} = {{ property.reference.class_name }}.from_dict(d["{{ property.name }}"])
2+
{{ property.python_name }} = {{ property.reference.class_name }}.from_dict(d["{{ property.name }}"])
33
{% else %}
4-
{{ property.name }} = None
5-
if ({{ property.name }}_data := d.get("{{ property.name }}")) is not None:
6-
{{ property.name }} = {{ property.reference.class_name }}.from_dict(cast(Dict, {{ property.name }}_data))
4+
{{ property.python_name }} = None
5+
if ({{ property.python_name }}_data := d.get("{{ property.name }}")) is not None:
6+
{{ property.python_name }} = {{ property.reference.class_name }}.from_dict(cast(Dict[str, Any], {{ property.python_name }}_data))
77
{% endif %}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
{{ property.name }} = []
2-
for {{ property.name }}_item in d.get("{{ property.name }}", []):
3-
{{ property.name }}.append({{ property.reference.class_name }}.from_dict({{ property.name }}_item))
1+
{{ property.python_name }} = []
2+
for {{ property.python_name }}_item in d.get("{{ property.python_name }}", []):
3+
{{ property.python_name }}.append({{ property.reference.class_name }}.from_dict({{ property.python_name }}_item))

0 commit comments

Comments
 (0)