Skip to content

Commit 50c71a1

Browse files
authored
Update OpenAPI spec for Python SDK (#439)
## Changes This PR updates the OpenAPI spec for the Python SDK to d136ad0541f036372601bad9a4382db06c3c912d. As part of this, we add some protection against fields or methods in our spec that conflict with reserved keywords in Python. ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [ ] `make test` run locally - [ ] `make fmt` applied - [ ] relevant integration tests applied
1 parent 69aa629 commit 50c71a1

38 files changed

+1536
-458
lines changed

.codegen.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"formatter": "yapf -pri $FILENAMES && autoflake -i $FILENAMES && isort $FILENAMES",
3+
"template_libraries": [
4+
".codegen/lib.tmpl"
5+
],
36
"packages": {
47
".codegen/service.py.tmpl": "databricks/sdk/service/{{.Name}}.py"
58
},

.codegen/_openapi_sha

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5903bb39137fd76ac384b2044e425f9c56840e00
1+
d136ad0541f036372601bad9a4382db06c3c912d

.codegen/lib.tmpl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{{ define "safe-name" -}}
2+
{{/* https://docs.python.org/3/reference/lexical_analysis.html#keywords */}}
3+
{{- $keywords := list "False" "await" "else" "import" "pass" "None" "break" "except" "in" "raise"
4+
"True" "class" "finally" "is" "return" "and" "continue" "for" "lambda" "try"
5+
"as" "def" "from" "nonlocal" "while" "assert" "del" "global" "not" "with"
6+
"async" "elif" "if" "or" "yield" -}}
7+
{{.}}{{ if in $keywords . }}_{{ end }}
8+
{{- end}}
9+
10+
{{ define "safe-snake-name" -}}
11+
{{ template "safe-name" .SnakeName }}
12+
{{- end}}

.codegen/service.py.tmpl

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ from databricks.sdk.service import {{.Package.Name}}{{end}}
2121
class {{.PascalName}}{{if eq "List" .PascalName}}Request{{end}}:{{if .Description}}
2222
"""{{.Comment " " 100}}"""
2323
{{end}}{{- range .RequiredFields | alphanumOnly}}
24-
{{.SnakeName}}: {{template "type" .Entity}}{{end}}{{- range .NonRequiredFields | alphanumOnly}}
25-
{{.SnakeName}}: Optional[{{template "type" .Entity}}] = None{{end}}
24+
{{template "safe-snake-name" .}}: {{template "type" .Entity}}{{end}}{{- range .NonRequiredFields | alphanumOnly}}
25+
{{template "safe-snake-name" .}}: Optional[{{template "type" .Entity}}] = None{{end}}
2626
{{if .HasJsonField -}}
2727
def as_dict(self) -> dict:
2828
body = {}
29-
{{range .Fields | alphanumOnly}}if self.{{.SnakeName}}{{with .Entity.IsPrimitive}} is not None{{end}}: body['{{.Name}}'] = {{template "as_request_type" .}}
29+
{{range .Fields | alphanumOnly}}if self.{{template "safe-snake-name" .}}{{with .Entity.IsPrimitive}} is not None{{end}}: body['{{.Name}}'] = {{template "as_request_type" .}}
3030
{{end -}}
3131
return body
3232

3333
@classmethod
3434
def from_dict(cls, d: Dict[str, any]) -> '{{.PascalName}}{{if eq "List" .PascalName}}Request{{end}}':
35-
return cls({{range $i, $f := .Fields | alphanumOnly}}{{if $i}}, {{end}}{{$f.SnakeName}}={{template "from_dict_type" $f}}{{end}})
35+
return cls({{range $i, $f := .Fields | alphanumOnly}}{{if $i}}, {{end}}{{template "safe-snake-name" $f}}={{template "from_dict_type" $f}}{{end}})
3636
{{end}}
3737
{{end}}
3838
{{else if .ArrayValue}}type {{.PascalName}} []{{template "type" .ArrayValue}}
@@ -56,10 +56,10 @@ class {{.PascalName}}{{if eq "List" .PascalName}}Request{{end}}:{{if .Descriptio
5656
{{- define "as_request_type" -}}
5757
{{- if not .Entity }}None # ERROR: No Type
5858
{{- /* This should be done recursively, but recursion in text templates is not supported. */ -}}
59-
{{- else if .Entity.ArrayValue }}[{{if or .Entity.ArrayValue.IsObject .Entity.ArrayValue.IsExternal}}v.as_dict(){{ else if .Entity.ArrayValue.Enum }}v.value{{else}}v{{end}} for v in self.{{.SnakeName}}]
60-
{{- else if or .Entity.IsObject .Entity.IsExternal }}self.{{.SnakeName}}.as_dict()
61-
{{- else if .Entity.Enum }}self.{{.SnakeName}}.value
62-
{{- else}}self.{{.SnakeName}}{{- end -}}
59+
{{- else if .Entity.ArrayValue }}[{{if or .Entity.ArrayValue.IsObject .Entity.ArrayValue.IsExternal}}v.as_dict(){{ else if .Entity.ArrayValue.Enum }}v.value{{else}}v{{end}} for v in self.{{template "safe-snake-name" .}}]
60+
{{- else if or .Entity.IsObject .Entity.IsExternal }}self.{{template "safe-snake-name" .}}.as_dict()
61+
{{- else if .Entity.Enum }}self.{{template "safe-snake-name" .}}.value
62+
{{- else}}self.{{template "safe-snake-name" .}}{{- end -}}
6363
{{- end -}}
6464
{{- define "type" -}}
6565
{{- if not . }}any # ERROR: No Type
@@ -113,22 +113,22 @@ class {{.Name}}API:{{if .Description}}
113113
def __init__(self, api_client):
114114
self._api = api_client
115115
{{range .Waits}}
116-
def {{.SnakeName}}(self{{range .Binding}}, {{.PollField.SnakeName}}: {{template "type-nq" .PollField.Entity}}{{end}},
116+
def {{template "safe-snake-name" .}}(self{{range .Binding}}, {{template "safe-snake-name" .PollField}}: {{template "type-nq" .PollField.Entity}}{{end}},
117117
timeout=timedelta(minutes={{.Timeout}}), callback: Optional[Callable[[{{.Poll.Response.PascalName}}], None]] = None) -> {{.Poll.Response.PascalName}}:
118118
deadline = time.time() + timeout.total_seconds()
119119
target_states = ({{range .Success}}{{.Entity.PascalName}}.{{.ConstantName}}, {{end}}){{if .Failure}}
120120
failure_states = ({{range .Failure}}{{.Entity.PascalName}}.{{.ConstantName}}, {{end}}){{end}}
121121
status_message = 'polling...'
122122
attempt = 1
123123
while time.time() < deadline:
124-
poll = self.{{.Poll.SnakeName}}({{range $i, $b := .Binding}}{{if $i}}, {{end}}{{.PollField.SnakeName}}={{.PollField.SnakeName}}{{- end}})
125-
status = poll{{range .StatusPath}}.{{.SnakeName}}{{end}}
124+
poll = self.{{template "safe-snake-name" .Poll}}({{range $i, $b := .Binding}}{{if $i}}, {{end}}{{template "safe-snake-name" .PollField}}={{template "safe-snake-name" .PollField}}{{- end}})
125+
status = poll{{range .StatusPath}}.{{template "safe-snake-name" .}}{{end}}
126126
{{if .ComplexMessagePath -}}
127127
status_message = f'current status: {status}'
128-
if poll.{{.MessagePathHead.SnakeName}}:
129-
status_message = poll{{range .MessagePath}}.{{.SnakeName}}{{end}}
128+
if poll.{{template "safe-snake-name" .MessagePathHead}}:
129+
status_message = poll{{range .MessagePath}}.{{template "safe-snake-name" .}}{{end}}
130130
{{- else if .MessagePath -}}
131-
status_message = poll{{range .MessagePath}}.{{.SnakeName}}{{end}}
131+
status_message = poll{{range .MessagePath}}.{{template "safe-snake-name" .}}{{end}}
132132
{{- else -}}
133133
status_message = f'current status: {status}'
134134
{{- end}}
@@ -141,7 +141,7 @@ class {{.Name}}API:{{if .Description}}
141141
msg = f'failed to reach {{range $i, $e := .Success}}{{if $i}} or {{end}}{{$e.Content}}{{end}}, got {status}: {status_message}'
142142
raise OperationFailed(msg)
143143
{{end}}prefix = f"{{range $i, $b := .Binding}}{{if $i}}, {{end -}}
144-
{{.PollField.SnakeName}}={{"{"}}{{.PollField.SnakeName}}{{"}"}}
144+
{{template "safe-snake-name" .PollField}}={{"{"}}{{template "safe-snake-name" .PollField}}{{"}"}}
145145
{{- end}}"
146146
sleep = attempt
147147
if sleep > 10:
@@ -154,25 +154,25 @@ class {{.Name}}API:{{if .Description}}
154154
{{end}}
155155

156156
{{range .Methods}}
157-
def {{.SnakeName}}{{if .IsNameReserved}}_{{end}}(self{{if .Request}}
158-
{{range .Request.RequiredFields}}, {{.SnakeName}}: {{template "type-nq" .Entity}}{{end}}
157+
def {{template "safe-snake-name" .}}(self{{if .Request}}
158+
{{range .Request.RequiredFields}}, {{template "safe-snake-name" .}}: {{template "type-nq" .Entity}}{{end}}
159159
{{if .Request.NonRequiredFields}}, *
160-
{{range .Request.NonRequiredFields}}, {{.SnakeName}}: Optional[{{template "type-nq" .Entity}}] = None{{end}}
160+
{{range .Request.NonRequiredFields}}, {{template "safe-snake-name" .}}: Optional[{{template "type-nq" .Entity}}] = None{{end}}
161161
{{- end}}
162162
{{- end}}){{template "method-return-type" .}}:
163163
{{if .Description}}"""{{.Comment " " 110 | trimSuffix "\"" }}
164164
{{with .Request}}{{range .RequiredFields}}
165-
:param {{.SnakeName}}: {{template "type-doc" .Entity}}{{if .Description}}
165+
:param {{template "safe-snake-name" .}}: {{template "type-doc" .Entity}}{{if .Description}}
166166
{{.Comment " " 110 | trimSuffix "\"" }}{{end}}
167167
{{- end}}{{range .NonRequiredFields}}
168-
:param {{.SnakeName}}: {{template "type-doc" .Entity}} (optional){{if .Description}}
168+
:param {{template "safe-snake-name" .}}: {{template "type-doc" .Entity}} (optional){{if .Description}}
169169
{{.Comment " " 110 | trimSuffix "\"" }}{{end}}
170170
{{- end}}
171171
{{end}}
172172
{{if and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) -}}
173173
:returns:
174174
Long-running operation waiter for {{template "type-doc" .Wait.Poll.Response}}.
175-
See :method:{{.Wait.SnakeName}} for more details.
175+
See :method:{{template "safe-snake-name" .Wait}} for more details.
176176
{{- else if .Response}}:returns: {{if .Response.ArrayValue -}}
177177
Iterator over {{template "type-doc" .Response.ArrayValue}}
178178
{{- else if .Pagination -}}
@@ -188,10 +188,10 @@ class {{.Name}}API:{{if .Description}}
188188
{{template "method-call" .}}
189189

190190
{{if and .Wait (and (not .IsCrudRead) (not (eq .SnakeName "get_run"))) }}
191-
def {{.SnakeName}}_and_wait(self{{range .Request.RequiredFields}}, {{.SnakeName}}: {{template "type-nq" .Entity}}{{end}}
192-
{{if .Request.NonRequiredFields}}, * {{range .Request.NonRequiredFields}}, {{.SnakeName}}: Optional[{{template "type-nq" .Entity}}] = None{{end}}{{- end}},
191+
def {{.SnakeName}}_and_wait(self{{range .Request.RequiredFields}}, {{template "safe-snake-name" .}}: {{template "type-nq" .Entity}}{{end}}
192+
{{if .Request.NonRequiredFields}}, * {{range .Request.NonRequiredFields}}, {{template "safe-snake-name" .}}: Optional[{{template "type-nq" .Entity}}] = None{{end}}{{- end}},
193193
timeout=timedelta(minutes={{.Wait.Timeout}})) -> {{.Wait.Poll.Response.PascalName}}:
194-
return self.{{.SnakeName}}({{range $i, $x := .Request.Fields}}{{if $i}}, {{end}}{{.SnakeName}}={{.SnakeName}}{{end}}).result(timeout=timeout)
194+
return self.{{template "safe-snake-name" .}}({{range $i, $x := .Request.Fields}}{{if $i}}, {{end}}{{template "safe-snake-name" .}}={{template "safe-snake-name" .}}{{end}}).result(timeout=timeout)
195195
{{end}}
196196
{{end -}}
197197
{{- end}}
@@ -202,9 +202,9 @@ class {{.Name}}API:{{if .Description}}
202202
query = {}{{end}}
203203
{{- range .Request.Fields}}{{ if not .IsPath }}
204204
{{- if .IsQuery }}
205-
if {{.SnakeName}} is not None: query['{{.Name}}'] = {{template "method-param-bind" .}}{{end}}
205+
if {{template "safe-snake-name" .}} is not None: query['{{.Name}}'] = {{template "method-param-bind" .}}{{end}}
206206
{{- if .IsJson }}
207-
if {{.SnakeName}} is not None: body['{{.Name}}'] = {{template "method-param-bind" .}}{{end}}
207+
if {{template "safe-snake-name" .}} is not None: body['{{.Name}}'] = {{template "method-param-bind" .}}{{end}}
208208
{{- end}}
209209
{{- end}}
210210
{{- end}}
@@ -221,10 +221,10 @@ class {{.Name}}API:{{if .Description}}
221221
{{- else if .Entity.ArrayValue }}[
222222
{{- if or .Entity.ArrayValue.IsObject .Entity.ArrayValue.IsExternal -}}v.as_dict()
223223
{{- else if .Entity.ArrayValue.Enum -}}v.value
224-
{{- else}}v{{end}} for v in {{.SnakeName}}]
225-
{{- else if .Entity.IsObject }}{{.SnakeName}}.as_dict()
226-
{{- else if .Entity.Enum }}{{.SnakeName}}.value
227-
{{- else}}{{.SnakeName}}{{- end -}}
224+
{{- else}}v{{end}} for v in {{template "safe-snake-name" .}}]
225+
{{- else if .Entity.IsObject }}{{template "safe-snake-name" .}}.as_dict()
226+
{{- else if .Entity.Enum }}{{template "safe-snake-name" .}}.value
227+
{{- else}}{{template "safe-snake-name" .}}{{- end -}}
228228
{{- end -}}
229229

230230
{{define "method-call" -}}
@@ -235,9 +235,9 @@ class {{.Name}}API:{{if .Description}}
235235

236236
{{define "method-call-retried" -}}
237237
{{if .Response}}op_response = {{end}}{{template "method-do" .}}
238-
return Wait(self.{{.Wait.SnakeName}}
238+
return Wait(self.{{template "safe-snake-name" .Wait}}
239239
{{if .Response}}, response = {{.Response.PascalName}}.from_dict(op_response){{end}}
240-
{{range .Wait.Binding}}, {{.PollField.SnakeName}}={{if .IsResponseBind}}op_response['{{.Bind.Name}}']{{else}}{{.Bind.SnakeName}}{{end}}
240+
{{range .Wait.Binding}}, {{template "safe-snake-name" .PollField}}={{if .IsResponseBind}}op_response['{{.Bind.Name}}']{{else}}{{template "safe-snake-name" .Bind}}{{end}}
241241
{{- end}})
242242
{{- end}}
243243

@@ -275,7 +275,7 @@ class {{.Name}}API:{{if .Description}}
275275
{{- end}}
276276
{{else -}}
277277
json = {{template "method-do" .}}
278-
parsed = {{.Response.PascalName}}.from_dict(json).{{.Pagination.Results.SnakeName}}
278+
parsed = {{.Response.PascalName}}.from_dict(json).{{template "safe-snake-name" .Pagination.Results}}
279279
return parsed if parsed is not None else []
280280
{{end}}
281281
{{- end}}
@@ -297,14 +297,14 @@ class {{.Name}}API:{{if .Description}}
297297
{{define "method-do" -}}
298298
self._api.do('{{.Verb}}',
299299
{{if .PathParts -}}
300-
f'{{range .PathParts}}{{.Prefix}}{{if .Field}}{{"{"}}{{.Field.SnakeName}}{{with .Field.Entity.Enum}}.value{{end}}{{"}"}}{{else if .IsAccountId}}{{"{self._api.account_id}"}}{{end}}{{ end }}'
300+
f'{{range .PathParts}}{{.Prefix}}{{if .Field}}{{"{"}}{{template "safe-snake-name" .Field}}{{with .Field.Entity.Enum}}.value{{end}}{{"}"}}{{else if .IsAccountId}}{{"{self._api.account_id}"}}{{end}}{{ end }}'
301301
{{- else}}'{{.Path}}'{{end}}
302302
{{if .Request}}
303303
{{- if .Request.HasQueryField}}, query=query{{end}}
304304
{{- if .Request.HasJsonField}}, body=body{{end}}
305305
{{end}}
306306
, headers=headers
307-
{{- if and .IsRequestByteStream .RequestBodyField }}, data={{.RequestBodyField.SnakeName}}{{ end }}
307+
{{- if and .IsRequestByteStream .RequestBodyField }}, data={{template "safe-snake-name" .RequestBodyField}}{{ end }}
308308
{{- if .IsResponseByteStream }}, raw=True{{ end }})
309309
{{- end}}
310310

databricks/sdk/__init__.py

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)