collab: Remove GET /billing/monthly_spend
endpoint (#31123)
This PR removes the `GET /billing/monthly_spend` endpoint, as it is no longer used. Release Notes: - N/A
This commit is contained in:
parent
f196288e2d
commit
b444b326cb
5 changed files with 2 additions and 148 deletions
|
@ -27,11 +27,9 @@ use crate::db::billing_subscription::{
|
||||||
StripeCancellationReason, StripeSubscriptionStatus, SubscriptionKind,
|
StripeCancellationReason, StripeSubscriptionStatus, SubscriptionKind,
|
||||||
};
|
};
|
||||||
use crate::llm::db::subscription_usage_meter::CompletionMode;
|
use crate::llm::db::subscription_usage_meter::CompletionMode;
|
||||||
use crate::llm::{
|
use crate::llm::{AGENT_EXTENDED_TRIAL_FEATURE_FLAG, DEFAULT_MAX_MONTHLY_SPEND};
|
||||||
AGENT_EXTENDED_TRIAL_FEATURE_FLAG, DEFAULT_MAX_MONTHLY_SPEND, FREE_TIER_MONTHLY_SPENDING_LIMIT,
|
|
||||||
};
|
|
||||||
use crate::rpc::{ResultExt as _, Server};
|
use crate::rpc::{ResultExt as _, Server};
|
||||||
use crate::{AppState, Cents, Error, Result};
|
use crate::{AppState, Error, Result};
|
||||||
use crate::{db::UserId, llm::db::LlmDatabase};
|
use crate::{db::UserId, llm::db::LlmDatabase};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{
|
db::{
|
||||||
|
@ -64,7 +62,6 @@ pub fn router() -> Router {
|
||||||
"/billing/subscriptions/sync",
|
"/billing/subscriptions/sync",
|
||||||
post(sync_billing_subscription),
|
post(sync_billing_subscription),
|
||||||
)
|
)
|
||||||
.route("/billing/monthly_spend", get(get_monthly_spend))
|
|
||||||
.route("/billing/usage", get(get_current_usage))
|
.route("/billing/usage", get(get_current_usage))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,54 +1220,6 @@ async fn handle_customer_subscription_event(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct GetMonthlySpendParams {
|
|
||||||
github_user_id: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
struct GetMonthlySpendResponse {
|
|
||||||
monthly_free_tier_spend_in_cents: u32,
|
|
||||||
monthly_free_tier_allowance_in_cents: u32,
|
|
||||||
monthly_spend_in_cents: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_monthly_spend(
|
|
||||||
Extension(app): Extension<Arc<AppState>>,
|
|
||||||
Query(params): Query<GetMonthlySpendParams>,
|
|
||||||
) -> Result<Json<GetMonthlySpendResponse>> {
|
|
||||||
let user = app
|
|
||||||
.db
|
|
||||||
.get_user_by_github_user_id(params.github_user_id)
|
|
||||||
.await?
|
|
||||||
.context("user not found")?;
|
|
||||||
|
|
||||||
let Some(llm_db) = app.llm_db.clone() else {
|
|
||||||
return Err(Error::http(
|
|
||||||
StatusCode::NOT_IMPLEMENTED,
|
|
||||||
"LLM database not available".into(),
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
let free_tier = user
|
|
||||||
.custom_llm_monthly_allowance_in_cents
|
|
||||||
.map(|allowance| Cents(allowance as u32))
|
|
||||||
.unwrap_or(FREE_TIER_MONTHLY_SPENDING_LIMIT);
|
|
||||||
|
|
||||||
let spending_for_month = llm_db
|
|
||||||
.get_user_spending_for_month(user.id, Utc::now())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let free_tier_spend = Cents::min(spending_for_month, free_tier);
|
|
||||||
let monthly_spend = spending_for_month.saturating_sub(free_tier);
|
|
||||||
|
|
||||||
Ok(Json(GetMonthlySpendResponse {
|
|
||||||
monthly_free_tier_spend_in_cents: free_tier_spend.0,
|
|
||||||
monthly_free_tier_allowance_in_cents: free_tier.0,
|
|
||||||
monthly_spend_in_cents: monthly_spend.0,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct GetCurrentUsageParams {
|
struct GetCurrentUsageParams {
|
||||||
github_user_id: i32,
|
github_user_id: i32,
|
||||||
|
|
|
@ -7,10 +7,6 @@ pub use token::*;
|
||||||
|
|
||||||
pub const AGENT_EXTENDED_TRIAL_FEATURE_FLAG: &str = "agent-extended-trial";
|
pub const AGENT_EXTENDED_TRIAL_FEATURE_FLAG: &str = "agent-extended-trial";
|
||||||
|
|
||||||
/// The maximum monthly spending an individual user can reach on the free tier
|
|
||||||
/// before they have to pay.
|
|
||||||
pub const FREE_TIER_MONTHLY_SPENDING_LIMIT: Cents = Cents::from_dollars(10);
|
|
||||||
|
|
||||||
/// The default value to use for maximum spend per month if the user did not
|
/// The default value to use for maximum spend per month if the user did not
|
||||||
/// explicitly set a maximum spend.
|
/// explicitly set a maximum spend.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
use crate::db::UserId;
|
|
||||||
use crate::llm::Cents;
|
|
||||||
use chrono::Datelike;
|
|
||||||
use futures::StreamExt as _;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use strum::IntoEnumIterator as _;
|
use strum::IntoEnumIterator as _;
|
||||||
|
|
||||||
|
@ -45,68 +41,4 @@ impl LlmDatabase {
|
||||||
.collect();
|
.collect();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_user_spending_for_month(
|
|
||||||
&self,
|
|
||||||
user_id: UserId,
|
|
||||||
now: DateTimeUtc,
|
|
||||||
) -> Result<Cents> {
|
|
||||||
self.transaction(|tx| async move {
|
|
||||||
let month = now.date_naive().month() as i32;
|
|
||||||
let year = now.date_naive().year();
|
|
||||||
|
|
||||||
let mut monthly_usages = monthly_usage::Entity::find()
|
|
||||||
.filter(
|
|
||||||
monthly_usage::Column::UserId
|
|
||||||
.eq(user_id)
|
|
||||||
.and(monthly_usage::Column::Month.eq(month))
|
|
||||||
.and(monthly_usage::Column::Year.eq(year)),
|
|
||||||
)
|
|
||||||
.stream(&*tx)
|
|
||||||
.await?;
|
|
||||||
let mut monthly_spending = Cents::ZERO;
|
|
||||||
|
|
||||||
while let Some(usage) = monthly_usages.next().await {
|
|
||||||
let usage = usage?;
|
|
||||||
let Ok(model) = self.model_by_id(usage.model_id) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
monthly_spending += calculate_spending(
|
|
||||||
model,
|
|
||||||
usage.input_tokens as usize,
|
|
||||||
usage.cache_creation_input_tokens as usize,
|
|
||||||
usage.cache_read_input_tokens as usize,
|
|
||||||
usage.output_tokens as usize,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(monthly_spending)
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_spending(
|
|
||||||
model: &model::Model,
|
|
||||||
input_tokens_this_month: usize,
|
|
||||||
cache_creation_input_tokens_this_month: usize,
|
|
||||||
cache_read_input_tokens_this_month: usize,
|
|
||||||
output_tokens_this_month: usize,
|
|
||||||
) -> Cents {
|
|
||||||
let input_token_cost =
|
|
||||||
input_tokens_this_month * model.price_per_million_input_tokens as usize / 1_000_000;
|
|
||||||
let cache_creation_input_token_cost = cache_creation_input_tokens_this_month
|
|
||||||
* model.price_per_million_cache_creation_input_tokens as usize
|
|
||||||
/ 1_000_000;
|
|
||||||
let cache_read_input_token_cost = cache_read_input_tokens_this_month
|
|
||||||
* model.price_per_million_cache_read_input_tokens as usize
|
|
||||||
/ 1_000_000;
|
|
||||||
let output_token_cost =
|
|
||||||
output_tokens_this_month * model.price_per_million_output_tokens as usize / 1_000_000;
|
|
||||||
let spending = input_token_cost
|
|
||||||
+ cache_creation_input_token_cost
|
|
||||||
+ cache_read_input_token_cost
|
|
||||||
+ output_token_cost;
|
|
||||||
Cents::new(spending as u32)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod monthly_usage;
|
|
||||||
pub mod provider;
|
pub mod provider;
|
||||||
pub mod subscription_usage;
|
pub mod subscription_usage;
|
||||||
pub mod subscription_usage_meter;
|
pub mod subscription_usage_meter;
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
use crate::{db::UserId, llm::db::ModelId};
|
|
||||||
use sea_orm::entity::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
|
||||||
#[sea_orm(table_name = "monthly_usages")]
|
|
||||||
pub struct Model {
|
|
||||||
#[sea_orm(primary_key)]
|
|
||||||
pub id: i32,
|
|
||||||
pub user_id: UserId,
|
|
||||||
pub model_id: ModelId,
|
|
||||||
pub month: i32,
|
|
||||||
pub year: i32,
|
|
||||||
pub input_tokens: i64,
|
|
||||||
pub cache_creation_input_tokens: i64,
|
|
||||||
pub cache_read_input_tokens: i64,
|
|
||||||
pub output_tokens: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
|
||||||
pub enum Relation {}
|
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
|
Loading…
Add table
Add a link
Reference in a new issue