claude_usage/lib.rs
1//! # claude-usage
2//!
3//! A library for fetching Claude API usage data from Anthropic.
4//!
5//! This crate provides a simple API to retrieve usage statistics including
6//! 5-hour and 7-day utilization percentages.
7//!
8//! ## Features
9//!
10//! - Cross-platform credential retrieval (macOS Keychain, Linux credential file)
11//! - Typed response structures for usage data
12//! - Secure credential handling (read, use, discard immediately)
13//!
14//! ## Platform Support
15//!
16//! | Platform | Credential Source |
17//! |----------|-------------------|
18//! | macOS | Keychain ("Claude Code-credentials") |
19//! | Linux | `~/.claude/.credentials.json` |
20//!
21//! ## Example
22//!
23//! ```rust,ignore
24//! use claude_usage::get_usage;
25//!
26//! let usage = get_usage()?;
27//! println!("5h utilization: {}%", usage.five_hour.utilization);
28//! println!("7d utilization: {}%", usage.seven_day.utilization);
29//!
30//! // Check if usage is sustainable
31//! if usage.five_hour_on_pace() {
32//! println!("5-hour usage is on pace");
33//! }
34//! ```
35//!
36//! ## Environment Variable
37//!
38//! The `CLAUDE_CODE_OAUTH_TOKEN` environment variable can be set to override
39//! file-based credential retrieval on any platform.
40
41pub mod client;
42pub mod credentials;
43pub mod error;
44pub mod types;
45
46#[cfg(feature = "blocking")]
47pub use client::fetch_usage_raw;
48pub use credentials::get_token;
49pub use error::{ApiError, CredentialError, Error};
50pub use types::{ExtraUsage, UsageData, UsagePeriod};
51
52/// Fetch current Claude API usage data.
53///
54/// This is the main entry point for the crate. It:
55/// 1. Retrieves credentials from platform-specific storage
56/// 2. Calls the Anthropic usage API
57/// 3. Returns typed usage data
58///
59/// # Example
60///
61/// ```rust,ignore
62/// use claude_usage::get_usage;
63///
64/// let usage = get_usage()?;
65/// println!("5h utilization: {}%", usage.five_hour.utilization);
66/// println!("7d utilization: {}%", usage.seven_day.utilization);
67/// ```
68///
69/// # Errors
70///
71/// Returns [`Error`] if:
72/// - Credentials are not found or expired
73/// - API call fails
74/// - Response parsing fails
75#[cfg(feature = "blocking")]
76pub fn get_usage() -> Result<UsageData, Error> {
77 let token = credentials::get_token()?;
78 let response = client::fetch_usage_raw(&token)?;
79 let usage: UsageData =
80 serde_json::from_str(&response).map_err(|e| Error::Parse(e.to_string()))?;
81 Ok(usage)
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 #[ignore = "requires real credentials"]
90 #[cfg(feature = "blocking")]
91 fn test_get_usage_integration() {
92 let result = get_usage();
93 match result {
94 Ok(usage) => {
95 println!("5h utilization: {}%", usage.five_hour.utilization);
96 println!("7d utilization: {}%", usage.seven_day.utilization);
97 assert!(usage.five_hour.utilization >= 0.0);
98 assert!(usage.seven_day.utilization >= 0.0);
99 }
100 Err(e) => {
101 println!("Error: {}", e);
102 }
103 }
104 }
105}