Spaces:
Sleeping
Sleeping
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() |