data-gov-ckan

Crates.iodata-gov-ckan
lib.rsdata-gov-ckan
version0.1.1
created_at2025-09-25 14:12:53.445632+00
updated_at2025-09-25 18:47:20.51159+00
descriptionClient for Data.Gov CKAN
homepagehttps://github.com/dspadea/data-gov-rs
repositoryhttps://github.com/dspadea/data-gov-rs
max_upload_size
id1854676
size199,514
Dave Spadea (dspadea)

documentation

README

data-gov-ckan

Async Rust client for CKAN APIs with first-class support for data.gov. It provides typed models, ergonomic helpers, and works with any CKAN-compatible portal.

License: Apache 2.0

Note: The client targets data.gov and its public API first. The code should work with other CKAN deployments that follow the same API surface, but those combinations have not been officially tested.

โš ๏ธ AI-assisted implementation: Much of this crate was produced with AI tooling. The client performs well in informal exercises, yet a thorough human audit and cleanup pass is still on the roadmap. Integrate it with awareness of that caveat.

Requirements

  • Rust 1.85+ (Rust 2024 edition)
  • Cargo and git
rustup toolchain install stable
rustup default stable

Install / depend

Use the published crate from crates.io:

[dependencies]
data-gov-ckan = "0.1.1"
tokio = { version = "1", features = ["full"] }

Working inside this repository? Point to the local path instead: data-gov-ckan = { path = "../data-gov-ckan" }. If you need the bleeding edge between releases, swap in the git dependency form: data-gov-ckan = { git = "https://github.com/dspadea/data-gov-rs", package = "data-gov-ckan" }.

Highlights

  • ๐Ÿ” Full coverage of CKAN action/* endpoints used by data.gov
  • โœ… Strongly typed models generated from the official OpenAPI spec
  • ๐ŸŒ Configurable base URL, authentication, and user-agent handling
  • โš™๏ธ Async support via reqwest + tokio
  • ๐Ÿงช Integration tests that target the live data.gov API

Quick start

use data_gov_ckan::{CkanClient, Configuration};
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = CkanClient::new(Arc::new(Configuration::default()));

    let results = client.package_search(Some("climate"), Some(10), Some(0), None).await?;
    println!("Found {} datasets", results.count.unwrap_or(0));

    if let Some(datasets) = results.results {
        for dataset in datasets.iter().take(3) {
            let title = dataset.title.as_deref().unwrap_or(&dataset.name);
            println!("โ€ข {title}");
        }
    }

    Ok(())
}

Custom configuration & auth

use data_gov_ckan::{ApiKey, CkanClient, Configuration};
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Configuration {
        base_path: "https://demo.ckan.org/api/3".to_string(),
        api_key: Some(ApiKey {
            prefix: None,
            key: "your-api-key".to_string(),
        }),
        ..Configuration::default()
    };

    let client = CkanClient::new(Arc::new(config));
    let dataset = client.package_show("example-dataset").await?;
    println!("Dataset: {}", dataset.title.as_deref().unwrap_or(&dataset.name));

    Ok(())
}

Filtering with Solr-style query strings:

let fq = r#"organization:"gsa-gov" AND res_format:"CSV""#;
let results = client.package_search(Some("budget"), Some(20), Some(0), Some(fq)).await?;

API surface

Core methods include package_search, package_show, organization_list, group_list, tag_list, and user_list. Autocomplete helpers cover datasets, organisations, groups, tags, and users. Errors are surfaced through the CkanError enum with variants for request, parse, and API failures.

Development

git clone https://github.com/dspadea/data-gov-rs.git
cd data-gov-rs/data-gov-ckan
cargo build
cargo test        # includes integration tests hitting data.gov
cargo run --example debug_search
cargo run --example raw_response

Integration tests require network access. Use cargo test -- --ignored to skip or select them as needed.

Authentication options

  • API keys: set Configuration.api_key = Some(ApiKey { .. })
  • Basic auth: populate Configuration.basic_auth
  • Custom headers: configure the inner reqwest::Client before passing the configuration into CkanClient

Reuse the same CkanClient for multiple requests to benefit from connection pooling. Combine async calls with tokio::try_join! for improved throughput.

License & support

Distributed under the Apache 2.0 license. Please open issues or pull requests on GitHub for questions and contributions.

Commit count: 38

cargo fmt