broadfield-dev commited on
Commit
a989290
Β·
verified Β·
1 Parent(s): 29de23f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -38
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import gradio as gr
2
  import requests
3
  import base64
4
- import json
5
  from PIL import Image
6
  import io
7
  import logging
@@ -11,63 +10,53 @@ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(level
11
  logger = logging.getLogger(__name__)
12
 
13
  # ==============================================================================
14
- # API CALL LOGIC
15
  # ==============================================================================
16
 
17
- def call_decoder_api(server_base_url: str, image: Image.Image) -> dict:
18
  """
19
  Takes a PIL image, converts it to base64, sends it to the specified server API,
20
  and returns the decrypted JSON data.
21
  """
22
  # --- Input Validation ---
23
- if not server_base_url or "hf.space" not in server_base_url:
24
- raise gr.Error("Please provide a valid Hugging Face Space URL for the server API.")
25
  if image is None:
26
  raise gr.Error("Please upload an encrypted image.")
27
 
28
- # The specific endpoint for our Gradio API
29
- api_endpoint = f"{server_base_url.strip('/')}/run/mcp_decode"
30
- logger.info(f"Attempting to call API at: {api_endpoint}")
31
 
32
  try:
33
  # 1. Convert the PIL Image to a base64 string
34
- buffer = io.BytesIO()
35
- image.save(buffer, format="PNG")
36
- image_bytes = buffer.getvalue()
37
- image_base64 = base64.b64encode(image_bytes).decode('utf-8')
38
 
39
  # 2. Prepare the JSON payload for the Gradio API
40
- # Gradio's /run/predict endpoint expects this specific structure: {"data": [input1, input2, ...]}
41
- payload = {
42
- "data": [
43
- image_base64
44
- ]
45
- }
46
 
47
  # 3. Make the POST request to the server API
48
  headers = {"Content-Type": "application/json"}
49
  response = requests.post(api_endpoint, headers=headers, json=payload, timeout=30)
50
 
51
  # 4. Process the response
 
52
  if response.status_code == 200:
53
- response_json = response.json()
54
  if "data" in response_json and len(response_json["data"]) > 0:
55
- # Gradio API wraps results in a "data" list. The actual result is the first element.
56
  return response_json["data"][0]
57
  elif "error" in response_json:
58
  raise gr.Error(f"API returned an error: {response_json['error']}")
59
- else:
60
- raise gr.Error(f"API returned an unexpected response format: {response_json}")
61
  else:
62
  # Handle non-200 responses with more detail
63
- error_text = response.text
64
- raise gr.Error(f"API Error (Status {response.status_code}): {error_text}")
65
 
66
  except requests.exceptions.RequestException as e:
67
  logger.error(f"Network error calling API: {e}")
68
  raise gr.Error(f"Could not connect to the API. Check the URL and server status. Error: {e}")
69
  except Exception as e:
70
- logger.error(f"An unexpected error occurred: {e}", exc_info=True)
71
  raise gr.Error(f"An unexpected error occurred: {e}")
72
 
73
  # ==============================================================================
@@ -77,34 +66,28 @@ def call_decoder_api(server_base_url: str, image: Image.Image) -> dict:
77
  with gr.Blocks(theme=gr.themes.Soft(), title="KeyLock API Client") as demo:
78
  gr.Markdown("# πŸ”‘ KeyLock API Client")
79
  gr.Markdown(
80
- "This is a user interface for the **Secure Decoder API**. It sends an encrypted image "
81
- "to the server for decryption."
82
  )
83
 
84
  with gr.Row():
85
  with gr.Column(scale=1):
86
- gr.Markdown("### 1. Configure Server URL")
87
  server_url_input = gr.Textbox(
88
- label="Decoder API Server URL",
89
- placeholder="Enter the direct URL of your Python server space...",
90
- info="Example: https://your-name-keylock-api-python.hf.space"
91
  )
92
 
93
  gr.Markdown("### 2. Upload Encrypted Image")
94
- image_input = gr.Image(
95
- type="pil",
96
- label="Upload Encrypted PNG Image",
97
- sources=["upload", "clipboard"]
98
- )
99
  submit_button = gr.Button("Decrypt via API", variant="primary")
100
 
101
  with gr.Column(scale=2):
102
  gr.Markdown("### 3. Decrypted Data")
103
  json_output = gr.JSON(label="Result from Server")
104
 
105
- # Connect the UI components to the API call function
106
  submit_button.click(
107
- fn=call_decoder_api,
108
  inputs=[server_url_input, image_input],
109
  outputs=[json_output]
110
  )
 
1
  import gradio as gr
2
  import requests
3
  import base64
 
4
  from PIL import Image
5
  import io
6
  import logging
 
10
  logger = logging.getLogger(__name__)
11
 
12
  # ==============================================================================
13
+ # CLIENT-SIDE API CALL LOGIC
14
  # ==============================================================================
15
 
16
+ def call_api(server_endpoint_url: str, image: Image.Image) -> dict:
17
  """
18
  Takes a PIL image, converts it to base64, sends it to the specified server API,
19
  and returns the decrypted JSON data.
20
  """
21
  # --- Input Validation ---
22
+ if not server_endpoint_url or "/run/mcp_decode" not in server_endpoint_url:
23
+ raise gr.Error("Please provide the FULL API endpoint URL, including the /run/mcp_decode path.")
24
  if image is None:
25
  raise gr.Error("Please upload an encrypted image.")
26
 
27
+ api_endpoint = server_endpoint_url.strip()
28
+ logger.info(f"Client attempting to call API at: {api_endpoint}")
 
29
 
30
  try:
31
  # 1. Convert the PIL Image to a base64 string
32
+ with io.BytesIO() as buffer:
33
+ image.save(buffer, format="PNG")
34
+ image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
 
35
 
36
  # 2. Prepare the JSON payload for the Gradio API
37
+ payload = {"data": [image_base64]}
 
 
 
 
 
38
 
39
  # 3. Make the POST request to the server API
40
  headers = {"Content-Type": "application/json"}
41
  response = requests.post(api_endpoint, headers=headers, json=payload, timeout=30)
42
 
43
  # 4. Process the response
44
+ response_json = response.json()
45
  if response.status_code == 200:
 
46
  if "data" in response_json and len(response_json["data"]) > 0:
 
47
  return response_json["data"][0]
48
  elif "error" in response_json:
49
  raise gr.Error(f"API returned an error: {response_json['error']}")
 
 
50
  else:
51
  # Handle non-200 responses with more detail
52
+ error_detail = response_json.get("error", "Unknown error.")
53
+ raise gr.Error(f"API Error (Status {response.status_code}): {error_detail}")
54
 
55
  except requests.exceptions.RequestException as e:
56
  logger.error(f"Network error calling API: {e}")
57
  raise gr.Error(f"Could not connect to the API. Check the URL and server status. Error: {e}")
58
  except Exception as e:
59
+ logger.error(f"An unexpected client-side error occurred: {e}", exc_info=True)
60
  raise gr.Error(f"An unexpected error occurred: {e}")
61
 
62
  # ==============================================================================
 
66
  with gr.Blocks(theme=gr.themes.Soft(), title="KeyLock API Client") as demo:
67
  gr.Markdown("# πŸ”‘ KeyLock API Client")
68
  gr.Markdown(
69
+ "This UI calls the **Secure Decoder API**. It sends an encrypted image to the server for decryption."
 
70
  )
71
 
72
  with gr.Row():
73
  with gr.Column(scale=1):
74
+ gr.Markdown("### 1. Configure Server Endpoint")
75
  server_url_input = gr.Textbox(
76
+ label="Full Decoder API Endpoint URL",
77
+ placeholder="https://your-server-space.hf.space/run/mcp_decode",
78
+ info="You must include the /run/mcp_decode path."
79
  )
80
 
81
  gr.Markdown("### 2. Upload Encrypted Image")
82
+ image_input = gr.Image(type="pil", label="Image encrypted with the server's public key", sources=["upload", "clipboard"])
 
 
 
 
83
  submit_button = gr.Button("Decrypt via API", variant="primary")
84
 
85
  with gr.Column(scale=2):
86
  gr.Markdown("### 3. Decrypted Data")
87
  json_output = gr.JSON(label="Result from Server")
88
 
 
89
  submit_button.click(
90
+ fn=call_api,
91
  inputs=[server_url_input, image_input],
92
  outputs=[json_output]
93
  )