Skip to main content

hanzo_client/apis/
functions_api.rs

1/*
2 * Hanzo Cloud API
3 *
4 * The Hanzo Cloud API as a customer calls it: every operation under /v1/ except the operator's admin product, relay routes, legacy spellings and capabilities still reached by flag. Tagged by product: the first path segment after /v1/.
5 *
6 * The version of the OpenAPI document: v1
7 * 
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`delete_functions_by_name`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum DeleteFunctionsByNameError {
22    UnknownValue(serde_json::Value),
23}
24
25/// struct for typed errors of method [`get_functions`]
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(untagged)]
28pub enum GetFunctionsError {
29    UnknownValue(serde_json::Value),
30}
31
32/// struct for typed errors of method [`get_functions_by_name`]
33#[derive(Debug, Clone, Serialize, Deserialize)]
34#[serde(untagged)]
35pub enum GetFunctionsByNameError {
36    UnknownValue(serde_json::Value),
37}
38
39/// struct for typed errors of method [`get_functions_by_name_invocations`]
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(untagged)]
42pub enum GetFunctionsByNameInvocationsError {
43    UnknownValue(serde_json::Value),
44}
45
46/// struct for typed errors of method [`get_functions_by_name_logs`]
47#[derive(Debug, Clone, Serialize, Deserialize)]
48#[serde(untagged)]
49pub enum GetFunctionsByNameLogsError {
50    UnknownValue(serde_json::Value),
51}
52
53/// struct for typed errors of method [`get_functions_deployments`]
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(untagged)]
56pub enum GetFunctionsDeploymentsError {
57    UnknownValue(serde_json::Value),
58}
59
60/// struct for typed errors of method [`get_functions_metrics`]
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(untagged)]
63pub enum GetFunctionsMetricsError {
64    UnknownValue(serde_json::Value),
65}
66
67/// struct for typed errors of method [`get_functions_secrets`]
68#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(untagged)]
70pub enum GetFunctionsSecretsError {
71    UnknownValue(serde_json::Value),
72}
73
74/// struct for typed errors of method [`get_functions_triggers`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum GetFunctionsTriggersError {
78    UnknownValue(serde_json::Value),
79}
80
81/// struct for typed errors of method [`post_functions`]
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(untagged)]
84pub enum PostFunctionsError {
85    UnknownValue(serde_json::Value),
86}
87
88/// struct for typed errors of method [`post_functions_by_name_invoke`]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90#[serde(untagged)]
91pub enum PostFunctionsByNameInvokeError {
92    Status502(models::InvocationView),
93    Status503(models::InvocationView),
94    UnknownValue(serde_json::Value),
95}
96
97
98/// Removes one of the caller org's functions and answers 204.  A name this org does not hold is 404 — never a silent success — and a name belonging to another tenant is the same 404, because the delete is predicated on the validated org.
99pub async fn delete_functions_by_name(configuration: &configuration::Configuration, name: &str) -> Result<serde_json::Value, Error<DeleteFunctionsByNameError>> {
100    // add a prefix to parameters to efficiently prevent name collisions
101    let p_name = name;
102
103    let uri_str = format!("{}/v1/functions/{name}", configuration.base_path, name=crate::apis::urlencode(p_name));
104    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
105
106    if let Some(ref user_agent) = configuration.user_agent {
107        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
108    }
109    if let Some(ref token) = configuration.bearer_access_token {
110        req_builder = req_builder.bearer_auth(token.to_owned());
111    };
112
113    let req = req_builder.build()?;
114    let resp = configuration.client.execute(req).await?;
115
116    let status = resp.status();
117    let content_type = resp
118        .headers()
119        .get("content-type")
120        .and_then(|v| v.to_str().ok())
121        .unwrap_or("application/octet-stream");
122    let content_type = super::ContentType::from(content_type);
123
124    if !status.is_client_error() && !status.is_server_error() {
125        let content = resp.text().await?;
126        match content_type {
127            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
128            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
129            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
130        }
131    } else {
132        let content = resp.text().await?;
133        let entity: Option<DeleteFunctionsByNameError> = serde_json::from_str(&content).ok();
134        Err(Error::ResponseError(ResponseContent { status, content, entity }))
135    }
136}
137
138/// Is every serverless function the caller's org has published, each with its real 7-day rollup.  A row carries the function's runtime, resource limits, deployment target and its invoke endpoint, plus envCount — how many secrets it mounts. The rollup fields are ABSENT rather than zero when the function has not run in the window, so a console renders \"—\" instead of a fabricated 0.  Requires a validated principal; the listing is scoped to its org.
139pub async fn get_functions(configuration: &configuration::Configuration, ) -> Result<models::FnList, Error<GetFunctionsError>> {
140
141    let uri_str = format!("{}/v1/functions", configuration.base_path);
142    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
143
144    if let Some(ref user_agent) = configuration.user_agent {
145        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
146    }
147    if let Some(ref token) = configuration.bearer_access_token {
148        req_builder = req_builder.bearer_auth(token.to_owned());
149    };
150
151    let req = req_builder.build()?;
152    let resp = configuration.client.execute(req).await?;
153
154    let status = resp.status();
155    let content_type = resp
156        .headers()
157        .get("content-type")
158        .and_then(|v| v.to_str().ok())
159        .unwrap_or("application/octet-stream");
160    let content_type = super::ContentType::from(content_type);
161
162    if !status.is_client_error() && !status.is_server_error() {
163        let content = resp.text().await?;
164        match content_type {
165            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
166            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FnList`"))),
167            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FnList`")))),
168        }
169    } else {
170        let content = resp.text().await?;
171        let entity: Option<GetFunctionsError> = serde_json::from_str(&content).ok();
172        Err(Error::ResponseError(ResponseContent { status, content, entity }))
173    }
174}
175
176/// Is one function with everything a detail page needs in one round-trip: its definition, its 7-day rollup, its trigger, its twenty most recent invocations and the NAMES of the secrets it mounts.  Secret values are never read or returned. A name the caller's org does not hold is 404, which is also what another tenant's function looks like from here.
177pub async fn get_functions_by_name(configuration: &configuration::Configuration, name: &str) -> Result<models::FunctionDetail, Error<GetFunctionsByNameError>> {
178    // add a prefix to parameters to efficiently prevent name collisions
179    let p_name = name;
180
181    let uri_str = format!("{}/v1/functions/{name}", configuration.base_path, name=crate::apis::urlencode(p_name));
182    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
183
184    if let Some(ref user_agent) = configuration.user_agent {
185        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
186    }
187    if let Some(ref token) = configuration.bearer_access_token {
188        req_builder = req_builder.bearer_auth(token.to_owned());
189    };
190
191    let req = req_builder.build()?;
192    let resp = configuration.client.execute(req).await?;
193
194    let status = resp.status();
195    let content_type = resp
196        .headers()
197        .get("content-type")
198        .and_then(|v| v.to_str().ok())
199        .unwrap_or("application/octet-stream");
200    let content_type = super::ContentType::from(content_type);
201
202    if !status.is_client_error() && !status.is_server_error() {
203        let content = resp.text().await?;
204        match content_type {
205            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
206            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FunctionDetail`"))),
207            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FunctionDetail`")))),
208        }
209    } else {
210        let content = resp.text().await?;
211        let entity: Option<GetFunctionsByNameError> = serde_json::from_str(&content).ok();
212        Err(Error::ResponseError(ResponseContent { status, content, entity }))
213    }
214}
215
216/// Is one function's past runs, newest first — each with its status, HTTP code, method, time and duration.  These are real recorded rows, not a projection: an invocation appears here only once it actually ran. Requires a validated principal; the read is scoped to its org.
217pub async fn get_functions_by_name_invocations(configuration: &configuration::Configuration, name: &str, limit: Option<i32>) -> Result<models::InvocationList, Error<GetFunctionsByNameInvocationsError>> {
218    // add a prefix to parameters to efficiently prevent name collisions
219    let p_name = name;
220    let p_limit = limit;
221
222    let uri_str = format!("{}/v1/functions/{name}/invocations", configuration.base_path, name=crate::apis::urlencode(p_name));
223    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
224
225    if let Some(ref param_value) = p_limit {
226        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
227    }
228    if let Some(ref user_agent) = configuration.user_agent {
229        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
230    }
231    if let Some(ref token) = configuration.bearer_access_token {
232        req_builder = req_builder.bearer_auth(token.to_owned());
233    };
234
235    let req = req_builder.build()?;
236    let resp = configuration.client.execute(req).await?;
237
238    let status = resp.status();
239    let content_type = resp
240        .headers()
241        .get("content-type")
242        .and_then(|v| v.to_str().ok())
243        .unwrap_or("application/octet-stream");
244    let content_type = super::ContentType::from(content_type);
245
246    if !status.is_client_error() && !status.is_server_error() {
247        let content = resp.text().await?;
248        match content_type {
249            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
250            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::InvocationList`"))),
251            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::InvocationList`")))),
252        }
253    } else {
254        let content = resp.text().await?;
255        let entity: Option<GetFunctionsByNameInvocationsError> = serde_json::from_str(&content).ok();
256        Err(Error::ResponseError(ResponseContent { status, content, entity }))
257    }
258}
259
260/// Is the output of a function's most recent run — its error text when that run failed, else what it printed.  It is the LAST run only, and it is empty when the function has never run. There is no log retention behind this beyond the recorded invocation itself.
261pub async fn get_functions_by_name_logs(configuration: &configuration::Configuration, name: &str) -> Result<models::LogLines, Error<GetFunctionsByNameLogsError>> {
262    // add a prefix to parameters to efficiently prevent name collisions
263    let p_name = name;
264
265    let uri_str = format!("{}/v1/functions/{name}/logs", configuration.base_path, name=crate::apis::urlencode(p_name));
266    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
267
268    if let Some(ref user_agent) = configuration.user_agent {
269        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
270    }
271    if let Some(ref token) = configuration.bearer_access_token {
272        req_builder = req_builder.bearer_auth(token.to_owned());
273    };
274
275    let req = req_builder.build()?;
276    let resp = configuration.client.execute(req).await?;
277
278    let status = resp.status();
279    let content_type = resp
280        .headers()
281        .get("content-type")
282        .and_then(|v| v.to_str().ok())
283        .unwrap_or("application/octet-stream");
284    let content_type = super::ContentType::from(content_type);
285
286    if !status.is_client_error() && !status.is_server_error() {
287        let content = resp.text().await?;
288        match content_type {
289            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
290            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::LogLines`"))),
291            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::LogLines`")))),
292        }
293    } else {
294        let content = resp.text().await?;
295        let entity: Option<GetFunctionsByNameLogsError> = serde_json::from_str(&content).ok();
296        Err(Error::ResponseError(ResponseContent { status, content, entity }))
297    }
298}
299
300/// Is what is live right now — each function's current record IS its live deployment, so this is the deployment inventory.  There is no deployment history behind it: a function has one record, and publishing replaces it. The 7-day rollup is deliberately absent here, because this read is about what is deployed rather than about how it has performed.
301pub async fn get_functions_deployments(configuration: &configuration::Configuration, ) -> Result<models::FnList, Error<GetFunctionsDeploymentsError>> {
302
303    let uri_str = format!("{}/v1/functions/deployments", configuration.base_path);
304    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
305
306    if let Some(ref user_agent) = configuration.user_agent {
307        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
308    }
309    if let Some(ref token) = configuration.bearer_access_token {
310        req_builder = req_builder.bearer_auth(token.to_owned());
311    };
312
313    let req = req_builder.build()?;
314    let resp = configuration.client.execute(req).await?;
315
316    let status = resp.status();
317    let content_type = resp
318        .headers()
319        .get("content-type")
320        .and_then(|v| v.to_str().ok())
321        .unwrap_or("application/octet-stream");
322    let content_type = super::ContentType::from(content_type);
323
324    if !status.is_client_error() && !status.is_server_error() {
325        let content = resp.text().await?;
326        match content_type {
327            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
328            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FnList`"))),
329            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FnList`")))),
330        }
331    } else {
332        let content = resp.text().await?;
333        let entity: Option<GetFunctionsDeploymentsError> = serde_json::from_str(&content).ok();
334        Err(Error::ResponseError(ResponseContent { status, content, entity }))
335    }
336}
337
338/// Is the org's serverless dashboard over a window: a per-function invocation costLine and how those invocations ended.  Every point is a REAL count of rows that fell in that bucket — nothing is interpolated or invented, so an empty window draws a flat line rather than a fabricated one.  costCents is null and stays null: there is no per-invocation cost source to read, and reporting a number computed some other way would be a guess presented as a measurement. Requires a validated principal; the read is scoped to its org.
339pub async fn get_functions_metrics(configuration: &configuration::Configuration, range: Option<&str>) -> Result<models::Usage, Error<GetFunctionsMetricsError>> {
340    // add a prefix to parameters to efficiently prevent name collisions
341    let p_range = range;
342
343    let uri_str = format!("{}/v1/functions/metrics", configuration.base_path);
344    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
345
346    if let Some(ref param_value) = p_range {
347        req_builder = req_builder.query(&[("range", &param_value.to_string())]);
348    }
349    if let Some(ref user_agent) = configuration.user_agent {
350        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
351    }
352    if let Some(ref token) = configuration.bearer_access_token {
353        req_builder = req_builder.bearer_auth(token.to_owned());
354    };
355
356    let req = req_builder.build()?;
357    let resp = configuration.client.execute(req).await?;
358
359    let status = resp.status();
360    let content_type = resp
361        .headers()
362        .get("content-type")
363        .and_then(|v| v.to_str().ok())
364        .unwrap_or("application/octet-stream");
365    let content_type = super::ContentType::from(content_type);
366
367    if !status.is_client_error() && !status.is_server_error() {
368        let content = resp.text().await?;
369        match content_type {
370            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
371            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Usage`"))),
372            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Usage`")))),
373        }
374    } else {
375        let content = resp.text().await?;
376        let entity: Option<GetFunctionsMetricsError> = serde_json::from_str(&content).ok();
377        Err(Error::ResponseError(ResponseContent { status, content, entity }))
378    }
379}
380
381/// Is the NAMES of the secrets the caller org's functions mount.  Values are NEVER read or returned — this surface knows which names a function asks for and nothing about what is behind them, which is what makes it safe to list at all. One row per distinct (namespace, name).
382pub async fn get_functions_secrets(configuration: &configuration::Configuration, ) -> Result<models::SecretList, Error<GetFunctionsSecretsError>> {
383
384    let uri_str = format!("{}/v1/functions/secrets", configuration.base_path);
385    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
386
387    if let Some(ref user_agent) = configuration.user_agent {
388        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
389    }
390    if let Some(ref token) = configuration.bearer_access_token {
391        req_builder = req_builder.bearer_auth(token.to_owned());
392    };
393
394    let req = req_builder.build()?;
395    let resp = configuration.client.execute(req).await?;
396
397    let status = resp.status();
398    let content_type = resp
399        .headers()
400        .get("content-type")
401        .and_then(|v| v.to_str().ok())
402        .unwrap_or("application/octet-stream");
403    let content_type = super::ContentType::from(content_type);
404
405    if !status.is_client_error() && !status.is_server_error() {
406        let content = resp.text().await?;
407        match content_type {
408            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
409            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SecretList`"))),
410            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SecretList`")))),
411        }
412    } else {
413        let content = resp.text().await?;
414        let entity: Option<GetFunctionsSecretsError> = serde_json::from_str(&content).ok();
415        Err(Error::ResponseError(ResponseContent { status, content, entity }))
416    }
417}
418
419/// Is what calls the caller org's functions — one row per function.  Every function has exactly one trigger today, its HTTP invoke endpoint, so this is the function list read as \"how is each of these reached\".
420pub async fn get_functions_triggers(configuration: &configuration::Configuration, ) -> Result<models::TriggerList, Error<GetFunctionsTriggersError>> {
421
422    let uri_str = format!("{}/v1/functions/triggers", configuration.base_path);
423    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
424
425    if let Some(ref user_agent) = configuration.user_agent {
426        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
427    }
428    if let Some(ref token) = configuration.bearer_access_token {
429        req_builder = req_builder.bearer_auth(token.to_owned());
430    };
431
432    let req = req_builder.build()?;
433    let resp = configuration.client.execute(req).await?;
434
435    let status = resp.status();
436    let content_type = resp
437        .headers()
438        .get("content-type")
439        .and_then(|v| v.to_str().ok())
440        .unwrap_or("application/octet-stream");
441    let content_type = super::ContentType::from(content_type);
442
443    if !status.is_client_error() && !status.is_server_error() {
444        let content = resp.text().await?;
445        match content_type {
446            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
447            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::TriggerList`"))),
448            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::TriggerList`")))),
449        }
450    } else {
451        let content = resp.text().await?;
452        let entity: Option<GetFunctionsTriggersError> = serde_json::from_str(&content).ok();
453        Err(Error::ResponseError(ResponseContent { status, content, entity }))
454    }
455}
456
457/// Publishes a serverless function under the caller's org and answers 201 with it.  The name is the key and is claimed once; the names that would shadow a collection route are reserved. runtime and environment are the same field — either spelling is accepted — and default to node.  Bounds are clamped rather than refused where a clamp is honest: a timeout above the 900-second ceiling becomes the ceiling instead of silently reverting to the 30-second default, and an omitted memory limit becomes 256Mi. target=fleet runs on the org's own GPU fleet and supports runtime=python only.  Requires a validated principal; the function is owned by that principal's org.
458pub async fn post_functions(configuration: &configuration::Configuration, definition: models::Definition) -> Result<models::FunctionView, Error<PostFunctionsError>> {
459    // add a prefix to parameters to efficiently prevent name collisions
460    let p_definition = definition;
461
462    let uri_str = format!("{}/v1/functions", configuration.base_path);
463    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
464
465    if let Some(ref user_agent) = configuration.user_agent {
466        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
467    }
468    if let Some(ref token) = configuration.bearer_access_token {
469        req_builder = req_builder.bearer_auth(token.to_owned());
470    };
471    req_builder = req_builder.json(&p_definition);
472
473    let req = req_builder.build()?;
474    let resp = configuration.client.execute(req).await?;
475
476    let status = resp.status();
477    let content_type = resp
478        .headers()
479        .get("content-type")
480        .and_then(|v| v.to_str().ok())
481        .unwrap_or("application/octet-stream");
482    let content_type = super::ContentType::from(content_type);
483
484    if !status.is_client_error() && !status.is_server_error() {
485        let content = resp.text().await?;
486        match content_type {
487            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
488            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FunctionView`"))),
489            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FunctionView`")))),
490        }
491    } else {
492        let content = resp.text().await?;
493        let entity: Option<PostFunctionsError> = serde_json::from_str(&content).ok();
494        Err(Error::ResponseError(ResponseContent { status, content, entity }))
495    }
496}
497
498/// Runs a function and records a REAL invocation.  The answer is the invocation record whatever happened to it: 200 when the org's code ran clean, 502 when it ran and failed, 503 when this deployment has no sandbox to run code in. The record IS the evidence, so it rides the failure rather than being replaced by an error envelope.  Billing is two-part and both parts are prepaid-then-metered on the one shared meter: a flat per-invocation request fee, gated BEFORE any sandbox compute runs so an unfunded org gets 402 and nothing executes, and a usage-native GB-seconds compute debit taken after the run. Either is independently free when its fee is zero, so an operator can bill by request alone, by compute alone, or by both — and a zero request fee removes the balance gate with it.  A TRANSPORT failure is not charged: the sandbox being unreachable ran no billable compute. Code that ran and exited non-zero IS charged — that is a successful invocation of a failing program, not a billing failure.  When the sandbox is not configured on this deployment, a non-fleet function fails closed before anything is recorded — no execution and no fabricated output. Scoped to the caller's org; requires a validated principal.
499pub async fn post_functions_by_name_invoke(configuration: &configuration::Configuration, name: &str, invoke_req: models::InvokeReq) -> Result<models::InvocationView, Error<PostFunctionsByNameInvokeError>> {
500    // add a prefix to parameters to efficiently prevent name collisions
501    let p_name = name;
502    let p_invoke_req = invoke_req;
503
504    let uri_str = format!("{}/v1/functions/{name}/invoke", configuration.base_path, name=crate::apis::urlencode(p_name));
505    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
506
507    if let Some(ref user_agent) = configuration.user_agent {
508        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
509    }
510    if let Some(ref token) = configuration.bearer_access_token {
511        req_builder = req_builder.bearer_auth(token.to_owned());
512    };
513    req_builder = req_builder.json(&p_invoke_req);
514
515    let req = req_builder.build()?;
516    let resp = configuration.client.execute(req).await?;
517
518    let status = resp.status();
519    let content_type = resp
520        .headers()
521        .get("content-type")
522        .and_then(|v| v.to_str().ok())
523        .unwrap_or("application/octet-stream");
524    let content_type = super::ContentType::from(content_type);
525
526    if !status.is_client_error() && !status.is_server_error() {
527        let content = resp.text().await?;
528        match content_type {
529            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
530            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::InvocationView`"))),
531            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::InvocationView`")))),
532        }
533    } else {
534        let content = resp.text().await?;
535        let entity: Option<PostFunctionsByNameInvokeError> = serde_json::from_str(&content).ok();
536        Err(Error::ResponseError(ResponseContent { status, content, entity }))
537    }
538}
539