traia-iatp 0.1.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of traia-iatp might be problematic. Click here for more details.

Files changed (107) hide show
  1. traia_iatp/README.md +368 -0
  2. traia_iatp/__init__.py +54 -0
  3. traia_iatp/cli/__init__.py +5 -0
  4. traia_iatp/cli/main.py +483 -0
  5. traia_iatp/client/__init__.py +10 -0
  6. traia_iatp/client/a2a_client.py +274 -0
  7. traia_iatp/client/crewai_a2a_tools.py +335 -0
  8. traia_iatp/client/d402_a2a_client.py +293 -0
  9. traia_iatp/client/grpc_a2a_tools.py +349 -0
  10. traia_iatp/client/root_path_a2a_client.py +1 -0
  11. traia_iatp/contracts/__init__.py +12 -0
  12. traia_iatp/contracts/iatp_contracts_config.py +263 -0
  13. traia_iatp/contracts/wallet_creator.py +255 -0
  14. traia_iatp/core/__init__.py +43 -0
  15. traia_iatp/core/models.py +172 -0
  16. traia_iatp/d402/__init__.py +55 -0
  17. traia_iatp/d402/chains.py +102 -0
  18. traia_iatp/d402/client.py +150 -0
  19. traia_iatp/d402/clients/__init__.py +7 -0
  20. traia_iatp/d402/clients/base.py +218 -0
  21. traia_iatp/d402/clients/httpx.py +219 -0
  22. traia_iatp/d402/common.py +114 -0
  23. traia_iatp/d402/encoding.py +28 -0
  24. traia_iatp/d402/examples/client_example.py +197 -0
  25. traia_iatp/d402/examples/server_example.py +171 -0
  26. traia_iatp/d402/facilitator.py +453 -0
  27. traia_iatp/d402/fastapi_middleware/__init__.py +6 -0
  28. traia_iatp/d402/fastapi_middleware/middleware.py +225 -0
  29. traia_iatp/d402/fastmcp_middleware.py +147 -0
  30. traia_iatp/d402/mcp_middleware.py +434 -0
  31. traia_iatp/d402/middleware.py +193 -0
  32. traia_iatp/d402/models.py +116 -0
  33. traia_iatp/d402/networks.py +98 -0
  34. traia_iatp/d402/path.py +43 -0
  35. traia_iatp/d402/payment_introspection.py +104 -0
  36. traia_iatp/d402/payment_signing.py +178 -0
  37. traia_iatp/d402/paywall.py +119 -0
  38. traia_iatp/d402/starlette_middleware.py +326 -0
  39. traia_iatp/d402/template.py +1 -0
  40. traia_iatp/d402/types.py +300 -0
  41. traia_iatp/mcp/__init__.py +18 -0
  42. traia_iatp/mcp/client.py +201 -0
  43. traia_iatp/mcp/d402_mcp_tool_adapter.py +361 -0
  44. traia_iatp/mcp/mcp_agent_template.py +481 -0
  45. traia_iatp/mcp/templates/Dockerfile.j2 +80 -0
  46. traia_iatp/mcp/templates/README.md.j2 +310 -0
  47. traia_iatp/mcp/templates/cursor-rules.md.j2 +520 -0
  48. traia_iatp/mcp/templates/deployment_params.json.j2 +20 -0
  49. traia_iatp/mcp/templates/docker-compose.yml.j2 +32 -0
  50. traia_iatp/mcp/templates/dockerignore.j2 +47 -0
  51. traia_iatp/mcp/templates/env.example.j2 +57 -0
  52. traia_iatp/mcp/templates/gitignore.j2 +77 -0
  53. traia_iatp/mcp/templates/mcp_health_check.py.j2 +150 -0
  54. traia_iatp/mcp/templates/pyproject.toml.j2 +32 -0
  55. traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
  56. traia_iatp/mcp/templates/run_local_docker.sh.j2 +390 -0
  57. traia_iatp/mcp/templates/server.py.j2 +175 -0
  58. traia_iatp/mcp/traia_mcp_adapter.py +543 -0
  59. traia_iatp/preview_diagrams.html +181 -0
  60. traia_iatp/registry/__init__.py +26 -0
  61. traia_iatp/registry/atlas_search_indexes.json +280 -0
  62. traia_iatp/registry/embeddings.py +298 -0
  63. traia_iatp/registry/iatp_search_api.py +846 -0
  64. traia_iatp/registry/mongodb_registry.py +771 -0
  65. traia_iatp/registry/readmes/ATLAS_SEARCH_INDEXES.md +252 -0
  66. traia_iatp/registry/readmes/ATLAS_SEARCH_SETUP.md +134 -0
  67. traia_iatp/registry/readmes/AUTHENTICATION_UPDATE.md +124 -0
  68. traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +172 -0
  69. traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +257 -0
  70. traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +208 -0
  71. traia_iatp/registry/readmes/README.md +251 -0
  72. traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +191 -0
  73. traia_iatp/scripts/__init__.py +2 -0
  74. traia_iatp/scripts/create_wallet.py +244 -0
  75. traia_iatp/server/__init__.py +15 -0
  76. traia_iatp/server/a2a_server.py +219 -0
  77. traia_iatp/server/example_template_usage.py +72 -0
  78. traia_iatp/server/iatp_server_agent_generator.py +237 -0
  79. traia_iatp/server/iatp_server_template_generator.py +235 -0
  80. traia_iatp/server/templates/.dockerignore.j2 +48 -0
  81. traia_iatp/server/templates/Dockerfile.j2 +49 -0
  82. traia_iatp/server/templates/README.md +137 -0
  83. traia_iatp/server/templates/README.md.j2 +425 -0
  84. traia_iatp/server/templates/__init__.py +1 -0
  85. traia_iatp/server/templates/__main__.py.j2 +565 -0
  86. traia_iatp/server/templates/agent.py.j2 +94 -0
  87. traia_iatp/server/templates/agent_config.json.j2 +22 -0
  88. traia_iatp/server/templates/agent_executor.py.j2 +279 -0
  89. traia_iatp/server/templates/docker-compose.yml.j2 +23 -0
  90. traia_iatp/server/templates/env.example.j2 +84 -0
  91. traia_iatp/server/templates/gitignore.j2 +78 -0
  92. traia_iatp/server/templates/grpc_server.py.j2 +218 -0
  93. traia_iatp/server/templates/pyproject.toml.j2 +78 -0
  94. traia_iatp/server/templates/run_local_docker.sh.j2 +103 -0
  95. traia_iatp/server/templates/server.py.j2 +243 -0
  96. traia_iatp/special_agencies/__init__.py +4 -0
  97. traia_iatp/special_agencies/registry_search_agency.py +392 -0
  98. traia_iatp/utils/__init__.py +10 -0
  99. traia_iatp/utils/docker_utils.py +251 -0
  100. traia_iatp/utils/general.py +64 -0
  101. traia_iatp/utils/iatp_utils.py +126 -0
  102. traia_iatp-0.1.29.dist-info/METADATA +423 -0
  103. traia_iatp-0.1.29.dist-info/RECORD +107 -0
  104. traia_iatp-0.1.29.dist-info/WHEEL +5 -0
  105. traia_iatp-0.1.29.dist-info/entry_points.txt +2 -0
  106. traia_iatp-0.1.29.dist-info/licenses/LICENSE +21 -0
  107. traia_iatp-0.1.29.dist-info/top_level.txt +1 -0
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ {{ api_name }} MCP Server - FastMCP with D402 Transport Wrapper
4
+
5
+ Uses FastMCP from official MCP SDK with D402MCPTransport wrapper for HTTP 402.
6
+
7
+ Architecture:
8
+ - FastMCP for tool decorators and Context objects
9
+ - D402MCPTransport wraps the /mcp route for HTTP 402 interception
10
+ - Proper HTTP 402 status codes (not JSON-RPC wrapped)
11
+
12
+ Generated from OpenAPI: {{ docs_url }}
13
+
14
+ Environment Variables:
15
+ {% if requires_auth %}- {{ api_key_env_var }}: Server's internal API key (for paid requests)
16
+ {% endif %}- SERVER_ADDRESS: Payment address (IATP wallet contract)
17
+ - MCP_OPERATOR_PRIVATE_KEY: Operator signing key
18
+ - D402_TESTING_MODE: Skip facilitator (default: true)
19
+ """
20
+
21
+ import os
22
+ import logging
23
+ import sys
24
+ from typing import Dict, Any, Optional
25
+ from datetime import datetime
26
+
27
+ import requests
28
+ from retry import retry
29
+ from dotenv import load_dotenv
30
+ import uvicorn
31
+
32
+ load_dotenv()
33
+
34
+ # Configure logging
35
+ logging.basicConfig(
36
+ level=os.getenv("LOG_LEVEL", "INFO").upper(),
37
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
38
+ )
39
+ logger = logging.getLogger('{{ api_slug }}_mcp')
40
+
41
+ # FastMCP from official SDK
42
+ from mcp.server.fastmcp import FastMCP, Context
43
+ from starlette.requests import Request
44
+ from starlette.responses import JSONResponse
45
+
46
+ # D402 payment protocol - using Starlette middleware
47
+ from traia_iatp.d402.starlette_middleware import D402PaymentMiddleware
48
+ from traia_iatp.d402.mcp_middleware import require_payment_for_tool, get_active_api_key
49
+ from traia_iatp.d402.payment_introspection import extract_payment_configs_from_mcp
50
+ from traia_iatp.d402.types import TokenAmount, TokenAsset, EIP712Domain
51
+
52
+ # Configuration
53
+ STAGE = os.getenv("STAGE", "MAINNET").upper()
54
+ PORT = int(os.getenv("PORT", "8000"))
55
+ SERVER_ADDRESS = os.getenv("SERVER_ADDRESS")
56
+ if not SERVER_ADDRESS:
57
+ raise ValueError("SERVER_ADDRESS required for payment protocol")
58
+
59
+ {% if requires_auth %}
60
+ API_KEY = os.getenv("{{ api_key_env_var }}")
61
+ if not API_KEY:
62
+ logger.warning(f"⚠️ {{ api_key_env_var }} not set - payment required for all requests")
63
+ {% else %}
64
+ API_KEY = None
65
+ {% endif %}
66
+
67
+ logger.info("="*80)
68
+ logger.info(f"{{ api_name }} MCP Server (FastMCP + D402 Wrapper)")
69
+ logger.info(f"API: {{ api_url }}")
70
+ logger.info(f"Payment: {SERVER_ADDRESS}")
71
+ {% if requires_auth %}
72
+ logger.info(f"API Key: {'✅' if API_KEY else '❌ Payment required'}")
73
+ {% endif %}
74
+ logger.info("="*80)
75
+
76
+ # Create FastMCP server
77
+ mcp = FastMCP("{{ api_name }} MCP Server")
78
+
79
+ logger.info(f"✅ FastMCP server created")
80
+
81
+ # ============================================================================
82
+ # TOOL IMPLEMENTATIONS
83
+ # ============================================================================
84
+ # Tool implementations will be added here by endpoint_implementer_crew
85
+ # Each tool will use the @mcp.tool() and @require_payment_for_tool() decorators
86
+ # TODO: Add your API-specific functions here
87
+
88
+ # ============================================================================
89
+ # APPLICATION SETUP WITH STARLETTE MIDDLEWARE
90
+ # ============================================================================
91
+
92
+ def create_app_with_middleware():
93
+ """
94
+ Create Starlette app with d402 payment middleware.
95
+
96
+ Strategy:
97
+ 1. Get FastMCP's Starlette app via streamable_http_app()
98
+ 2. Extract payment configs from @require_payment_for_tool decorators
99
+ 3. Add Starlette middleware with extracted configs
100
+ 4. Single source of truth - no duplication!
101
+ """
102
+ logger.info("🔧 Creating FastMCP app with middleware...")
103
+
104
+ # Get FastMCP's Starlette app
105
+ app = mcp.streamable_http_app()
106
+ logger.info(f"✅ Got FastMCP Starlette app")
107
+
108
+ # Extract payment configs from decorators (single source of truth!)
109
+ tool_payment_configs = extract_payment_configs_from_mcp(mcp, SERVER_ADDRESS)
110
+ logger.info(f"📊 Extracted {len(tool_payment_configs)} payment configs from @require_payment_for_tool decorators")
111
+
112
+ # Add D402 payment middleware with extracted configs
113
+ app.add_middleware(
114
+ D402PaymentMiddleware,
115
+ tool_payment_configs=tool_payment_configs,
116
+ server_address=SERVER_ADDRESS,
117
+ {% if requires_auth %}
118
+ requires_auth=True, # Extracts API keys + checks payment
119
+ internal_api_key=API_KEY, # Server's internal key (for Mode 2: paid access)
120
+ {% else %}
121
+ requires_auth=False, # Only checks payment
122
+ {% endif %}
123
+ testing_mode=os.getenv("D402_TESTING_MODE", "true").lower() == "true",
124
+ facilitator_url=os.getenv("D402_FACILITATOR_URL"),
125
+ facilitator_api_key=os.getenv("D402_FACILITATOR_API_KEY")
126
+ )
127
+ logger.info("✅ Added D402PaymentMiddleware")
128
+ {% if requires_auth %}
129
+ logger.info(" - Auth extraction: Enabled")
130
+ logger.info(" - Dual mode: API key OR payment")
131
+ {% else %}
132
+ logger.info(" - Payment-only mode")
133
+ {% endif %}
134
+
135
+ # Add health check endpoint (bypasses middleware)
136
+ @app.route("/health", methods=["GET"])
137
+ async def health_check(request: Request) -> JSONResponse:
138
+ """Health check endpoint for container orchestration."""
139
+ return JSONResponse(
140
+ content={
141
+ "status": "healthy",
142
+ "service": "{{ api_slug }}-mcp-server",
143
+ "timestamp": datetime.now().isoformat()
144
+ }
145
+ )
146
+ logger.info("✅ Added /health endpoint")
147
+
148
+ return app
149
+
150
+ if __name__ == "__main__":
151
+ logger.info("="*80)
152
+ logger.info(f"Starting {{ api_name }} MCP Server")
153
+ logger.info("="*80)
154
+ logger.info("Architecture:")
155
+ logger.info(" 1. D402PaymentMiddleware intercepts requests")
156
+ {% if requires_auth %}
157
+ logger.info(" - Extracts API keys from Authorization header")
158
+ logger.info(" - Checks payment → HTTP 402 if no API key AND no payment")
159
+ {% else %}
160
+ logger.info(" - Checks payment → HTTP 402 if missing")
161
+ {% endif %}
162
+ logger.info(" 2. FastMCP processes valid requests with tool decorators")
163
+ logger.info("="*80)
164
+
165
+ # Create app with middleware
166
+ app = create_app_with_middleware()
167
+
168
+ # Run with uvicorn
169
+ uvicorn.run(
170
+ app,
171
+ host="0.0.0.0",
172
+ port=PORT,
173
+ log_level=os.getenv("LOG_LEVEL", "info").lower()
174
+ )
175
+