siera_cloudagent_python/
web.rs1use crate::agent::CloudAgentPython;
2use reqwest::{Client, RequestBuilder, Url};
3use serde::de::DeserializeOwned;
4use serde_json::Value;
5use siera_agent::error::{Error, Result};
6use std::fmt::Debug;
7
8impl CloudAgentPython {
10 pub async fn get<T: DeserializeOwned + Debug>(
16 &self,
17 url: Url,
18 query: Option<Vec<(&str, String)>>,
19 ) -> Result<T> {
20 let client = match &query {
21 Some(q) => Client::new().get(url).query(&q),
22 None => Client::new().get(url),
23 };
24
25 trace!({ "message": "Get request query", "query": query });
26
27 self.send::<T>(client).await
28 }
29
30 pub async fn patch<T: DeserializeOwned + Debug>(
36 &self,
37 url: Url,
38 query: Option<Vec<(&str, String)>>,
39 ) -> Result<T> {
40 let client = match &query {
41 Some(q) => Client::new().patch(url).query(&q),
42 None => Client::new().patch(url),
43 };
44
45 trace!({ "message": "Patch request query", "query": query});
46
47 self.send::<T>(client).await
48 }
49
50 pub async fn post<T: DeserializeOwned + Debug>(
56 &self,
57 url: Url,
58 query: Option<Vec<(&str, String)>>,
59 body: Option<Value>,
60 ) -> Result<T> {
61 let client = Client::new().post(url).query(&query);
62
63 let client = match &body {
64 Some(b) => client.json(&b),
65 None => client,
66 };
67
68 trace!({ "message": "Post request body", "body": body, "query": query });
69
70 self.send::<T>(client).await
71 }
72
73 pub async fn send<T: DeserializeOwned + Debug>(&self, client: RequestBuilder) -> Result<T> {
79 let client = match &self.api_key {
80 Some(a) => client.header("X-API-KEY", a),
81 None => client,
82 };
83
84 let client = match &self.auth_token {
85 Some(token) => client.header("Authorization", format!("Bearer {token}")),
86 None => client,
87 };
88
89 trace!({ "message": "About to send request" });
90 match client.send().await {
91 Ok(response) => {
92 let status_code = response.status().as_u16();
93 debug!({ "status_code": status_code });
94 match status_code {
95 200..=299 => {
96 let parsed: Value = response.json().await?;
97 debug!({ "response": parsed });
98 let parsed = if parsed.is_null() {
99 serde_json::json!(())
100 } else {
101 parsed
102 };
103 serde_json::from_value(parsed).map_err(|e| {
104 warn!({"error": e.to_string() });
105 Error::UnableToParseResponse.into()
106 })
107 }
108 400 => Err(response.text().await?.into()),
110 401 => Err(Error::AuthorizationFailed.into()),
111 404 => Err(Error::UrlDoesNotExist.into()),
112 422 => Err(response.text().await?.into()),
113 503 => Err(Error::HttpServiceUnavailable.into()),
114 500..=599 => Err(Error::InternalServerError(
115 response.status().as_u16(),
116 response.text().await?,
117 )
118 .into()),
119 _ => Err(Error::UnknownResponseStatusCode(response.text().await?).into()),
120 }
121 }
122 Err(e) => {
123 warn!({ "message": "request failed", "error": e.to_string() });
124 Err(Error::UnreachableUrl.into())
125 }
126 }
127 }
128}