o
    i5[                     @   sF  d Z ddlmZ ddlmZ ddlmZmZmZ ee	Z
dedB dedB fd	d
Z	ddeeef dedB deeef fddZdeeef deeef fddZ	ddededeeeef eeeeef f f fddZdedeeef fddZ		d deeef deeef dB dedB deeef dB fddZg dZdS )!z5Schema manipulation utilities for OpenAPI operations.    )Any)
get_logger   )	HTTPRoute
JsonSchemaResponseInfoschemaNreturnc                 C   s   | rt | ts	| S |  }g d}|D ]}||v r|| qd|v r9dd |d  D |d< |d s9|d d|v rNt|d |d< |d sN|d d|v rjt |d trct|d |d< |S |d du rj	 |S )zW
    Clean up a schema dictionary for display by removing internal/complex fields.
    )allOfanyOfoneOfnotnullablediscriminatorreadOnly	writeOnly
deprecatedxmlexternalDocs
propertiesc                 S      i | ]	\}}|t |qS  )clean_schema_for_display).0kvr   r   t/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/fastmcp/experimental/utilities/openapi/schemas.py
<dictcomp>0   s    z,clean_schema_for_display.<locals>.<dictcomp>itemsadditionalPropertiesT)
isinstancedictcopypopr   r   )r   cleanedfields_to_removefieldr   r   r   r      s6   




r   infodescriptionc                 C   s4  |   }|d }r2t|tr1|dr$|dd }d| |d< n9|ds1td| dn+|d	 }rPd|v rDt||d	< nd
d | D |d	< n|d }r]t||d< dD ]}t	||g D ]\}}	t|	|| |< qiq_|d }
rt|
t
st|
|d< | d|r|ds||d< |S )a  
    Replace openapi $ref with jsonschema $defs recursively.

    Examples:
    - {"type": "object", "properties": {"$ref": "#/components/schemas/..."}}
    - {"type": "object", "additionalProperties": {"$ref": "#/components/schemas/..."}, "properties": {...}}
    - {"$ref": "#/components/schemas/..."}
    - {"items": {"$ref": "#/components/schemas/..."}}
    - {"anyOf": [{"$ref": "#/components/schemas/..."}]}
    - {"allOf": [{"$ref": "#/components/schemas/..."}]}
    - {"oneOf": [{"$ref": "#/components/schemas/..."}]}

    Args:
        info: dict[str, Any]
        description: str | None

    Returns:
        dict[str, Any]
    $refz#/components/schemas//#/$defs/z#/z/External or non-local reference not supported: z. FastMCP only supports local schema references starting with '#/'. Please include all schema definitions within the OpenAPI document.r   c                 S   r   r   )_replace_ref_with_defs)r   	prop_nameprop_schemar   r   r   r   p   s    z*_replace_ref_with_defs.<locals>.<dictcomp>r   )r   r
   r   r   r(   )r"   getr    str
startswithsplit
ValueErrorr-   r   	enumeratebool)r'   r(   r   ref_pathschema_namer   item_schemasectioniitemr   r   r   r   r-   J   s>   




r-   c                 C   s  d| v sd| v sd| v r| S t | dtrd| d v r| S d| v r| d }t |tr|dv r|dkr[d| v r[|  }g d	}i }|D ]}||v rP||||< qC|ddig|d< |S |d
krd| v r|  }g d	}i }|D ]}||v r|||||< qo|ddig|d< |S i }|  }g d	}|D ]}||v r||||< q|ddig|d< |S g d	}i }|  }|D ]}||v r||||< q|ddig|d< |S | S )z
    Make an optional parameter schema nullable to allow None values.

    For optional parameters, we need to allow null values in addition to the
    specified type to handle cases where None is passed for optional parameters.
    r   r   r
   typenull)arrayobjectr?   r   )defaultr(   titleexampler@   r   )r    r0   listr1   r"   r#   )r   original_typearray_schematop_level_fieldsnullable_schemar&   object_schemaoriginal_schemar   r   r   !_make_optional_parameter_nullable   s^   
rK   Trouteconvert_refsc                     s  i }g }i }t  t  t  t  d}i }| jD ]}||j |j q| jr| jjrtt| jj}|r<t	| jj| }	n| jj| }	| jj
rQ|	dsQ| jj
|	d< d|	v rt|	d tri }
g }|	d D ]}t|trd|v rv|
|d  d|v r||d  qd|
|	d< |rt  fdd|D |	d< |	dd |	di }t  }| D ]}|| qt | }||@ }| jD ]}|j|v r!|j d	|j }|jr|| |j|jd
||< |rt	|j|j
}n|j }|j
r|ds|j
|d< |dd}d|j  d}|r| d| |d< n||d< |||< q|jr+||j |j|jd
||j< |r@t	|j|j
}n|j }|j
rT|dsT|j
|d< |||j< q| jr| jjrd|	v r|s|	|d< | jjry|d ddd
|d< n[|r| D ]\}}|||< d|d
||< q| jjr||	dg  n4|	dd }ddl}|dd|}|r|d  rd}|	||< | jjr|| d|d
||< d||d}| j}|rP|rL| }| D ]\}}t|trt	|||< qt   fdd  | rHd}|s;t}tD ]}||v r0 ||  q#t|k}|rfdd| D |d< ||fS ||d< ||fS )a  
    Combines parameter and request body schemas into a single schema.
    Handles parameter name collisions by adding location suffixes.
    Also returns parameter mapping for request director.

    Args:
        route: HTTPRoute object

    Returns:
        Tuple of (combined schema dictionary, parameter mapping)
        Parameter mapping format: {'flat_arg_name': {'location': 'path', 'openapi_name': 'id'}}
    )pathqueryheadercookier(   r
   r   requiredc                    s"   g | ]}| v s  |s|qS r   )add)r   x)seenr   r   
<listcomp>  s    z3_combine_schemas_and_map_params.<locals>.<listcomp>N__)locationopenapi_name (z parameter) r)   bodyrB   r   z[^a-zA-Z0-9_]_	body_datar@   )r=   r   rR   c                    s   t | tr0d| v r#t | d tr#| d }|dr#|dd  |  D ]} | q'dS t | tr>| D ]} | q7dS dS )z%Recursively find all $ref references.r)   r,   r*   r+   N)r    r!   r1   r2   rS   r3   valuesrD   )valuerefr   r<   )find_refs_in_value	used_refsr   r   rc     s   




z;_combine_schemas_and_map_params.<locals>.find_refs_in_valueFc                    s   i | ]\}}| v r||qS r   r   )r   name
def_schema)rd   r   r   r     s
    z3_combine_schemas_and_map_params.<locals>.<dictcomp>$defs) set
parametersrX   rS   re   request_bodycontent_schemanextiterr-   r(   r0   r    rD   r!   updateextendr#   r`   keysrR   appendschema_r"   
capitalizer   lowerresubisdigitrequest_schemaslen) rL   rM   r   rR   parameter_mapparam_names_by_location
body_propsparamcontent_typebody_schemamerged_propsmerged_required
sub_schemaall_non_body_paramslocation_paramsbody_param_namescolliding_paramssuffixed_nameparam_schemaoriginal_desclocation_descr.   r/   
param_nameru   resultschema_defsall_defsre   r   collected_allinitial_countr   )rc   rU   rd   r   _combine_schemas_and_map_params   s   




















	r   c                 C   s   t | \}}|S )a@  
    Combines parameter and request body schemas into a single schema.
    Handles parameter name collisions by adding location suffixes.

    This is a backward compatibility wrapper around _combine_schemas_and_map_params.

    Args:
        route: HTTPRoute object

    Returns:
        Combined schema dictionary
    )r   )rL   r   r^   r   r   r   _combine_schemas  s   r   	responsesschema_definitionsopenapi_versionc                 C   s  | sdS g d}d}|D ]}|| v r| | } nq|du r/|   D ]\}}|dr.|} nq!|du s6|js8dS g d}d}|D ]}	|	|jv rN|j|	 } nq@|du rj|jrjtt|j}
|j|
 }td|
  |rqt|tssdS t	|}d|v r|r|d }|dr|
dd	 }||v rt	|| }|r|d
rddlm} |||}|ddkrdd|idgdd}|}|r| }|  D ]\}}t|trt	|||< q|r|d
rddlm} t| D ]}||| |||< q||d< |S )a  
    Extract output schema from OpenAPI responses for use as MCP tool output schema.

    This function finds the first successful response (200, 201, 202, 204) with a
    JSON-compatible content type and extracts its schema. If the schema is not an
    object type, it wraps it to comply with MCP requirements.

    Args:
        responses: Dictionary of ResponseInfo objects keyed by status code
        schema_definitions: Optional schema definitions to include in the output schema
        openapi_version: OpenAPI version string, used to optimize nullable field handling

    Returns:
        dict: MCP-compliant output schema with potential wrapping, or None if no suitable schema found
    N)2002012022042)zapplication/jsonzapplication/vnd.api+jsonzapplication/hal+jsonzapplication/ld+jsonz	text/jsonz/Using non-JSON content type for output schema: r)   r,   r*   r+   z3.0r   )%convert_openapi_schema_to_json_schemar=   r@   r   T)r=   r   rR   zx-fastmcp-wrap-resultrg   )r   r2   rk   rl   rm   loggerdebugr    r!   r-   r3   json_schema_converterr   r0   r"   rD   rp   )r   r   r   success_codesresponse_infostatus_code	resp_infojson_compatible_typesr   r~   first_content_typeoutput_schemar7   r8   r   wrapped_schemaprocessed_defsre   def_namer   r   r   $extract_output_schema_from_responses  s   






r   )r   r   rK   r   r   )N)T)NN)__doc__typingr   fastmcp.utilities.loggingr   modelsr   r   r   __name__r   r   r!   r1   r-   rK   r6   tupler   r   r   __all__r   r   r   r   <module>   sJ    ?


"9P"
 l

~