Browse Source

Do not allow duplicate tag names (OpenAPI object)

Addresses issue #5552
pull/5553/head
Peter Aradi 3 years ago
parent
commit
f7c318c819
  1. 10
      fastapi/openapi/models.py
  2. 5
      fastapi/openapi/utils.py
  3. 22
      tests/test_duplicate_openapi_tags.py

10
fastapi/openapi/models.py

@ -2,7 +2,7 @@ from enum import Enum
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
from pydantic import AnyUrl, BaseModel, Field, validator
try:
import email_validator # type: ignore
@ -400,6 +400,14 @@ class OpenAPI(BaseModel):
class Config:
extra = "allow"
@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
Schema.update_forward_refs()
Operation.update_forward_refs()

5
fastapi/openapi/utils.py

@ -444,5 +444,8 @@ def get_openapi(
output["components"] = components
output["paths"] = 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