mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-07-27 16:26:39 +00:00
[api] Add /api prefix to all paths in OpenAPI spec
- Updated all API paths (except internal routes) to include /api/ prefix - Changed server URL from "/api" back to "/" and added prefix to individual paths - Updated test fixtures to not add /api prefix since paths already include it - Fixed all test assertions to use the new paths with /api/ prefix This addresses the review comment about endpoints needing the /api/ prefix and implements it correctly by hardcoding the prefix in each path definition. Fixes #8219
This commit is contained in:
parent
82c1852390
commit
d6270cbdf3
131
openapi.yaml
131
openapi.yaml
@ -1,42 +1,46 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: ComfyUI API
|
||||
description: |
|
||||
API for ComfyUI - A powerful and modular UI for Stable Diffusion.
|
||||
description: 'API for ComfyUI - A powerful and modular UI for Stable Diffusion.
|
||||
|
||||
|
||||
This API allows you to interact with ComfyUI programmatically, including:
|
||||
|
||||
- Submitting workflows for execution
|
||||
|
||||
- Managing the execution queue
|
||||
|
||||
- Retrieving generated images
|
||||
|
||||
- Managing models
|
||||
|
||||
- Retrieving node information
|
||||
|
||||
'
|
||||
version: 1.0.0
|
||||
license:
|
||||
name: GNU General Public License v3.0
|
||||
url: https://github.com/comfyanonymous/ComfyUI/blob/master/LICENSE
|
||||
|
||||
servers:
|
||||
- url: /api
|
||||
- url: /
|
||||
description: Default ComfyUI server
|
||||
|
||||
tags:
|
||||
- name: workflow
|
||||
- name: workflow
|
||||
description: Workflow execution and management
|
||||
- name: queue
|
||||
- name: queue
|
||||
description: Queue management
|
||||
- name: image
|
||||
- name: image
|
||||
description: Image handling
|
||||
- name: node
|
||||
- name: node
|
||||
description: Node information
|
||||
- name: model
|
||||
- name: model
|
||||
description: Model management
|
||||
- name: system
|
||||
- name: system
|
||||
description: System information
|
||||
- name: internal
|
||||
- name: internal
|
||||
description: Internal API routes
|
||||
|
||||
paths:
|
||||
/prompt:
|
||||
/api/prompt:
|
||||
get:
|
||||
tags:
|
||||
- workflow
|
||||
@ -54,9 +58,11 @@ paths:
|
||||
tags:
|
||||
- workflow
|
||||
summary: Submit a workflow for execution
|
||||
description: |
|
||||
Submit a workflow to be executed by the backend.
|
||||
description: 'Submit a workflow to be executed by the backend.
|
||||
|
||||
The workflow is a JSON object describing the nodes and their connections.
|
||||
|
||||
'
|
||||
operationId: executePrompt
|
||||
requestBody:
|
||||
required: true
|
||||
@ -77,8 +83,7 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/queue:
|
||||
/api/queue:
|
||||
get:
|
||||
tags:
|
||||
- queue
|
||||
@ -117,8 +122,7 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
||||
/interrupt:
|
||||
/api/interrupt:
|
||||
post:
|
||||
tags:
|
||||
- workflow
|
||||
@ -128,8 +132,7 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
||||
/free:
|
||||
/api/free:
|
||||
post:
|
||||
tags:
|
||||
- system
|
||||
@ -152,8 +155,7 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
||||
/history:
|
||||
/api/history:
|
||||
get:
|
||||
tags:
|
||||
- workflow
|
||||
@ -202,8 +204,7 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
||||
/history/{prompt_id}:
|
||||
/api/history/{prompt_id}:
|
||||
get:
|
||||
tags:
|
||||
- workflow
|
||||
@ -225,8 +226,7 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HistoryItem'
|
||||
|
||||
/object_info:
|
||||
/api/object_info:
|
||||
get:
|
||||
tags:
|
||||
- node
|
||||
@ -242,8 +242,7 @@ paths:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/NodeInfo'
|
||||
|
||||
/object_info/{node_class}:
|
||||
/api/object_info/{node_class}:
|
||||
get:
|
||||
tags:
|
||||
- node
|
||||
@ -266,8 +265,7 @@ paths:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/NodeInfo'
|
||||
|
||||
/upload/image:
|
||||
/api/upload/image:
|
||||
post:
|
||||
tags:
|
||||
- image
|
||||
@ -290,7 +288,10 @@ paths:
|
||||
description: Whether to overwrite if file exists (true/false)
|
||||
type:
|
||||
type: string
|
||||
enum: [input, temp, output]
|
||||
enum:
|
||||
- input
|
||||
- temp
|
||||
- output
|
||||
description: Type of directory to store the image in
|
||||
subfolder:
|
||||
type: string
|
||||
@ -314,8 +315,7 @@ paths:
|
||||
description: Type of directory the image was stored in
|
||||
'400':
|
||||
description: Bad request
|
||||
|
||||
/upload/mask:
|
||||
/api/upload/mask:
|
||||
post:
|
||||
tags:
|
||||
- image
|
||||
@ -355,8 +355,7 @@ paths:
|
||||
description: Type of directory the mask was stored in
|
||||
'400':
|
||||
description: Bad request
|
||||
|
||||
/view:
|
||||
/api/view:
|
||||
get:
|
||||
tags:
|
||||
- image
|
||||
@ -376,7 +375,10 @@ paths:
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [input, temp, output]
|
||||
enum:
|
||||
- input
|
||||
- temp
|
||||
- output
|
||||
default: output
|
||||
- name: subfolder
|
||||
in: query
|
||||
@ -396,7 +398,10 @@ paths:
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [rgb, a, rgba]
|
||||
enum:
|
||||
- rgb
|
||||
- a
|
||||
- rgba
|
||||
default: rgba
|
||||
responses:
|
||||
'200':
|
||||
@ -410,8 +415,7 @@ paths:
|
||||
description: Bad request
|
||||
'404':
|
||||
description: File not found
|
||||
|
||||
/view_metadata/{folder_name}:
|
||||
/api/view_metadata/{folder_name}:
|
||||
get:
|
||||
tags:
|
||||
- model
|
||||
@ -440,8 +444,7 @@ paths:
|
||||
type: object
|
||||
'404':
|
||||
description: File not found
|
||||
|
||||
/models:
|
||||
/api/models:
|
||||
get:
|
||||
tags:
|
||||
- model
|
||||
@ -457,8 +460,7 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
/models/{folder}:
|
||||
/api/models/{folder}:
|
||||
get:
|
||||
tags:
|
||||
- model
|
||||
@ -483,8 +485,7 @@ paths:
|
||||
type: string
|
||||
'404':
|
||||
description: Folder not found
|
||||
|
||||
/embeddings:
|
||||
/api/embeddings:
|
||||
get:
|
||||
tags:
|
||||
- model
|
||||
@ -500,8 +501,7 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
/extensions:
|
||||
/api/extensions:
|
||||
get:
|
||||
tags:
|
||||
- system
|
||||
@ -517,8 +517,7 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
/system_stats:
|
||||
/api/system_stats:
|
||||
get:
|
||||
tags:
|
||||
- system
|
||||
@ -532,15 +531,17 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SystemStats'
|
||||
|
||||
/ws:
|
||||
/api/ws:
|
||||
get:
|
||||
tags:
|
||||
- workflow
|
||||
summary: WebSocket connection
|
||||
description: |
|
||||
Establishes a WebSocket connection for real-time communication.
|
||||
This endpoint is used for receiving progress updates, status changes, and results from workflow executions.
|
||||
description: 'Establishes a WebSocket connection for real-time communication.
|
||||
|
||||
This endpoint is used for receiving progress updates, status changes, and
|
||||
results from workflow executions.
|
||||
|
||||
'
|
||||
operationId: webSocketConnect
|
||||
parameters:
|
||||
- name: clientId
|
||||
@ -552,7 +553,6 @@ paths:
|
||||
responses:
|
||||
'101':
|
||||
description: Switching Protocols to WebSocket
|
||||
|
||||
/internal/logs:
|
||||
get:
|
||||
tags:
|
||||
@ -567,7 +567,6 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
/internal/logs/raw:
|
||||
get:
|
||||
tags:
|
||||
@ -603,7 +602,6 @@ paths:
|
||||
rows:
|
||||
type: integer
|
||||
description: Terminal rows
|
||||
|
||||
/internal/logs/subscribe:
|
||||
patch:
|
||||
tags:
|
||||
@ -627,7 +625,6 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
||||
/internal/folder_paths:
|
||||
get:
|
||||
tags:
|
||||
@ -644,7 +641,6 @@ paths:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
|
||||
/internal/files/{directory_type}:
|
||||
get:
|
||||
tags:
|
||||
@ -659,7 +655,10 @@ paths:
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [output, input, temp]
|
||||
enum:
|
||||
- output
|
||||
- input
|
||||
- temp
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
@ -671,7 +670,6 @@ paths:
|
||||
type: string
|
||||
'400':
|
||||
description: Invalid directory type
|
||||
|
||||
components:
|
||||
schemas:
|
||||
PromptRequest:
|
||||
@ -696,7 +694,6 @@ components:
|
||||
client_id:
|
||||
type: string
|
||||
description: Client ID for attribution of the prompt
|
||||
|
||||
PromptResponse:
|
||||
type: object
|
||||
properties:
|
||||
@ -711,7 +708,6 @@ components:
|
||||
type: object
|
||||
description: Any errors in the nodes of the prompt
|
||||
additionalProperties: true
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
@ -735,7 +731,6 @@ components:
|
||||
type: object
|
||||
description: Node-specific errors
|
||||
additionalProperties: true
|
||||
|
||||
PromptInfo:
|
||||
type: object
|
||||
properties:
|
||||
@ -745,7 +740,6 @@ components:
|
||||
queue_remaining:
|
||||
type: integer
|
||||
description: Number of items remaining in the queue
|
||||
|
||||
QueueInfo:
|
||||
type: object
|
||||
properties:
|
||||
@ -761,7 +755,6 @@ components:
|
||||
type: object
|
||||
description: Pending items in the queue
|
||||
additionalProperties: true
|
||||
|
||||
HistoryItem:
|
||||
type: object
|
||||
properties:
|
||||
@ -781,7 +774,6 @@ components:
|
||||
type: object
|
||||
description: Output data from the execution
|
||||
additionalProperties: true
|
||||
|
||||
NodeInfo:
|
||||
type: object
|
||||
properties:
|
||||
@ -843,7 +835,6 @@ components:
|
||||
api_node:
|
||||
type: boolean
|
||||
description: Whether this is an API node
|
||||
|
||||
SystemStats:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -93,8 +93,8 @@ def api_client(base_url: str) -> Generator[Optional[requests.Session], None, Non
|
||||
|
||||
# Helper function to construct URLs
|
||||
def get_url(path: str) -> str:
|
||||
# All API endpoints use the /api prefix
|
||||
return urljoin(base_url, '/api' + path)
|
||||
# Paths in the OpenAPI spec already include /api prefix where needed
|
||||
return urljoin(base_url, path)
|
||||
|
||||
# Add url helper to the session
|
||||
session.get_url = get_url # type: ignore
|
||||
|
@ -77,12 +77,12 @@ def test_endpoints_exist(all_endpoints: List[Dict[str, Any]]):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("endpoint_path", [
|
||||
"/", # Root path
|
||||
"/prompt", # Get prompt info
|
||||
"/queue", # Get queue
|
||||
"/models", # Get model types
|
||||
"/object_info", # Get node info
|
||||
"/system_stats" # Get system stats
|
||||
"/", # Root path (doesn't have /api prefix)
|
||||
"/api/prompt", # Get prompt info
|
||||
"/api/queue", # Get queue
|
||||
"/api/models", # Get model types
|
||||
"/api/object_info", # Get node info
|
||||
"/api/system_stats" # Get system stats
|
||||
])
|
||||
def test_basic_get_endpoints(require_server, api_client, endpoint_path: str):
|
||||
"""
|
||||
@ -116,7 +116,7 @@ def test_websocket_endpoint_exists(require_server, base_url: str):
|
||||
require_server: Fixture that skips if server is not available
|
||||
base_url: Base server URL
|
||||
"""
|
||||
# WebSocket endpoint uses /api prefix
|
||||
# WebSocket endpoint path from OpenAPI spec
|
||||
ws_url = urljoin(base_url, "/api/ws")
|
||||
|
||||
# For WebSocket, we can't use a normal GET request
|
||||
@ -143,7 +143,7 @@ def test_api_models_folder_endpoint(require_server, api_client):
|
||||
api_client: API client fixture
|
||||
"""
|
||||
# First get available model types
|
||||
models_url = api_client.get_url("/models") # type: ignore
|
||||
models_url = api_client.get_url("/api/models") # type: ignore
|
||||
|
||||
try:
|
||||
models_response = api_client.get(models_url)
|
||||
@ -157,14 +157,14 @@ def test_api_models_folder_endpoint(require_server, api_client):
|
||||
|
||||
# Test with the first model type
|
||||
model_type = model_types[0]
|
||||
models_folder_url = api_client.get_url(f"/models/{model_type}") # type: ignore
|
||||
models_folder_url = api_client.get_url(f"/api/models/{model_type}") # type: ignore
|
||||
|
||||
folder_response = api_client.get(models_folder_url)
|
||||
|
||||
# We're just checking that the endpoint exists
|
||||
assert folder_response.status_code != 404, f"Endpoint /models/{model_type} does not exist"
|
||||
assert folder_response.status_code != 404, f"Endpoint /api/models/{model_type} does not exist"
|
||||
|
||||
logger.info(f"Endpoint /models/{model_type} exists with status code {folder_response.status_code}")
|
||||
logger.info(f"Endpoint /api/models/{model_type} exists with status code {folder_response.status_code}")
|
||||
|
||||
except requests.RequestException as e:
|
||||
pytest.fail(f"Request failed: {str(e)}")
|
||||
@ -181,7 +181,7 @@ def test_api_object_info_node_endpoint(require_server, api_client):
|
||||
api_client: API client fixture
|
||||
"""
|
||||
# First get available node classes
|
||||
objects_url = api_client.get_url("/object_info") # type: ignore
|
||||
objects_url = api_client.get_url("/api/object_info") # type: ignore
|
||||
|
||||
try:
|
||||
objects_response = api_client.get(objects_url)
|
||||
@ -195,14 +195,14 @@ def test_api_object_info_node_endpoint(require_server, api_client):
|
||||
|
||||
# Test with the first node class
|
||||
node_class = next(iter(node_classes.keys()))
|
||||
node_url = api_client.get_url(f"/object_info/{node_class}") # type: ignore
|
||||
node_url = api_client.get_url(f"/api/object_info/{node_class}") # type: ignore
|
||||
|
||||
node_response = api_client.get(node_url)
|
||||
|
||||
# We're just checking that the endpoint exists
|
||||
assert node_response.status_code != 404, f"Endpoint /object_info/{node_class} does not exist"
|
||||
assert node_response.status_code != 404, f"Endpoint /api/object_info/{node_class} does not exist"
|
||||
|
||||
logger.info(f"Endpoint /object_info/{node_class} exists with status code {node_response.status_code}")
|
||||
logger.info(f"Endpoint /api/object_info/{node_class} exists with status code {node_response.status_code}")
|
||||
|
||||
except requests.RequestException as e:
|
||||
pytest.fail(f"Request failed: {str(e)}")
|
||||
|
@ -132,11 +132,11 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("endpoint_path,method", [
|
||||
("/system_stats", "get"),
|
||||
("/prompt", "get"),
|
||||
("/queue", "get"),
|
||||
("/models", "get"),
|
||||
("/embeddings", "get")
|
||||
("/api/system_stats", "get"),
|
||||
("/api/prompt", "get"),
|
||||
("/api/queue", "get"),
|
||||
("/api/models", "get"),
|
||||
("/api/embeddings", "get")
|
||||
])
|
||||
def test_response_schema_validation(
|
||||
require_server,
|
||||
@ -182,7 +182,7 @@ def test_response_schema_validation(
|
||||
return
|
||||
|
||||
# Special handling for system_stats endpoint
|
||||
if endpoint_path == '/system_stats' and isinstance(response_data, dict):
|
||||
if endpoint_path == '/api/system_stats' and isinstance(response_data, dict):
|
||||
# Remove null index fields before validation
|
||||
for device in response_data.get('devices', []):
|
||||
if 'index' in device and device['index'] is None:
|
||||
@ -217,7 +217,7 @@ def test_system_stats_response(require_server, api_client, api_spec: Dict[str, A
|
||||
api_client: API client fixture
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
url = api_client.get_url("/system_stats") # type: ignore
|
||||
url = api_client.get_url("/api/system_stats") # type: ignore
|
||||
|
||||
try:
|
||||
response = api_client.get(url)
|
||||
@ -259,7 +259,7 @@ def test_system_stats_response(require_server, api_client, api_spec: Dict[str, A
|
||||
validation_result = validate_response(
|
||||
stats,
|
||||
api_spec,
|
||||
"/system_stats",
|
||||
"/api/system_stats",
|
||||
"get"
|
||||
)
|
||||
|
||||
@ -279,7 +279,7 @@ def test_system_stats_response(require_server, api_client, api_spec: Dict[str, A
|
||||
assert validation_result['valid'], "System stats response does not match schema"
|
||||
|
||||
except requests.RequestException as e:
|
||||
pytest.fail(f"Request to /system_stats failed: {str(e)}")
|
||||
pytest.fail(f"Request to /api/system_stats failed: {str(e)}")
|
||||
|
||||
|
||||
def test_models_listing_response(require_server, api_client, api_spec: Dict[str, Any]):
|
||||
@ -291,7 +291,7 @@ def test_models_listing_response(require_server, api_client, api_spec: Dict[str,
|
||||
api_client: API client fixture
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
url = api_client.get_url("/models") # type: ignore
|
||||
url = api_client.get_url("/api/models") # type: ignore
|
||||
|
||||
try:
|
||||
response = api_client.get(url)
|
||||
@ -312,7 +312,7 @@ def test_models_listing_response(require_server, api_client, api_spec: Dict[str,
|
||||
validation_result = validate_response(
|
||||
models,
|
||||
api_spec,
|
||||
"/models",
|
||||
"/api/models",
|
||||
"get"
|
||||
)
|
||||
|
||||
@ -333,7 +333,7 @@ def test_models_listing_response(require_server, api_client, api_spec: Dict[str,
|
||||
assert validation_result['valid'], "Models response does not match schema"
|
||||
|
||||
except requests.RequestException as e:
|
||||
pytest.fail(f"Request to /models failed: {str(e)}")
|
||||
pytest.fail(f"Request to /api/models failed: {str(e)}")
|
||||
|
||||
|
||||
def test_object_info_response(require_server, api_client, api_spec: Dict[str, Any]):
|
||||
@ -345,7 +345,7 @@ def test_object_info_response(require_server, api_client, api_spec: Dict[str, An
|
||||
api_client: API client fixture
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
url = api_client.get_url("/object_info") # type: ignore
|
||||
url = api_client.get_url("/api/object_info") # type: ignore
|
||||
|
||||
try:
|
||||
response = api_client.get(url)
|
||||
@ -373,7 +373,7 @@ def test_object_info_response(require_server, api_client, api_spec: Dict[str, An
|
||||
validation_result = validate_response(
|
||||
objects,
|
||||
api_spec,
|
||||
"/object_info",
|
||||
"/api/object_info",
|
||||
"get"
|
||||
)
|
||||
|
||||
@ -394,7 +394,7 @@ def test_object_info_response(require_server, api_client, api_spec: Dict[str, An
|
||||
assert validation_result['valid'], "Object info response does not match schema"
|
||||
|
||||
except requests.RequestException as e:
|
||||
pytest.fail(f"Request to /object_info failed: {str(e)}")
|
||||
pytest.fail(f"Request to /api/object_info failed: {str(e)}")
|
||||
except (KeyError, StopIteration) as e:
|
||||
pytest.fail(f"Failed to process response: {str(e)}")
|
||||
|
||||
@ -408,7 +408,7 @@ def test_queue_response(require_server, api_client, api_spec: Dict[str, Any]):
|
||||
api_client: API client fixture
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
url = api_client.get_url("/queue") # type: ignore
|
||||
url = api_client.get_url("/api/queue") # type: ignore
|
||||
|
||||
try:
|
||||
response = api_client.get(url)
|
||||
@ -430,7 +430,7 @@ def test_queue_response(require_server, api_client, api_spec: Dict[str, Any]):
|
||||
validation_result = validate_response(
|
||||
queue,
|
||||
api_spec,
|
||||
"/queue",
|
||||
"/api/queue",
|
||||
"get"
|
||||
)
|
||||
|
||||
|
@ -61,9 +61,9 @@ def test_workflow_endpoints_exist(api_spec: Dict[str, Any]):
|
||||
Args:
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
assert '/prompt' in api_spec['paths'], "Spec must define /prompt endpoint"
|
||||
assert 'post' in api_spec['paths']['/prompt'], "Spec must define POST /prompt"
|
||||
assert 'get' in api_spec['paths']['/prompt'], "Spec must define GET /prompt"
|
||||
assert '/api/prompt' in api_spec['paths'], "Spec must define /api/prompt endpoint"
|
||||
assert 'post' in api_spec['paths']['/api/prompt'], "Spec must define POST /api/prompt"
|
||||
assert 'get' in api_spec['paths']['/api/prompt'], "Spec must define GET /api/prompt"
|
||||
|
||||
|
||||
def test_image_endpoints_exist(api_spec: Dict[str, Any]):
|
||||
@ -73,8 +73,8 @@ def test_image_endpoints_exist(api_spec: Dict[str, Any]):
|
||||
Args:
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
assert '/upload/image' in api_spec['paths'], "Spec must define /upload/image endpoint"
|
||||
assert '/view' in api_spec['paths'], "Spec must define /view endpoint"
|
||||
assert '/api/upload/image' in api_spec['paths'], "Spec must define /api/upload/image endpoint"
|
||||
assert '/api/view' in api_spec['paths'], "Spec must define /api/view endpoint"
|
||||
|
||||
|
||||
def test_model_endpoints_exist(api_spec: Dict[str, Any]):
|
||||
@ -84,8 +84,8 @@ def test_model_endpoints_exist(api_spec: Dict[str, Any]):
|
||||
Args:
|
||||
api_spec: Loaded OpenAPI spec
|
||||
"""
|
||||
assert '/models' in api_spec['paths'], "Spec must define /models endpoint"
|
||||
assert '/models/{folder}' in api_spec['paths'], "Spec must define /models/{folder} endpoint"
|
||||
assert '/api/models' in api_spec['paths'], "Spec must define /api/models endpoint"
|
||||
assert '/api/models/{folder}' in api_spec['paths'], "Spec must define /api/models/{folder} endpoint"
|
||||
|
||||
|
||||
def test_operation_ids_are_unique(api_spec: Dict[str, Any]):
|
||||
|
Loading…
x
Reference in New Issue
Block a user