aradipe 2 days ago
committed by GitHub
parent
commit
edaebbdea1
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      fastapi/openapi/models.py
  2. 7
      fastapi/openapi/utils.py
  3. 22
      tests/test_duplicate_openapi_tags.py

11
fastapi/openapi/models.py

@ -10,7 +10,7 @@ from fastapi._compat import (
with_info_plain_validator_function,
)
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
from pydantic import AnyUrl, BaseModel, Field, validator
from typing_extensions import Annotated, Literal, TypedDict
from typing_extensions import deprecated as typing_deprecated
@ -439,6 +439,15 @@ class OpenAPI(BaseModelWithConfig):
tags: Optional[List[Tag]] = None
externalDocs: Optional[ExternalDocumentation] = None
@validator("tags")
def check_tags(cls, tags): # type: ignore
unique_names = set()
assert not any(
t.name in unique_names or unique_names.add(t.name)
for t in tags # type: ignore
), "Tag names must be unique"
return tags
_model_rebuild(Schema)
_model_rebuild(Operation)

7
fastapi/openapi/utils.py

@ -565,5 +565,10 @@ def get_openapi(
if webhook_paths:
output["webhooks"] = webhook_paths
if tags:
output["tags"] = tags
# discard tags with non-unique names as it is against the OpenAPI spec
# https://swagger.io/specification/#openapi-object
names = set()
output["tags"] = [
t for t in tags if t["name"] not in names and not names.add(t["name"])
] # type: ignore
return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore

22
tests/test_duplicate_openapi_tags.py

@ -0,0 +1,22 @@
"""Test case for possible tag duplication at OpenAPI object level"""
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI(
openapi_tags=[
{"name": "items", "description": "items1"},
{"name": "items", "description": "items2"},
]
)
client = TestClient(app)
def test_openapi_for_duplicates():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
tag_list = response.json()["tags"]
assert len(tag_list) == 1
assert tag_list[0]["name"] == "items"
assert tag_list[0]["description"] == "items1"
Loading…
Cancel
Save