arkindex-client 1.1.1__py3-none-any.whl → 1.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,9 +3,9 @@ import re
3
3
  from urllib.parse import urljoin
4
4
 
5
5
  import typesystem
6
+ from typesystem.json_schema import JSONSchema
6
7
 
7
- from arkindex.document import Document, Field, Link, Section
8
- from arkindex.schema.jsonschema import JSON_SCHEMA
8
+ from arkindex.document import Document, Field, Link
9
9
 
10
10
  SCHEMA_REF = typesystem.Object(
11
11
  properties={"$ref": typesystem.String(pattern="^#/components/schemas/")}
@@ -13,92 +13,27 @@ SCHEMA_REF = typesystem.Object(
13
13
  REQUESTBODY_REF = typesystem.Object(
14
14
  properties={"$ref": typesystem.String(pattern="^#/components/requestBodies/")}
15
15
  )
16
- RESPONSE_REF = typesystem.Object(
17
- properties={"$ref": typesystem.String(pattern="^#/components/responses/")}
18
- )
19
16
 
20
- definitions = typesystem.SchemaDefinitions()
17
+ definitions = typesystem.Definitions()
21
18
 
22
- OPEN_API = typesystem.Object(
23
- title="OpenAPI",
24
- properties={
19
+ OPEN_API = typesystem.Schema(
20
+ fields={
25
21
  "openapi": typesystem.String(),
26
- "info": typesystem.Reference("Info", definitions=definitions),
27
22
  "servers": typesystem.Array(
28
- items=typesystem.Reference("Server", definitions=definitions)
23
+ items=typesystem.Reference("Server", definitions=definitions),
24
+ default=[],
29
25
  ),
30
26
  "paths": typesystem.Reference("Paths", definitions=definitions),
31
- "components": typesystem.Reference("Components", definitions=definitions),
32
- "security": typesystem.Array(
33
- items=typesystem.Reference("SecurityRequirement", definitions=definitions)
34
- ),
35
- "tags": typesystem.Array(
36
- items=typesystem.Reference("Tag", definitions=definitions)
27
+ "components": typesystem.Reference(
28
+ "Components", default=None, definitions=definitions
37
29
  ),
38
- "externalDocs": typesystem.Reference(
39
- "ExternalDocumentation", definitions=definitions
40
- ),
41
- },
42
- pattern_properties={"^x-": typesystem.Any()},
43
- additional_properties=False,
44
- required=["openapi", "info", "paths"],
45
- )
46
-
47
- definitions["Info"] = typesystem.Object(
48
- properties={
49
- "title": typesystem.String(allow_blank=True),
50
- "description": typesystem.Text(allow_blank=True),
51
- "termsOfService": typesystem.String(format="url"),
52
- "contact": typesystem.Reference("Contact", definitions=definitions),
53
- "license": typesystem.Reference("License", definitions=definitions),
54
- "version": typesystem.String(allow_blank=True),
55
- },
56
- pattern_properties={"^x-": typesystem.Any()},
57
- additional_properties=False,
58
- required=["title", "version"],
59
- )
60
-
61
- definitions["Contact"] = typesystem.Object(
62
- properties={
63
- "name": typesystem.String(allow_blank=True),
64
- "url": typesystem.String(format="url"),
65
- "email": typesystem.String(format="email"),
66
30
  },
67
- pattern_properties={"^x-": typesystem.Any()},
68
- additional_properties=False,
69
31
  )
70
32
 
71
- definitions["License"] = typesystem.Object(
72
- properties={"name": typesystem.String(), "url": typesystem.String(format="url")},
73
- required=["name"],
74
- pattern_properties={"^x-": typesystem.Any()},
75
- additional_properties=False,
76
- )
77
-
78
- definitions["Server"] = typesystem.Object(
79
- properties={
33
+ definitions["Server"] = typesystem.Schema(
34
+ fields={
80
35
  "url": typesystem.String(),
81
- "description": typesystem.Text(allow_blank=True),
82
- "variables": typesystem.Object(
83
- additional_properties=typesystem.Reference(
84
- "ServerVariable", definitions=definitions
85
- )
86
- ),
87
- },
88
- pattern_properties={"^x-": typesystem.Any()},
89
- additional_properties=False,
90
- required=["url"],
91
- )
92
-
93
- definitions["ServerVariable"] = typesystem.Object(
94
- properties={
95
- "enum": typesystem.Array(items=typesystem.String()),
96
- "default": typesystem.String(),
97
- "description": typesystem.Text(allow_blank=True),
98
36
  },
99
- pattern_properties={"^x-": typesystem.Any()},
100
- additional_properties=False,
101
- required=["default"],
102
37
  )
103
38
 
104
39
  definitions["Paths"] = typesystem.Object(
@@ -112,7 +47,6 @@ definitions["Paths"] = typesystem.Object(
112
47
  definitions["Path"] = typesystem.Object(
113
48
  properties={
114
49
  "summary": typesystem.String(allow_blank=True),
115
- "description": typesystem.Text(allow_blank=True),
116
50
  "get": typesystem.Reference("Operation", definitions=definitions),
117
51
  "put": typesystem.Reference("Operation", definitions=definitions),
118
52
  "post": typesystem.Reference("Operation", definitions=definitions),
@@ -129,18 +63,11 @@ definitions["Path"] = typesystem.Object(
129
63
  ),
130
64
  # TODO: | ReferenceObject
131
65
  },
132
- pattern_properties={"^x-": typesystem.Any()},
133
- additional_properties=False,
66
+ additional_properties=True,
134
67
  )
135
68
 
136
69
  definitions["Operation"] = typesystem.Object(
137
70
  properties={
138
- "tags": typesystem.Array(items=typesystem.String()),
139
- "summary": typesystem.String(allow_blank=True),
140
- "description": typesystem.Text(allow_blank=True),
141
- "externalDocs": typesystem.Reference(
142
- "ExternalDocumentation", definitions=definitions
143
- ),
144
71
  "operationId": typesystem.String(),
145
72
  "parameters": typesystem.Array(
146
73
  items=typesystem.Reference("Parameter", definitions=definitions)
@@ -149,61 +76,29 @@ definitions["Operation"] = typesystem.Object(
149
76
  | typesystem.Reference(
150
77
  "RequestBody", definitions=definitions
151
78
  ), # TODO: RequestBody | ReferenceObject
152
- "responses": typesystem.Reference("Responses", definitions=definitions),
153
- # TODO: 'callbacks'
154
79
  "deprecated": typesystem.Boolean(),
155
- "security": typesystem.Array(
156
- typesystem.Reference("SecurityRequirement", definitions=definitions)
157
- ),
158
80
  "servers": typesystem.Array(
159
81
  items=typesystem.Reference("Server", definitions=definitions)
160
82
  ),
83
+ # A custom property added by Arkindex to provide a hint to the API client
84
+ # that this endpoint is paginated, which changes the behavior of ArkindexClient.paginate.
85
+ "x-paginated": typesystem.Boolean(default=None),
161
86
  },
162
- pattern_properties={"^x-": typesystem.Any()},
163
- additional_properties=False,
164
- )
165
-
166
- definitions["ExternalDocumentation"] = typesystem.Object(
167
- properties={
168
- "description": typesystem.Text(allow_blank=True),
169
- "url": typesystem.String(format="url"),
170
- },
171
- pattern_properties={"^x-": typesystem.Any()},
172
- additional_properties=False,
173
- required=["url"],
87
+ additional_properties=True,
174
88
  )
175
89
 
176
- definitions["Parameter"] = typesystem.Object(
177
- properties={
90
+ definitions["Parameter"] = typesystem.Schema(
91
+ fields={
178
92
  "name": typesystem.String(),
179
93
  "in": typesystem.Choice(choices=["query", "header", "path", "cookie"]),
180
- "description": typesystem.Text(allow_blank=True),
181
- "required": typesystem.Boolean(),
182
- "deprecated": typesystem.Boolean(),
183
- "allowEmptyValue": typesystem.Boolean(),
184
- "style": typesystem.Choice(
185
- choices=[
186
- "matrix",
187
- "label",
188
- "form",
189
- "simple",
190
- "spaceDelimited",
191
- "pipeDelimited",
192
- "deepObject",
193
- ]
194
- ),
195
- "schema": JSON_SCHEMA | SCHEMA_REF,
196
- "example": typesystem.Any(),
197
- # TODO: Other fields
94
+ "required": typesystem.Boolean(default=False),
95
+ "deprecated": typesystem.Boolean(default=False),
96
+ "schema": JSONSchema | SCHEMA_REF,
198
97
  },
199
- pattern_properties={"^x-": typesystem.Any()},
200
- additional_properties=False,
201
- required=["name", "in"],
202
98
  )
203
99
 
204
100
  definitions["RequestBody"] = typesystem.Object(
205
101
  properties={
206
- "description": typesystem.String(allow_blank=True),
207
102
  "content": typesystem.Object(
208
103
  additional_properties=typesystem.Reference(
209
104
  "MediaType", definitions=definitions
@@ -211,88 +106,19 @@ definitions["RequestBody"] = typesystem.Object(
211
106
  ),
212
107
  "required": typesystem.Boolean(),
213
108
  },
214
- pattern_properties={"^x-": typesystem.Any()},
215
- additional_properties=False,
216
- )
217
-
218
- definitions["Responses"] = typesystem.Object(
219
- properties={
220
- "default": typesystem.Reference("Response", definitions=definitions)
221
- | RESPONSE_REF
222
- },
223
- pattern_properties={
224
- "^([1-5][0-9][0-9]|[1-5]XX)$": typesystem.Reference(
225
- "Response", definitions=definitions
226
- )
227
- | RESPONSE_REF,
228
- "^x-": typesystem.Any(),
229
- },
230
- additional_properties=False,
231
- )
232
-
233
- definitions["Response"] = typesystem.Object(
234
- properties={
235
- "description": typesystem.String(allow_blank=True),
236
- "content": typesystem.Object(
237
- additional_properties=typesystem.Reference(
238
- "MediaType", definitions=definitions
239
- )
240
- ),
241
- "headers": typesystem.Object(
242
- additional_properties=typesystem.Reference(
243
- "Header", definitions=definitions
244
- )
245
- ),
246
- # TODO: Header | ReferenceObject
247
- # TODO: links
248
- },
249
- pattern_properties={"^x-": typesystem.Any()},
250
- additional_properties=False,
109
+ additional_properties=True,
251
110
  )
252
111
 
253
112
  definitions["MediaType"] = typesystem.Object(
254
113
  properties={
255
- "schema": JSON_SCHEMA | SCHEMA_REF,
256
- "example": typesystem.Any(),
257
- # TODO 'examples', 'encoding'
114
+ "schema": JSONSchema | SCHEMA_REF,
258
115
  },
259
- pattern_properties={"^x-": typesystem.Any()},
260
- additional_properties=False,
261
- )
262
-
263
- definitions["Header"] = typesystem.Object(
264
- properties={
265
- "description": typesystem.Text(),
266
- "required": typesystem.Boolean(),
267
- "deprecated": typesystem.Boolean(),
268
- "allowEmptyValue": typesystem.Boolean(),
269
- "style": typesystem.Choice(
270
- choices=[
271
- "matrix",
272
- "label",
273
- "form",
274
- "simple",
275
- "spaceDelimited",
276
- "pipeDelimited",
277
- "deepObject",
278
- ]
279
- ),
280
- "schema": JSON_SCHEMA | SCHEMA_REF,
281
- "example": typesystem.Any(),
282
- # TODO: Other fields
283
- },
284
- pattern_properties={"^x-": typesystem.Any()},
285
- additional_properties=False,
116
+ additional_properties=True,
286
117
  )
287
118
 
288
119
  definitions["Components"] = typesystem.Object(
289
120
  properties={
290
- "schemas": typesystem.Object(additional_properties=JSON_SCHEMA),
291
- "responses": typesystem.Object(
292
- additional_properties=typesystem.Reference(
293
- "Response", definitions=definitions
294
- )
295
- ),
121
+ "schemas": typesystem.Object(additional_properties=JSONSchema),
296
122
  "parameters": typesystem.Object(
297
123
  additional_properties=typesystem.Reference(
298
124
  "Parameter", definitions=definitions
@@ -303,53 +129,10 @@ definitions["Components"] = typesystem.Object(
303
129
  "RequestBody", definitions=definitions
304
130
  )
305
131
  ),
306
- "securitySchemes": typesystem.Object(
307
- additional_properties=typesystem.Reference(
308
- "SecurityScheme", definitions=definitions
309
- )
310
- ),
311
- # TODO: Other fields
312
- },
313
- pattern_properties={"^x-": typesystem.Any()},
314
- additional_properties=False,
315
- )
316
-
317
- definitions["Tag"] = typesystem.Object(
318
- properties={
319
- "name": typesystem.String(),
320
- "description": typesystem.Text(allow_blank=True),
321
- "externalDocs": typesystem.Reference(
322
- "ExternalDocumentation", definitions=definitions
323
- ),
324
- },
325
- pattern_properties={"^x-": typesystem.Any()},
326
- additional_properties=False,
327
- required=["name"],
328
- )
329
-
330
- definitions["SecurityRequirement"] = typesystem.Object(
331
- additional_properties=typesystem.Array(items=typesystem.String())
332
- )
333
-
334
- definitions["SecurityScheme"] = typesystem.Object(
335
- properties={
336
- "type": typesystem.Choice(
337
- choices=["apiKey", "http", "oauth2", "openIdConnect"]
338
- ),
339
- "description": typesystem.Text(allow_blank=True),
340
- "name": typesystem.String(),
341
- "in": typesystem.Choice(choices=["query", "header", "cookie"]),
342
- "scheme": typesystem.String(),
343
- "bearerFormat": typesystem.String(),
344
- "flows": typesystem.Any(), # TODO: OAuthFlows
345
- "openIdConnectUrl": typesystem.String(format="url"),
346
132
  },
347
- pattern_properties={"^x-": typesystem.Any()},
348
- additional_properties=False,
349
- required=["type"],
133
+ additional_properties=True,
350
134
  )
351
135
 
352
-
353
136
  METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"]
354
137
 
355
138
 
@@ -373,23 +156,13 @@ def _simple_slugify(text):
373
156
 
374
157
  class OpenAPI:
375
158
  def load(self, data):
376
- title = lookup(data, ["info", "title"])
377
- description = lookup(data, ["info", "description"])
378
- version = lookup(data, ["info", "version"])
379
- base_url = lookup(data, ["servers", 0, "url"])
380
159
  schema_definitions = self.get_schema_definitions(data)
381
- content = self.get_content(data, base_url, schema_definitions)
382
-
383
- return Document(
384
- title=title,
385
- description=description,
386
- version=version,
387
- url=base_url,
388
- content=content,
389
- )
160
+ links = self.get_links(data, schema_definitions)
161
+
162
+ return Document(links=links)
390
163
 
391
164
  def get_schema_definitions(self, data):
392
- definitions = typesystem.SchemaDefinitions()
165
+ definitions = typesystem.Definitions()
393
166
  schemas = lookup(data, ["components", "schemas"], {})
394
167
  for key, value in schemas.items():
395
168
  ref = f"#/components/schemas/{key}"
@@ -398,19 +171,16 @@ class OpenAPI:
398
171
  )
399
172
  return definitions
400
173
 
401
- def get_content(self, data, base_url, schema_definitions):
174
+ def get_links(self, data, schema_definitions):
402
175
  """
403
- Return all the links in the document, laid out by tag and operationId.
176
+ Return all the links in the document, laid out by operationId.
404
177
  """
405
- links_by_tag = {}
406
178
  links = []
407
179
 
408
180
  for path, path_info in data.get("paths", {}).items():
409
181
  operations = {key: path_info[key] for key in path_info if key in METHODS}
410
182
  for operation, operation_info in operations.items():
411
- tag = lookup(operation_info, ["tags", 0])
412
183
  link = self.get_link(
413
- base_url,
414
184
  path,
415
185
  path_info,
416
186
  operation,
@@ -420,36 +190,20 @@ class OpenAPI:
420
190
  if link is None:
421
191
  continue
422
192
 
423
- if tag is None:
424
- links.append(link)
425
- elif tag not in links_by_tag:
426
- links_by_tag[tag] = [link]
427
- else:
428
- links_by_tag[tag].append(link)
193
+ links.append(link)
429
194
 
430
- sections = [
431
- Section(name=_simple_slugify(tag), title=tag.title(), content=links)
432
- for tag, links in links_by_tag.items()
433
- ]
434
- return links + sections
195
+ return links
435
196
 
436
- def get_link(
437
- self, base_url, path, path_info, operation, operation_info, schema_definitions
438
- ):
197
+ def get_link(self, path, path_info, operation, operation_info, schema_definitions):
439
198
  """
440
199
  Return a single link in the document.
441
200
  """
442
- name = operation_info.get("operationId")
443
- title = operation_info.get("summary")
444
- description = operation_info.get("description")
445
-
446
- if name is None:
447
- name = _simple_slugify(title)
448
- if not name:
449
- return None
201
+ name = operation_info["operationId"]
202
+ deprecated = operation_info.get("deprecated", False)
203
+ paginated = operation_info.get("x-paginated")
450
204
 
451
- # Allow path info and operation info to override the base url.
452
- base_url = lookup(path_info, ["servers", 0, "url"], default=base_url)
205
+ # Allow path info and operation info to override the base URL, which is normally managed by the ArkindexClient.
206
+ base_url = lookup(path_info, ["servers", 0, "url"], default=None)
453
207
  base_url = lookup(operation_info, ["servers", 0, "url"], default=base_url)
454
208
 
455
209
  # Parameters are taken both from the path info, and from the operation.
@@ -487,10 +241,10 @@ class OpenAPI:
487
241
  name=name,
488
242
  url=urljoin(base_url, path),
489
243
  method=operation,
490
- title=title,
491
- description=description,
492
244
  fields=fields,
493
245
  encoding=encoding,
246
+ deprecated=deprecated,
247
+ paginated=paginated,
494
248
  )
495
249
 
496
250
  def get_field(self, parameter, schema_definitions):
@@ -499,10 +253,9 @@ class OpenAPI:
499
253
  """
500
254
  name = parameter.get("name")
501
255
  location = parameter.get("in")
502
- description = parameter.get("description")
503
256
  required = parameter.get("required", False)
504
257
  schema = parameter.get("schema")
505
- example = parameter.get("example")
258
+ deprecated = parameter.get("deprecated", False)
506
259
 
507
260
  if schema is not None:
508
261
  if "$ref" in schema:
@@ -516,8 +269,7 @@ class OpenAPI:
516
269
  return Field(
517
270
  name=name,
518
271
  location=location,
519
- description=description,
520
272
  required=required,
521
273
  schema=schema,
522
- example=example,
274
+ deprecated=deprecated,
523
275
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arkindex-client
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: API client for the Arkindex project
5
5
  Home-page: https://gitlab.teklia.com/arkindex/api-client
6
6
  Author: Teklia <contact@teklia.com>
@@ -23,6 +23,6 @@ License-File: LICENSE
23
23
  Requires-Dist: PyYAML==6.0.2
24
24
  Requires-Dist: requests~=2.28
25
25
  Requires-Dist: tenacity==8.2.3
26
- Requires-Dist: typesystem==0.2.5
26
+ Requires-Dist: typesystem==0.4.1
27
27
 
28
28
  Documentation is available at https://api.arkindex.org
@@ -3,21 +3,18 @@ apistar/exceptions.py,sha256=yzjDlUB5o0xaORBabqTXmf4ckYjNHz1ceV8ECg3jDek,328
3
3
  arkindex/__init__.py,sha256=OBw25Nwe6r1AN3a36-8lnUcDy3nkDIiebBgYNK2Zo9o,99
4
4
  arkindex/auth.py,sha256=OeuzFeCQ8FAt0kqPECjsEz-Ki9__-y69z5sAuyTZ28c,1550
5
5
  arkindex/compat.py,sha256=Kjxu--QoF8sBxKOvXMtNcDQ0XK7MLc_2C8Q2knll4Lk,805
6
- arkindex/document.py,sha256=SUmzvuJpeHlRC4ozqnqsPFpzZ9_Yb9p6vxIZpMjMCSA,6783
6
+ arkindex/document.py,sha256=YyqSm3Kc35j3iWuJujyfrLfMy-gNydBtmcR45pUtfC4,3732
7
7
  arkindex/exceptions.py,sha256=hDxbgC7uAD8wbTQS1DaEJZ25Nun41Io8Y0BiwrZ1ZSM,2016
8
8
  arkindex/mock.py,sha256=olYBFCkLQuuf9gGu7wlmZiLFMQknGGi8evS531RjjUE,2755
9
9
  arkindex/pagination.py,sha256=c6dG_OkQDG00ZfGUbHuZxu-UvOpmYf7dJP1ZaUaha1Y,9008
10
10
  arkindex/client/__init__.py,sha256=g_G_bSfMbduYzpi9iURTn0cYLV4nMulDR8rD7x-DLyc,142
11
- arkindex/client/base.py,sha256=vlR5HjaNQ_LzIP_FAzaZbhJSh7VzD9mXc0T8C5FB8EU,3400
12
- arkindex/client/client.py,sha256=lfHyicizHDxdymPA1hl0kJj7vdrudVvbE2Ei3qtZqQM,12019
11
+ arkindex/client/client.py,sha256=UEkOYXg9HUdKd_20VNpNpXRLWvwTeKpbu-IkV6Xfv2I,15416
13
12
  arkindex/client/decoders.py,sha256=F_uBGOrh1BFnZzuW0MTjwm8wAArbybPsrIVol_2vYN0,7886
14
- arkindex/client/transports.py,sha256=482CHa-8S5p190Z4cX6TiCWgz99enfloT7FCNuS02yY,4055
15
13
  arkindex/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- arkindex/schema/jsonschema.py,sha256=sJ0OlkowXoE4FnA3r9_QdOmLlDP46K7YPPQm58NkfMo,2572
17
- arkindex/schema/openapi.py,sha256=bwVAEjdHNUf9iRPVdbQwruivs4GAwbe0db1KkLNKa80,17603
14
+ arkindex/schema/openapi.py,sha256=HHAHyUxqa6sK1l8aEy7SHx-9w20Pbov54AB4rHPjguk,9183
18
15
  arkindex/schema/validator.py,sha256=N2sda7vxfivw68VuyX-MfmUlrXjf_LEHNg6OCKc1mjQ,1926
19
- arkindex_client-1.1.1.dist-info/LICENSE,sha256=s7yDHdG8liSj2PiaVwRi9G5wR1qDXSPmhPJPgWbrkWU,34504
20
- arkindex_client-1.1.1.dist-info/METADATA,sha256=IzsAvC5p34ps77eNhP8x9s-GSN-_qIp1eSlXemcQJLA,1080
21
- arkindex_client-1.1.1.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
22
- arkindex_client-1.1.1.dist-info/top_level.txt,sha256=ALyF0lTPpxOheUGmSVwEhgI6eMYwm_9Eu37G-RwGBRM,17
23
- arkindex_client-1.1.1.dist-info/RECORD,,
16
+ arkindex_client-1.1.2.dist-info/LICENSE,sha256=s7yDHdG8liSj2PiaVwRi9G5wR1qDXSPmhPJPgWbrkWU,34504
17
+ arkindex_client-1.1.2.dist-info/METADATA,sha256=DsYRcnTdzzByCuCFxpIPxL1pagT_pN0rPzztb0Cb0y8,1080
18
+ arkindex_client-1.1.2.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
19
+ arkindex_client-1.1.2.dist-info/top_level.txt,sha256=ALyF0lTPpxOheUGmSVwEhgI6eMYwm_9Eu37G-RwGBRM,17
20
+ arkindex_client-1.1.2.dist-info/RECORD,,
arkindex/client/base.py DELETED
@@ -1,98 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- from urllib.parse import quote, urljoin, urlparse
3
-
4
- import typesystem
5
-
6
- from arkindex import exceptions
7
- from arkindex.client.transports import HTTPTransport
8
- from arkindex.schema.validator import validate
9
-
10
-
11
- class BaseClient:
12
- def __init__(
13
- self,
14
- schema,
15
- encoding=None,
16
- auth=None,
17
- decoders=None,
18
- headers=None,
19
- session=None,
20
- allow_cookies=True,
21
- verify=True,
22
- ):
23
- self.document = validate(schema, encoding=encoding)
24
- self.transport = HTTPTransport(
25
- auth=auth,
26
- decoders=decoders,
27
- headers=headers,
28
- session=session,
29
- allow_cookies=allow_cookies,
30
- verify=verify,
31
- )
32
-
33
- def lookup_operation(self, operation_id: str):
34
- for item in self.document.walk_links():
35
- if item.link.name == operation_id:
36
- return item.link
37
- text = 'Operation ID "%s" not found in schema.' % operation_id
38
- message = exceptions.ErrorMessage(text=text, code="invalid-operation")
39
- raise exceptions.ClientError(messages=[message])
40
-
41
- def get_url(self, link, params):
42
- url = urljoin(self.document.url, link.url)
43
-
44
- scheme = urlparse(url).scheme.lower()
45
-
46
- if not scheme:
47
- text = "URL missing scheme '%s'." % url
48
- message = exceptions.ErrorMessage(text=text, code="invalid-url")
49
- raise exceptions.ClientError(messages=[message])
50
-
51
- if scheme not in self.transport.schemes:
52
- text = "Unsupported URL scheme '%s'." % scheme
53
- message = exceptions.ErrorMessage(text=text, code="invalid-url")
54
- raise exceptions.ClientError(messages=[message])
55
-
56
- for field in link.get_path_fields():
57
- value = str(params[field.name])
58
- if "{%s}" % field.name in url:
59
- url = url.replace("{%s}" % field.name, quote(value, safe=""))
60
- elif "{+%s}" % field.name in url:
61
- url = url.replace("{+%s}" % field.name, quote(value, safe="/"))
62
-
63
- return url
64
-
65
- def get_query_params(self, link, params):
66
- return {
67
- field.name: params[field.name]
68
- for field in link.get_query_fields()
69
- if field.name in params
70
- }
71
-
72
- def get_content_and_encoding(self, link, params):
73
- body_field = link.get_body_field()
74
- if body_field and body_field.name in params:
75
- return (params[body_field.name], link.encoding)
76
- return (None, None)
77
-
78
- def request(self, operation_id: str, **params):
79
- link = self.lookup_operation(operation_id)
80
-
81
- validator = typesystem.Object(
82
- properties={field.name: typesystem.Any() for field in link.fields},
83
- required=[field.name for field in link.fields if field.required],
84
- additional_properties=False,
85
- )
86
- try:
87
- validator.validate(params)
88
- except typesystem.ValidationError as exc:
89
- raise exceptions.ClientError(messages=exc.messages()) from None
90
-
91
- method = link.method
92
- url = self.get_url(link, params)
93
- query_params = self.get_query_params(link, params)
94
- (content, encoding) = self.get_content_and_encoding(link, params)
95
-
96
- return self.transport.send(
97
- method, url, query_params=query_params, content=content, encoding=encoding
98
- )