File size: 2,926 Bytes
a6cc09a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fcc2e99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a6cc09a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import argparse, sys, yaml, os
import gradio as gr
from openapi_loader import prepare_app

def ping(message: str) -> str:
    return f"pong: {message}"

def _hello_blocks() -> gr.Blocks:
    with gr.Blocks() as demo:
        gr.Markdown("## AnyAPI→MCP Factory (Skeleton)")
        inp = gr.Textbox(label="Message")
        out = gr.Textbox(label="Reply")
        gr.Button("Ping").click(ping, inp, out, api_name="ping")
    return demo

def _load_profile(name: str):
    path = os.path.join(os.getcwd(), "profiles.yaml")
    if not os.path.exists(path):
        raise FileNotFoundError("profiles.yaml not found.")
    data = yaml.safe_load(open(path, "r", encoding="utf-8"))
    if name not in data:
        raise KeyError(f"profile '{name}' not in profiles.yaml. Have: {list(data.keys())}")
    prof = data[name] or {}
    return prof.get("spec"), prof.get("base_url"), prof.get("bearer")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--spec", type=str, help="OpenAPI spec URL or local path")
    parser.add_argument("--base-url", type=str, default=None, help="Override API base URL (e.g., https://api.example.com)")
    parser.add_argument("--bearer", type=str, default=None, help="Bearer token")
    parser.add_argument("--profile", type=str, default=None, help="Profile name from profiles.yaml")
    parser.add_argument("--share", action="store_true", help="Share link for quick demos")
    args = parser.parse_args()

    spec, base_url, bearer = args.spec, args.base_url, args.bearer

    # If running in Spaces (no CLI flags), autoload a profile.
    if not (spec or args.profile):
        default_profile = os.getenv("DEFAULT_PROFILE", "httpbin")
        try:
            p_spec, p_base, p_bearer = _load_profile(default_profile)
            spec = p_spec
            base_url = base_url or p_base
            # only take bearer from profile if user didn't pass one
            bearer = bearer if (bearer is not None and bearer != "") else (p_bearer or None)
            args.profile = default_profile
            print(f"[Space] No flags; auto-loading profile '{default_profile}'")
        except Exception as e:
            print(f"[Space] Could not autoload profile '{default_profile}': {e}")

    if args.profile:
        p_spec, p_base, p_bearer = _load_profile(args.profile)
        # CLI flags take precedence if provided, else use profile values
        spec = spec or p_spec
        base_url = base_url or p_base
        bearer = bearer if (bearer is not None and bearer != "") else (p_bearer or None)

    if spec:
        demo, origin = prepare_app(spec, base_url=base_url, bearer_token=bearer)
        print(f"[AnyAPI→MCP] Loaded spec from: {origin}")
        if bearer:
            print("[AnyAPI→MCP] Bearer token provided (masked).")
    else:
        demo = _hello_blocks()

    demo.launch(mcp_server=True, share=args.share)

if __name__ == "__main__":
    main()