diff --git a/examples/v1/alerts.py b/examples/v1/alerts.py new file mode 100644 index 00000000..e4280dec --- /dev/null +++ b/examples/v1/alerts.py @@ -0,0 +1,62 @@ +"""Examples for the Alerts resource. + +Covers creating and archiving threshold alerts. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/alerts.py +""" + +from metronome import Metronome + +client = Metronome() + + +def create_alert(): + """Create a threshold alert that fires when a condition is met.""" + response = client.v1.alerts.create( + alert_type="spend_threshold_reached", + name="High Spend Alert", + threshold=10000.0, + # customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", # Specific customer (omit for all) + # evaluate_on_create=True, # Evaluate immediately for existing customers + ) + print(f"Created alert: {response.data}") + + +def create_usage_alert(): + """Create an alert that fires when usage reaches a threshold.""" + response = client.v1.alerts.create( + alert_type="usage_threshold_reached", + name="API Usage Alert", + threshold=1000000.0, + billable_metric_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + ) + print(f"Created usage alert: {response.data}") + + +def create_low_credit_alert(): + """Create an alert that fires when credit balance drops below a threshold.""" + response = client.v1.alerts.create( + alert_type="low_credit_balance_reached", + name="Low Credit Balance", + threshold=500.0, + ) + print(f"Created credit alert: {response.data}") + + +def archive_alert(): + """Archive an alert.""" + response = client.v1.alerts.archive( + id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Archived alert: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_alert() + # create_usage_alert() + # create_low_credit_alert() + # archive_alert() + pass diff --git a/examples/v1/audit_logs.py b/examples/v1/audit_logs.py new file mode 100644 index 00000000..95ed1a80 --- /dev/null +++ b/examples/v1/audit_logs.py @@ -0,0 +1,27 @@ +"""Examples for the Audit Logs resource. + +Covers listing audit log entries. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/audit_logs.py +""" + +from metronome import Metronome + +client = Metronome() + + +def list_audit_logs(): + """List audit log entries with auto-pagination.""" + for log in client.v1.audit_logs.list( + # starting_on="2025-01-01T00:00:00Z", # Filter by date range + # ending_before="2025-02-01T00:00:00Z", + ): + print(f"Audit log: {log}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_audit_logs() + pass diff --git a/examples/v1/billable_metrics.py b/examples/v1/billable_metrics.py new file mode 100644 index 00000000..26191f30 --- /dev/null +++ b/examples/v1/billable_metrics.py @@ -0,0 +1,66 @@ +"""Examples for the Billable Metrics resource. + +Covers creating, retrieving, listing, and archiving billable metrics. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/billable_metrics.py +""" + +from metronome import Metronome + +client = Metronome() + + +def create_billable_metric(): + """Create a new billable metric using aggregation.""" + response = client.v1.billable_metrics.create( + name="CPU Seconds", + aggregation_type="SUM", + aggregation_key="cpu_seconds", + event_type_filter={"in_values": ["heartbeat"]}, + # group_keys=[["region"]], # Group usage by region + # property_filters=[{"name": "cluster_id", "exists": True}], + ) + print(f"Created billable metric: {response.data}") + + +def create_billable_metric_with_sql(): + """Create a billable metric using a SQL query.""" + response = client.v1.billable_metrics.create( + name="Active Users", + sql="SELECT COUNT(DISTINCT user_id) as value FROM events WHERE event_type = 'login'", + ) + print(f"Created billable metric: {response.data}") + + +def retrieve_billable_metric(): + """Retrieve a specific billable metric by ID.""" + response = client.v1.billable_metrics.retrieve( + billable_metric_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + ) + print(f"Billable metric: {response.data}") + + +def list_billable_metrics(): + """List all billable metrics with auto-pagination.""" + for metric in client.v1.billable_metrics.list(): + print(f"Metric: {metric}") + + +def archive_billable_metric(): + """Archive a billable metric.""" + response = client.v1.billable_metrics.archive( + id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + ) + print(f"Archived: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_billable_metric() + # create_billable_metric_with_sql() + # retrieve_billable_metric() + # list_billable_metrics() + # archive_billable_metric() + pass diff --git a/examples/v1/contract_named_schedules.py b/examples/v1/contract_named_schedules.py new file mode 100644 index 00000000..c0caf01c --- /dev/null +++ b/examples/v1/contract_named_schedules.py @@ -0,0 +1,44 @@ +"""Examples for the Contract Named Schedules resource. + +Covers retrieving and updating named schedules on contracts. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/contract_named_schedules.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def retrieve_named_schedule(): + """Retrieve a named schedule for a contract.""" + response = client.v1.contracts.named_schedules.retrieve( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + schedule_name="my-schedule", + ) + print(f"Named schedule: {response.data}") + + +def update_named_schedule(): + """Update a named schedule on a contract.""" + client.v1.contracts.named_schedules.update( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + schedule_name="my-schedule", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + value={"custom_field": "custom_value"}, + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), + ) + print("Contract named schedule updated") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # retrieve_named_schedule() + # update_named_schedule() + pass diff --git a/examples/v1/contract_products.py b/examples/v1/contract_products.py new file mode 100644 index 00000000..dc7111ea --- /dev/null +++ b/examples/v1/contract_products.py @@ -0,0 +1,67 @@ +"""Examples for the Contract Products resource. + +Covers creating, retrieving, updating, listing, and archiving contract products. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/contract_products.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_product(): + """Create a new contract product.""" + response = client.v1.contracts.products.create( + name="API Calls", + type="USAGE", + # type can be: USAGE, FIXED, COMPOSITE, SUBSCRIPTION, PROFESSIONAL_SERVICE, PRO_SERVICE + ) + print(f"Created product: {response.data}") + + +def retrieve_product(): + """Retrieve a specific product by ID.""" + response = client.v1.contracts.products.retrieve( + id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + ) + print(f"Product: {response.data}") + + +def update_product(): + """Update a product (e.g., change name, add tags).""" + response = client.v1.contracts.products.update( + product_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + # name="Updated API Calls", + # tags=["compute", "api"], + ) + print(f"Updated product: {response.data}") + + +def list_products(): + """List all contract products with auto-pagination.""" + for product in client.v1.contracts.products.list(): + print(f"Product: {product}") + + +def archive_product(): + """Archive a contract product.""" + response = client.v1.contracts.products.archive( + product_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + ) + print(f"Archived: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_product() + # retrieve_product() + # update_product() + # list_products() + # archive_product() + pass diff --git a/examples/v1/contract_rate_cards.py b/examples/v1/contract_rate_cards.py new file mode 100644 index 00000000..053bb3a8 --- /dev/null +++ b/examples/v1/contract_rate_cards.py @@ -0,0 +1,205 @@ +"""Examples for the Contract Rate Cards resource and sub-resources. + +Covers rate card CRUD operations, plus managing product orders, rates, and named schedules. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/contract_rate_cards.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +# ============================================================================ +# Rate Cards +# ============================================================================ + + +def create_rate_card(): + """Create a new rate card.""" + response = client.v1.contracts.rate_cards.create( + name="Standard Rate Card", + # description="Default rate card for standard customers", + # fiat_credit_type_id="2714e483-4ff1-48e4-9e25-ac732e8f24f2", + ) + print(f"Created rate card: {response.data}") + + +def retrieve_rate_card(): + """Retrieve a specific rate card by ID.""" + response = client.v1.contracts.rate_cards.retrieve( + id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + ) + print(f"Rate card: {response.data}") + + +def update_rate_card(): + """Update a rate card (e.g., change name or description).""" + response = client.v1.contracts.rate_cards.update( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + # name="Updated Rate Card", + # description="Updated description", + ) + print(f"Updated rate card: {response.data}") + + +def list_rate_cards(): + """List all rate cards with auto-pagination.""" + for rate_card in client.v1.contracts.rate_cards.list(): + print(f"Rate card: {rate_card}") + + +def archive_rate_card(): + """Archive a rate card.""" + response = client.v1.contracts.rate_cards.archive( + id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + ) + print(f"Archived: {response.data}") + + +def retrieve_rate_schedule(): + """Retrieve the rate schedule for a rate card.""" + response = client.v1.contracts.rate_cards.retrieve_rate_schedule( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), + ) + print(f"Rate schedule: {response.data}") + + +# ============================================================================ +# Product Orders +# ============================================================================ + + +def update_product_orders(): + """Move (reorder) products within a rate card.""" + response = client.v1.contracts.rate_cards.product_orders.update( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + product_moves=[ + { + "product_id": "b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + "position": 0, + } + ], + ) + print(f"Updated product order: {response.data}") + + +def set_product_orders(): + """Set the complete product order for a rate card.""" + response = client.v1.contracts.rate_cards.product_orders.set( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + product_order=[ + "b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + "c4d5e6f7-2a3b-4c5d-0e1f-2a3b4c5d6e7f", + ], + ) + print(f"Set product order: {response.data}") + + +# ============================================================================ +# Rates +# ============================================================================ + + +def list_rates(): + """List rates for a rate card at a specific point in time.""" + for rate in client.v1.contracts.rate_cards.rates.list( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + at=datetime.fromisoformat("2025-01-01T00:00:00"), + ): + print(f"Rate: {rate}") + + +def add_rate(): + """Add a single rate to a rate card.""" + response = client.v1.contracts.rate_cards.rates.add( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + product_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + entitled=True, + rate_type="FLAT", + # price=0.01, # Price per unit + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), + ) + print(f"Added rate: {response.data}") + + +def add_many_rates(): + """Add multiple rates to a rate card in a single request.""" + response = client.v1.contracts.rate_cards.rates.add_many( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + rates=[ + { + "product_id": "b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + "starting_at": "2025-01-01T00:00:00Z", + "entitled": True, + "rate_type": "FLAT", + "price": 0.01, + }, + { + "product_id": "c4d5e6f7-2a3b-4c5d-0e1f-2a3b4c5d6e7f", + "starting_at": "2025-01-01T00:00:00Z", + "entitled": True, + "rate_type": "FLAT", + "price": 0.05, + }, + ], + ) + print(f"Added rates: {response.data}") + + +# ============================================================================ +# Rate Card Named Schedules +# ============================================================================ + + +def retrieve_rate_card_named_schedule(): + """Retrieve a named schedule for a rate card.""" + response = client.v1.contracts.rate_cards.named_schedules.retrieve( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + schedule_name="my-schedule", + ) + print(f"Named schedule: {response.data}") + + +def update_rate_card_named_schedule(): + """Update a named schedule for a rate card.""" + client.v1.contracts.rate_cards.named_schedules.update( + rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + schedule_name="my-schedule", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + value={"discount_percentage": 15}, + ) + print("Rate card named schedule updated") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + + # Rate Cards + # create_rate_card() + # retrieve_rate_card() + # update_rate_card() + # list_rate_cards() + # archive_rate_card() + # retrieve_rate_schedule() + + # Product Orders + # update_product_orders() + # set_product_orders() + + # Rates + # list_rates() + # add_rate() + # add_many_rates() + + # Named Schedules + # retrieve_rate_card_named_schedule() + # update_rate_card_named_schedule() + pass diff --git a/examples/v1/contracts.py b/examples/v1/contracts.py new file mode 100644 index 00000000..51bee203 --- /dev/null +++ b/examples/v1/contracts.py @@ -0,0 +1,192 @@ +"""Examples for the Contracts resource. + +Covers creating, retrieving, listing, amending, and managing contracts. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/contracts.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_contract(): + """Create a new contract for a customer.""" + response = client.v1.contracts.create( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), # Optional end date + # rate_card_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + # billing_provider_configuration={ + # "billing_provider": "stripe", + # "delivery_method": "direct_to_billing_provider", + # }, + ) + print(f"Created contract: {response.data}") + + +def retrieve_contract(): + """Retrieve a specific contract.""" + response = client.v1.contracts.retrieve( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(f"Contract: {response.data}") + + +def list_contracts(): + """List all contracts for a customer.""" + response = client.v1.contracts.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(f"Contracts: {response.data}") + + +def amend_contract(): + """Amend an existing contract (e.g., add commits, overrides, or change terms).""" + response = client.v1.contracts.amend( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + starting_at=datetime.fromisoformat("2025-06-01T00:00:00"), + ) + print(f"Amendment: {response.data}") + + +def archive_contract(): + """Archive a contract.""" + response = client.v1.contracts.archive( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + void_invoices=True, + ) + print(f"Archived: {response.data}") + + +def add_manual_balance_entry(): + """Add a manual balance entry to a contract's commit or credit ledger.""" + client.v1.contracts.add_manual_balance_entry( + id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + amount=1000.0, + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + reason="Manual credit adjustment for overage", + segment_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print("Manual balance entry added") + + +def create_historical_invoices(): + """Create historical invoices for a contract.""" + response = client.v1.contracts.create_historical_invoices( + invoices=[ + { + "contract_id": "d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + "customer_id": "13117714-3f05-48e5-a6e9-a66093f13b4d", + "credit_type_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2", + "exclusive_end_date": datetime.fromisoformat("2025-02-01T00:00:00"), + "inclusive_start_date": datetime.fromisoformat("2025-01-01T00:00:00"), + "issue_date": datetime.fromisoformat("2025-02-01T00:00:00"), + } + ], + preview=False, + ) + print(f"Historical invoices: {response.data}") + + +def get_net_balance(): + """Get the net balance for a customer's commits and credits.""" + response = client.v1.contracts.get_net_balance( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + # id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", # Specific commit/credit ID + ) + print(f"Net balance: {response}") + + +def list_balances(): + """List commit and credit balances for a customer.""" + for balance in client.v1.contracts.list_balances( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + # include_balance=True, # Include the current balance (may be slower) + # include_ledgers=True, # Include ledger entries + ): + print(f"Balance: {balance}") + + +def retrieve_rate_schedule(): + """Retrieve the rate schedule for a contract.""" + response = client.v1.contracts.retrieve_rate_schedule( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + # at=datetime.fromisoformat("2025-06-01T00:00:00"), # Rates at a specific time + ) + print(f"Rate schedule: {response.data}") + + +def retrieve_subscription_quantity_history(): + """Retrieve the quantity history for a subscription on a contract.""" + response = client.v1.contracts.retrieve_subscription_quantity_history( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + subscription_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Subscription quantity history: {response.data}") + + +def schedule_pro_services_invoice(): + """Schedule a professional services invoice.""" + response = client.v1.contracts.schedule_pro_services_invoice( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + issued_at=datetime.fromisoformat("2025-02-01T00:00:00"), + line_items=[ + { + "professional_service_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + "amount": 5000.0, + } + ], + ) + print(f"Pro services invoice: {response.data}") + + +def set_usage_filter(): + """Set a usage filter on a contract to control which events are billable.""" + client.v1.contracts.set_usage_filter( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + group_key="region", + group_values=["us-east-1", "us-west-2"], + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + ) + print("Usage filter set") + + +def update_end_date(): + """Update the end date of a contract.""" + response = client.v1.contracts.update_end_date( + contract_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ending_before=datetime.fromisoformat("2025-12-31T00:00:00"), + ) + print(f"Updated contract end date: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_contract() + # retrieve_contract() + # list_contracts() + # amend_contract() + # archive_contract() + # add_manual_balance_entry() + # create_historical_invoices() + # get_net_balance() + # list_balances() + # retrieve_rate_schedule() + # retrieve_subscription_quantity_history() + # schedule_pro_services_invoice() + # set_usage_filter() + # update_end_date() + pass diff --git a/examples/v1/credit_grants.py b/examples/v1/credit_grants.py new file mode 100644 index 00000000..64dfd838 --- /dev/null +++ b/examples/v1/credit_grants.py @@ -0,0 +1,78 @@ +"""Examples for the Credit Grants resource. + +Covers creating, listing, editing, voiding credit grants, and listing ledger entries. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/credit_grants.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_credit_grant(): + """Create a new credit grant for a customer.""" + response = client.v1.credit_grants.create( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + name="Promotional Credit", + priority=100.0, + expires_at=datetime.fromisoformat("2026-01-01T00:00:00"), + grant_amount={ + "amount": 5000.0, + "credit_type_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2", + }, + paid_amount={ + "amount": 0.0, + "credit_type_id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2", + }, + # reason="Sign-up bonus", + ) + print(f"Created credit grant: {response.data}") + + +def list_credit_grants(): + """List all credit grants with auto-pagination.""" + for grant in client.v1.credit_grants.list( + # customer_ids=["13117714-3f05-48e5-a6e9-a66093f13b4d"], # Filter by customer + ): + print(f"Credit grant: {grant}") + + +def edit_credit_grant(): + """Edit an existing credit grant (e.g., change expiration).""" + response = client.v1.credit_grants.edit( + id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + # expires_at=datetime.fromisoformat("2026-06-01T00:00:00"), + # name="Updated Credit Grant", + ) + print(f"Edited credit grant: {response.data}") + + +def list_entries(): + """List credit ledger entries showing how credits were used.""" + for entry in client.v1.credit_grants.list_entries( + # customer_ids=["13117714-3f05-48e5-a6e9-a66093f13b4d"], + ): + print(f"Ledger entry: {entry}") + + +def void_credit_grant(): + """Void a credit grant, removing any remaining balance.""" + response = client.v1.credit_grants.void( + id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Voided credit grant: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_credit_grant() + # list_credit_grants() + # edit_credit_grant() + # list_entries() + # void_credit_grant() + pass diff --git a/examples/v1/custom_fields.py b/examples/v1/custom_fields.py new file mode 100644 index 00000000..9bca7793 --- /dev/null +++ b/examples/v1/custom_fields.py @@ -0,0 +1,69 @@ +"""Examples for the Custom Fields resource. + +Covers adding keys, setting values, listing keys, deleting values, and removing keys. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/custom_fields.py +""" + +from metronome import Metronome + +client = Metronome() + + +def add_key(): + """Add a custom field key to an entity type.""" + client.v1.custom_fields.add_key( + enforce_uniqueness=True, + entity="customer", + key="salesforce_id", + ) + print("Custom field key added") + + +def set_values(): + """Set custom field values on a specific entity.""" + client.v1.custom_fields.set_values( + custom_fields={"salesforce_id": "SF-12345", "industry": "Technology"}, + entity="customer", + entity_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print("Custom field values set") + + +def list_keys(): + """List all custom field keys.""" + for key in client.v1.custom_fields.list_keys( + # entity="customer", # Filter by entity type + ): + print(f"Custom field key: {key}") + + +def delete_values(): + """Delete custom field values from an entity.""" + client.v1.custom_fields.delete_values( + entity="customer", + entity_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + keys=["salesforce_id"], + ) + print("Custom field values deleted") + + +def remove_key(): + """Remove a custom field key from an entity type.""" + client.v1.custom_fields.remove_key( + entity="customer", + key="salesforce_id", + ) + print("Custom field key removed") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # add_key() + # set_values() + # list_keys() + # delete_values() + # remove_key() + pass diff --git a/examples/v1/customer_alerts.py b/examples/v1/customer_alerts.py new file mode 100644 index 00000000..cd7f7678 --- /dev/null +++ b/examples/v1/customer_alerts.py @@ -0,0 +1,46 @@ +"""Examples for the Customer Alerts resource. + +Covers retrieving, listing, and resetting customer-specific alerts. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_alerts.py +""" + +from metronome import Metronome + +client = Metronome() + + +def retrieve_alert(): + """Retrieve a specific alert for a customer.""" + response = client.v1.customers.alerts.retrieve( + alert_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(f"Alert: {response.data}") + + +def list_alerts(): + """List all alerts for a customer.""" + for alert in client.v1.customers.alerts.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Alert: {alert}") + + +def reset_alert(): + """Reset an alert for a customer, re-evaluating the alert condition.""" + client.v1.customers.alerts.reset( + alert_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print("Alert reset successfully") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # retrieve_alert() + # list_alerts() + # reset_alert() + pass diff --git a/examples/v1/customer_billing_config.py b/examples/v1/customer_billing_config.py new file mode 100644 index 00000000..cf752b9b --- /dev/null +++ b/examples/v1/customer_billing_config.py @@ -0,0 +1,48 @@ +"""Examples for the Customer Billing Config resource. + +Covers creating, retrieving, and deleting billing provider configurations for customers. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_billing_config.py +""" + +from metronome import Metronome + +client = Metronome() + + +def create_billing_config(): + """Create a billing configuration for a customer.""" + client.v1.customers.billing_config.create( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + billing_provider_type="stripe", + billing_provider_customer_id="cus_abc123", + ) + print("Billing config created") + + +def retrieve_billing_config(): + """Retrieve a customer's billing configuration for a specific provider.""" + response = client.v1.customers.billing_config.retrieve( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + billing_provider_type="stripe", + ) + print(f"Billing config: {response.data}") + + +def delete_billing_config(): + """Delete a customer's billing configuration for a specific provider.""" + client.v1.customers.billing_config.delete( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + billing_provider_type="stripe", + ) + print("Billing config deleted") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_billing_config() + # retrieve_billing_config() + # delete_billing_config() + pass diff --git a/examples/v1/customer_commits.py b/examples/v1/customer_commits.py new file mode 100644 index 00000000..854260ad --- /dev/null +++ b/examples/v1/customer_commits.py @@ -0,0 +1,71 @@ +"""Examples for the Customer Commits resource. + +Covers creating, listing, and updating end dates for customer commits. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_commits.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_commit(): + """Create a prepaid commit for a customer.""" + response = client.v1.customers.commits.create( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + type="PREPAID", + priority=100.0, + product_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + access_schedule={ + "schedule_items": [ + { + "amount": 10000.0, + "starting_at": "2025-01-01T00:00:00Z", + "ending_before": "2026-01-01T00:00:00Z", + } + ], + }, + # invoice_schedule={ # Optional invoice schedule + # "schedule_items": [ + # { + # "timestamp": "2025-01-01T00:00:00Z", + # "amount": 10000.0, + # } + # ], + # }, + # name="Annual Prepaid Commit", + # description="Annual prepaid commitment for API usage", + ) + print(f"Created commit: {response.data}") + + +def list_commits(): + """List all commits for a customer.""" + for commit in client.v1.customers.commits.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Commit: {commit}") + + +def update_end_date(): + """Update the end date of a customer's commit.""" + response = client.v1.customers.commits.update_end_date( + commit_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + # access_ending_before=datetime.fromisoformat("2025-12-31T00:00:00"), + # invoices_ending_before=datetime.fromisoformat("2025-12-31T00:00:00"), + ) + print(f"Updated commit end date: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_commit() + # list_commits() + # update_end_date() + pass diff --git a/examples/v1/customer_credits.py b/examples/v1/customer_credits.py new file mode 100644 index 00000000..62bec50a --- /dev/null +++ b/examples/v1/customer_credits.py @@ -0,0 +1,61 @@ +"""Examples for the Customer Credits resource. + +Covers creating, listing, and updating end dates for customer credits. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_credits.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_credit(): + """Create a credit for a customer.""" + response = client.v1.customers.credits.create( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + priority=100.0, + product_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + access_schedule={ + "schedule_items": [ + { + "amount": 5000.0, + "starting_at": "2025-01-01T00:00:00Z", + "ending_before": "2026-01-01T00:00:00Z", + } + ], + }, + # name="Promotional Credit", + # description="Credit for service disruption", + ) + print(f"Created credit: {response.data}") + + +def list_credits(): + """List all credits for a customer.""" + for credit in client.v1.customers.credits.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Credit: {credit}") + + +def update_end_date(): + """Update the end date of a customer's credit.""" + response = client.v1.customers.credits.update_end_date( + credit_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + access_ending_before=datetime.fromisoformat("2025-12-31T00:00:00"), + ) + print(f"Updated credit end date: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_credit() + # list_credits() + # update_end_date() + pass diff --git a/examples/v1/customer_invoices.py b/examples/v1/customer_invoices.py new file mode 100644 index 00000000..78b70a99 --- /dev/null +++ b/examples/v1/customer_invoices.py @@ -0,0 +1,77 @@ +"""Examples for the Customer Invoices resource. + +Covers retrieving, listing, adding charges, listing breakdowns, and downloading PDFs. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_invoices.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def retrieve_invoice(): + """Retrieve a specific invoice for a customer.""" + response = client.v1.customers.invoices.retrieve( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + invoice_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Invoice: {response.data}") + + +def list_invoices(): + """List all invoices for a customer.""" + for invoice in client.v1.customers.invoices.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Invoice: {invoice.id}") + + +def add_charge(): + """Add a one-time charge to a customer's next invoice.""" + response = client.v1.customers.invoices.add_charge( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + charge_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + customer_plan_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + description="One-time setup fee", + invoice_start_timestamp=datetime.fromisoformat("2025-01-01T00:00:00"), + price=500.00, + quantity=1.0, + ) + print(f"Added charge: {response}") + + +def list_breakdowns(): + """List invoice breakdowns showing line-item details.""" + for breakdown in client.v1.customers.invoices.list_breakdowns( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + starting_on=datetime.fromisoformat("2025-01-01T00:00:00"), + ending_before=datetime.fromisoformat("2025-02-01T00:00:00"), + ): + print(f"Breakdown: {breakdown}") + + +def retrieve_pdf(): + """Download an invoice as a PDF file.""" + response = client.v1.customers.invoices.retrieve_pdf( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + invoice_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + # Write the PDF binary content to a file + with open("invoice.pdf", "wb") as f: + f.write(response.content) + print("Invoice PDF saved to invoice.pdf") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # retrieve_invoice() + # list_invoices() + # add_charge() + # list_breakdowns() + # retrieve_pdf() + pass diff --git a/examples/v1/customer_named_schedules.py b/examples/v1/customer_named_schedules.py new file mode 100644 index 00000000..7bb375fc --- /dev/null +++ b/examples/v1/customer_named_schedules.py @@ -0,0 +1,42 @@ +"""Examples for the Customer Named Schedules resource. + +Covers retrieving and updating named schedules for customers. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_named_schedules.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def retrieve_named_schedule(): + """Retrieve a named schedule for a customer.""" + response = client.v1.customers.named_schedules.retrieve( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + schedule_name="my-schedule", + ) + print(f"Named schedule: {response.data}") + + +def update_named_schedule(): + """Update a named schedule for a customer.""" + client.v1.customers.named_schedules.update( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + schedule_name="my-schedule", + starting_at=datetime.fromisoformat("2025-01-01T00:00:00"), + value={"discount_percentage": 10}, + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), + ) + print("Named schedule updated") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # retrieve_named_schedule() + # update_named_schedule() + pass diff --git a/examples/v1/customer_plans.py b/examples/v1/customer_plans.py new file mode 100644 index 00000000..fedee575 --- /dev/null +++ b/examples/v1/customer_plans.py @@ -0,0 +1,62 @@ +"""Examples for the Customer Plans resource. + +Covers listing, adding, ending plans for customers, and viewing price adjustments. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customer_plans.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def list_plans(): + """List all plans for a customer.""" + for plan in client.v1.customers.plans.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Plan: {plan}") + + +def add_plan(): + """Add a plan to a customer.""" + response = client.v1.customers.plans.add( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + plan_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + starting_on=datetime.fromisoformat("2025-01-01T00:00:00"), + # ending_before=datetime.fromisoformat("2026-01-01T00:00:00"), # Optional end date + ) + print(f"Added plan: {response.data}") + + +def end_plan(): + """End a customer's plan.""" + response = client.v1.customers.plans.end( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + customer_plan_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + # ending_before=datetime.fromisoformat("2025-06-01T00:00:00"), # Specific end date + # void_invoices=True, # Void any pending invoices + ) + print(f"Ended plan: {response.data}") + + +def list_price_adjustments(): + """List price adjustments for a customer's plan.""" + for adjustment in client.v1.customers.plans.list_price_adjustments( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + customer_plan_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ): + print(f"Price adjustment: {adjustment}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_plans() + # add_plan() + # end_plan() + # list_price_adjustments() + pass diff --git a/examples/v1/customers.py b/examples/v1/customers.py new file mode 100644 index 00000000..7a4b079b --- /dev/null +++ b/examples/v1/customers.py @@ -0,0 +1,162 @@ +"""Examples for the Customers resource. + +Covers creating, retrieving, listing, and managing customer configurations. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/customers.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def create_customer(): + """Create a new customer.""" + response = client.v1.customers.create( + name="Acme Corp", + # ingest_aliases=["acme-corp", "acme"], # Aliases for usage events + # custom_fields={"industry": "SaaS", "tier": "enterprise"}, + ) + print(f"Created customer: {response.data}") + + +def create_customer_with_billing(): + """Create a customer with billing provider configuration.""" + response = client.v1.customers.create( + name="Acme Corp", + billing_config={ + "billing_provider_type": "stripe", + "billing_provider_customer_id": "cus_abc123", + "stripe_collection_method": "charge_automatically", + }, + ) + print(f"Created customer: {response.data}") + + +def retrieve_customer(): + """Retrieve a single customer by ID.""" + response = client.v1.customers.retrieve( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(f"Customer: {response.data}") + + +def list_customers(): + """List all customers with auto-pagination.""" + for customer in client.v1.customers.list(): + print(f"Customer: {customer.id} - {customer.name}") + + +def archive_customer(): + """Archive (soft-delete) a customer.""" + response = client.v1.customers.archive( + id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(f"Archived customer: {response.data}") + + +def list_billable_metrics(): + """List billable metrics associated with a customer.""" + for metric in client.v1.customers.list_billable_metrics( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ): + print(f"Metric: {metric}") + + +def list_costs(): + """List costs for a customer over a time period.""" + for cost in client.v1.customers.list_costs( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + starting_on=datetime.fromisoformat("2025-01-01T00:00:00"), + ending_before=datetime.fromisoformat("2025-02-01T00:00:00"), + ): + print(f"Cost: {cost}") + + +def preview_events(): + """Preview how events would be processed for a customer.""" + response = client.v1.customers.preview_events( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + events=[ + { + "event_type": "heartbeat", + "timestamp": "2025-01-01T00:00:00Z", + "transaction_id": "preview-001", + "properties": {"cpu_seconds": 60}, + } + ], + ) + print(response) + + +def retrieve_billing_configurations(): + """Retrieve billing provider configurations for a customer.""" + response = client.v1.customers.retrieve_billing_configurations( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ) + print(response) + + +def set_billing_configurations(): + """Set billing provider configurations for a customer.""" + response = client.v1.customers.set_billing_configurations( + data=[ + { + "customer_id": "13117714-3f05-48e5-a6e9-a66093f13b4d", + "billing_provider": "stripe", + "delivery_method": "direct_to_billing_provider", + # configuration={"stripe_customer_id": "cus_abc123"}, + } + ], + ) + print(response) + + +def set_ingest_aliases(): + """Set ingest aliases that can be used to refer to a customer in usage events.""" + client.v1.customers.set_ingest_aliases( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + ingest_aliases=["acme-corp", "acme"], + ) + print("Ingest aliases set successfully") + + +def set_name(): + """Update the name of a customer.""" + response = client.v1.customers.set_name( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + name="Acme Corporation", + ) + print(f"Updated customer: {response.data}") + + +def update_config(): + """Update customer configuration settings.""" + client.v1.customers.update_config( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + leave_stripe_invoices_in_draft=True, + # salesforce_account_id="001abc123", + ) + print("Customer config updated") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # create_customer() + # create_customer_with_billing() + # retrieve_customer() + # list_customers() + # archive_customer() + # list_billable_metrics() + # list_costs() + # preview_events() + # retrieve_billing_configurations() + # set_billing_configurations() + # set_ingest_aliases() + # set_name() + # update_config() + pass diff --git a/examples/v1/dashboards.py b/examples/v1/dashboards.py new file mode 100644 index 00000000..25966633 --- /dev/null +++ b/examples/v1/dashboards.py @@ -0,0 +1,41 @@ +"""Examples for the Dashboards resource. + +Covers generating embeddable dashboard URLs for customer-facing analytics. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/dashboards.py +""" + +from metronome import Metronome + +client = Metronome() + + +def get_embeddable_url(): + """Generate an embeddable URL for a customer dashboard.""" + response = client.v1.dashboards.get_embeddable_url( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + dashboard="usage", + # dashboard options: "invoices", "usage", "credits", "commits_and_credits" + # color_overrides=[ # Customize dashboard colors + # {"name": "Primary_medium", "value": "#1a73e8"}, + # ], + ) + print(f"Embeddable URL: {response.data}") + + +def get_invoice_dashboard_url(): + """Generate an embeddable URL for the invoices dashboard.""" + response = client.v1.dashboards.get_embeddable_url( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + dashboard="invoices", + ) + print(f"Invoice dashboard URL: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # get_embeddable_url() + # get_invoice_dashboard_url() + pass diff --git a/examples/v1/invoices.py b/examples/v1/invoices.py new file mode 100644 index 00000000..2f5d7971 --- /dev/null +++ b/examples/v1/invoices.py @@ -0,0 +1,35 @@ +"""Examples for the Invoices resource (top-level). + +Covers regenerating and voiding invoices. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/invoices.py +""" + +from metronome import Metronome + +client = Metronome() + + +def regenerate_invoice(): + """Regenerate an invoice (e.g., after updating contract terms).""" + response = client.v1.invoices.regenerate( + id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Regenerated invoice: {response.data}") + + +def void_invoice(): + """Void an invoice.""" + response = client.v1.invoices.void( + id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Voided invoice: {response.data}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # regenerate_invoice() + # void_invoice() + pass diff --git a/examples/v1/payments.py b/examples/v1/payments.py new file mode 100644 index 00000000..2c0d5287 --- /dev/null +++ b/examples/v1/payments.py @@ -0,0 +1,47 @@ +"""Examples for the Payments resource. + +Covers listing, attempting, and canceling payments. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/payments.py +""" + +from metronome import Metronome + +client = Metronome() + + +def list_payments(): + """List payments for a customer's invoice.""" + for payment in client.v1.payments.list( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + invoice_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ): + print(f"Payment: {payment}") + + +def attempt_payment(): + """Attempt to process a payment for a customer's invoice.""" + response = client.v1.payments.attempt( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + invoice_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Payment attempt: {response}") + + +def cancel_payment(): + """Cancel a pending payment for a customer's invoice.""" + response = client.v1.payments.cancel( + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + invoice_id="a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d", + ) + print(f"Payment canceled: {response}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_payments() + # attempt_payment() + # cancel_payment() + pass diff --git a/examples/v1/plans.py b/examples/v1/plans.py new file mode 100644 index 00000000..96ff08b8 --- /dev/null +++ b/examples/v1/plans.py @@ -0,0 +1,51 @@ +"""Examples for the Plans resource. + +Covers listing plans, getting plan details, and listing plan charges and customers. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/plans.py +""" + +from metronome import Metronome + +client = Metronome() + + +def list_plans(): + """List all plans with auto-pagination.""" + for plan in client.v1.plans.list(): + print(f"Plan: {plan}") + + +def get_plan_details(): + """Get detailed information about a specific plan.""" + response = client.v1.plans.get_details( + plan_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + ) + print(f"Plan details: {response.data}") + + +def list_plan_charges(): + """List all charges associated with a plan.""" + for charge in client.v1.plans.list_charges( + plan_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + ): + print(f"Charge: {charge}") + + +def list_plan_customers(): + """List all customers on a specific plan.""" + for customer in client.v1.plans.list_customers( + plan_id="d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc", + ): + print(f"Customer: {customer}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_plans() + # get_plan_details() + # list_plan_charges() + # list_plan_customers() + pass diff --git a/examples/v1/pricing_units.py b/examples/v1/pricing_units.py new file mode 100644 index 00000000..27149818 --- /dev/null +++ b/examples/v1/pricing_units.py @@ -0,0 +1,24 @@ +"""Examples for the Pricing Units resource. + +Covers listing available pricing units (credit types / currencies). + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/pricing_units.py +""" + +from metronome import Metronome + +client = Metronome() + + +def list_pricing_units(): + """List all available pricing units (credit types).""" + for unit in client.v1.pricing_units.list(): + print(f"Pricing unit: {unit}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_pricing_units() + pass diff --git a/examples/v1/services.py b/examples/v1/services.py new file mode 100644 index 00000000..d2a67ecb --- /dev/null +++ b/examples/v1/services.py @@ -0,0 +1,24 @@ +"""Examples for the Services resource. + +Covers listing available services. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/services.py +""" + +from metronome import Metronome + +client = Metronome() + + +def list_services(): + """List all available services.""" + response = client.v1.services.list() + print(f"Services: {response}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # list_services() + pass diff --git a/examples/v1/settings.py b/examples/v1/settings.py new file mode 100644 index 00000000..485130b1 --- /dev/null +++ b/examples/v1/settings.py @@ -0,0 +1,63 @@ +"""Examples for the Settings resource and Billing Providers sub-resource. + +Covers managing Avalara credentials and billing provider configurations. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/settings.py +""" + +from metronome import Metronome + +client = Metronome() + + +# ============================================================================ +# Settings +# ============================================================================ + + +def upsert_avalara_credentials(): + """Create or update Avalara tax provider credentials.""" + response = client.v1.settings.upsert_avalara_credentials( + avalara_environment="production", + avalara_password="your-avalara-password", + avalara_username="your-avalara-username", + delivery_method_ids=["a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"], + ) + print(f"Avalara credentials: {response}") + + +# ============================================================================ +# Billing Providers +# ============================================================================ + + +def create_billing_provider(): + """Set up a billing provider configuration.""" + response = client.v1.settings.billing_providers.create( + billing_provider="stripe", + delivery_method="direct_to_billing_provider", + configuration={ + "stripe_api_key": "sk_live_...", + }, + ) + print(f"Created billing provider: {response}") + + +def list_billing_providers(): + """List all configured billing providers.""" + response = client.v1.settings.billing_providers.list() + print(f"Billing providers: {response}") + + +if __name__ == "__main__": + # Uncomment the example you want to run: + + # Settings + # upsert_avalara_credentials() + + # Billing Providers + # create_billing_provider() + # list_billing_providers() + pass diff --git a/examples/v1/usage.py b/examples/v1/usage.py new file mode 100644 index 00000000..41ed9098 --- /dev/null +++ b/examples/v1/usage.py @@ -0,0 +1,102 @@ +"""Examples for the Usage resource. + +Covers ingesting usage events and querying aggregated usage data. + +Usage: + export METRONOME_BEARER_TOKEN="your-api-token" + python examples/v1/usage.py +""" + +from datetime import datetime + +from metronome import Metronome + +client = Metronome() + + +def ingest_usage(): + """Send usage events to Metronome.""" + client.v1.usage.ingest( + usage=[ + { + "transaction_id": "90e9401f-0f8c-4cd3-9a9f-d6beb56d8d72", + "customer_id": "team@example.com", + "event_type": "heartbeat", + "timestamp": "2025-01-01T00:00:00Z", + "properties": { + "cluster_id": "42", + "cpu_seconds": 60, + "region": "Europe", + }, + } + ], + ) + print("Usage event ingested successfully") + + +def ingest_multiple_events(): + """Send multiple usage events in a single batch.""" + client.v1.usage.ingest( + usage=[ + { + "transaction_id": "event-001", + "customer_id": "team@example.com", + "event_type": "api_call", + "timestamp": "2025-01-01T00:00:00Z", + "properties": {"endpoint": "/v1/data", "response_ms": 120}, + }, + { + "transaction_id": "event-002", + "customer_id": "team@example.com", + "event_type": "api_call", + "timestamp": "2025-01-01T00:01:00Z", + "properties": {"endpoint": "/v1/query", "response_ms": 250}, + }, + ], + ) + print("Batch of usage events ingested successfully") + + +def list_usage(): + """Query aggregated usage data for a time period.""" + for usage in client.v1.usage.list( + starting_on=datetime.fromisoformat("2025-01-01T00:00:00"), + ending_before=datetime.fromisoformat("2025-02-01T00:00:00"), + window_size="DAY", + # customer_ids=["13117714-3f05-48e5-a6e9-a66093f13b4d"], # Filter by customer + ): + print(usage) + + +def list_usage_with_groups(): + """Query usage data grouped by a specific property.""" + for usage in client.v1.usage.list_with_groups( + billable_metric_id="b3f3e5a4-1b2c-4d5e-9f0a-1b2c3d4e5f6a", + customer_id="13117714-3f05-48e5-a6e9-a66093f13b4d", + window_size="DAY", + # starting_on="2025-01-01T00:00:00Z", + # ending_before="2025-02-01T00:00:00Z", + # group_by={"key": "region"}, # Group results by region property + ): + print(usage) + + +def search_events(): + """Search for specific usage events by transaction ID.""" + response = client.v1.usage.search( + transaction_ids=[ + "90e9401f-0f8c-4cd3-9a9f-d6beb56d8d72", + "event-001", + ], + ) + print(response) + + +if __name__ == "__main__": + # Uncomment the example you want to run: + # ingest_usage() + # ingest_multiple_events() + # list_usage() + # list_usage_with_groups() + # search_events() + pass