cdg_api

A simple Rust library to interact with the US Congress API.
Installation
Add cdg_api
to your Cargo.toml
:
[dependencies]
cdg_api = "1.3.6"
Or use cargo
to add the dependency:
cargo add cdg_api
If you don't want to pull in reqwest as a dependency, you can disable the requests
feature by just disabling the default features:
[dependencies]
cdg_api = { version = "1.3.6", default-features = false }
or
cargo add cdg_api --no-default-features
Getting Started
Setting Up Your API Key
Obtain an API key from the US Congress API. Provide it to the CongressApiClient
either via an environment variable or direct initialization:
-
Environment Variable:
export CDG_API_KEY="your_api_key_here"
-
Direct Initialization:
use cdg_api::CongressApiClient;
let client = CongressApiClient::new(Some("your_api_key_here".to_string())).unwrap();
Note: Using environment variables is recommended to avoid hardcoding sensitive information.
Using CongressApiClient
[CongressApiClient
] allows you to interact with various API endpoints. Below are examples demonstrating how to fetch different types of data, including the fetch-all Endpoints::Generic
variant.
For more detailed information, see the documentation, the
examples directory, and the US Congress API documentation.
Example 1: Fetching Members
Fetch a list of current members of Congress and display their names, party affiliations, and states.
use cdg_api::CongressApiClient;
use cdg_api::endpoints::{Endpoints, NewEndpoint};
use cdg_api::param_models::MemberListParams;
use cdg_api::cdg_types::FormatType;
use cdg_api::response_models::MembersResponse;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = CongressApiClient::new(None)?;
let endpoint = Endpoints::new_member_list(
MemberListParams::default()
.format(FormatType::Json)
.limit(10)
.current_member(true)
);
let response: MembersResponse = client.fetch(endpoint)?;
for member in response.members {
println!("{}, {}, {}\n",
member.name.unwrap_or_default(),
member.state.unwrap_or_default(),
member.party_name.unwrap_or_default()
);
}
Ok(())
}
Example 2: Using GenericResponse
with parse_response
Fetch detailed information about a specific bill using GenericResponse
and parse it into a specific response model.
use cdg_api::CongressApiClient;
use cdg_api::endpoints::{Endpoints, NewEndpoint};
use cdg_api::param_models::BillDetailsParams;
use cdg_api::cdg_types::{BillType, FormatType};
use cdg_api::response_models::{BillDetailsResponse, GenericResponse, serialize_response, parse_response};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let client = CongressApiClient::new(None)?;
let params = BillDetailsParams::default()
.format(FormatType::Json);
let endpoint = Endpoints::new_bill_details(118, BillType::Hr, 148, params);
let response: GenericResponse = client.fetch(endpoint)?;
let bill_details: BillDetailsResponse = match parse_response(&response) {
Ok(bill_details) => bill_details,
Err(e) => {
println!("Failed to parse response: {}", e);
println!("Response:\n\n{}", serialize_response(&response, true)?);
return Ok(());
}
};
let bill = bill_details.bill;
println!("Bill: {}", bill.number.unwrap_or_default());
println!("Title: {}", bill.title.unwrap_or_default());
println!("Summary: {:#?}", bill.summaries.unwrap_or_default());
Ok(())
}
Example 3: Using Endpoints::Generic
for Custom Endpoints
When working with custom or unknown endpoints, you can use Endpoints::Generic
to specify the endpoint string such as daily-congressional-record
and GenericParams
to define query parameters. The response can be fetched as GenericResponse
.
The Endpoint
created can then call parse_response
to parse the response into a specific response model. If parsing fails, the GenericResponse
can be serialized to see the response structure.
This is essentially the Endpoints equivalent of the GenericResponse example above. One for requests and the other for responses.
use cdg_api::CongressApiClient;
use cdg_api::endpoints::{Endpoints, NewEndpoint};
use cdg_api::response_models::{DailyCongressionalRecordResponse, GenericResponse, serialize_response, parse_response};
use cdg_api::param_models::GenericParams;
use cdg_api::cdg_types::*;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let client = CongressApiClient::new(None)?;
let endpoint = Endpoints::new_generic(
"daily-congressional-record".to_string(),
GenericParams::default().format(FormatType::Json)
);
let response: GenericResponse = client.fetch(endpoint)?;
match parse_response::<DailyCongressionalRecordResponse, GenericResponse>(&response) {
Ok(daily_record) => {
let record = daily_record.daily_congressional_record;
for issue in record {
println!("Issue Number: {}", issue.issue_number.unwrap_or_default());
println!("Volume Number: {}", issue.volume_number.unwrap_or_default());
println!("Issue Date: {}", issue.issue_date.unwrap_or_default());
println!("Congress: {}", issue.congress.unwrap_or_default());
println!("Session Number: {}", issue.session_number.unwrap_or_default());
println!("URL: {}", issue.url.unwrap_or_default());
println!("Sections:");
if let Some(full) = issue.full_issue {
println!("Full Record: {:#?}", full);
}
println!("----------------------------");
}
},
Err(e) => {
println!("Failed to parse response: {}", e);
println!("Response:\n\n{}", serialize_response(&response, true)?);
}
}
Ok(())
}
Related Projects
- loc_api : A Rust library for interacting with the Library of Congress API. Less polished than
cdg_api
, barebones interface, but functional.
License
This project is licensed under the terms of the MIT license.
Repository
https://github.com/t-fbd/cdg_api
Acknowledgements
The data is sourced from the U.S. Congress API.
See their repository for more information: LibraryOfCongress/api.congress.gov.
Contact
For questions or feedback, please contact me on github.
If you find this project helpful, consider donating PayPal.