runpod_sdk/service/billing.rs
1use std::future::Future;
2
3#[cfg(feature = "tracing")]
4use crate::TRACING_TARGET_SERVICE;
5use crate::model::{
6 BillingRecords, EndpointBillingQuery, NetworkVolumeBillingQuery, PodBillingQuery,
7};
8use crate::{Result, RunpodClient};
9
10/// Trait for retrieving billing information and usage data.
11///
12/// The `BillingService` provides methods to query billing records for various
13/// RunPod resources including Pods, Serverless endpoints, and Network volumes.
14/// It allows filtering by time ranges, grouping by different criteria, and
15/// retrieving detailed usage statistics for cost analysis and monitoring.
16///
17/// This trait is implemented on the [`RunpodClient`](crate::client::RunpodClient).
18///
19/// # Features
20///
21/// - Query Pod billing history with flexible time ranges
22/// - Retrieve Serverless endpoint billing data with detailed metrics
23/// - Access Network volume usage and billing information
24/// - Support for different time bucket sizes (hour, day, week, month, year)
25/// - Flexible grouping options for data aggregation
26///
27/// # Time Ranges
28///
29/// All billing queries support optional start and end time parameters.
30/// Times should be provided in ISO 8601 format (e.g., "2024-01-01T00:00:00Z").
31/// If not specified, the service will return recent billing data.
32pub trait BillingService {
33 /// Retrieves detailed Pod billing history and usage data.
34 ///
35 /// This method returns billing records for GPU and CPU Pod usage, including
36 /// runtime costs, resource utilization, and time-based billing information.
37 /// Results can be filtered by time range and grouped by various criteria
38 /// such as Pod ID, GPU type, or data center.
39 ///
40 /// # Arguments
41 ///
42 /// * `query` - Query parameters to filter and group the billing data
43 /// - `bucket_size`: Time granularity (hour, day, week, month, year)
44 /// - `grouping`: How to group the results (by Pod ID, GPU type, etc.)
45 /// - `start_time`/`end_time`: Time range filter in ISO 8601 format
46 /// - `pod_id`: Filter by specific Pod ID
47 /// - `gpu_type_id`: Filter by specific GPU type
48 ///
49 /// # Returns
50 ///
51 /// A vector of `BillingRecord` containing:
52 /// - Runtime duration and costs
53 /// - Resource type and specifications
54 /// - Time-based billing breakdowns
55 /// - Pod identification and metadata
56 ///
57 /// # Example
58 ///
59 /// ```no_run
60 /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
61 /// # use runpod_sdk::model::{PodBillingQuery, BucketSize};
62 /// # use runpod_sdk::service::BillingService;
63 /// # async fn example() -> Result<()> {
64 /// let config = RunpodConfig::from_env()?;
65 /// let client = RunpodClient::new(config)?;
66 ///
67 /// let query = PodBillingQuery {
68 /// bucket_size: Some(BucketSize::Day),
69 /// start_time: Some("2024-01-01T00:00:00Z".to_string()),
70 /// end_time: Some("2024-01-31T23:59:59Z".to_string()),
71 /// ..Default::default()
72 /// };
73 ///
74 /// let records = client.get_pod_billing(query).await?;
75 /// println!("Found {} pod billing records", records.len());
76 /// # Ok(())
77 /// # }
78 /// ```
79 fn get_pod_billing(
80 &self,
81 query: PodBillingQuery,
82 ) -> impl Future<Output = Result<BillingRecords>>;
83
84 /// Retrieves comprehensive Serverless endpoint billing history and metrics.
85 ///
86 /// This method provides detailed billing information for Serverless endpoint
87 /// usage, including request processing costs, idle time charges, and scaling
88 /// metrics. The data helps analyze endpoint performance and cost efficiency.
89 ///
90 /// # Arguments
91 ///
92 /// * `query` - Query parameters for filtering and grouping endpoint billing data
93 /// - `bucket_size`: Time granularity for aggregating billing data
94 /// - `grouping`: Grouping criteria (endpoint ID, template ID, etc.)
95 /// - `start_time`/`end_time`: Time range for the billing period
96 /// - `endpoint_id`: Filter by specific endpoint
97 /// - `template_id`: Filter by template used by endpoints
98 /// - `gpu_type_id`: Filter by GPU type used
99 ///
100 /// # Returns
101 ///
102 /// A vector of `BillingRecord` containing:
103 /// - Request processing costs and duration
104 /// - Idle time and scaling charges
105 /// - Worker utilization metrics
106 /// - Template and resource information
107 /// - Time-based cost breakdowns
108 ///
109 /// # Example
110 ///
111 /// ```no_run
112 /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
113 /// # use runpod_sdk::model::{EndpointBillingQuery, BucketSize, BillingGrouping};
114 /// # use runpod_sdk::service::BillingService;
115 /// # async fn example() -> Result<()> {
116 /// let config = RunpodConfig::from_env()?;
117 /// let client = RunpodClient::new(config)?;
118 ///
119 /// let query = EndpointBillingQuery {
120 /// bucket_size: Some(BucketSize::Day),
121 /// grouping: Some(BillingGrouping::EndpointId),
122 /// start_time: Some("2024-01-01T00:00:00Z".to_string()),
123 /// end_time: Some("2024-01-31T23:59:59Z".to_string()),
124 /// ..Default::default()
125 /// };
126 ///
127 /// let records = client.get_endpoint_billing(query).await?;
128 /// println!("Found {} endpoint billing records", records.len());
129 /// # Ok(())
130 /// # }
131 /// ```
132 fn get_endpoint_billing(
133 &self,
134 query: EndpointBillingQuery,
135 ) -> impl Future<Output = Result<BillingRecords>>;
136
137 /// Retrieves Network Volume billing history and storage usage metrics.
138 ///
139 /// This method returns billing information for Network Volume storage,
140 /// including storage capacity costs, data transfer charges, and usage
141 /// patterns. This data is essential for managing storage costs and
142 /// optimizing volume utilization across your infrastructure.
143 ///
144 /// # Arguments
145 ///
146 /// * `query` - Query parameters for filtering volume billing data
147 /// - `bucket_size`: Time granularity for billing aggregation
148 /// - `grouping`: How to group results (by volume ID, data center, etc.)
149 /// - `start_time`/`end_time`: Time range for billing period
150 /// - `volume_id`: Filter by specific Network Volume ID
151 /// - `data_center_id`: Filter by data center location
152 ///
153 /// # Returns
154 ///
155 /// A vector of `BillingRecord` containing:
156 /// - Storage capacity costs and duration
157 /// - Data transfer and bandwidth charges
158 /// - Volume utilization metrics
159 /// - Data center and regional cost breakdown
160 /// - Time-based storage billing details
161 ///
162 /// # Example
163 ///
164 /// ```no_run
165 /// # use runpod_sdk::{RunpodClient, RunpodConfig, Result};
166 /// # use runpod_sdk::model::{NetworkVolumeBillingQuery, BucketSize, BillingGrouping};
167 /// # use runpod_sdk::service::BillingService;
168 /// # async fn example() -> Result<()> {
169 /// let config = RunpodConfig::from_env()?;
170 /// let client = RunpodClient::new(config)?;
171 ///
172 /// let query = NetworkVolumeBillingQuery {
173 /// bucket_size: Some(BucketSize::Day),
174 /// start_time: Some("2024-01-01T00:00:00Z".to_string()),
175 /// end_time: Some("2024-01-31T23:59:59Z".to_string()),
176 /// ..Default::default()
177 /// };
178 ///
179 /// let records = client.get_volume_billing(query).await?;
180 /// println!("Found {} volume billing records", records.len());
181 /// # Ok(())
182 /// # }
183 /// ```
184 fn get_volume_billing(
185 &self,
186 query: NetworkVolumeBillingQuery,
187 ) -> impl Future<Output = Result<BillingRecords>>;
188}
189
190impl BillingService for RunpodClient {
191 async fn get_pod_billing(&self, query: PodBillingQuery) -> Result<BillingRecords> {
192 #[cfg(feature = "tracing")]
193 tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting pod billing records");
194
195 let response = self.get("/billing/pods").query(&query).send().await?;
196 let response = response.error_for_status()?;
197 let records: BillingRecords = response.json().await?;
198
199 #[cfg(feature = "tracing")]
200 tracing::debug!(
201 count = records.len(),
202 "Pod billing records retrieved successfully"
203 );
204
205 Ok(records)
206 }
207
208 async fn get_endpoint_billing(&self, query: EndpointBillingQuery) -> Result<BillingRecords> {
209 #[cfg(feature = "tracing")]
210 tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting endpoint billing records");
211
212 let response = self.get("/billing/endpoints").query(&query).send().await?;
213 let response = response.error_for_status()?;
214 let records: BillingRecords = response.json().await?;
215
216 #[cfg(feature = "tracing")]
217 tracing::debug!(
218 count = records.len(),
219 "Endpoint billing records retrieved successfully"
220 );
221
222 Ok(records)
223 }
224
225 async fn get_volume_billing(&self, query: NetworkVolumeBillingQuery) -> Result<BillingRecords> {
226 #[cfg(feature = "tracing")]
227 tracing::debug!(target: TRACING_TARGET_SERVICE, "Getting network volume billing records");
228
229 let response = self
230 .get("/billing/networkvolumes")
231 .query(&query)
232 .send()
233 .await?;
234 let response = response.error_for_status()?;
235 let records: BillingRecords = response.json().await?;
236
237 #[cfg(feature = "tracing")]
238 tracing::debug!(
239 count = records.len(),
240 "Network volume billing records retrieved successfully"
241 );
242
243 Ok(records)
244 }
245}