### Install Pingen2 SDK for Python Source: https://github.com/pingencom/pingen2-sdk-python/blob/main/README.md Installs or upgrades the Pingen2 SDK package using pip. This command is used by developers who want to integrate the SDK into their Python projects. ```sh pip install --upgrade pingen2sdk ``` -------------------------------- ### Pingen2 SDK Python Usage Example (Client Credentials Grant) Source: https://github.com/pingencom/pingen2-sdk-python/blob/main/README.md Demonstrates how to use the Pingen2 SDK in Python with the client credentials grant type. It shows setting up credentials, obtaining an access token, retrieving organization data, and uploading/creating a letter. This example requires valid client ID, client secret, and a local 'letter.pdf' file. ```python import pingen2sdk pingen2sdk.client_id = "YOUR_CLIENT_ID" pingen2sdk.client_secret = "YOU_SECRET" resp = pingen2sdk.OAuth.get_token( use_staging=True, grant_type="client_credentials", scope="letter batch webhook organisation_read", ) access_token = resp["access_token"] organisationList = pingen2sdk.Organisations(access_token, True).get_collection() organisation_id = organisationList.data["data"][0]["id"] LettersEndpoint = pingen2sdk.Letters(organisation_id, access_token, True) response = LettersEndpoint.upload_and_create( "./letter.pdf", "sdk.pdf", "left", False, "fast", "simplex", "color", ) letter_id = response.data["data"]["id"] ``` -------------------------------- ### Verify and Process Incoming Webhooks with Pingen2 SDK and Flask Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt This example demonstrates how to validate incoming webhook signatures and process webhook events securely using the Pingen2 SDK and Flask. It includes setting up a Flask app, defining a webhook endpoint, verifying the signature, and handling different event types like 'letter.sent', 'letter.delivered', and 'letter.undeliverable'. Requires a signing key. ```python import pingen2sdk from flask import Flask, request app = Flask(__name__) @app.route("/webhooks/pingen", methods=["POST"]) def handle_webhook(): payload = request.data headers = dict(request.headers) signing_key = "your_secret_signing_key_min_32_chars" try: # Verify signature and construct event event = pingen2sdk.IncomingWebhook.construct_event( payload=payload, header=headers, secret=signing_key ) # Access event data event_type = event.data["data"]["attributes"]["event"] resource_id = event.data["data"]["relationships"]["letter"]["data"]["id"] if event_type == "letter.sent": print(f"Letter {resource_id} was sent!") elif event_type == "letter.delivered": print(f"Letter {resource_id} was delivered!") elif event_type == "letter.undeliverable": print(f"Letter {resource_id} is undeliverable!") return "OK", 200 except pingen2sdk.error.WebhookSignatureException as e: print(f"Invalid webhook signature: {e}") return "Invalid signature", 401 ``` -------------------------------- ### Get Letter Details and Collection with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Retrieve a list of letters with optional filtering and pagination, get details for a specific letter, or download its PDF file. Requires an organisation ID, access token, and the pingen2sdk library. ```python import pingen2sdk letters = pingen2sdk.Letters(organisation_id, access_token, use_staging=False) # Get all letters with pagination collection = letters.get_collection( params={ "page[number]": 1, "page[size]": 20, "filter[status]": "sent" } ) for letter in collection.data["data"]: print(f"Letter {letter['id']}: {letter['attributes']['status']}") # Get specific letter details details = letters.get_details("letter-uuid-456") print(f"Address: {details.data['data']['attributes']['address']}") print(f"Pages: {details.data['data']['attributes']['page_count']}") # Download the letter PDF file file_content = letters.get_file("letter-uuid-456") with open("downloaded_letter.pdf", "wb") as f: f.write(file_content.encode()) ``` -------------------------------- ### Get Letter Events with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Track the lifecycle events of letters, including sent, delivered, undeliverable, and issue events. This requires the pingen2sdk library, organisation ID, and access token. ```python import pingen2sdk letter_events = pingen2sdk.LetterEvents(organisation_id, access_token, use_staging=False) # Get all events for a specific letter events = letter_events.get_collection("letter-uuid-456") for event in events.data["data"]: print(f"Event: {event['attributes']['event']} at {event['attributes']['created_at']}") # Get all letters with delivery issues across the organisation issues = letter_events.get_issue_collection() for issue in issues.data["data"]: print(f"Issue on letter {issue['relationships']['letter']['data']['id']}") # Get all undeliverable letters undeliverable = letter_events.get_undeliverable_collection() # Get all delivered letters delivered = letter_events.get_delivered_collection() # Get all sent letters sent = letter_events.get_sent_collection() ``` -------------------------------- ### Create and Upload Letters with Pingen SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Demonstrates the workflow for uploading a PDF file and creating a letter resource in a single call. Supports configuration of print modes, delivery products, and metadata. ```python import pingen2sdk access_token = "your_access_token" organisation_id = "org-uuid-123" # Initialize Letters endpoint letters = pingen2sdk.Letters(organisation_id, access_token, use_staging=False) # Upload a PDF and create a letter in one call response = letters.upload_and_create( path_to_file="./invoice.pdf", file_original_name="invoice.pdf", address_position="left", # "left" or "right" auto_send=False, # Set True to send immediately delivery_product="fast", # "fast", "priority", "economy" print_mode="simplex", # "simplex" or "duplex" print_spectrum="color", # "color" or "grayscale" sender_address="Company Name\nStreet 1\n8000 Zurich", meta_data={"invoice_id": "INV-001", "customer": "John Doe"} ) letter_id = response.data["data"]["id"] print(f"Letter created: {letter_id}") ``` -------------------------------- ### Create and Manage Webhooks with Pingen2 SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt This snippet illustrates how to configure webhooks for real-time notifications about letter and batch events using the Pingen2 SDK. It covers creating a new webhook with event category, URL, and signing key, retrieving all webhooks, fetching specific details, and deleting a webhook. Requires an organisation ID and access token. ```python import pingen2sdk webhooks = pingen2sdk.Webhooks(organisation_id, access_token, use_staging=False) # Create a new webhook response = webhooks.create( event_category="letter", # "letter" or "batch" url="https://your-app.com/webhooks/pingen", signing_key="your_secret_signing_key_min_32_chars" ) webhook_id = response.data["data"]["id"] print(f"Webhook created: {webhook_id}") # Get all webhooks collection = webhooks.get_collection() for webhook in collection.data["data"]: print(f"Webhook {webhook['id']}: {webhook['attributes']['url']}") # Get specific webhook details details = webhooks.get_details(webhook_id) # Delete a webhook webhooks.delete(webhook_id) ``` -------------------------------- ### Upload and Create Batch with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Upload a PDF or ZIP file containing multiple letters to create a batch for mass mailings. This function requires the pingen2sdk library, organisation ID, and access token. ```python import pingen2sdk batches = pingen2sdk.Batches(organisation_id, access_token, use_staging=False) # Upload and create a batch from a merged PDF or ZIP file response = batches.upload_and_create( path_to_file="./invoices_batch.pdf", name="Monthly Invoices March 2024", icon="document", # Options: campaign, megaphone, rocket, bell, document, etc. file_original_name="invoices_batch.pdf", address_position="left", grouping_type="merge", # "zip" for ZIP files, "merge" for merged PDFs grouping_options_split_type="page", # "file", "page", "custom", "qr_invoice" grouping_options_split_size=2 # 2 pages per letter ) batch_id = response.data["data"]["id"] print(f"Batch created: {batch_id}") ``` -------------------------------- ### Manage eBills with Pingen2 SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt This code demonstrates how to create and manage Swiss eBill deliveries using the Pingen2 SDK. It includes uploading a file, creating an eBill with recipient details, retrieving all eBills, and fetching specific eBill details. Requires an organisation ID and access token. ```python import pingen2sdk ebills = pingen2sdk.Ebills(organisation_id, access_token, use_staging=False) # Upload and create an eBill response = ebills.upload_and_create( path_to_file="./invoice.pdf", file_original_name="invoice.pdf", auto_send=True, meta_data={"ebill_account_id": "41100000000000001", "amount": "150.00"} ) ebill_id = response.data["data"]["id"] # Get all eBills collection = ebills.get_collection() for ebill in collection.data["data"]: print(f"eBill {ebill['id']}: {ebill['attributes']['status']}") # Get specific eBill details details = ebills.get_details(ebill_id) ``` -------------------------------- ### Handle Pingen SDK Authentication Errors in Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Illustrates how to catch `AuthenticationError` exceptions from the Pingen SDK for Python, which occur when authentication with the Pingen API fails. This is essential for diagnosing and resolving issues related to API credentials or token validity. ```python import pingen2sdk try: # ... (code that might cause authentication error) ... except pingen2sdk.error.AuthenticationError as e: print(f"Authentication failed: {e}") ``` -------------------------------- ### Send Emails with Pingen2 SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt This snippet shows how to send digital copies of documents via email using the Pingen2 SDK. It covers uploading a file, creating an email delivery with metadata, retrieving all email deliveries, and fetching specific email details. Requires an organisation ID and access token. ```python import pingen2sdk emails = pingen2sdk.Emails(organisation_id, access_token, use_staging=False) # Upload and create an email delivery response = emails.upload_and_create( path_to_file="./document.pdf", file_original_name="document.pdf", auto_send=True, meta_data={"recipient": "customer@example.com", "subject": "Your Invoice"} ) email_id = response.data["data"]["id"] # Get all email deliveries collection = emails.get_collection() for email in collection.data["data"]: print(f"Email {email['id']}: {email['attributes']['status']}") # Get specific email details details = emails.get_details(email_id) print(f"Delivered: {details.data['data']['attributes']['delivered_at']}") ``` -------------------------------- ### Run Pingen2 SDK Tests with Tox Source: https://github.com/pingencom/pingen2-sdk-python/blob/main/README.md Executes tests for the Pingen2 SDK using Tox. This command is used by developers to ensure code quality and compatibility across different Python versions. It includes commands for running tests against a specific Python version, linting, and formatting. ```sh tox -e py312 tox -e lint tox -e fmt ``` -------------------------------- ### Authenticate with Pingen API using OAuth Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Handles authentication using client credentials flow to obtain access tokens. It also provides helper methods for authorization code flow URLs and parsing implicit flow tokens. ```python import pingen2sdk # Set credentials globally pingen2sdk.client_id = "YOUR_CLIENT_ID" pingen2sdk.client_secret = "YOUR_CLIENT_SECRET" # Get access token using client credentials grant resp = pingen2sdk.OAuth.get_token( use_staging=False, # Set True for staging environment grant_type="client_credentials", scope="letter batch webhook organisation_read" ) access_token = resp["access_token"] expires_in = resp["expires_in"] # For authorization code flow, generate the authorize URL auth_url = pingen2sdk.OAuth.authorize_url( use_staging=False, redirect_uri="https://your-app.com/callback", scope="letter batch webhook" ) # Parse token from implicit flow fragment fragment = "access_token=abc123&expires_in=3600" token_data = pingen2sdk.OAuth.get_token_from_implicit(fragment) ``` -------------------------------- ### Manage Organisations via Pingen SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Retrieves organisation information required for subsequent API operations. Includes methods to list all organisations and fetch details for a specific organisation ID. ```python import pingen2sdk access_token = "your_access_token" # Initialize Organisations endpoint organisations = pingen2sdk.Organisations(access_token, use_staging=False) # Get all organisations org_list = organisations.get_collection() print(org_list.data) organisation_id = org_list.data["data"][0]["id"] # Get specific organisation details org_details = organisations.get_details(organisation_id) print(org_details.data["data"]["attributes"]["name"]) ``` -------------------------------- ### Retrieve User and Association Details with Pingen2 SDK Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt This snippet shows how to retrieve information about the authenticated user and their organization memberships using the Pingen2 SDK. It covers fetching current user details (email, name) and listing user's organization associations, including organisation ID and role. Requires an access token. ```python import pingen2sdk # Get current user details users = pingen2sdk.Users(access_token, use_staging=False) user_details = users.get_details() print(f"User: {user_details.data['data']['attributes']['email']}") print(f"Name: {user_details.data['data']['attributes']['first_name']} {user_details.data['data']['attributes']['last_name']}") # Get user's organisation associations associations = pingen2sdk.UserAssociations(access_token, use_staging=False) assoc_list = associations.get_collection() for assoc in assoc_list.data["data"]: print(f"Organisation: {assoc['relationships']['organisation']['data']['id']}") print(f"Role: {assoc['attributes']['role']}") ``` -------------------------------- ### Monitor Batch Events with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Monitor processing and delivery events for batches. This function requires the pingen2sdk library, organisation ID, and access token. ```python import pingen2sdk batch_events = pingen2sdk.BatchEvents(organisation_id, access_token, use_staging=False) # Get all events for a batch events = batch_events.get_collection("batch-uuid-789") for event in events.data["data"]: print(f"Batch event: {event['attributes']['event']}") print(f" Timestamp: {event['attributes']['created_at']}") ``` -------------------------------- ### Handle Pingen SDK API Errors in Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Demonstrates how to catch `PingenError` exceptions raised by the Pingen SDK for Python when API requests fail. It shows how to access the status code, request ID, and the error response body for detailed debugging. This is crucial for understanding and responding to issues during API interactions. ```python import pingen2sdk letters = pingen2sdk.Letters(organisation_id, access_token, use_staging=False) try: response = letters.get_details("invalid-letter-id") except pingen2sdk.PingenError as e: print(f"API Error: {e.status_code}") print(f"Request ID: {e.request_id}") print(f"Error body: {e.json_body}") # { "errors": [{"status": "404", "title": "Not Found", "detail": "Letter not found"}] } ``` -------------------------------- ### Manage Batch Lifecycle and Statistics with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Send all letters in a batch, retrieve batch statistics, cancel pending letters, delete a batch, or edit paper types for all letters within a batch. Requires the pingen2sdk library, organisation ID, and access token. ```python import pingen2sdk batches = pingen2sdk.Batches(organisation_id, access_token, use_staging=False) batch_id = "batch-uuid-789" # Send all letters in a batch send_response = batches.send( batch_id=batch_id, delivery_product={"CH": "fast", "DE": "priority"}, # Per-country settings print_mode="duplex", print_spectrum="color" ) # Get batch statistics (letter count, status breakdown) stats = batches.get_statistics(batch_id) print(f"Total letters: {stats.data['data']['attributes']['total']}") print(f"Sent: {stats.data['data']['attributes']['sent']}") print(f"Pending: {stats.data['data']['attributes']['pending']}") # Cancel all pending letters in a batch batches.cancel(batch_id) # Delete a batch and all its letters batches.delete(batch_id) # Edit paper types for all letters in a batch batches.edit(batch_id, paper_types=["normal", "normal"]) ``` -------------------------------- ### Send, Cancel, and Delete Letters Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Provides methods to manage the lifecycle of a created letter, including sending for delivery, cancelling pending letters, or deleting drafts. ```python import pingen2sdk letters = pingen2sdk.Letters(organisation_id, access_token, use_staging=False) letter_id = "letter-uuid-456" # Send a letter that was created with auto_send=False send_response = letters.send( letter_id=letter_id, delivery_product="fast", print_mode="duplex", print_spectrum="grayscale" ) # Cancel a letter that hasn't been printed yet cancel_response = letters.cancel(letter_id) # Delete a draft letter delete_response = letters.delete(letter_id) ``` -------------------------------- ### Calculate Letter Price and Edit with Python Source: https://context7.com/pingencom/pingen2-sdk-python/llms.txt Calculate the printing cost for a letter before sending and modify letter attributes such as paper types. This function requires the pingen2sdk library, organisation ID, and access token. ```python import pingen2sdk letters = pingen2sdk.Letters(organisation_id, access_token, use_staging=False) # Calculate price for a letter price_response = letters.calculate_price( country="CH", paper_types=["normal", "normal"], # One entry per page print_mode="duplex", print_spectrum="color", delivery_product="fast" ) print(f"Price: {price_response.data['data']['attributes']['price']} CHF") # Edit paper types for a letter edit_response = letters.edit( letter_id="letter-uuid-456", paper_types=["normal", "qr"] # First page normal, second page QR invoice paper ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.