Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for APIs in the new API version 2024-09-30.acacia #1404

Merged
merged 6 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion OPENAPI_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1267
v1268
11 changes: 11 additions & 0 deletions examples/README.md
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. 👍
44 changes: 44 additions & 0 deletions examples/meter_event_stream.py
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,
)
8 changes: 8 additions & 0 deletions examples/new_example.py
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....
40 changes: 40 additions & 0 deletions examples/stripe_webhook_handler.py
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):
meter = event.fetch_related_object()
meter_id = meter.id
print("Success! " + str(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)
55 changes: 52 additions & 3 deletions stripe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Optional
import sys as _sys
import os
import warnings

# Stripe Python bindings
# API docs at http://stripe.com/docs/api
Expand All @@ -25,29 +26,70 @@
DEFAULT_API_BASE: str = "https://api.stripe.com"
DEFAULT_CONNECT_API_BASE: str = "https://connect.stripe.com"
DEFAULT_UPLOAD_API_BASE: str = "https://files.stripe.com"
DEFAULT_METER_EVENTS_API_BASE: str = "https://meter-events.stripe.com"


api_key: Optional[str] = None
client_id: Optional[str] = None
api_base: str = DEFAULT_API_BASE
connect_api_base: str = DEFAULT_CONNECT_API_BASE
upload_api_base: str = DEFAULT_UPLOAD_API_BASE
meter_events_api_base: str = DEFAULT_METER_EVENTS_API_BASE
api_version: str = _ApiVersion.CURRENT
verify_ssl_certs: bool = True
proxy: Optional[str] = None
default_http_client: Optional["HTTPClient"] = None
app_info: Optional[AppInfo] = None
enable_telemetry: bool = True
max_network_retries: int = 0
max_network_retries: int = 2
ca_bundle_path: str = os.path.join(
os.path.dirname(__file__), "data", "ca-certificates.crt"
)

# Lazily initialized stripe.default_http_client
default_http_client = None
_default_proxy = None


def ensure_default_http_client():
if default_http_client:
_warn_if_mismatched_proxy()
return
_init_default_http_client()


def _init_default_http_client():
global _default_proxy
global default_http_client

# If the stripe.default_http_client has not been set by the user
# yet, we'll set it here. This way, we aren't creating a new
# HttpClient for every request.
default_http_client = new_default_http_client(
verify_ssl_certs=verify_ssl_certs, proxy=proxy
)
_default_proxy = proxy


def _warn_if_mismatched_proxy():
global _default_proxy
from stripe import proxy

if proxy != _default_proxy:
warnings.warn(
"stripe.proxy was updated after sending a "
"request - this is a no-op. To use a different proxy, "
"set stripe.default_http_client to a new client "
"configured with the proxy."
)


# Set to either 'debug' or 'info', controls console logging
log: Optional[Literal["debug", "info"]] = None

# OAuth
from stripe._oauth import OAuth as OAuth
from stripe._oauth_service import OAuthService as OAuthService

# Webhooks
from stripe._webhook import (
Expand All @@ -58,6 +100,8 @@
# StripeClient
from stripe._stripe_client import StripeClient as StripeClient # noqa

from stripe.v2._event import ThinEvent as ThinEvent # noqa


# Sets some basic information about the running application that's sent along
# with API requests. Useful for plugin authors to identify their plugin when
Expand Down Expand Up @@ -180,8 +224,6 @@ def set_app_info(
from stripe import _request_metrics as request_metrics
from stripe._file import File as FileUpload

import warnings

# Python 3.7+ supports module level __getattr__ that allows us to lazy load deprecated modules
# this matters because if we pre-load all modules from api_resources while suppressing warning
# users will never see those warnings
Expand Down Expand Up @@ -218,6 +260,7 @@ def __getattr__(name):
checkout as checkout,
climate as climate,
entitlements as entitlements,
events as events,
financial_connections as financial_connections,
forwarding as forwarding,
identity as identity,
Expand All @@ -229,6 +272,7 @@ def __getattr__(name):
terminal as terminal,
test_helpers as test_helpers,
treasury as treasury,
v2 as v2,
)
from stripe._account import Account as Account
from stripe._account_capability_service import (
Expand Down Expand Up @@ -355,6 +399,9 @@ def __getattr__(name):
from stripe._ephemeral_key_service import (
EphemeralKeyService as EphemeralKeyService,
)
from stripe._error import (
TemporarySessionExpiredError as TemporarySessionExpiredError,
)
from stripe._event import Event as Event
from stripe._event_service import EventService as EventService
from stripe._exchange_rate import ExchangeRate as ExchangeRate
Expand Down Expand Up @@ -397,6 +444,7 @@ def __getattr__(name):
from stripe._login_link import LoginLink as LoginLink
from stripe._mandate import Mandate as Mandate
from stripe._mandate_service import MandateService as MandateService
from stripe._margin import Margin as Margin
from stripe._payment_intent import PaymentIntent as PaymentIntent
from stripe._payment_intent_service import (
PaymentIntentService as PaymentIntentService,
Expand Down Expand Up @@ -529,6 +577,7 @@ def __getattr__(name):
from stripe._usage_record_summary import (
UsageRecordSummary as UsageRecordSummary,
)
from stripe._v2_services import V2Services as V2Services
from stripe._webhook_endpoint import WebhookEndpoint as WebhookEndpoint
from stripe._webhook_endpoint_service import (
WebhookEndpointService as WebhookEndpointService,
Expand Down
2 changes: 1 addition & 1 deletion stripe/_api_mode.py
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"]
Loading
Loading