Executing a checklist on a run#
Execute a published checklist on a run that has ended, so each of its checks is evaluated against the run’s data. To build a checklist, or to execute one live on an asset, see Automated checks.
In code#
from nominal.core import EventType, NominalClient
client = NominalClient.from_profile("default")
checklist = client.get_checklist("<ri.scout.instance.check-collection.identifier>") # a published checklist
review = checklist.execute("<ri.scout.instance.run.identifier>").poll_for_completion()
violations = [e for e in review.get_events() if e.type == EventType.ERROR]
print(f"{len(violations)} violations", review.nominal_url)
use std::{collections::BTreeSet, sync::Arc, time::Duration};
use nominal::streaming::api::clients::event::{AsyncEventService, AsyncEventServiceClient};
use nominal::streaming::api::clients::scout::datareview::api::{AsyncDataReviewService, AsyncDataReviewServiceClient};
use nominal::streaming::api::objects::scout::datareview::api::{AutomaticCheckEvaluationState as State, BatchInitiateDataReviewRequest, CreateDataReviewRequest};
use nominal::streaming::api::objects::{event::EventType, scout::{rids::api::ChecklistRid, run::api::RunRid}};
use nominal::streaming::client::{async_conjure_client, conjure::http::client::{AsyncService, ConjureRuntime}};
use nominal::streaming::prelude::{BearerToken, ResourceIdentifier};
let config = nominal::Config::load()?;
let profile = config.get_profile("default").ok_or("no profile named default")?;
let token = BearerToken::new(profile.token())?;
let api = async_conjure_client("data-review", profile.base_url().parse()?).map_err(nominal::Error::from)?;
let runtime = Arc::new(ConjureRuntime::default());
let reviews = AsyncDataReviewServiceClient::new(api.clone(), &runtime);
// Execute the latest version of the checklist on the run
let request = BatchInitiateDataReviewRequest::builder()
.push_requests(CreateDataReviewRequest::new(
RunRid(ResourceIdentifier::new("<ri.scout.instance.run.identifier>")?),
ChecklistRid(ResourceIdentifier::new("<ri.scout.instance.check-collection.identifier>")?),
))
.build();
let review_rid = reviews.batch_initiate(&token, &request).await.map_err(nominal::Error::from)?.rids()[0].clone();
// Finished when no check is still pending or executing
let review = loop {
let review = reviews.get(&token, &review_rid).await.map_err(nominal::Error::from)?;
if !review.check_evaluations().iter().any(|c| matches!(c.state(), State::PendingExecution(_) | State::Executing(_))) {
break review;
}
tokio::time::sleep(Duration::from_secs(2)).await;
};
// Each check that created events lists them
let event_rids: BTreeSet<_> = review.check_evaluations().iter()
.filter_map(|c| match c.state() { State::GeneratedAlerts(s) => Some(s.event_rids().clone()), _ => None })
.flatten()
.collect();
let events = AsyncEventServiceClient::new(api, &runtime)
.batch_get_events(&token, &event_rids).await.map_err(nominal::Error::from)?;
let violations = events.iter().filter(|e| *e.type_() == EventType::Error).count();
println!("{violations} violations");
In the Nominal app#
On the run’s page, open the Checklist executions tab and click EXECUTE CHECKLIST.
Select the checklist and click EXECUTE.
To execute a checklist on several runs at once, open the published checklist, click EXECUTE ON…, choose Run, select the runs, and click EXECUTE CHECKLIST ON RUN. Only runs with an end time are listed.