Skip to content

Commit 72e0612

Browse files
committed
Add python api_resource template
1 parent ad04cc4 commit 72e0612

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
{% set api_mod_name %}{{ resource.name | to_snake_case }}_api{% endset -%}
2+
{% set resource_class_name = resource.name | to_upper_camel_case -%}
3+
{% set resource_type_name = resource.name | to_upper_camel_case -%}
4+
5+
import typing as t
6+
from datetime import datetime
7+
from dataclasses import dataclass,asdict
8+
9+
from deprecated import deprecated
10+
from .common import PostOptions, ApiBase, BaseOptions
11+
from ..internal.openapi_client.client import AuthenticatedClient
12+
from ..internal.openapi_client import models
13+
14+
{% if resource.operations | length > 0 %}
15+
16+
from ..internal.openapi_client.api.{{ resource.name | to_snake_case }} import (
17+
{% for op in resource.operations %}
18+
{{ op.id | to_snake_case }},
19+
{%- endfor %}
20+
)
21+
{% for op in resource.operations -%}
22+
{#-
23+
FIXME: this is a hack. i want to be able to export the resource types from this file so i have to import them (not just use models.Resource)
24+
But this will result in duplicate import statements. ruff check --fix will remove them, but ideally we find a better way to do this
25+
-#}
26+
{%- if op.request_body_schema_name is defined %}
27+
from ..internal.openapi_client.models.{{ op.request_body_schema_name | to_snake_case }} import {{ op.request_body_schema_name | to_upper_camel_case }}
28+
{%- endif -%}
29+
{%- if op.response_body_schema_name is defined %}
30+
from ..internal.openapi_client.models.{{ op.response_body_schema_name | to_snake_case }} import {{ op.response_body_schema_name | to_upper_camel_case }}
31+
{%- endif -%}
32+
{% endfor %}
33+
{% endif %}
34+
35+
36+
{# FIXME: need to understand how this template generates newlines and stop generating newlines #}
37+
{% for op in resource.operations %}
38+
{% if op.query_params | length > 0 or op.header_params | length > 0 %}
39+
@dataclass
40+
class {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options(BaseOptions):
41+
{%- for p in op.query_params %}
42+
{%- if p.description is defined %}
43+
# {{ p.description }}
44+
{%- endif %}
45+
{%- if p.required %}
46+
{{ p.name }}: {{ p.type.to_python() }}
47+
{%- else %}
48+
{{ p.name }}: t.Optional[{{ p.type.to_python() }}] = None
49+
{%- endif %}
50+
{%- endfor %}
51+
{# FIXME: hardcoding idempotency-key for now since that is the only header param #}
52+
{%- if op.header_params | length > 0 %}
53+
idempotency_key: t.Optional[str] = None
54+
{%- endif %}
55+
{%- endif %}
56+
{%- endfor %}
57+
58+
59+
{%- for is_async in [true, false] %}
60+
class {{ resource.name | to_upper_camel_case }}{% if is_async %}Async{% endif %}(ApiBase):
61+
{%- if resource.operations | length != 0 %}
62+
{%- for op in resource.operations %}
63+
{# FIXME: find a better way to deal with python's reserved keywords!, for now i do this hack #}
64+
{%- if op.name == "import" %}
65+
{%- set op_name = "import_" %}
66+
{%- else %}
67+
{%- set op_name = op.name | to_snake_case %}
68+
{%- endif %}
69+
{% if op.deprecated %}
70+
@deprecated
71+
{%- endif %}
72+
{%- if is_async -%}
73+
{%- set func_def = "async def" %}
74+
{%- else %}
75+
{%- set func_def = "def" %}
76+
{%- endif %}
77+
{{ func_def }} {{ op_name }}(self
78+
{#- path parameters are non optional strings #}
79+
{% for p in op.path_params -%}
80+
,{{ p }}: str
81+
{% endfor -%}
82+
{# body parameter struct #}
83+
{%- if op.request_body_schema_name is defined %}
84+
,{{ op.request_body_schema_name | to_snake_case }}: {{ op.request_body_schema_name }}
85+
{%- endif %}
86+
87+
{# add query_options type #}
88+
{%- if op.query_params | length > 0 or op.header_params | length > 0 %}
89+
,options: {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options = {{ resource_type_name }}{{ op.name | to_upper_camel_case }}Options()
90+
{%- endif %}
91+
92+
) ->
93+
{%- if op.response_body_schema_name is defined -%}
94+
{{ op.response_body_schema_name | to_upper_camel_case }}:
95+
{% else -%}
96+
None:
97+
{%- endif %}
98+
{% if op.description is defined -%}
99+
{{ op.description | to_doc_comment(style="python") }}
100+
{%- endif -%}
101+
{%- set internal_func_name -%}
102+
{{ op.id | to_snake_case }}{% if is_async -%}.request_asyncio{% else -%}.request_sync{% endif -%}
103+
{%- endset -%}
104+
{% set ret -%}
105+
{%- if is_async -%}return await{% else %}return{% endif -%}
106+
{%- endset %}
107+
{{ ret }} {{ internal_func_name }}(client=self._client
108+
{%- for p in op.path_params -%}
109+
,{{ p }}={{ p }}
110+
{%- endfor -%}
111+
{% if op.request_body_schema_name is defined -%}
112+
,json_body={{ op.request_body_schema_name | to_snake_case }}
113+
{% endif -%}
114+
{% if (op.query_params | length > 0 )or (op.header_params | length > 0) %}
115+
{# FIXME: how do we know there is no duplicate options in the path params #}
116+
,**options.to_dict()
117+
{% endif -%}
118+
)
119+
{% endfor -%}
120+
{% else %}
121+
{# empty class with no functions, so we have a pass here #}
122+
pass
123+
{% endif %}
124+
{% endfor %}

0 commit comments

Comments
 (0)