traia-iatp 0.1.2__py3-none-any.whl → 0.1.67__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.
- traia_iatp/__init__.py +105 -8
- traia_iatp/cli/main.py +85 -1
- traia_iatp/client/__init__.py +28 -3
- traia_iatp/client/crewai_a2a_tools.py +32 -12
- traia_iatp/client/d402_a2a_client.py +348 -0
- traia_iatp/contracts/__init__.py +11 -0
- traia_iatp/contracts/data/abis/contract-abis-localhost.json +4091 -0
- traia_iatp/contracts/data/abis/contract-abis-sepolia.json +4890 -0
- traia_iatp/contracts/data/addresses/contract-addresses.json +17 -0
- traia_iatp/contracts/data/addresses/contract-proxies.json +12 -0
- traia_iatp/contracts/iatp_contracts_config.py +263 -0
- traia_iatp/contracts/wallet_creator.py +369 -0
- traia_iatp/core/models.py +17 -3
- traia_iatp/d402/MIDDLEWARE_ARCHITECTURE.md +205 -0
- traia_iatp/d402/PRICE_BUILDER_USAGE.md +249 -0
- traia_iatp/d402/README.md +489 -0
- traia_iatp/d402/__init__.py +54 -0
- traia_iatp/d402/asgi_wrapper.py +469 -0
- traia_iatp/d402/chains.py +102 -0
- traia_iatp/d402/client.py +150 -0
- traia_iatp/d402/clients/__init__.py +7 -0
- traia_iatp/d402/clients/base.py +218 -0
- traia_iatp/d402/clients/httpx.py +266 -0
- traia_iatp/d402/common.py +114 -0
- traia_iatp/d402/encoding.py +28 -0
- traia_iatp/d402/examples/client_example.py +197 -0
- traia_iatp/d402/examples/server_example.py +171 -0
- traia_iatp/d402/facilitator.py +481 -0
- traia_iatp/d402/mcp_middleware.py +296 -0
- traia_iatp/d402/models.py +116 -0
- traia_iatp/d402/networks.py +98 -0
- traia_iatp/d402/path.py +43 -0
- traia_iatp/d402/payment_introspection.py +126 -0
- traia_iatp/d402/payment_signing.py +183 -0
- traia_iatp/d402/price_builder.py +164 -0
- traia_iatp/d402/servers/__init__.py +61 -0
- traia_iatp/d402/servers/base.py +139 -0
- traia_iatp/d402/servers/example_general_server.py +140 -0
- traia_iatp/d402/servers/fastapi.py +253 -0
- traia_iatp/d402/servers/mcp.py +304 -0
- traia_iatp/d402/servers/starlette.py +878 -0
- traia_iatp/d402/starlette_middleware.py +529 -0
- traia_iatp/d402/types.py +300 -0
- traia_iatp/mcp/D402_MCP_ADAPTER_FLOW.md +357 -0
- traia_iatp/mcp/__init__.py +3 -0
- traia_iatp/mcp/d402_mcp_tool_adapter.py +526 -0
- traia_iatp/mcp/mcp_agent_template.py +78 -13
- traia_iatp/mcp/templates/Dockerfile.j2 +27 -4
- traia_iatp/mcp/templates/README.md.j2 +104 -8
- traia_iatp/mcp/templates/cursor-rules.md.j2 +194 -0
- traia_iatp/mcp/templates/deployment_params.json.j2 +1 -2
- traia_iatp/mcp/templates/docker-compose.yml.j2 +13 -3
- traia_iatp/mcp/templates/env.example.j2 +60 -0
- traia_iatp/mcp/templates/mcp_health_check.py.j2 +2 -2
- traia_iatp/mcp/templates/pyproject.toml.j2 +11 -5
- traia_iatp/mcp/templates/pyrightconfig.json.j2 +22 -0
- traia_iatp/mcp/templates/run_local_docker.sh.j2 +320 -10
- traia_iatp/mcp/templates/server.py.j2 +174 -197
- traia_iatp/mcp/traia_mcp_adapter.py +182 -20
- traia_iatp/registry/__init__.py +47 -12
- traia_iatp/registry/atlas_search_indexes.json +108 -54
- traia_iatp/registry/iatp_search_api.py +169 -39
- traia_iatp/registry/mongodb_registry.py +241 -69
- traia_iatp/registry/readmes/EMBEDDINGS_SETUP.md +1 -1
- traia_iatp/registry/readmes/IATP_SEARCH_API_GUIDE.md +8 -8
- traia_iatp/registry/readmes/MONGODB_X509_AUTH.md +1 -1
- traia_iatp/registry/readmes/README.md +3 -3
- traia_iatp/registry/readmes/REFACTORING_SUMMARY.md +6 -6
- traia_iatp/scripts/__init__.py +2 -0
- traia_iatp/scripts/create_wallet.py +244 -0
- traia_iatp/server/a2a_server.py +22 -7
- traia_iatp/server/iatp_server_template_generator.py +23 -0
- traia_iatp/server/templates/.dockerignore.j2 +48 -0
- traia_iatp/server/templates/Dockerfile.j2 +23 -1
- traia_iatp/server/templates/README.md +2 -2
- traia_iatp/server/templates/README.md.j2 +5 -5
- traia_iatp/server/templates/__main__.py.j2 +374 -66
- traia_iatp/server/templates/agent.py.j2 +12 -11
- traia_iatp/server/templates/agent_config.json.j2 +3 -3
- traia_iatp/server/templates/agent_executor.py.j2 +45 -27
- traia_iatp/server/templates/env.example.j2 +32 -4
- traia_iatp/server/templates/gitignore.j2 +7 -0
- traia_iatp/server/templates/pyproject.toml.j2 +13 -12
- traia_iatp/server/templates/run_local_docker.sh.j2 +143 -11
- traia_iatp/server/templates/server.py.j2 +197 -10
- traia_iatp/special_agencies/registry_search_agency.py +1 -1
- traia_iatp/utils/iatp_utils.py +6 -6
- traia_iatp-0.1.67.dist-info/METADATA +320 -0
- traia_iatp-0.1.67.dist-info/RECORD +117 -0
- traia_iatp-0.1.2.dist-info/METADATA +0 -414
- traia_iatp-0.1.2.dist-info/RECORD +0 -72
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/WHEEL +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/entry_points.txt +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/licenses/LICENSE +0 -0
- {traia_iatp-0.1.2.dist-info → traia_iatp-0.1.67.dist-info}/top_level.txt +0 -0
|
@@ -11,15 +11,241 @@ YELLOW='\033[1;33m'
|
|
|
11
11
|
RED='\033[0;31m'
|
|
12
12
|
NC='\033[0m' # No Color
|
|
13
13
|
|
|
14
|
-
# Configuration
|
|
14
|
+
# Configuration (will be overridden by .env if present)
|
|
15
15
|
IMAGE_NAME="{{ api_slug }}-mcp-server"
|
|
16
16
|
CONTAINER_NAME="{{ api_slug }}-mcp-local"
|
|
17
|
-
HOST_PORT
|
|
18
|
-
CONTAINER_PORT
|
|
17
|
+
HOST_PORT=${PORT:-8000}
|
|
18
|
+
CONTAINER_PORT=${PORT:-8000}
|
|
19
19
|
|
|
20
20
|
echo -e "${BLUE}🚀 Building and running {{ api_name }} MCP Server...${NC}"
|
|
21
21
|
echo
|
|
22
22
|
|
|
23
|
+
# Setup .env file for local development
|
|
24
|
+
# Step 1: Copy .env.example to .env (if .env doesn't exist)
|
|
25
|
+
if [ ! -f .env ]; then
|
|
26
|
+
echo -e "${BLUE}📋 Setting up .env file for local development...${NC}"
|
|
27
|
+
|
|
28
|
+
if [ -f .env.example ]; then
|
|
29
|
+
echo -e "${BLUE} Copying .env.example to .env...${NC}"
|
|
30
|
+
cp .env.example .env
|
|
31
|
+
else
|
|
32
|
+
echo -e "${YELLOW}⚠️ .env.example not found, creating minimal .env template...${NC}"
|
|
33
|
+
# Create minimal .env template
|
|
34
|
+
cat > .env << EOF
|
|
35
|
+
# {{ api_name }} MCP Server Configuration
|
|
36
|
+
PORT=8000
|
|
37
|
+
STAGE=MAINNET
|
|
38
|
+
LOG_LEVEL=INFO
|
|
39
|
+
|
|
40
|
+
{% if requires_auth %}
|
|
41
|
+
# API Authentication (server's internal key for payment mode)
|
|
42
|
+
{{ api_key_env_var }}=
|
|
43
|
+
{% endif %}
|
|
44
|
+
# D402 Payment Protocol Configuration
|
|
45
|
+
SERVER_ADDRESS=
|
|
46
|
+
MCP_OPERATOR_PRIVATE_KEY=
|
|
47
|
+
MCP_OPERATOR_ADDRESS=
|
|
48
|
+
# Facilitator options:
|
|
49
|
+
# - Remote (production): https://test-facilitator.d402.net
|
|
50
|
+
# - Local (development): http://host.docker.internal:7070
|
|
51
|
+
D402_FACILITATOR_URL=https://test-facilitator.d402.net
|
|
52
|
+
D402_FACILITATOR_API_KEY=
|
|
53
|
+
DEFAULT_SETTLEMENT_TOKEN=0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
|
|
54
|
+
DEFAULT_SETTLEMENT_NETWORK=sepolia
|
|
55
|
+
D402_TESTING_MODE=false
|
|
56
|
+
NETWORK=sepolia
|
|
57
|
+
EOF
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Step 2: Fix pyproject.toml to use local IATP path for account generation
|
|
62
|
+
# This is needed because uv run python requires a valid pyproject.toml
|
|
63
|
+
echo -e "${BLUE}🔧 Fixing pyproject.toml for local development...${NC}"
|
|
64
|
+
|
|
65
|
+
# Find local IATP path
|
|
66
|
+
IATP_PATH=""
|
|
67
|
+
if [ -d "/Users/eitanlavi/workspace/traia/IATP" ]; then
|
|
68
|
+
IATP_PATH="/Users/eitanlavi/workspace/traia/IATP"
|
|
69
|
+
elif [ -d "$(dirname $(pwd))/IATP" ]; then
|
|
70
|
+
IATP_PATH="$(dirname $(pwd))/IATP"
|
|
71
|
+
elif [ -d "$HOME/workspace/traia/IATP" ]; then
|
|
72
|
+
IATP_PATH="$HOME/workspace/traia/IATP"
|
|
73
|
+
elif [ -n "$LOCAL_IATP_PATH" ] && [ -d "$LOCAL_IATP_PATH" ]; then
|
|
74
|
+
IATP_PATH="$LOCAL_IATP_PATH"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Temporarily update pyproject.toml to use local IATP path (if /tmp/IATP is present)
|
|
78
|
+
if grep -q "file:///tmp/IATP" pyproject.toml 2>/dev/null; then
|
|
79
|
+
if [ -n "$IATP_PATH" ] && [ -d "$IATP_PATH" ]; then
|
|
80
|
+
echo -e "${BLUE} Updating pyproject.toml to use: $IATP_PATH${NC}"
|
|
81
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
82
|
+
sed -i '' "s|file:///tmp/IATP|file://$IATP_PATH|g" pyproject.toml
|
|
83
|
+
else
|
|
84
|
+
sed -i "s|file:///tmp/IATP|file://$IATP_PATH|g" pyproject.toml
|
|
85
|
+
fi
|
|
86
|
+
else
|
|
87
|
+
echo -e "${RED}❌ Local IATP not found. Cannot generate accounts.${NC}"
|
|
88
|
+
echo -e "${YELLOW} Please set LOCAL_IATP_PATH environment variable or ensure IATP is at /Users/eitanlavi/workspace/traia/IATP${NC}"
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Step 3: Generate Ethereum accounts for local development (workaround)
|
|
94
|
+
# Only generate if not already set with valid values
|
|
95
|
+
SKIP_GENERATION=false
|
|
96
|
+
if grep -q "^SERVER_ADDRESS=0x[0-9a-fA-F]\{40\}" .env && grep -q "^MCP_OPERATOR_PRIVATE_KEY=" .env; then
|
|
97
|
+
echo -e "${GREEN}✅ SERVER_ADDRESS and MCP_OPERATOR_PRIVATE_KEY already set in .env${NC}"
|
|
98
|
+
echo -e "${BLUE} Skipping account generation (keeping existing values)${NC}"
|
|
99
|
+
SKIP_GENERATION=true
|
|
100
|
+
else
|
|
101
|
+
echo -e "${BLUE}🔐 Generating Ethereum accounts for local testing...${NC}"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
if [ "$SKIP_GENERATION" = "false" ]; then
|
|
105
|
+
# Generate accounts using Python (web3 library)
|
|
106
|
+
# Use uv run to ensure web3 is available from the project dependencies
|
|
107
|
+
uv run python << 'PYTHON_SCRIPT'
|
|
108
|
+
import sys
|
|
109
|
+
import secrets
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
from web3 import Web3
|
|
113
|
+
|
|
114
|
+
# Generate server address (EOA for local testing)
|
|
115
|
+
# This is a workaround - in production, SERVER_ADDRESS comes from IATP wallet contract
|
|
116
|
+
server_private_key = "0x" + secrets.token_hex(32)
|
|
117
|
+
server_account = Web3().eth.account.from_key(server_private_key)
|
|
118
|
+
server_address = server_account.address
|
|
119
|
+
|
|
120
|
+
# Generate operator private key and address
|
|
121
|
+
# This is a workaround - in production, these come from IATP wallet contract
|
|
122
|
+
operator_private_key = "0x" + secrets.token_hex(32)
|
|
123
|
+
operator_account = Web3().eth.account.from_key(operator_private_key)
|
|
124
|
+
operator_address = operator_account.address
|
|
125
|
+
|
|
126
|
+
# Write to temporary file
|
|
127
|
+
with open('.env.generated', 'w') as f:
|
|
128
|
+
f.write(f"SERVER_ADDRESS={server_address}\n")
|
|
129
|
+
f.write(f"MCP_OPERATOR_PRIVATE_KEY={operator_private_key}\n")
|
|
130
|
+
f.write(f"MCP_OPERATOR_ADDRESS={operator_address}\n")
|
|
131
|
+
|
|
132
|
+
print(f"Generated SERVER_ADDRESS: {server_address}")
|
|
133
|
+
print(f"Generated MCP_OPERATOR_ADDRESS: {operator_address}")
|
|
134
|
+
sys.exit(0)
|
|
135
|
+
except ImportError:
|
|
136
|
+
print("ERROR: web3 library not found. Install it with: pip install web3", file=sys.stderr)
|
|
137
|
+
sys.exit(1)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f"ERROR: Failed to generate accounts: {e}", file=sys.stderr)
|
|
140
|
+
sys.exit(1)
|
|
141
|
+
PYTHON_SCRIPT
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
# Step 4: Fill in generated values into .env
|
|
145
|
+
if [ $? -eq 0 ] && [ -f .env.generated ]; then
|
|
146
|
+
# Load generated values
|
|
147
|
+
source .env.generated
|
|
148
|
+
|
|
149
|
+
# Update .env file with generated values (macOS-compatible sed)
|
|
150
|
+
# Use a temporary file approach for portability
|
|
151
|
+
if grep -q "^SERVER_ADDRESS=" .env; then
|
|
152
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
153
|
+
sed -i '' "s|^SERVER_ADDRESS=.*|SERVER_ADDRESS=$SERVER_ADDRESS|" .env
|
|
154
|
+
else
|
|
155
|
+
sed -i "s|^SERVER_ADDRESS=.*|SERVER_ADDRESS=$SERVER_ADDRESS|" .env
|
|
156
|
+
fi
|
|
157
|
+
else
|
|
158
|
+
echo "SERVER_ADDRESS=$SERVER_ADDRESS" >> .env
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
if grep -q "^MCP_OPERATOR_PRIVATE_KEY=" .env; then
|
|
162
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
163
|
+
sed -i '' "s|^MCP_OPERATOR_PRIVATE_KEY=.*|MCP_OPERATOR_PRIVATE_KEY=$MCP_OPERATOR_PRIVATE_KEY|" .env
|
|
164
|
+
else
|
|
165
|
+
sed -i "s|^MCP_OPERATOR_PRIVATE_KEY=.*|MCP_OPERATOR_PRIVATE_KEY=$MCP_OPERATOR_PRIVATE_KEY|" .env
|
|
166
|
+
fi
|
|
167
|
+
else
|
|
168
|
+
echo "MCP_OPERATOR_PRIVATE_KEY=$MCP_OPERATOR_PRIVATE_KEY" >> .env
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
if grep -q "^MCP_OPERATOR_ADDRESS=" .env; then
|
|
172
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
173
|
+
sed -i '' "s|^MCP_OPERATOR_ADDRESS=.*|MCP_OPERATOR_ADDRESS=$MCP_OPERATOR_ADDRESS|" .env
|
|
174
|
+
else
|
|
175
|
+
sed -i "s|^MCP_OPERATOR_ADDRESS=.*|MCP_OPERATOR_ADDRESS=$MCP_OPERATOR_ADDRESS|" .env
|
|
176
|
+
fi
|
|
177
|
+
else
|
|
178
|
+
echo "MCP_OPERATOR_ADDRESS=$MCP_OPERATOR_ADDRESS" >> .env
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
rm -f .env.generated
|
|
182
|
+
echo -e "${GREEN}✅ Generated Ethereum accounts and updated .env${NC}"
|
|
183
|
+
else
|
|
184
|
+
if [ "$SKIP_GENERATION" = "false" ]; then
|
|
185
|
+
echo -e "${RED}❌ Failed to generate accounts. Please install web3: pip install web3${NC}"
|
|
186
|
+
echo -e "${YELLOW} Or set SERVER_ADDRESS, MCP_OPERATOR_PRIVATE_KEY, and MCP_OPERATOR_ADDRESS manually in .env${NC}"
|
|
187
|
+
exit 1
|
|
188
|
+
fi
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# Step 4: Ensure D402_TESTING_MODE is set (preserves user's manual edits)
|
|
192
|
+
# This runs whether accounts were generated or not
|
|
193
|
+
if ! grep -q "^D402_TESTING_MODE=" .env; then
|
|
194
|
+
echo -e "${BLUE}📋 Setting D402_TESTING_MODE...${NC}"
|
|
195
|
+
echo "D402_TESTING_MODE=false" >> .env
|
|
196
|
+
echo -e "${YELLOW} Set D402_TESTING_MODE=false (default for local dev)${NC}"
|
|
197
|
+
else
|
|
198
|
+
echo -e "${GREEN}✅ D402_TESTING_MODE already set in .env (keeping existing value)${NC}"
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# Step 5: Prompt for API key if required (only if not already set)
|
|
202
|
+
{% if requires_auth %}
|
|
203
|
+
if ! grep -q "^{{ api_key_env_var }}=[^[:space:]]" .env; then
|
|
204
|
+
if [ -t 0 ]; then
|
|
205
|
+
echo ""
|
|
206
|
+
echo -e "${YELLOW}📝 Please enter your {{ api_name }} API key:${NC}"
|
|
207
|
+
echo -e "${YELLOW} (This is the server's internal API key used when clients pay via 402)${NC}"
|
|
208
|
+
read -p "{{ api_key_env_var }}: " API_KEY_VALUE
|
|
209
|
+
if [ -n "$API_KEY_VALUE" ]; then
|
|
210
|
+
if grep -q "^{{ api_key_env_var }}=" .env; then
|
|
211
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
212
|
+
sed -i '' "s|^{{ api_key_env_var }}=.*|{{ api_key_env_var }}=$API_KEY_VALUE|" .env
|
|
213
|
+
else
|
|
214
|
+
sed -i "s|^{{ api_key_env_var }}=.*|{{ api_key_env_var }}=$API_KEY_VALUE|" .env
|
|
215
|
+
fi
|
|
216
|
+
else
|
|
217
|
+
echo "{{ api_key_env_var }}=$API_KEY_VALUE" >> .env
|
|
218
|
+
fi
|
|
219
|
+
echo -e "${GREEN}✅ API key saved to .env${NC}"
|
|
220
|
+
else
|
|
221
|
+
echo -e "${YELLOW}⚠️ No API key provided. You can set it later in .env${NC}"
|
|
222
|
+
fi
|
|
223
|
+
else
|
|
224
|
+
echo -e "${YELLOW}⚠️ Non-interactive mode: Please set {{ api_key_env_var }} in .env manually${NC}"
|
|
225
|
+
fi
|
|
226
|
+
else
|
|
227
|
+
echo -e "${GREEN}✅ {{ api_key_env_var }} already set in .env${NC}"
|
|
228
|
+
fi
|
|
229
|
+
{% endif %}
|
|
230
|
+
|
|
231
|
+
echo ""
|
|
232
|
+
echo -e "${GREEN}✅ .env file configured for local development!${NC}"
|
|
233
|
+
echo -e "${BLUE}📋 Review .env file if needed before continuing...${NC}"
|
|
234
|
+
if [ -t 0 ]; then
|
|
235
|
+
echo -e "${YELLOW}Press Enter to continue, or Ctrl+C to cancel...${NC}"
|
|
236
|
+
read
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
# Load environment variables from .env file
|
|
240
|
+
echo -e "${BLUE}📋 Loading environment variables from .env file...${NC}"
|
|
241
|
+
set -a # Export all variables
|
|
242
|
+
source .env
|
|
243
|
+
set +a # Stop exporting
|
|
244
|
+
|
|
245
|
+
# Update port variables after loading .env
|
|
246
|
+
HOST_PORT=${PORT:-8000}
|
|
247
|
+
CONTAINER_PORT=${PORT:-8000}
|
|
248
|
+
|
|
23
249
|
# Check if Docker is installed
|
|
24
250
|
if ! command -v docker &> /dev/null; then
|
|
25
251
|
echo -e "${RED}❌ Docker is not installed. Please install Docker first.${NC}"
|
|
@@ -35,19 +261,92 @@ fi
|
|
|
35
261
|
|
|
36
262
|
# Build the Docker image
|
|
37
263
|
echo -e "${BLUE}🔨 Building Docker image...${NC}"
|
|
38
|
-
|
|
264
|
+
|
|
265
|
+
# Check if pyproject.toml uses local IATP path (for local development)
|
|
266
|
+
if grep -q "file://" pyproject.toml 2>/dev/null; then
|
|
267
|
+
# Extract IATP path from pyproject.toml (macOS-compatible, no Perl regex)
|
|
268
|
+
IATP_PATH_FROM_TOML=$(grep "file://" pyproject.toml | sed -E 's|.*file://([^"]+).*|\1|' | head -1)
|
|
269
|
+
|
|
270
|
+
# If path is /tmp/IATP (Docker path), find the actual local IATP path
|
|
271
|
+
if [ "$IATP_PATH_FROM_TOML" = "/tmp/IATP" ] || [ ! -d "$IATP_PATH_FROM_TOML" ]; then
|
|
272
|
+
# Try to find local IATP path (common locations)
|
|
273
|
+
if [ -d "/Users/eitanlavi/workspace/traia/IATP" ]; then
|
|
274
|
+
IATP_PATH="/Users/eitanlavi/workspace/traia/IATP"
|
|
275
|
+
elif [ -d "$(dirname $(pwd))/IATP" ]; then
|
|
276
|
+
IATP_PATH="$(dirname $(pwd))/IATP"
|
|
277
|
+
elif [ -d "$HOME/workspace/traia/IATP" ]; then
|
|
278
|
+
IATP_PATH="$HOME/workspace/traia/IATP"
|
|
279
|
+
elif [ -n "$LOCAL_IATP_PATH" ] && [ -d "$LOCAL_IATP_PATH" ]; then
|
|
280
|
+
IATP_PATH="$LOCAL_IATP_PATH"
|
|
281
|
+
else
|
|
282
|
+
IATP_PATH=""
|
|
283
|
+
fi
|
|
284
|
+
else
|
|
285
|
+
IATP_PATH="$IATP_PATH_FROM_TOML"
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
if [ -n "$IATP_PATH" ] && [ -d "$IATP_PATH" ]; then
|
|
289
|
+
echo -e "${BLUE}📦 Using local IATP package: $IATP_PATH${NC}"
|
|
290
|
+
# Copy IATP into build context for Docker (exclude .venv to save space!)
|
|
291
|
+
mkdir -p .docker-iatp
|
|
292
|
+
|
|
293
|
+
# Use rsync if available (much better), otherwise cp with find
|
|
294
|
+
if command -v rsync &> /dev/null; then
|
|
295
|
+
rsync -a --exclude='.venv' --exclude='__pycache__' --exclude='.git' --exclude='build' --exclude='dist' --exclude='*.egg-info' "$IATP_PATH/" .docker-iatp/IATP/
|
|
296
|
+
echo -e "${BLUE} Copied IATP to build context (excluded .venv, ${GREEN}saved ~900MB${BLUE})${NC}"
|
|
297
|
+
else
|
|
298
|
+
# Fallback: use cp but warn about size
|
|
299
|
+
cp -r "$IATP_PATH" .docker-iatp/IATP
|
|
300
|
+
# Try to remove .venv after copy
|
|
301
|
+
rm -rf .docker-iatp/IATP/.venv .docker-iatp/IATP/__pycache__ .docker-iatp/IATP/.git 2>/dev/null
|
|
302
|
+
echo -e "${BLUE} Copied IATP to build context (cleaned .venv after copy)${NC}"
|
|
303
|
+
fi
|
|
304
|
+
# Temporarily update pyproject.toml to use Docker path
|
|
305
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
306
|
+
sed -i.bak 's|file://.*IATP|file:///tmp/IATP|g' pyproject.toml
|
|
307
|
+
else
|
|
308
|
+
sed -i.bak 's|file://.*IATP|file:///tmp/IATP|g' pyproject.toml
|
|
309
|
+
fi
|
|
310
|
+
docker build --no-cache -t $IMAGE_NAME .
|
|
311
|
+
BUILD_EXIT_CODE=$?
|
|
312
|
+
# Restore original pyproject.toml
|
|
313
|
+
mv pyproject.toml.bak pyproject.toml
|
|
314
|
+
rm -rf .docker-iatp
|
|
315
|
+
if [ $BUILD_EXIT_CODE -ne 0 ]; then
|
|
316
|
+
exit $BUILD_EXIT_CODE
|
|
317
|
+
fi
|
|
318
|
+
else
|
|
319
|
+
echo -e "${YELLOW}⚠️ Local IATP path not found${NC}"
|
|
320
|
+
echo -e "${YELLOW} Falling back to published version (may fail if not published)${NC}"
|
|
321
|
+
# If pyproject.toml has /tmp/IATP, replace with published version
|
|
322
|
+
if grep -q "file:///tmp/IATP" pyproject.toml 2>/dev/null; then
|
|
323
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
324
|
+
sed -i.bak 's|file:///tmp/IATP|traia-iatp>=0.1.27|g' pyproject.toml
|
|
325
|
+
else
|
|
326
|
+
sed -i.bak 's|file:///tmp/IATP|traia-iatp>=0.1.27|g' pyproject.toml
|
|
327
|
+
fi
|
|
328
|
+
docker build --no-cache -t $IMAGE_NAME .
|
|
329
|
+
BUILD_EXIT_CODE=$?
|
|
330
|
+
mv pyproject.toml.bak pyproject.toml
|
|
331
|
+
if [ $BUILD_EXIT_CODE -ne 0 ]; then
|
|
332
|
+
exit $BUILD_EXIT_CODE
|
|
333
|
+
fi
|
|
334
|
+
else
|
|
335
|
+
docker build --no-cache -t $IMAGE_NAME .
|
|
336
|
+
fi
|
|
337
|
+
fi
|
|
338
|
+
else
|
|
339
|
+
# Using published version, normal build
|
|
340
|
+
docker build --no-cache -t $IMAGE_NAME .
|
|
341
|
+
fi
|
|
39
342
|
|
|
40
343
|
# Run the container
|
|
41
344
|
echo -e "${BLUE}🏃 Starting container...${NC}"
|
|
345
|
+
# Use --env-file to load all variables from .env file
|
|
42
346
|
docker run -d \
|
|
43
347
|
--name $CONTAINER_NAME \
|
|
44
348
|
-p $HOST_PORT:$CONTAINER_PORT \
|
|
45
|
-
-
|
|
46
|
-
-e LOG_LEVEL="${LOG_LEVEL:-INFO}" \
|
|
47
|
-
{% if api_key_env_var %}
|
|
48
|
-
-e {{ api_key_env_var }}="{% raw %}${{% endraw %}{{ api_key_env_var }}{% raw %}}{% endraw %}" \
|
|
49
|
-
{% endif %}
|
|
50
|
-
-e PORT="$CONTAINER_PORT" \
|
|
349
|
+
--env-file .env \
|
|
51
350
|
$IMAGE_NAME
|
|
52
351
|
|
|
53
352
|
# Wait for the server to start
|
|
@@ -91,4 +390,15 @@ if curl -s -o /dev/null -w "%{http_code}" "http://localhost:${HOST_PORT}/mcp" |
|
|
|
91
390
|
echo -e "${GREEN}✅ Server is responding!${NC}"
|
|
92
391
|
else
|
|
93
392
|
echo -e "${YELLOW}⚠️ Server may still be starting up. Check logs with: docker logs -f ${CONTAINER_NAME}${NC}"
|
|
393
|
+
fi
|
|
394
|
+
|
|
395
|
+
# Cleanup: Restore pyproject.toml to use /tmp/IATP (git-committed version)
|
|
396
|
+
echo -e "${BLUE}🧹 Cleaning up...${NC}"
|
|
397
|
+
if grep -q "file:///Users/eitanlavi/workspace/traia/IATP" pyproject.toml 2>/dev/null; then
|
|
398
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
399
|
+
sed -i '' "s|file:///Users/eitanlavi/workspace/traia/IATP|file:///tmp/IATP|g" pyproject.toml
|
|
400
|
+
else
|
|
401
|
+
sed -i "s|file:///Users/eitanlavi/workspace/traia/IATP|file:///tmp/IATP|g" pyproject.toml
|
|
402
|
+
fi
|
|
403
|
+
echo -e "${GREEN}✅ Restored pyproject.toml to git state${NC}"
|
|
94
404
|
fi
|