(&self, ctx: ExecutionContext)
| 117 | } |
| 118 | |
| 119 | async fn execute(&self, ctx: ExecutionContext) -> NodeResult { |
| 120 | let code = ctx.config.get("code") |
| 121 | .and_then(|v| v.as_str()) |
| 122 | .unwrap_or("return {}"); |
| 123 | |
| 124 | let dependencies = ctx.config.get("dependencies") |
| 125 | .and_then(|v| v.as_str()) |
| 126 | .unwrap_or(""); |
| 127 | |
| 128 | let outcome = if is_local_deployment() { |
| 129 | // Local dev: run with the host's python3, no sandbox, no API call. |
| 130 | // The user is running their own code on their own machine; same |
| 131 | // threat model as `python script.py`. Dependencies field is ignored: |
| 132 | // users install their own libs in their own environment. |
| 133 | tracing::warn!( |
| 134 | "ExecPython: running user code on the host (DEPLOYMENT_MODE != cloud). \ |
| 135 | This must NEVER happen in a multi-tenant deployment." |
| 136 | ); |
| 137 | let wrapped = build_local_python(code, &ctx.input); |
| 138 | match run_local_python(&wrapped).await { |
| 139 | Ok(o) => o, |
| 140 | Err(msg) => return NodeResult::failed(&msg), |
| 141 | } |
| 142 | } else { |
| 143 | let api_key = match ctx.resolve_api_key(None, "e2b") { |
| 144 | Some(r) => r.key, |
| 145 | None => return NodeResult::failed( |
| 146 | "E2B_API_KEY is not configured on this node-runner. Code execution is unavailable." |
| 147 | ), |
| 148 | }; |
| 149 | let wrapped = build_e2b_python(code, dependencies, &ctx.input); |
| 150 | let outcome = match run_in_e2b(&ctx.http_client, &api_key, &wrapped).await { |
| 151 | Ok(o) => o, |
| 152 | Err(msg) => return NodeResult::failed(&msg), |
| 153 | }; |
| 154 | |
| 155 | // Report estimated cost to billing. Actual sandbox lifetime is hard |
| 156 | // to know per-call; the 30s estimate covers the typical glue workload. |
| 157 | let cost_usd = E2B_ESTIMATED_RUN_SECS |
| 158 | * (E2B_DEFAULT_VCPUS * E2B_VCPU_USD_PER_SEC |
| 159 | + E2B_DEFAULT_RAM_GIB * E2B_RAM_USD_PER_GIB_SEC); |
| 160 | ctx.report_usage_cost( |
| 161 | "e2b-code-interpreter", |
| 162 | "code_exec", |
| 163 | cost_usd, |
| 164 | false, |
| 165 | Some(serde_json::json!({ |
| 166 | "estimatedDurationSecs": E2B_ESTIMATED_RUN_SECS, |
| 167 | "vcpus": E2B_DEFAULT_VCPUS, |
| 168 | "ramGib": E2B_DEFAULT_RAM_GIB, |
| 169 | })), |
| 170 | ).await; |
| 171 | outcome |
| 172 | }; |
| 173 | |
| 174 | match outcome { |
| 175 | ExecOutcome::Ok { ports, stdout, stderr } => { |
| 176 | let mut output = ports; |
nothing calls this directly
no test coverage detected