diff --git a/python/xquik_openapi_example/README.md b/python/xquik_openapi_example/README.md new file mode 100644 index 0000000..73a1ab9 --- /dev/null +++ b/python/xquik_openapi_example/README.md @@ -0,0 +1,31 @@ +# Xquik OpenAPI UTCP example + +This example shows how to register Xquik's public OpenAPI document as a UTCP HTTP provider. It lets a UTCP client discover Xquik tools for X data workflows such as tweet search, user lookup, follower export, monitoring, webhooks, and write actions. + +The script only lists matching tools by default. Set a real `XQUIK_API_KEY` before calling any Xquik endpoint. + +## Setup + +```sh +pip install -r requirements.txt +``` + +Edit `example.env` and replace the placeholder value: + +```sh +XQUIK_API_KEY=xq_replace_with_your_key +``` + +## Run + +```sh +python xquik_openapi_example.py +``` + +The example loads `providers.json`, fetches , registers the discovered tools, and prints the first matching tools. + +## Notes + +- Keep API keys in local environment files or a secret store. +- Do not commit real API keys. +- Xquik MCP setup is documented at . diff --git a/python/xquik_openapi_example/example.env b/python/xquik_openapi_example/example.env new file mode 100644 index 0000000..c3c50f6 --- /dev/null +++ b/python/xquik_openapi_example/example.env @@ -0,0 +1 @@ +XQUIK_API_KEY=xq_replace_with_your_key diff --git a/python/xquik_openapi_example/providers.json b/python/xquik_openapi_example/providers.json new file mode 100644 index 0000000..51eb3b8 --- /dev/null +++ b/python/xquik_openapi_example/providers.json @@ -0,0 +1,31 @@ +{ + "load_variables_from": [ + { + "variable_loader_type": "dotenv", + "env_file_path": "example.env" + } + ], + "tool_repository": { + "tool_repository_type": "in_memory" + }, + "tool_search_strategy": { + "tool_search_strategy_type": "tag_and_description_word_match", + "description_weight": 1, + "tag_weight": 3 + }, + "manual_call_templates": [ + { + "name": "xquik", + "call_template_type": "http", + "http_method": "GET", + "url": "https://xquik.com/openapi.json", + "content_type": "application/json", + "auth_tools": { + "auth_type": "api_key", + "api_key": "$XQUIK_API_KEY", + "var_name": "x-api-key", + "location": "header" + } + } + ] +} diff --git a/python/xquik_openapi_example/requirements.txt b/python/xquik_openapi_example/requirements.txt new file mode 100644 index 0000000..c53d604 --- /dev/null +++ b/python/xquik_openapi_example/requirements.txt @@ -0,0 +1,3 @@ +python-dotenv +utcp +utcp-http diff --git a/python/xquik_openapi_example/xquik_openapi_example.py b/python/xquik_openapi_example/xquik_openapi_example.py new file mode 100644 index 0000000..c0d930e --- /dev/null +++ b/python/xquik_openapi_example/xquik_openapi_example.py @@ -0,0 +1,31 @@ +import asyncio +import json +from pathlib import Path + +from utcp.data.utcp_client_config import UtcpClientConfigSerializer +from utcp.utcp_client import UtcpClient + + +async def main(): + base_dir = Path(__file__).parent + config_path = base_dir / "providers.json" + config_data = json.loads(config_path.read_text(encoding="utf-8")) + + for variable_loader in config_data.get("load_variables_from", []): + if variable_loader.get("variable_loader_type") == "dotenv": + variable_loader["env_file_path"] = str(base_dir / "example.env") + + config = UtcpClientConfigSerializer().validate_dict(config_data) + client = await UtcpClient.create(root_dir=str(base_dir), config=config) + + tools = await client.search_tools("tweet search user lookup follower export", limit=12) + print("Matching Xquik tools:") + for tool in tools: + description = getattr(tool, "description", "") + print(f" - {tool.name}: {description}") + + print("\nSet XQUIK_API_KEY in example.env before calling a Xquik tool.") + + +if __name__ == "__main__": + asyncio.run(main())