Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import json | |
| # Zu.lk API Base URL | |
| API_BASE_URL = "https://api.zu.lk" | |
| def parse_auth_header(auth_header): | |
| """Parse authorization header to extract API key and secret""" | |
| if not auth_header or auth_header.strip() == "": | |
| return None, None | |
| # Format: "Bearer OfNJsl3lmt:$2b$10$qf2ZMINlvw" | |
| try: | |
| # Split by space and get the second part (after "Bearer ") | |
| parts = auth_header.strip().split(" ", 1) | |
| if len(parts) != 2 or parts[0] != "Bearer": | |
| return None, None | |
| # Split the credentials by colon | |
| credentials = parts[1] | |
| api_key, api_secret = credentials.split(":", 1) | |
| return api_key, api_secret | |
| except ValueError: | |
| return None, None | |
| def make_api_request(endpoint, method="GET", data=None, api_key=None, api_secret=None): | |
| """Make authenticated request to Zu.lk API""" | |
| if not api_key or not api_secret: | |
| return {"error": "Invalid authentication credentials"} | |
| headers = { | |
| "X-API-KEY": api_key, | |
| "X-API-Secret": api_secret, | |
| "Content-Type": "application/json" | |
| } | |
| url = f"{API_BASE_URL}{endpoint}" | |
| try: | |
| if method == "GET": | |
| response = requests.get(url, headers=headers) | |
| elif method == "POST": | |
| response = requests.post(url, headers=headers, json=data) | |
| elif method == "PUT": | |
| response = requests.put(url, headers=headers, json=data) | |
| elif method == "DELETE": | |
| response = requests.delete(url, headers=headers) | |
| else: | |
| return {"error": f"Unsupported method: {method}"} | |
| return response.json() | |
| except requests.exceptions.RequestException as e: | |
| return {"error": f"Request failed: {str(e)}"} | |
| except json.JSONDecodeError: | |
| return {"error": "Invalid JSON response"} | |
| def get_organizations(request: gr.Request): | |
| """Get user organizations""" | |
| api_key, api_secret = parse_auth_header(request.headers.get('authorization', '')) | |
| if not api_key or not api_secret: | |
| return "Error: Authorization is required (format: Bearer api_key:api_secret)" | |
| result = make_api_request("/v1/organizations", api_key=api_key, api_secret=api_secret) | |
| return json.dumps(result, indent=2) | |
| def create_link(org_id, url, custom_key, length, request: gr.Request): | |
| """Create a new short link""" | |
| api_key, api_secret = parse_auth_header(request.headers.get('authorization', '')) | |
| if not api_key or not api_secret: | |
| return "Error: Authorization is required (format: Bearer api_key:api_secret)" | |
| if not org_id or not url: | |
| return "Error: Organization ID and URL are required" | |
| data = {"url": url} | |
| if custom_key: | |
| data["key"] = custom_key | |
| if length and length > 0: | |
| data["length"] = length | |
| result = make_api_request(f"/v1/organizations/{org_id}/links", method="POST", | |
| data=data, api_key=api_key, api_secret=api_secret) | |
| return json.dumps(result, indent=2) | |
| def get_org_links(org_id, request: gr.Request): | |
| """Get all links for an organization""" | |
| api_key, api_secret = parse_auth_header(request.headers.get('authorization', '')) | |
| if not api_key or not api_secret: | |
| return "Error: Authorization is required (format: Bearer api_key:api_secret)" | |
| if not org_id: | |
| return "Error: Organization ID is required" | |
| result = make_api_request(f"/v1/organizations/{org_id}/links", | |
| api_key=api_key, api_secret=api_secret) | |
| return json.dumps(result, indent=2) | |
| def get_analytics(org_id, date_from, date_to, interval, request: gr.Request): | |
| """Get organization analytics""" | |
| api_key, api_secret = parse_auth_header(request.headers.get('authorization', '')) | |
| if not api_key or not api_secret: | |
| return "Error: Authorization is required (format: Bearer api_key:api_secret)" | |
| if not org_id: | |
| return "Error: Organization ID is required" | |
| params = [] | |
| if date_from: | |
| params.append(f"date_from={date_from}") | |
| if date_to: | |
| params.append(f"date_to={date_to}") | |
| if interval: | |
| params.append(f"interval={interval}") | |
| query_string = "&".join(params) | |
| endpoint = f"/v1/organizations/{org_id}/analytics/clicks" | |
| if query_string: | |
| endpoint += f"?{query_string}" | |
| result = make_api_request(endpoint, api_key=api_key, api_secret=api_secret) | |
| return json.dumps(result, indent=2) | |
| def update_link(org_id, link_id, new_url, new_key, request: gr.Request): | |
| """Update an existing link""" | |
| api_key, api_secret = parse_auth_header(request.headers.get('authorization', '')) | |
| if not api_key or not api_secret: | |
| return "Error: Authorization is required (format: Bearer api_key:api_secret)" | |
| if not org_id or not link_id or not new_url or not new_key: | |
| return "Error: Organization ID, Link ID, URL, and Key are required" | |
| data = {"url": new_url, "key": new_key} | |
| result = make_api_request(f"/v1/organizations/{org_id}/links/{link_id}", | |
| method="PUT", data=data, api_key=api_key, api_secret=api_secret) | |
| return json.dumps(result, indent=2) | |
| # Create Gradio interface with tabs | |
| with gr.Blocks(title="Zu.lk API Client") as demo: | |
| gr.Markdown("# Zu.lk API Client") | |
| gr.Markdown("Authorization format: `Bearer api_key:api_secret`") | |
| with gr.Tab("Organizations"): | |
| with gr.Row(): | |
| org_btn = gr.Button("Get My Organizations") | |
| org_output = gr.Textbox(label="Organizations", lines=10) | |
| org_btn.click(get_organizations, outputs=org_output) | |
| with gr.Tab("Create Link"): | |
| with gr.Column(): | |
| create_org_id = gr.Textbox(label="Organization ID", placeholder="1") | |
| create_url = gr.Textbox(label="URL to Shorten", placeholder="https://example.com") | |
| create_key = gr.Textbox(label="Custom Key (optional)", placeholder="my-link") | |
| create_length = gr.Number(label="Key Length (3-10)", value=6, minimum=3, maximum=10) | |
| create_btn = gr.Button("Create Link") | |
| create_output = gr.Textbox(label="Result", lines=8) | |
| create_btn.click(create_link, | |
| inputs=[create_org_id, create_url, create_key, create_length], | |
| outputs=create_output) | |
| with gr.Tab("Manage Links"): | |
| with gr.Column(): | |
| links_org_id = gr.Textbox(label="Organization ID", placeholder="1") | |
| get_links_btn = gr.Button("Get All Links") | |
| links_output = gr.Textbox(label="Links", lines=10) | |
| get_links_btn.click(get_org_links, | |
| inputs=[links_org_id], | |
| outputs=links_output) | |
| with gr.Tab("Update Link"): | |
| with gr.Column(): | |
| update_org_id = gr.Textbox(label="Organization ID", placeholder="1") | |
| update_link_id = gr.Textbox(label="Link ID", placeholder="1") | |
| update_url = gr.Textbox(label="New URL", placeholder="https://updated-example.com") | |
| update_key = gr.Textbox(label="New Key", placeholder="updated-key") | |
| update_btn = gr.Button("Update Link") | |
| update_output = gr.Textbox(label="Result", lines=8) | |
| update_btn.click(update_link, | |
| inputs=[update_org_id, update_link_id, update_url, update_key], | |
| outputs=update_output) | |
| with gr.Tab("Analytics"): | |
| with gr.Column(): | |
| analytics_org_id = gr.Textbox(label="Organization ID", placeholder="1") | |
| analytics_from = gr.Textbox(label="Date From (optional)", placeholder="-7d") | |
| analytics_to = gr.Textbox(label="Date To (optional)", placeholder="today") | |
| analytics_interval = gr.Textbox(label="Interval (optional)", placeholder="day") | |
| analytics_btn = gr.Button("Get Analytics") | |
| analytics_output = gr.Textbox(label="Analytics", lines=12) | |
| analytics_btn.click(get_analytics, | |
| inputs=[analytics_org_id, analytics_from, analytics_to, analytics_interval], | |
| outputs=analytics_output) | |
| if __name__ == "__main__": | |
| demo.launch(mcp_server=True, share=True) | |