Skip to content

Commit 0d1df64

Browse files
committed
Support multiple tags in each endpoint
1 parent 47e576c commit 0d1df64

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

openapi_python_client/parser/openapi.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,22 @@ def from_data(
5757
operation: Optional[oai.Operation] = getattr(path_data, method)
5858
if operation is None:
5959
continue
60-
tag = utils.PythonIdentifier(value=(operation.tags or ["default"])[0], prefix="tag")
61-
collection = endpoints_by_tag.setdefault(tag, EndpointCollection(tag=tag))
60+
61+
tags = [
62+
utils.PythonIdentifier(value=tag, prefix="tag")
63+
for tag in operation.tags or ["default"]
64+
]
65+
66+
collections = [
67+
endpoints_by_tag.setdefault(tag, EndpointCollection(tag=tag))
68+
for tag in tags
69+
]
70+
6271
endpoint, schemas, parameters = Endpoint.from_data(
6372
data=operation,
6473
path=path,
6574
method=method,
66-
tag=tag,
75+
tags=tags,
6776
schemas=schemas,
6877
parameters=parameters,
6978
config=config,
@@ -77,14 +86,17 @@ def from_data(
7786
endpoint = Endpoint.sort_parameters(endpoint=endpoint)
7887
if isinstance(endpoint, ParseError):
7988
endpoint.header = (
80-
f"WARNING parsing {method.upper()} {path} within {tag}. Endpoint will not be generated."
89+
f"WARNING parsing {method.upper()} {path} within {'/'.join(tags)}. Endpoint will not be generated."
8190
)
82-
collection.parse_errors.append(endpoint)
91+
for collection in collections:
92+
collection.parse_errors.append(endpoint)
8393
continue
8494
for error in endpoint.errors:
85-
error.header = f"WARNING parsing {method.upper()} {path} within {tag}."
86-
collection.parse_errors.append(error)
87-
collection.endpoints.append(endpoint)
95+
error.header = f"WARNING parsing {method.upper()} {path} within {'/'.join(tags)}."
96+
for collection in collections:
97+
collection.parse_errors.append(error)
98+
for collection in collections:
99+
collection.endpoints.append(endpoint)
88100

89101
return endpoints_by_tag, schemas, parameters
90102

@@ -111,7 +123,7 @@ class Endpoint:
111123
description: Optional[str]
112124
name: str
113125
requires_security: bool
114-
tag: str
126+
tags: List[str]
115127
summary: Optional[str] = ""
116128
relative_imports: Set[str] = field(default_factory=set)
117129
query_parameters: Dict[str, Property] = field(default_factory=dict)
@@ -464,7 +476,7 @@ def from_data(
464476
data: oai.Operation,
465477
path: str,
466478
method: str,
467-
tag: str,
479+
tags: List[str],
468480
schemas: Schemas,
469481
parameters: Parameters,
470482
config: Config,
@@ -483,7 +495,7 @@ def from_data(
483495
description=utils.remove_string_escapes(data.description) if data.description else "",
484496
name=name,
485497
requires_security=bool(data.security),
486-
tag=tag,
498+
tags=tags,
487499
)
488500

489501
result, schemas, parameters = Endpoint.add_parameters(

tests/test_parser/test_openapi.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def make_endpoint(self):
130130
description=None,
131131
name="name",
132132
requires_security=False,
133-
tag="tag",
133+
tags=["tag"],
134134
relative_imports={"import_3"},
135135
)
136136

@@ -981,7 +981,7 @@ def test_from_data_bad_params(self, mocker):
981981
data=data,
982982
path=path,
983983
method=method,
984-
tag="default",
984+
tags=["default"],
985985
schemas=initial_schemas,
986986
parameters=parameters,
987987
config=config,
@@ -1016,7 +1016,7 @@ def test_from_data_bad_responses(self, mocker):
10161016
data=data,
10171017
path=path,
10181018
method=method,
1019-
tag="default",
1019+
tags=["default"],
10201020
schemas=initial_schemas,
10211021
parameters=initial_parameters,
10221022
config=config,
@@ -1059,7 +1059,7 @@ def test_from_data_standard(self, mocker):
10591059
data=data,
10601060
path=path,
10611061
method=method,
1062-
tag="default",
1062+
tags=["default"],
10631063
schemas=initial_schemas,
10641064
parameters=initial_parameters,
10651065
config=config,
@@ -1075,7 +1075,7 @@ def test_from_data_standard(self, mocker):
10751075
summary="",
10761076
name=data.operationId,
10771077
requires_security=True,
1078-
tag="default",
1078+
tags=["default"],
10791079
),
10801080
data=data,
10811081
schemas=initial_schemas,
@@ -1113,7 +1113,7 @@ def test_from_data_no_operation_id(self, mocker):
11131113
parameters = mocker.MagicMock()
11141114

11151115
endpoint, return_schemas, return_params = Endpoint.from_data(
1116-
data=data, path=path, method=method, tag="default", schemas=schemas, parameters=parameters, config=config
1116+
data=data, path=path, method=method, tags=["default"], schemas=schemas, parameters=parameters, config=config
11171117
)
11181118

11191119
assert (endpoint, return_schemas) == _add_body.return_value
@@ -1126,7 +1126,7 @@ def test_from_data_no_operation_id(self, mocker):
11261126
summary="",
11271127
name="get_path_with_param",
11281128
requires_security=True,
1129-
tag="default",
1129+
tags=["default"],
11301130
),
11311131
data=data,
11321132
schemas=schemas,
@@ -1167,7 +1167,7 @@ def test_from_data_no_security(self, mocker):
11671167
config = MagicMock()
11681168

11691169
Endpoint.from_data(
1170-
data=data, path=path, method=method, tag="a", schemas=schemas, parameters=parameters, config=config
1170+
data=data, path=path, method=method, tags=["a"], schemas=schemas, parameters=parameters, config=config
11711171
)
11721172

11731173
add_parameters.assert_called_once_with(
@@ -1178,7 +1178,7 @@ def test_from_data_no_security(self, mocker):
11781178
summary="",
11791179
name=data.operationId,
11801180
requires_security=False,
1181-
tag="a",
1181+
tags=["a"],
11821182
),
11831183
data=data,
11841184
parameters=parameters,
@@ -1241,9 +1241,9 @@ def test_from_data(self, mocker):
12411241
"path_1": oai.PathItem.construct(post=path_1_post, put=path_1_put),
12421242
"path_2": oai.PathItem.construct(get=path_2_get),
12431243
}
1244-
endpoint_1 = mocker.MagicMock(autospec=Endpoint, tag="default", relative_imports={"1", "2"}, path="path_1")
1245-
endpoint_2 = mocker.MagicMock(autospec=Endpoint, tag="tag_2", relative_imports={"2"}, path="path_1")
1246-
endpoint_3 = mocker.MagicMock(autospec=Endpoint, tag="default", relative_imports={"2", "3"}, path="path_2")
1244+
endpoint_1 = mocker.MagicMock(autospec=Endpoint, tags=["default"], relative_imports={"1", "2"}, path="path_1")
1245+
endpoint_2 = mocker.MagicMock(autospec=Endpoint, tags=["tag_2"], relative_imports={"2"}, path="path_1")
1246+
endpoint_3 = mocker.MagicMock(autospec=Endpoint, tags=["default"], relative_imports={"2", "3"}, path="path_2")
12471247
schemas_1 = mocker.MagicMock()
12481248
schemas_2 = mocker.MagicMock()
12491249
schemas_3 = mocker.MagicMock()
@@ -1271,7 +1271,7 @@ def test_from_data(self, mocker):
12711271
data=path_1_put,
12721272
path="path_1",
12731273
method="put",
1274-
tag="default",
1274+
tags=["default"],
12751275
schemas=schemas,
12761276
parameters=parameters,
12771277
config=config,
@@ -1280,7 +1280,7 @@ def test_from_data(self, mocker):
12801280
data=path_1_post,
12811281
path="path_1",
12821282
method="post",
1283-
tag="tag_2",
1283+
tags=["tag_2", "tag_3"],
12841284
schemas=schemas_1,
12851285
parameters=parameters_1,
12861286
config=config,
@@ -1289,7 +1289,7 @@ def test_from_data(self, mocker):
12891289
data=path_2_get,
12901290
path="path_2",
12911291
method="get",
1292-
tag="default",
1292+
tags=["default"],
12931293
schemas=schemas_2,
12941294
parameters=parameters_2,
12951295
config=config,
@@ -1300,6 +1300,7 @@ def test_from_data(self, mocker):
13001300
{
13011301
"default": EndpointCollection("default", endpoints=[endpoint_1, endpoint_3]),
13021302
"tag_2": EndpointCollection("tag_2", endpoints=[endpoint_2]),
1303+
"tag_3": EndpointCollection("tag_3", endpoints=[endpoint_2]),
13031304
},
13041305
schemas_3,
13051306
parameters_3,
@@ -1372,7 +1373,7 @@ def test_from_data_errors(self, mocker):
13721373
data=path_1_put,
13731374
path="path_1",
13741375
method="put",
1375-
tag="default",
1376+
tags=["default"],
13761377
schemas=schemas,
13771378
parameters=parameters,
13781379
config=config,
@@ -1381,7 +1382,7 @@ def test_from_data_errors(self, mocker):
13811382
data=path_1_post,
13821383
path="path_1",
13831384
method="post",
1384-
tag="tag_2",
1385+
tags=["tag_2", "tag_3"],
13851386
schemas=schemas_1,
13861387
parameters=parameters_1,
13871388
config=config,
@@ -1390,7 +1391,7 @@ def test_from_data_errors(self, mocker):
13901391
data=path_2_get,
13911392
path="path_2",
13921393
method="get",
1393-
tag="default",
1394+
tags=["default"],
13941395
schemas=schemas_2,
13951396
parameters=parameters_2,
13961397
config=config,
@@ -1412,11 +1413,11 @@ def test_from_data_tags_snake_case_sanitizer(self, mocker):
14121413
"path_1": oai.PathItem.construct(post=path_1_post, put=path_1_put),
14131414
"path_2": oai.PathItem.construct(get=path_2_get),
14141415
}
1415-
endpoint_1 = mocker.MagicMock(autospec=Endpoint, tag="default", relative_imports={"1", "2"}, path="path_1")
1416+
endpoint_1 = mocker.MagicMock(autospec=Endpoint, tags=["default"], relative_imports={"1", "2"}, path="path_1")
14161417
endpoint_2 = mocker.MagicMock(
1417-
autospec=Endpoint, tag="AMFSubscriptionInfo (Document)", relative_imports={"2"}, path="path_1"
1418+
autospec=Endpoint, tags=["AMFSubscriptionInfo (Document)"], relative_imports={"2"}, path="path_1"
14181419
)
1419-
endpoint_3 = mocker.MagicMock(autospec=Endpoint, tag="default", relative_imports={"2", "3"}, path="path_2")
1420+
endpoint_3 = mocker.MagicMock(autospec=Endpoint, tags=["default"], relative_imports={"2", "3"}, path="path_2")
14201421
schemas_1 = mocker.MagicMock()
14211422
schemas_2 = mocker.MagicMock()
14221423
schemas_3 = mocker.MagicMock()
@@ -1444,7 +1445,7 @@ def test_from_data_tags_snake_case_sanitizer(self, mocker):
14441445
data=path_1_put,
14451446
path="path_1",
14461447
method="put",
1447-
tag="default",
1448+
tags=["default"],
14481449
schemas=schemas,
14491450
parameters=parameters,
14501451
config=config,
@@ -1453,7 +1454,7 @@ def test_from_data_tags_snake_case_sanitizer(self, mocker):
14531454
data=path_1_post,
14541455
path="path_1",
14551456
method="post",
1456-
tag="amf_subscription_info_document",
1457+
tags=["amf_subscription_info_document", "tag_3"],
14571458
schemas=schemas_1,
14581459
parameters=parameters_1,
14591460
config=config,
@@ -1462,7 +1463,7 @@ def test_from_data_tags_snake_case_sanitizer(self, mocker):
14621463
data=path_2_get,
14631464
path="path_2",
14641465
method="get",
1465-
tag="tag3_abc",
1466+
tags=["tag3_abc"],
14661467
schemas=schemas_2,
14671468
parameters=parameters_2,
14681469
config=config,
@@ -1475,6 +1476,9 @@ def test_from_data_tags_snake_case_sanitizer(self, mocker):
14751476
"amf_subscription_info_document": EndpointCollection(
14761477
"amf_subscription_info_document", endpoints=[endpoint_2]
14771478
),
1479+
"tag_3": EndpointCollection(
1480+
"tag_3", endpoints=[endpoint_2]
1481+
),
14781482
"tag3_abc": EndpointCollection("tag3_abc", endpoints=[endpoint_3]),
14791483
},
14801484
schemas_3,

0 commit comments

Comments
 (0)