o
    ưiRn                     @   s  d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZmZmZmZmZm Z  e Z!e!j"ddgeegeddCdee# fddZ$e!j%ddgeegedeefdede
fddZ&e!j"ddgeegedde#fddZ'e!j%ddgeegedeefde#dede
fddZ(e!j)ddgeegedeefde#de de
fdd Z*e!j"d!dgeegedd"e#d#e#fd$d%Z+e!j,d&dgeegd'de#fd(d)Z-e!j"d*dgeegedde#fd+d,Z.e!j)d*dgeegedeefde#dede
fd-d.Z/e!j,d*dgeegd'de#fd/d0Z0e!j"d1dgeegd'de#fd2d3Z1e!j%d4dgeegd'eefdede
fd5d6Z2e!j"d7dgeegedd8d9 Z3e!j%d:dgeegedeefdede
fd;d<Z4e!j"d=dgeegedd>e#fd?d@Z5e!j,d=dgeegd'd>e#fdAdBZ6dS )Dzh
CRUD ENDPOINTS FOR POLICIES

Provides REST API endpoints for managing policies and policy attachments.
    )Optional)	APIRouterDependsHTTPException)verbose_proxy_logger)UserAPIKeyAuth)user_api_key_auth)get_attachment_registry)PipelineExecutor)get_policy_registry)GuardrailPipelinePipelineTestRequestPolicyAttachmentCreateRequestPolicyAttachmentDBResponsePolicyAttachmentListResponsePolicyCreateRequestPolicyDBResponsePolicyListDBResponsePolicyUpdateRequestPolicyVersionCompareResponsePolicyVersionCreateRequestPolicyVersionListResponse PolicyVersionStatusUpdateRequestz/policies/listZPolicies)tagsdependenciesZresponse_modelNversion_statusc              
      s   ddl m} |du rtdddzt j|| dI dH }t|t|dW S  tyA } zt	d	|  tdt
|dd}~ww )
a  
    List all policies from the database. Optionally filter by version_status.

    Query params:
    - version_status: Optional. One of "draft", "published", "production".
      If omitted, all versions are returned.

    Example Request:
    ```bash
    curl -X GET "http://localhost:4000/policies/list" \
        -H "Authorization: Bearer <your_api_key>"
    curl -X GET "http://localhost:4000/policies/list?version_status=production" \
        -H "Authorization: Bearer <your_api_key>"
    ```

    Example Response:
    ```json
    {
        "policies": [
            {
                "policy_id": "123e4567-e89b-12d3-a456-426614174000",
                "policy_name": "global-baseline",
                "version_number": 1,
                "version_status": "production",
                "inherit": null,
                "description": "Base guardrails for all requests",
                "guardrails_add": ["pii_masking"],
                "guardrails_remove": [],
                "condition": null,
                "created_at": "2024-01-01T00:00:00Z",
                "updated_at": "2024-01-01T00:00:00Z"
            }
        ],
        "total_count": 1
    }
    ```
    r   prisma_clientN  Database not connectedstatus_codedetailr   )policiestotal_countzError listing policies: )litellm.proxy.proxy_serverr   r   r   get_all_policies_from_dbr   len	Exceptionr   	exceptionstr)r   r   r$   e r-   c/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/policy_engine/policy_endpoints.pylist_policies"   s   ,r/   z	/policiesrequestuser_api_key_dictc              
      s   ddl m} |du rtdddz|j}t j| ||dI dH }|W S  tyR } z#td|  d	t	|
 v rFtd
d| j ddtdt	|dd}~ww )a  
    Create a new policy.

    Example Request:
    ```bash
    curl -X POST "http://localhost:4000/policies" \
        -H "Authorization: Bearer <your_api_key>" \
        -H "Content-Type: application/json" \
        -d '{
            "policy_name": "global-baseline",
            "description": "Base guardrails for all requests",
            "guardrails_add": ["pii_masking", "prompt_injection"],
            "guardrails_remove": []
        }'
    ```

    Example Response:
    ```json
    {
        "policy_id": "123e4567-e89b-12d3-a456-426614174000",
        "policy_name": "global-baseline",
        "inherit": null,
        "description": "Base guardrails for all requests",
        "guardrails_add": ["pii_masking", "prompt_injection"],
        "guardrails_remove": [],
        "condition": null,
        "created_at": "2024-01-01T00:00:00Z",
        "updated_at": "2024-01-01T00:00:00Z"
    }
    ```
    r   r   Nr   r   r    )policy_requestr   
created_byzError creating policy: zunique constraint  zPolicy with name 'z' already exists)r&   r   r   user_idr   Zadd_policy_to_dbr)   r   r*   r+   lowerpolicy_name)r0   r1   r   r3   resultr,   r-   r-   r.   create_policy]   s,   )r9   z%/policies/name/{policy_name}/versionsr7   c              
      t   ddl m} |du rtdddzt j| |dI dH W S  ty9 } ztd|  tdt|dd}~ww )	zV
    List all versions of a policy by name, ordered by version_number descending.
    r   r   Nr   r   r    r7   r   zError listing policy versions: )	r&   r   r   r   Zget_versions_by_policy_namer)   r   r*   r+   r7   r   r,   r-   r-   r.   list_policy_versions   s   
r=   c              
      s   ddl m} |du rtdddz|j}t j| ||j|dI dH W S  tyW } z(t	d|  d	t
| v sCd
t
| v rKtdt
|dtdt
|dd}~ww )z
    Create a new draft version of a policy. Copies all fields from the source.
    Source is current production if source_policy_id is not provided.
    r   r   Nr   r   r    )r7   r   source_policy_idr3   zError creating policy version: 	not foundzno production  )r&   r   r   r5   r   Zcreate_new_versionr>   r)   r   r*   r+   r6   )r7   r0   r1   r   r3   r,   r-   r-   r.   create_policy_version   s&    rA   z/policies/{policy_id}/status	policy_idc              
      s   ddl m} |du rtdddz|j}t j| |j||dI dH W S  ty+     tyv } z@t	d|  d	t
| v sRd
t
| v sRdt
| v rZtdt
|ddt
| v rjtdt
|dtdt
|dd}~ww )z
    Update a policy version's status. Valid transitions:
    - draft -> published
    - published -> production (demotes current production to published)
    - production -> published (demotes, policy becomes inactive)
    r   r   Nr   r   r    )rB   Z
new_statusr   
updated_byzError updating version status: zinvalid statusz
only draftzcannot promoter4   r?   r@   )r&   r   r   r5   r   Zupdate_version_statusr   r)   r   r*   r+   r6   )rB   r0   r1   r   rC   r,   r-   r-   r.   update_policy_version_status   s.   0rD   z/policies/compare	version_a	version_bc              
      s   ddl m} |du rtdddzt j| ||dI dH W S  tyJ } z td|  d	t|	 v r>td
t|dtdt|dd}~ww )z_
    Compare two policy versions. Query params: version_a, version_b (policy version IDs).
    r   r   Nr   r   r    )Zpolicy_id_aZpolicy_id_br   zError comparing versions: r?   r@   )
r&   r   r   r   Zcompare_versionsr)   r   r*   r+   r6   )rE   rF   r   r,   r-   r-   r.   compare_policy_versions  s"   rG   z)/policies/name/{policy_name}/all-versions)r   r   c              
      r:   )	zP
    Delete all versions of a policy. Also removes from in-memory registry.
    r   r   Nr   r   r    r;   zError deleting all versions: )	r&   r   r   r   Zdelete_all_versionsr)   r   r*   r+   r<   r-   r-   r.   delete_all_policy_versions&  s   	rH   z/policies/{policy_id}c              
         ddl m} |du rtdddzt j| |dI dH }|du r+tdd	|  d
d|W S  ty5     tyP } ztd|  tdt|dd}~ww )z
    Get a policy by ID.

    Example Request:
    ```bash
    curl -X GET "http://localhost:4000/policies/123e4567-e89b-12d3-a456-426614174000" \
        -H "Authorization: Bearer <your_api_key>"
    ```
    r   r   Nr   r   r    rB   r   r@   Policy with ID 
 not foundzError getting policy: )	r&   r   r   r   get_policy_by_id_from_dbr)   r   r*   r+   )rB   r   r8   r,   r-   r-   r.   
get_policyC  s*   rN   c              
      s   ddl m} |du rtdddz:t j| |dI dH }|du r+tdd	|  d
dt|dddkr9tddd|j}t j| |||dI dH }|W S  tyS     tyn } zt	
d|  tdt|dd}~ww )a  
    Update an existing policy.

    Example Request:
    ```bash
    curl -X PUT "http://localhost:4000/policies/123e4567-e89b-12d3-a456-426614174000" \
        -H "Authorization: Bearer <your_api_key>" \
        -H "Content-Type: application/json" \
        -d '{
            "description": "Updated description",
            "guardrails_add": ["pii_masking", "toxicity_filter"]
        }'
    ```
    r   r   Nr   r   r    rJ   r@   rK   rL   r   
productionZdraftr4   zcOnly draft versions can be updated. Publish or create a new version to change published/production.)rB   r2   r   rC   zError updating policy: )r&   r   r   r   rM   getattrr5   Zupdate_policy_in_dbr)   r   r*   r+   )rB   r0   r1   r   existingrC   r8   r,   r-   r-   r.   update_policyi  sB   rR   c              
         ddl m} |du rtdddz't j| |dI dH }|du r+tdd	|  d
dt j| |dI dH }|W S  ty@     ty[ } ztd|  tdt	|dd}~ww )a^  
    Delete a policy.

    Example Request:
    ```bash
    curl -X DELETE "http://localhost:4000/policies/123e4567-e89b-12d3-a456-426614174000" \
        -H "Authorization: Bearer <your_api_key>"
    ```

    Example Response:
    ```json
    {
        "message": "Policy 123e4567-e89b-12d3-a456-426614174000 deleted successfully"
    }
    ```
    r   r   Nr   r   r    rJ   r@   rK   rL   zError deleting policy: )
r&   r   r   r   rM   Zdelete_policy_from_dbr)   r   r*   r+   )rB   r   rQ   r8   r,   r-   r-   r.   delete_policy  s2   rT   z)/policies/{policy_id}/resolved-guardrailsc              
      s   ddl m} |du rtdddz.t j| |dI dH }|du r+tdd	|  d
dt j|j|dI dH }|j|j|dW S  tyG     tyZ } ztdt	|dd}~w t
yu } ztd|  tdt	|dd}~ww )a  
    Get the resolved guardrails for a policy (including inherited guardrails).

    This endpoint resolves the full inheritance chain and returns the final
    set of guardrails that would be applied for this policy.

    Example Request:
    ```bash
    curl -X GET "http://localhost:4000/policies/123e4567-e89b-12d3-a456-426614174000/resolved-guardrails" \
        -H "Authorization: Bearer <your_api_key>"
    ```

    Example Response:
    ```json
    {
        "policy_id": "123e4567-e89b-12d3-a456-426614174000",
        "policy_name": "healthcare-compliance",
        "resolved_guardrails": ["pii_masking", "prompt_injection", "toxicity_filter"]
    }
    ```
    r   r   Nr   r   r    rJ   r@   rK   rL   r;   )rB   r7   Zresolved_guardrailsr4   zError resolving guardrails: )r&   r   r   r   rM   Zresolve_guardrails_from_dbr7   rB   
ValueErrorr+   r)   r   r*   )rB   r   policyresolvedr,   r-   r-   r.   get_resolved_guardrails  s>   rX   z/policies/test-pipelinec              
      s   z
t di | j}W n ty  } z	tdd| dd}~ww | jdi d}ztj|j|j||ddd	I dH }|	 W S  tyY } zt
d
|  tdt|dd}~ww )a   
    Test a guardrail pipeline with sample messages.

    Executes the pipeline steps against the provided test messages and returns
    step-by-step results showing which guardrails passed/failed, actions taken,
    and timing information.

    Example Request:
    ```bash
    curl -X POST "http://localhost:4000/policies/test-pipeline" \
        -H "Authorization: Bearer <your_api_key>" \
        -H "Content-Type: application/json" \
        -d '{
            "pipeline": {
                "mode": "pre_call",
                "steps": [
                    {"guardrail": "pii-guard", "on_pass": "next", "on_fail": "block"}
                ]
            },
            "test_messages": [{"role": "user", "content": "My SSN is 123-45-6789"}]
        }'
    ```
    r4   zInvalid pipeline: r    Ntest)messagesmodelmetadata
completionztest-pipeline)stepsmodedatar1   Z	call_typer7   zError testing pipeline: r   r-   )r   Zpipeliner)   r   Ztest_messagesr
   Zexecute_stepsr^   r_   Z
model_dumpr   r*   r+   )r0   r1   Zvalidated_pipeliner,   r`   r8   r-   r-   r.   test_pipeline  s4    
ra   z/policies/attachments/listc               
      s   ddl m}  | du rtdddzt | I dH }t|t|dW S  ty? } zt	d|  tdt
|dd}~ww )	a  
    List all policy attachments from the database.

    Example Request:
    ```bash
    curl -X GET "http://localhost:4000/policies/attachments/list" \
        -H "Authorization: Bearer <your_api_key>"
    ```

    Example Response:
    ```json
    {
        "attachments": [
            {
                "attachment_id": "123e4567-e89b-12d3-a456-426614174000",
                "policy_name": "global-baseline",
                "scope": "*",
                "teams": [],
                "keys": [],
                "models": [],
                "created_at": "2024-01-01T00:00:00Z",
                "updated_at": "2024-01-01T00:00:00Z"
            }
        ],
        "total_count": 1
    }
    ```
    r   r   Nr   r   r    )attachmentsr%   z"Error listing policy attachments: )r&   r   r   r	   Zget_all_attachments_from_dbr   r(   r)   r   r*   r+   )r   rb   r,   r-   r-   r.   list_policy_attachments\  s    #
rc   z/policies/attachmentsc              
      s   ddl m} |du rtdddz4t j|ddI dH }d	d
 |D }| j|vr4tdd| j dd|j}t j| ||dI dH }|W S  tyM     t	yh } zt
d|  tdt|dd}~ww )a  
    Create a new policy attachment.

    Example Request:
    ```bash
    curl -X POST "http://localhost:4000/policies/attachments" \
        -H "Authorization: Bearer <your_api_key>" \
        -H "Content-Type: application/json" \
        -d '{
            "policy_name": "global-baseline",
            "scope": "*"
        }'
    ```

    Example with team-specific attachment:
    ```bash
    curl -X POST "http://localhost:4000/policies/attachments" \
        -H "Authorization: Bearer <your_api_key>" \
        -H "Content-Type: application/json" \
        -d '{
            "policy_name": "healthcare-compliance",
            "teams": ["healthcare-team", "medical-research"]
        }'
    ```

    Example Response:
    ```json
    {
        "attachment_id": "123e4567-e89b-12d3-a456-426614174000",
        "policy_name": "global-baseline",
        "scope": "*",
        "teams": [],
        "keys": [],
        "models": [],
        "created_at": "2024-01-01T00:00:00Z",
        "updated_at": "2024-01-01T00:00:00Z"
    }
    ```
    r   r   Nr   r   r    rO   r#   c                 S   s   h | ]}|j qS r-   )r7   ).0pr-   r-   r.   	<setcomp>  s    z+create_policy_attachment.<locals>.<setcomp>r@   zPolicy 'z%' not found. Create the policy first.)Zattachment_requestr   r3   z"Error creating policy attachment: )r&   r   r   r   r'   r7   r5   r	   Zadd_attachment_to_dbr)   r   r*   r+   )r0   r1   r   r$   Zpolicy_namesr3   r8   r,   r-   r-   r.   create_policy_attachment  s8   1
rg   z%/policies/attachments/{attachment_id}attachment_idc              
      rI   )z
    Get a policy attachment by ID.

    Example Request:
    ```bash
    curl -X GET "http://localhost:4000/policies/attachments/123e4567-e89b-12d3-a456-426614174000" \
        -H "Authorization: Bearer <your_api_key>"
    ```
    r   r   Nr   r   r    rh   r   r@   Attachment with ID rL   z!Error getting policy attachment: )	r&   r   r   r	   get_attachment_by_id_from_dbr)   r   r*   r+   )rh   r   r8   r,   r-   r-   r.   get_policy_attachment  s,   
rl   c              
      rS   )ay  
    Delete a policy attachment.

    Example Request:
    ```bash
    curl -X DELETE "http://localhost:4000/policies/attachments/123e4567-e89b-12d3-a456-426614174000" \
        -H "Authorization: Bearer <your_api_key>"
    ```

    Example Response:
    ```json
    {
        "message": "Attachment 123e4567-e89b-12d3-a456-426614174000 deleted successfully"
    }
    ```
    r   r   Nr   r   r    ri   r@   rj   rL   z"Error deleting policy attachment: )
r&   r   r   r	   rk   Zdelete_attachment_from_dbr)   r   r*   r+   )rh   r   rQ   r8   r,   r-   r-   r.   delete_policy_attachment  s4   
rm   )N)7__doc__typingr   Zfastapir   r   r   Zlitellm._loggingr   Zlitellm.proxy._typesr   Z$litellm.proxy.auth.user_api_key_authr   Z/litellm.proxy.policy_engine.attachment_registryr	   Z-litellm.proxy.policy_engine.pipeline_executorr
   Z+litellm.proxy.policy_engine.policy_registryr   Z!litellm.types.proxy.policy_enginer   r   r   r   r   r   r   r   r   r   r   r   r   Zroutergetr+   r/   postr9   r=   rA   putrD   rG   deleterH   rN   rR   rT   rX   ra   rc   rg   rl   rm   r-   r-   r-   r.   <module>   s<   <5?		# 	7.?:
.J!