-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding support for the new Usage Billing APIs (#1397)
- Loading branch information
1 parent
791fc11
commit 8fc7af7
Showing
62 changed files
with
2,640 additions
and
224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
## Running an example | ||
|
||
From the examples folder, run: | ||
`PYTHONPATH=../ python your_example.py` | ||
|
||
## Adding a new example | ||
|
||
1. Clone new_example.py | ||
2. Implement your example | ||
3. Run it (as per above) | ||
4. 👍 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from datetime import datetime, timezone | ||
import stripe | ||
|
||
# Global variable for the meter event session | ||
meter_event_session = None | ||
|
||
|
||
def refresh_meter_event_session(api_key): | ||
global meter_event_session | ||
|
||
# Check if the session is None or expired | ||
if meter_event_session is None or datetime.fromisoformat( | ||
meter_event_session["expires_at"] | ||
) <= datetime.now(timezone.utc): | ||
# Create a new meter event session if the existing session has expired | ||
client = stripe.StripeClient(api_key) | ||
meter_event_session = client.v2.billing.meter_event_session.create() | ||
|
||
|
||
def send_meter_event(meter_event, api_key): | ||
# Refresh the meter event session if necessary | ||
refresh_meter_event_session(api_key) | ||
if not meter_event_session: | ||
raise RuntimeError("Unable to refresh meter event session") | ||
|
||
# Create a meter event with the current session's authentication token | ||
client = stripe.StripeClient(meter_event_session["authentication_token"]) | ||
client.v2.billing.meter_event_stream.create( | ||
params={"events": [meter_event]} | ||
) | ||
|
||
|
||
# Set your API key here | ||
api_key = "{{API_KEY}}" | ||
customer_id = "{{CUSTOMER_ID}}" | ||
|
||
# Send meter event | ||
send_meter_event( | ||
{ | ||
"event_name": "alpaca_ai_tokens", | ||
"payload": {"stripe_customer_id": customer_id, "value": "25"}, | ||
}, | ||
api_key, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import stripe | ||
|
||
# Set your API key here | ||
api_key = "{{API_KEY}}" | ||
|
||
print("Hello world") | ||
# client = stripe.StripeClient(api_key) | ||
# client.v2.... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import os | ||
from stripe import StripeClient | ||
from stripe.events import V1BillingMeterErrorReportTriggeredEvent | ||
|
||
from flask import Flask, request, jsonify | ||
|
||
app = Flask(__name__) | ||
api_key = os.environ.get("STRIPE_API_KEY") | ||
webhook_secret = os.environ.get("WEBHOOK_SECRET") | ||
|
||
client = StripeClient(api_key) | ||
|
||
|
||
@app.route("/webhook", methods=["POST"]) | ||
def webhook(): | ||
webhook_body = request.data | ||
sig_header = request.headers.get("Stripe-Signature") | ||
|
||
try: | ||
thin_event = client.parse_thin_event( | ||
webhook_body, sig_header, webhook_secret | ||
) | ||
|
||
# Fetch the event data to understand the failure | ||
event = client.v2.core.events.retrieve(thin_event.id) | ||
if isinstance(event, V1BillingMeterErrorReportTriggeredEvent): | ||
# CHECK: fetch_object is present and callable, returning a strongly-typed object (without casting) | ||
meter = event.fetch_related_object() | ||
meter_id = meter.id | ||
|
||
# Record the failures and alert your team | ||
# Add your logic here | ||
|
||
return jsonify(success=True), 200 | ||
except Exception as e: | ||
return jsonify(error=str(e)), 400 | ||
|
||
|
||
if __name__ == "__main__": | ||
app.run(port=4242) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
from typing_extensions import Literal | ||
|
||
|
||
ApiMode = Literal["V1"] | ||
ApiMode = Literal["V1", "V2"] |
Oops, something went wrong.