pub struct DataGovClient { /* private fields */ }Expand description
Async client for exploring data.gov datasets.
DataGovClient layers ergonomic helpers on top of the lower-level
data_gov_ckan::CkanClient. In addition to search and metadata lookups it
handles download destinations, progress reporting, and colour-aware output
that matches the data-gov CLI defaults.
Implementations§
Source§impl DataGovClient
impl DataGovClient
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Create a new DataGov client with default configuration
Examples found in repository?
5async fn main() -> Result<(), Box<dyn Error>> {
6 println!("🇺🇸 Data.gov Rust Client Demo");
7 println!("================================\n");
8
9 // Create a client
10 let client = DataGovClient::new()?;
11
12 // 1. Search for datasets
13 println!("🔍 Searching for 'climate' datasets...");
14 let search_results = client.search("climate", Some(5), None, None, None).await?;
15
16 println!("Found {} results:\n", search_results.count.unwrap_or(0));
17
18 if let Some(results) = &search_results.results {
19 for (i, dataset) in results.iter().enumerate() {
20 println!(
21 "{}. {} ({})",
22 i + 1,
23 dataset.title.as_deref().unwrap_or(&dataset.name),
24 dataset.name
25 );
26
27 // Show resource count
28 let resources = DataGovClient::get_downloadable_resources(dataset);
29 println!(" 📁 {} downloadable resources", resources.len());
30
31 if let Some(notes) = &dataset.notes {
32 let truncated = if notes.len() > 100 {
33 format!("{}...", ¬es[..100])
34 } else {
35 notes.clone()
36 };
37 println!(" 📄 {}", truncated);
38 }
39 println!();
40 }
41 }
42
43 // 2. Get organizations
44 println!("🏛️ Listing government organizations...");
45 let orgs = client.list_organizations(Some(10)).await?;
46 println!("Found {} organizations:", orgs.len());
47 for (i, org) in orgs.iter().enumerate().take(5) {
48 println!(" {}. {}", i + 1, org);
49 }
50 println!();
51
52 // 3. Autocomplete example
53 println!("🔍 Autocomplete for 'energy'...");
54 let suggestions = client.autocomplete_datasets("energy", Some(5)).await?;
55 println!("Suggestions:");
56 for suggestion in suggestions {
57 println!(" • {}", suggestion);
58 }
59 println!();
60
61 println!("✅ Demo completed! Try the interactive REPL with:");
62 println!(" data-gov");
63 println!();
64 println!("Example CLI commands:");
65 println!(" data-gov search \"climate data\"");
66 println!(" data-gov show consumer-complaint-database");
67 println!(" data-gov download consumer-complaint-database 0");
68 println!(" data-gov list organizations");
69 println!(" data-gov --help");
70
71 Ok(())
72}Sourcepub fn with_config(config: DataGovConfig) -> Result<Self>
pub fn with_config(config: DataGovConfig) -> Result<Self>
Create a new DataGov client with custom configuration
Sourcepub async fn search(
&self,
query: &str,
limit: Option<i32>,
offset: Option<i32>,
organization: Option<&str>,
format: Option<&str>,
) -> Result<PackageSearchResult>
pub async fn search( &self, query: &str, limit: Option<i32>, offset: Option<i32>, organization: Option<&str>, format: Option<&str>, ) -> Result<PackageSearchResult>
Search for datasets on data.gov.
§Arguments
query- Search terms (searches titles, descriptions, tags)limit- Maximum number of results (default: 10, max: 1000)offset- Number of results to skip for pagination (default: 0)organization- Filter by organization name (optional)format- Filter by resource format (optional, e.g., “CSV”, “JSON”)
§Examples
Basic search:
let client = DataGovClient::new()?;
let results = client.search("climate data", Some(20), None, None, None).await?;Search with filters:
let results = client.search("energy", Some(10), None, Some("doe-gov"), Some("CSV")).await?;Examples found in repository?
5async fn main() -> Result<(), Box<dyn Error>> {
6 println!("🇺🇸 Data.gov Rust Client Demo");
7 println!("================================\n");
8
9 // Create a client
10 let client = DataGovClient::new()?;
11
12 // 1. Search for datasets
13 println!("🔍 Searching for 'climate' datasets...");
14 let search_results = client.search("climate", Some(5), None, None, None).await?;
15
16 println!("Found {} results:\n", search_results.count.unwrap_or(0));
17
18 if let Some(results) = &search_results.results {
19 for (i, dataset) in results.iter().enumerate() {
20 println!(
21 "{}. {} ({})",
22 i + 1,
23 dataset.title.as_deref().unwrap_or(&dataset.name),
24 dataset.name
25 );
26
27 // Show resource count
28 let resources = DataGovClient::get_downloadable_resources(dataset);
29 println!(" 📁 {} downloadable resources", resources.len());
30
31 if let Some(notes) = &dataset.notes {
32 let truncated = if notes.len() > 100 {
33 format!("{}...", ¬es[..100])
34 } else {
35 notes.clone()
36 };
37 println!(" 📄 {}", truncated);
38 }
39 println!();
40 }
41 }
42
43 // 2. Get organizations
44 println!("🏛️ Listing government organizations...");
45 let orgs = client.list_organizations(Some(10)).await?;
46 println!("Found {} organizations:", orgs.len());
47 for (i, org) in orgs.iter().enumerate().take(5) {
48 println!(" {}. {}", i + 1, org);
49 }
50 println!();
51
52 // 3. Autocomplete example
53 println!("🔍 Autocomplete for 'energy'...");
54 let suggestions = client.autocomplete_datasets("energy", Some(5)).await?;
55 println!("Suggestions:");
56 for suggestion in suggestions {
57 println!(" • {}", suggestion);
58 }
59 println!();
60
61 println!("✅ Demo completed! Try the interactive REPL with:");
62 println!(" data-gov");
63 println!();
64 println!("Example CLI commands:");
65 println!(" data-gov search \"climate data\"");
66 println!(" data-gov show consumer-complaint-database");
67 println!(" data-gov download consumer-complaint-database 0");
68 println!(" data-gov list organizations");
69 println!(" data-gov --help");
70
71 Ok(())
72}Sourcepub async fn get_dataset(&self, dataset_id: &str) -> Result<Package>
pub async fn get_dataset(&self, dataset_id: &str) -> Result<Package>
Fetch the full package_show payload for a dataset.
Sourcepub async fn autocomplete_datasets(
&self,
partial: &str,
limit: Option<i32>,
) -> Result<Vec<String>>
pub async fn autocomplete_datasets( &self, partial: &str, limit: Option<i32>, ) -> Result<Vec<String>>
Fetch dataset name suggestions for interactive prompts.
Examples found in repository?
5async fn main() -> Result<(), Box<dyn Error>> {
6 println!("🇺🇸 Data.gov Rust Client Demo");
7 println!("================================\n");
8
9 // Create a client
10 let client = DataGovClient::new()?;
11
12 // 1. Search for datasets
13 println!("🔍 Searching for 'climate' datasets...");
14 let search_results = client.search("climate", Some(5), None, None, None).await?;
15
16 println!("Found {} results:\n", search_results.count.unwrap_or(0));
17
18 if let Some(results) = &search_results.results {
19 for (i, dataset) in results.iter().enumerate() {
20 println!(
21 "{}. {} ({})",
22 i + 1,
23 dataset.title.as_deref().unwrap_or(&dataset.name),
24 dataset.name
25 );
26
27 // Show resource count
28 let resources = DataGovClient::get_downloadable_resources(dataset);
29 println!(" 📁 {} downloadable resources", resources.len());
30
31 if let Some(notes) = &dataset.notes {
32 let truncated = if notes.len() > 100 {
33 format!("{}...", ¬es[..100])
34 } else {
35 notes.clone()
36 };
37 println!(" 📄 {}", truncated);
38 }
39 println!();
40 }
41 }
42
43 // 2. Get organizations
44 println!("🏛️ Listing government organizations...");
45 let orgs = client.list_organizations(Some(10)).await?;
46 println!("Found {} organizations:", orgs.len());
47 for (i, org) in orgs.iter().enumerate().take(5) {
48 println!(" {}. {}", i + 1, org);
49 }
50 println!();
51
52 // 3. Autocomplete example
53 println!("🔍 Autocomplete for 'energy'...");
54 let suggestions = client.autocomplete_datasets("energy", Some(5)).await?;
55 println!("Suggestions:");
56 for suggestion in suggestions {
57 println!(" • {}", suggestion);
58 }
59 println!();
60
61 println!("✅ Demo completed! Try the interactive REPL with:");
62 println!(" data-gov");
63 println!();
64 println!("Example CLI commands:");
65 println!(" data-gov search \"climate data\"");
66 println!(" data-gov show consumer-complaint-database");
67 println!(" data-gov download consumer-complaint-database 0");
68 println!(" data-gov list organizations");
69 println!(" data-gov --help");
70
71 Ok(())
72}Sourcepub async fn list_organizations(
&self,
limit: Option<i32>,
) -> Result<Vec<String>>
pub async fn list_organizations( &self, limit: Option<i32>, ) -> Result<Vec<String>>
List the publisher slugs for government organizations.
Examples found in repository?
5async fn main() -> Result<(), Box<dyn Error>> {
6 println!("🇺🇸 Data.gov Rust Client Demo");
7 println!("================================\n");
8
9 // Create a client
10 let client = DataGovClient::new()?;
11
12 // 1. Search for datasets
13 println!("🔍 Searching for 'climate' datasets...");
14 let search_results = client.search("climate", Some(5), None, None, None).await?;
15
16 println!("Found {} results:\n", search_results.count.unwrap_or(0));
17
18 if let Some(results) = &search_results.results {
19 for (i, dataset) in results.iter().enumerate() {
20 println!(
21 "{}. {} ({})",
22 i + 1,
23 dataset.title.as_deref().unwrap_or(&dataset.name),
24 dataset.name
25 );
26
27 // Show resource count
28 let resources = DataGovClient::get_downloadable_resources(dataset);
29 println!(" 📁 {} downloadable resources", resources.len());
30
31 if let Some(notes) = &dataset.notes {
32 let truncated = if notes.len() > 100 {
33 format!("{}...", ¬es[..100])
34 } else {
35 notes.clone()
36 };
37 println!(" 📄 {}", truncated);
38 }
39 println!();
40 }
41 }
42
43 // 2. Get organizations
44 println!("🏛️ Listing government organizations...");
45 let orgs = client.list_organizations(Some(10)).await?;
46 println!("Found {} organizations:", orgs.len());
47 for (i, org) in orgs.iter().enumerate().take(5) {
48 println!(" {}. {}", i + 1, org);
49 }
50 println!();
51
52 // 3. Autocomplete example
53 println!("🔍 Autocomplete for 'energy'...");
54 let suggestions = client.autocomplete_datasets("energy", Some(5)).await?;
55 println!("Suggestions:");
56 for suggestion in suggestions {
57 println!(" • {}", suggestion);
58 }
59 println!();
60
61 println!("✅ Demo completed! Try the interactive REPL with:");
62 println!(" data-gov");
63 println!();
64 println!("Example CLI commands:");
65 println!(" data-gov search \"climate data\"");
66 println!(" data-gov show consumer-complaint-database");
67 println!(" data-gov download consumer-complaint-database 0");
68 println!(" data-gov list organizations");
69 println!(" data-gov --help");
70
71 Ok(())
72}Sourcepub async fn autocomplete_organizations(
&self,
partial: &str,
limit: Option<i32>,
) -> Result<Vec<String>>
pub async fn autocomplete_organizations( &self, partial: &str, limit: Option<i32>, ) -> Result<Vec<String>>
Fetch organization name suggestions for interactive prompts.
Sourcepub fn get_downloadable_resources(package: &Package) -> Vec<Resource>
pub fn get_downloadable_resources(package: &Package) -> Vec<Resource>
Return resources that look like downloadable files.
The returned list is filtered to resources that expose a direct URL, are not marked as API endpoints, and advertise a file format.
Examples found in repository?
5async fn main() -> Result<(), Box<dyn Error>> {
6 println!("🇺🇸 Data.gov Rust Client Demo");
7 println!("================================\n");
8
9 // Create a client
10 let client = DataGovClient::new()?;
11
12 // 1. Search for datasets
13 println!("🔍 Searching for 'climate' datasets...");
14 let search_results = client.search("climate", Some(5), None, None, None).await?;
15
16 println!("Found {} results:\n", search_results.count.unwrap_or(0));
17
18 if let Some(results) = &search_results.results {
19 for (i, dataset) in results.iter().enumerate() {
20 println!(
21 "{}. {} ({})",
22 i + 1,
23 dataset.title.as_deref().unwrap_or(&dataset.name),
24 dataset.name
25 );
26
27 // Show resource count
28 let resources = DataGovClient::get_downloadable_resources(dataset);
29 println!(" 📁 {} downloadable resources", resources.len());
30
31 if let Some(notes) = &dataset.notes {
32 let truncated = if notes.len() > 100 {
33 format!("{}...", ¬es[..100])
34 } else {
35 notes.clone()
36 };
37 println!(" 📄 {}", truncated);
38 }
39 println!();
40 }
41 }
42
43 // 2. Get organizations
44 println!("🏛️ Listing government organizations...");
45 let orgs = client.list_organizations(Some(10)).await?;
46 println!("Found {} organizations:", orgs.len());
47 for (i, org) in orgs.iter().enumerate().take(5) {
48 println!(" {}. {}", i + 1, org);
49 }
50 println!();
51
52 // 3. Autocomplete example
53 println!("🔍 Autocomplete for 'energy'...");
54 let suggestions = client.autocomplete_datasets("energy", Some(5)).await?;
55 println!("Suggestions:");
56 for suggestion in suggestions {
57 println!(" • {}", suggestion);
58 }
59 println!();
60
61 println!("✅ Demo completed! Try the interactive REPL with:");
62 println!(" data-gov");
63 println!();
64 println!("Example CLI commands:");
65 println!(" data-gov search \"climate data\"");
66 println!(" data-gov show consumer-complaint-database");
67 println!(" data-gov download consumer-complaint-database 0");
68 println!(" data-gov list organizations");
69 println!(" data-gov --help");
70
71 Ok(())
72}Sourcepub fn get_resource_filename(
resource: &Resource,
fallback_name: Option<&str>,
) -> String
pub fn get_resource_filename( resource: &Resource, fallback_name: Option<&str>, ) -> String
Pick a filesystem-friendly filename for a resource download.
Sourcepub async fn download_dataset_resource(
&self,
resource: &Resource,
dataset_name: &str,
) -> Result<PathBuf>
pub async fn download_dataset_resource( &self, resource: &Resource, dataset_name: &str, ) -> Result<PathBuf>
Download a single resource into the dataset-specific directory.
§Arguments
resource- The resource to downloaddataset_name- Name of the dataset (used for subdirectory)
Returns the path where the file was saved
Sourcepub async fn download_resource(
&self,
resource: &Resource,
output_path: Option<PathBuf>,
) -> Result<PathBuf>
pub async fn download_resource( &self, resource: &Resource, output_path: Option<PathBuf>, ) -> Result<PathBuf>
Download a single resource to a specific path.
§Arguments
resource- The resource to downloadoutput_path- Where to save the file (if None, uses base download directory)
Returns the path where the file was saved
Sourcepub async fn download_resources(
&self,
resources: &[Resource],
output_dir: Option<&Path>,
) -> Vec<Result<PathBuf>> ⓘ
pub async fn download_resources( &self, resources: &[Resource], output_dir: Option<&Path>, ) -> Vec<Result<PathBuf>> ⓘ
Download multiple resources concurrently.
Returns one Result per resource so callers can inspect partial failures.
Sourcepub async fn download_dataset_resources(
&self,
resources: &[Resource],
dataset_name: &str,
) -> Vec<Result<PathBuf>> ⓘ
pub async fn download_dataset_resources( &self, resources: &[Resource], dataset_name: &str, ) -> Vec<Result<PathBuf>> ⓘ
Download multiple resources into the dataset-specific directory.
Returns one Result per resource so callers can inspect partial failures.
Sourcepub async fn validate_download_dir(&self) -> Result<()>
pub async fn validate_download_dir(&self) -> Result<()>
Check if the base download directory exists and is writable
Sourcepub fn download_dir(&self) -> PathBuf
pub fn download_dir(&self) -> PathBuf
Get the current base download directory
Sourcepub fn ckan_client(&self) -> &CkanClient
pub fn ckan_client(&self) -> &CkanClient
Get the underlying CKAN client for advanced operations