File size: 3,628 Bytes
b2bb8dd
acd0086
b2bb8dd
13b7cd0
b2bb8dd
29de23f
b2bb8dd
29de23f
 
 
b2bb8dd
 
13b7cd0
b2bb8dd
13b7cd0
 
b2bb8dd
13b7cd0
b2bb8dd
13b7cd0
 
 
b2bb8dd
 
 
13b7cd0
29de23f
b2bb8dd
13b7cd0
 
 
 
 
a989290
 
 
b2bb8dd
13b7cd0
 
 
 
 
 
 
 
b2bb8dd
13b7cd0
 
 
b2bb8dd
 
13b7cd0
a989290
b2bb8dd
 
 
 
 
13b7cd0
b2bb8dd
29de23f
13b7cd0
 
 
 
b2bb8dd
 
 
13b7cd0
 
 
 
 
29de23f
 
 
a989290
b2bb8dd
 
 
29de23f
b2bb8dd
 
 
a989290
13b7cd0
b2bb8dd
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import gradio as gr
from gradio_client import Client
from PIL import Image
import base64
import io
import logging

# --- Configure Logging ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# ==============================================================================
#  CLIENT-SIDE API CALL LOGIC (Using the Official Gradio Client)
# ==============================================================================

def call_api(server_space_id: str, image: Image.Image) -> dict:
    """
    Uses the official gradio_client to call the secure decoder API.
    """
    # --- Input Validation ---
    if not server_space_id or "/" not in server_space_id:
        raise gr.Error("Please provide the Server Space ID in the format 'username/space-name'.")
    if image is None:
        raise gr.Error("Please upload an encrypted image.")

    logger.info(f"Initializing client for server space: {server_space_id}")

    try:
        # 1. Initialize the Gradio Client
        # This points the client to your server space.
        client = Client(src=server_space_id)

        # 2. Convert the PIL Image to a base64 string
        with io.BytesIO() as buffer:
            image.save(buffer, format="PNG")
            image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')

        # 3. Call the specific API endpoint on the server
        # This matches the documentation you provided exactly.
        logger.info(f"Calling api_name='/keylock-auth-decoder' on {server_space_id}")
        result = client.predict(
            # The keyword argument MUST match the server function's parameter name.
            image_base64_string=image_base64,
            api_name="/keylock-auth-decoder"
        )
        
        logger.info("Successfully received result from API.")
        # The result from a successful predict call is the data itself.
        return result

    except Exception as e:
        # Handle other unexpected errors
        logger.error(f"An unexpected client-side error occurred: {e}", exc_info=True)
        raise gr.Error(f"An unexpected error occurred: {e}")

# ==============================================================================
#  GRADIO INTERFACE
# ==============================================================================

with gr.Blocks(theme=gr.themes.Soft(), title="KeyLock API Client") as demo:
    gr.Markdown("# πŸ”‘ KeyLock API Client")
    gr.Markdown(
        "This UI calls the **Secure Decoder API**. It sends an encrypted image to the server for decryption "
        "using the official `gradio_client` library."
    )

    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### 1. Configure Server Space ID")
            server_id_input = gr.Textbox(
                label="Decoder Server Space ID",
                value="broadfield-dev/KeyLock-Auth",
                info="This is the Hugging Face ID of your server, e.g., 'username/space-name'."
            )

            gr.Markdown("### 2. Upload Encrypted Image")
            image_input = gr.Image(type="pil", label="Image encrypted with the server's public key", sources=["upload", "clipboard"])
            submit_button = gr.Button("Decrypt via API", variant="primary")

        with gr.Column(scale=2):
            gr.Markdown("### 3. Decrypted Data")
            json_output = gr.JSON(label="Result from Server")

    submit_button.click(
        fn=call_api,
        inputs=[server_id_input, image_input],
        outputs=[json_output]
    )

if __name__ == "__main__":
    demo.launch()