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 (any valid format)
Returns:
str: Success or error message
"""
if not handle:
return "Error: Please enter a handle"
# Initialize client
client = Client()
# First try: raw input
try:
response = client.resolve_handle(handle)
return f"DID: {response.did}"
except BadRequestError:
# Second try: cleaned input
try:
cleaned_handle = clean_handle(handle)
if cleaned_handle != handle: # Only try if cleaning actually changed something
response = client.resolve_handle(cleaned_handle)
return f"DID: {response.did}"
except BadRequestError as e:
return (f"Error: Could not resolve handle. Please check the format.\n"
f"Tried both '{handle}' and '{cleaned_handle}'")
except Exception as e:
return f"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 (with or without @ symbol)"
)
],
outputs=gr.Textbox(label="Result"),
title="Bluesky DID Lookup",
description="Look up the DID (Decentralized Identifier) for any Bluesky handle.
Built by @danielvanstrien.bsky.social
Part of Bluesky Community",
examples=[
["atproto.bsky.social"],
["bsky.app"],
["danielvanstrien.bsky.social"],
["@jay.bsky.team"],
],
theme=gr.themes.Default(),
allow_flagging="never"
)
if __name__ == "__main__":
demo.launch()