import gradio as gr
from atproto import Client
from atproto_client.exceptions import BadRequestError
def clean_handle(handle: str) -> str:
"""Clean the handle by removing special characters and whitespace."""
# Remove @ symbol, whitespace, and any invisible characters
handle = ''.join(char for char in handle if char.isprintable())
handle = handle.strip().replace('@', '').strip()
return handle
def get_did_from_handle(handle: str) -> str:
"""
Get the DID for a given Bluesky handle.
Args:
handle (str): Bluesky handle (e.g., 'username.bsky.social')
Returns:
str: Success or error message
"""
# Clean the handle
handle = clean_handle(handle)
if not handle:
return "Error: Please enter a handle"
if not handle.endswith('.bsky.social'):
return "Error: Handle must end with .bsky.social"
# Initialize client
client = Client()
try:
# Attempt to resolve handle
response = client.resolve_handle(handle)
return f"DID: {response.did}"
except BadRequestError as e:
# Add debugging information
return (f"Error processing handle: '{handle}'\n"
f"Length: {len(handle)}\n"
f"Characters (for debugging): {[ord(c) for c in handle]}\n"
f"Original error: {str(e)}")
except Exception as e:
return f"Error: {str(e)}"
# Create Gradio interface
demo = gr.Interface(
fn=get_did_from_handle,
inputs=[
gr.Textbox(
label="Enter Bluesky Handle",
placeholder="username.bsky.social",
info="Enter a Bluesky handle to get its DID (without the @ symbol)"
)
],
outputs=gr.Textbox(label="Result"),
title="Bluesky DID Lookup",
description="Look up the DID (Decentralized Identifier) for any Bluesky handle. Enter a handle in the format 'username.bsky.social'.
Built by @danielvanstrien.bsky.social
Part of Bluesky Community",
examples=[
["atproto.bsky.social"],
["bsky.app"],
["danielvanstrien.bsky.social"],
],
theme=gr.themes.Default(),
)
if __name__ == "__main__":
demo.launch()