utils.py•5.45 kB
from typing import Any, Dict
def get_single_param_type_from_schema(param_schema: Dict[str, Any]) -> str:
"""
Get the type of a parameter from the schema.
If the schema is a union type, return the first type.
"""
if "anyOf" in param_schema:
types = {schema.get("type") for schema in param_schema["anyOf"] if schema.get("type")}
if "null" in types:
types.remove("null")
if types:
return next(iter(types))
return "string"
return param_schema.get("type", "string")
def resolve_schema_references(schema_part: Dict[str, Any], reference_schema: Dict[str, Any]) -> Dict[str, Any]:
"""
Resolve schema references in OpenAPI schemas.
Args:
schema_part: The part of the schema being processed that may contain references
reference_schema: The complete schema used to resolve references from
Returns:
The schema with references resolved
"""
# Make a copy to avoid modifying the input schema
schema_part = schema_part.copy()
# Handle $ref directly in the schema
if "$ref" in schema_part:
ref_path = schema_part["$ref"]
# Standard OpenAPI references are in the format "#/components/schemas/ModelName"
if ref_path.startswith("#/components/schemas/"):
model_name = ref_path.split("/")[-1]
if "components" in reference_schema and "schemas" in reference_schema["components"]:
if model_name in reference_schema["components"]["schemas"]:
# Replace with the resolved schema
ref_schema = reference_schema["components"]["schemas"][model_name].copy()
# Remove the $ref key and merge with the original schema
schema_part.pop("$ref")
schema_part.update(ref_schema)
# Recursively resolve references in all dictionary values
for key, value in schema_part.items():
if isinstance(value, dict):
schema_part[key] = resolve_schema_references(value, reference_schema)
elif isinstance(value, list):
# Only process list items that are dictionaries since only they can contain refs
schema_part[key] = [
resolve_schema_references(item, reference_schema) if isinstance(item, dict) else item for item in value
]
return schema_part
def clean_schema_for_display(schema: Dict[str, Any]) -> Dict[str, Any]:
"""
Clean up a schema for display by removing internal fields.
Args:
schema: The schema to clean
Returns:
The cleaned schema
"""
# Make a copy to avoid modifying the input schema
schema = schema.copy()
# Remove common internal fields that are not helpful for LLMs
fields_to_remove = [
"allOf",
"anyOf",
"oneOf",
"nullable",
"discriminator",
"readOnly",
"writeOnly",
"xml",
"externalDocs",
]
for field in fields_to_remove:
if field in schema:
schema.pop(field)
# Process nested properties
if "properties" in schema:
for prop_name, prop_schema in schema["properties"].items():
if isinstance(prop_schema, dict):
schema["properties"][prop_name] = clean_schema_for_display(prop_schema)
# Process array items
if "type" in schema and schema["type"] == "array" and "items" in schema:
if isinstance(schema["items"], dict):
schema["items"] = clean_schema_for_display(schema["items"])
return schema
def generate_example_from_schema(schema: Dict[str, Any]) -> Any:
"""
Generate a simple example response from a JSON schema.
Args:
schema: The JSON schema to generate an example from
Returns:
An example object based on the schema
"""
if not schema or not isinstance(schema, dict):
return None
# Handle different types
schema_type = schema.get("type")
if schema_type == "object":
result = {}
if "properties" in schema:
for prop_name, prop_schema in schema["properties"].items():
# Generate an example for each property
prop_example = generate_example_from_schema(prop_schema)
if prop_example is not None:
result[prop_name] = prop_example
return result
elif schema_type == "array":
if "items" in schema:
# Generate a single example item
item_example = generate_example_from_schema(schema["items"])
if item_example is not None:
return [item_example]
return []
elif schema_type == "string":
# Check if there's a format
format_type = schema.get("format")
if format_type == "date-time":
return "2023-01-01T00:00:00Z"
elif format_type == "date":
return "2023-01-01"
elif format_type == "email":
return "user@example.com"
elif format_type == "uri":
return "https://example.com"
# Use title or property name if available
return schema.get("title", "string")
elif schema_type == "integer":
return 1
elif schema_type == "number":
return 1.0
elif schema_type == "boolean":
return True
elif schema_type == "null":
return None
# Default case
return None