Current section
Files
Jump to
Current section
Files
src/ezconfig.gleam
// EZConfig - Community-maintained API rate limits and concurrency settings
//
// Usage:
// import ezconfig
//
// case ezconfig.get_config("api.openai.com") {
// Some(config) -> {
// // Use config.rps and config.max_concurrent
// }
// None -> {
// // Use default values
// }
// }
import gleam/dict.{type Dict}
import gleam/option.{type Option}
/// API rate limit configuration
pub type ApiConfig {
ApiConfig(
rps: Int,
// Requests per second
max_concurrent: Int,
// Maximum concurrent requests
notes: String,
)
}
/// Community-maintained API configurations
/// Update this dict and publish a new version to add/modify APIs
fn api_configs() -> Dict(String, ApiConfig) {
dict.from_list([
#(
"api.openai.com",
ApiConfig(60, 10, "Tier 1: 60 req/min = 1 req/sec, but bursts allowed"),
),
#(
"api.anthropic.com",
ApiConfig(50, 5, "Claude API rate limits"),
),
#(
"api.stripe.com",
ApiConfig(
100,
20,
"Stripe has high rate limits, can handle concurrent requests well",
),
),
#(
"api.github.com",
ApiConfig(
10,
3,
"GitHub API: 5000 req/hour = ~1.4 req/sec, be conservative",
),
),
#(
"api.twitter.com",
ApiConfig(15, 5, "Twitter API v2 rate limits vary by endpoint"),
),
#(
"graph.facebook.com",
ApiConfig(200, 10, "Facebook Graph API has high limits"),
),
#(
"www.googleapis.com",
ApiConfig(10, 5, "Google APIs vary widely, this is conservative default"),
),
#(
"slack.com",
ApiConfig(1, 1, "Slack webhooks: 1 req/sec tier limit"),
),
#(
"discord.com",
ApiConfig(50, 10, "Discord API has generous rate limits"),
),
#(
"api.sendgrid.com",
ApiConfig(10, 5, "SendGrid email API"),
),
#(
"api.twilio.com",
ApiConfig(20, 5, "Twilio messaging API"),
),
#(
"api.hubspot.com",
ApiConfig(10, 3, "HubSpot CRM API: 100 req/10sec = 10 req/sec"),
),
#(
"api.notion.com",
ApiConfig(3, 2, "Notion API: 3 req/sec rate limit"),
),
#(
"api.airtable.com",
ApiConfig(5, 2, "Airtable API: 5 req/sec rate limit"),
),
#(
"shopify.com",
ApiConfig(2, 2, "Shopify REST API: 2 req/sec (burst 40)"),
),
])
}
/// Get configuration for a specific API domain
pub fn get_config(domain: String) -> Option(ApiConfig) {
dict.get(api_configs(), domain) |> option.from_result
}
/// Get RPS for a domain, or None if not configured
pub fn get_rps(domain: String) -> Option(Int) {
case get_config(domain) {
option.Some(config) -> option.Some(config.rps)
option.None -> option.None
}
}
/// Get max_concurrent for a domain, or None if not configured
pub fn get_max_concurrent(domain: String) -> Option(Int) {
case get_config(domain) {
option.Some(config) -> option.Some(config.max_concurrent)
option.None -> option.None
}
}
/// Get all configured domains
pub fn list_domains() -> List(String) {
dict.keys(api_configs())
}
/// Check if a domain has a configuration
pub fn has_config(domain: String) -> Bool {
case get_config(domain) {
option.Some(_) -> True
option.None -> False
}
}