Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(commands): label trends report from csv #315

Merged
merged 1 commit into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod resources;
pub mod retry;

use chrono::{DateTime, Utc};
use http::Method;
use http::{header::ACCEPT, Method};
use log::debug;
use once_cell::sync::Lazy;
use reqwest::{
Expand Down Expand Up @@ -834,6 +834,7 @@ impl Client {
&None::<()>,
&None::<()>,
&Retry::Yes,
None,
)?;

let mut buffer = Vec::new();
Expand Down Expand Up @@ -1063,6 +1064,26 @@ impl Client {
)
}

pub fn query_dataset_csv(
&self,
dataset_name: &DatasetFullName,
params: &QueryRequestParams,
) -> Result<String> {
let response = self
.raw_request(
&Method::POST,
&self.endpoints.query_dataset(dataset_name)?,
&Some(serde_json::to_value(params).expect("query params serialization error")),
&None::<()>,
&Retry::Yes,
Some(HeaderValue::from_str("text/csv").expect("Could not parse csv header")),
)?
.text()
.expect("Could not get csv text");

Ok(response)
}

pub fn query_dataset(
&self,
dataset_name: &DatasetFullName,
Expand Down Expand Up @@ -1392,17 +1413,25 @@ impl Client {
body: &Option<RequestT>,
query: &Option<QueryT>,
retry: &Retry,
accept_header: Option<HeaderValue>,
) -> Result<reqwest::blocking::Response>
where
LocationT: IntoUrl + Display + Clone,
RequestT: Serialize,
QueryT: Serialize,
{
let mut headers = self.headers.clone();

if let Some(accept_header) = accept_header {
headers.insert(ACCEPT, accept_header);
}

let do_request = || {
let request = self
.http_client
.request(method.clone(), url.clone())
.headers(self.headers.clone());
.headers(headers.clone());

let request = match &query {
Some(query) => request.query(query),
None => request,
Expand Down Expand Up @@ -1499,7 +1528,7 @@ impl Client {
for<'de> SuccessT: Deserialize<'de>,
{
debug!("Attempting {} `{}`", method, url);
let http_response = self.raw_request(method, url, body, query, retry)?;
let http_response = self.raw_request(method, url, body, query, retry, None)?;

let status = http_response.status();

Expand Down Expand Up @@ -2240,7 +2269,7 @@ impl Endpoints {
}
}

const DEFAULT_HTTP_TIMEOUT_SECONDS: u64 = 120;
const DEFAULT_HTTP_TIMEOUT_SECONDS: u64 = 240;

fn build_http_client(config: &Config) -> Result<HttpClient> {
let mut builder = HttpClient::builder()
Expand Down
9 changes: 5 additions & 4 deletions api/src/resources/dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ pub struct QueryRequestParams {

pub filter: CommentFilter,

pub limit: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<usize>,

pub order: OrderEnum,
}
Expand Down Expand Up @@ -401,7 +402,7 @@ mod tests {
continuation: Some(Continuation(
"36498883b7f4c2c12cc364be0a44d806-8abb3088feffef3f".to_string(),
)),
limit: 20,
limit: Some(20),
order: OrderEnum::Recent,
};

Expand Down Expand Up @@ -436,7 +437,7 @@ mod tests {
continuation: Some(Continuation(
"36498883b7f4c2c12cc364be0a44d806-8abb3088feffef3f".to_string(),
)),
limit: 20,
limit: Some(20),
order: OrderEnum::ByLabel {
label: "Access Management".to_string(),
},
Expand Down Expand Up @@ -510,7 +511,7 @@ mod tests {
let params = QueryRequestParams {
attribute_filters: Vec::new(),
continuation: None,
limit: 20,
limit: Some(20),
order: OrderEnum::Recent,
filter: CommentFilter {
reviewed: None,
Expand Down
71 changes: 35 additions & 36 deletions cli/src/commands/get/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ pub fn get_single(client: &Client, args: &GetSingleCommentArgs) -> Result<()> {
)
}

const PROPERTY_VALUE_COUNT_CIRCUIT_BREAKER: usize = 256;

pub fn get_user_properties_filter_interactively(summary: &Summary) -> Result<UserPropertiesFilter> {
let string_user_property_selections = MultiSelect::new()
.with_prompt("Select which string user properties you want to set up filters for")
Expand Down Expand Up @@ -226,28 +228,40 @@ pub fn get_user_properties_filter_interactively(summary: &Summary) -> Result<Use
.expect("Could not get property filter action selection from user");

let get_property_value_selections =
|prompt: String,
possible_values: Vec<String>|
-> Result<(Vec<usize>, Vec<PropertyValue>)> {
let selections = MultiSelect::new()
.with_prompt(prompt)
.items(&possible_values)
.interact()?;

Ok((
selections.clone(),
selections
|prompt: String, possible_values: &mut Vec<String>| -> Result<Vec<PropertyValue>> {
if possible_values.len() < PROPERTY_VALUE_COUNT_CIRCUIT_BREAKER {
let selections = MultiSelect::new()
.with_prompt(prompt)
.items(possible_values)
.interact()?;

let values = selections
.iter()
.map(|selection| {
let selection_value = &possible_values[*selection];
PropertyValue::String(selection_value.clone())
})
.collect(),
))
.collect();

for selection in &selections {
possible_values.remove(*selection);
}
Ok(values)
} else {
let comma_sep_values: String = Input::new()
.with_prompt("Please enter your values seperated by comma")
.interact_text()?;

Ok(comma_sep_values
.to_lowercase()
.split(',')
.map(|value| PropertyValue::String(value.trim().to_string()))
.collect())
}
};

let mut filter: PropertyFilter = Default::default();
let possible_values =
let mut possible_values =
get_possible_values_for_string_property(summary, &property.full_name)
.unwrap_or_else(|_| {
panic!(
Expand All @@ -262,53 +276,38 @@ pub fn get_user_properties_filter_interactively(summary: &Summary) -> Result<Use
"What values do you want to include for the property \"{}\"",
property.full_name
),
possible_values,
&mut possible_values,
)
.expect("Could not get property selection from user")
.1
}
"Exclusion" => {
filter.not_one_of = get_property_value_selections(
format!(
"What values do you want to exclude for the property \"{}\"",
property.full_name
),
possible_values,
&mut possible_values,
)
.expect("Could not get property selection from user")
.1
}
"Both" => {
let (idxs, one_ofs) = get_property_value_selections(
let one_ofs = get_property_value_selections(
format!(
"What values do you want to include for the property \"{}\"",
property.full_name
),
possible_values.clone(),
&mut possible_values,
)
.expect("Could not get property selection from user");

let remaining_values: Vec<String> = possible_values
.into_iter()
.enumerate()
.filter_map(|(idx, value)| {
if idxs.contains(&idx) {
None
} else {
Some(value)
}
})
.collect();

let not_one_ofs = get_property_value_selections(
format!(
"What values do you want to exclude for the property \"{}\"",
property.full_name
),
remaining_values,
&mut possible_values,
)
.expect("Could not get property selection from user")
.1;
.expect("Could not get property selection from user");

filter.one_of = one_ofs;
filter.not_one_of = not_one_ofs;
Expand Down Expand Up @@ -830,7 +829,7 @@ fn get_comments_from_uids(
sources: vec![source.id],
messages: options.messages_filter.clone(),
},
limit: DEFAULT_QUERY_PAGE_SIZE,
limit: Some(DEFAULT_QUERY_PAGE_SIZE),
order: if options.shuffle {
OrderEnum::Sample {
seed: rand::thread_rng().gen_range(0..2_i64.pow(31) - 1) as usize,
Expand Down
Loading
Loading