Skip to content

Latest commit

 

History

History
359 lines (259 loc) · 7.45 KB

File metadata and controls

359 lines (259 loc) · 7.45 KB

Python Integration

Complete setup for Django, Flask, FastAPI, and standalone Python applications.

Package Installation

pip install honeybadger sentry-sdk devcycle-python-server-sdk appwrite

Basic Setup

services.py

import os
import sentry_sdk
from honeybadger import honeybadger
from devcycle_python_sdk import DevCycleLocalClient, DevCycleLocalOptions
from appwrite.client import Client
from appwrite.services.databases import Databases
from appwrite.services.users import Users


def init_services():
    """Initialize all monitoring and backend services."""

    # Sentry
    sentry_sdk.init(
        dsn=os.environ.get("SENTRY_DSN"),
        environment=os.environ.get("ENVIRONMENT", "development"),
        traces_sample_rate=0.1,
    )

    # Honeybadger
    honeybadger.configure(
        api_key=os.environ.get("HONEYBADGER_API_KEY"),
        environment=os.environ.get("ENVIRONMENT", "development"),
    )

    # DevCycle
    devcycle_options = DevCycleLocalOptions()
    devcycle = DevCycleLocalClient(
        os.environ.get("DEVCYCLE_SERVER_SDK_KEY"),
        devcycle_options
    )

    # Appwrite
    appwrite = Client()
    appwrite.set_endpoint(os.environ.get("APPWRITE_ENDPOINT"))
    appwrite.set_project(os.environ.get("APPWRITE_PROJECT_ID"))
    appwrite.set_key(os.environ.get("APPWRITE_API_KEY"))

    return {
        "devcycle": devcycle,
        "appwrite": appwrite,
        "databases": Databases(appwrite),
        "users": Users(appwrite),
    }

Django Integration

settings.py

import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

sentry_sdk.init(
    dsn=os.environ.get("SENTRY_DSN"),
    integrations=[DjangoIntegration()],
    traces_sample_rate=0.1,
    send_default_pii=True,
)

middleware.py

from honeybadger import honeybadger


class HoneybadgerMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        honeybadger.configure(api_key=os.environ.get("HONEYBADGER_API_KEY"))

    def __call__(self, request):
        return self.get_response(request)

    def process_exception(self, request, exception):
        honeybadger.notify(exception, context={
            "user_id": getattr(request.user, "id", None),
            "path": request.path,
        })

Flask Integration

app.py

from flask import Flask
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from honeybadger.contrib.flask import FlaskHoneybadger

app = Flask(__name__)

# Sentry
sentry_sdk.init(
    dsn=os.environ.get("SENTRY_DSN"),
    integrations=[FlaskIntegration()],
    traces_sample_rate=0.1,
)

# Honeybadger
app.config["HONEYBADGER_API_KEY"] = os.environ.get("HONEYBADGER_API_KEY")
FlaskHoneybadger(app)


@app.route("/")
def hello():
    return "Hello World"

FastAPI Integration

main.py

from fastapi import FastAPI, Request
import sentry_sdk
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
from honeybadger import honeybadger

sentry_sdk.init(
    dsn=os.environ.get("SENTRY_DSN"),
    traces_sample_rate=0.1,
)

honeybadger.configure(api_key=os.environ.get("HONEYBADGER_API_KEY"))

app = FastAPI()
app = SentryAsgiMiddleware(app)


@app.exception_handler(Exception)
async def exception_handler(request: Request, exc: Exception):
    honeybadger.notify(exc, context={"path": request.url.path})
    raise exc


@app.get("/")
async def root():
    return {"message": "Hello World"}

Feature Flags

features.py

from devcycle_python_sdk import DevCycleLocalClient, DevCycleLocalOptions

_client = None


def get_devcycle_client():
    global _client
    if _client is None:
        options = DevCycleLocalOptions()
        _client = DevCycleLocalClient(
            os.environ.get("DEVCYCLE_SERVER_SDK_KEY"),
            options
        )
    return _client


def get_feature_flag(user_id: str, flag_key: str, default=False):
    """Get a feature flag value for a user."""
    client = get_devcycle_client()
    user = {"user_id": user_id}
    return client.variable_value(user, flag_key, default)


# Usage
if get_feature_flag(user.id, "new-checkout", default=False):
    return new_checkout_flow()
else:
    return legacy_checkout_flow()

Error Handling

errors.py

import sentry_sdk
from honeybadger import honeybadger
import logging

logger = logging.getLogger(__name__)


def capture_error(error: Exception, context: dict = None):
    """Report error to monitoring services."""
    context = context or {}

    # Log locally
    logger.exception(error)

    # Report to Sentry
    with sentry_sdk.push_scope() as scope:
        for key, value in context.items():
            scope.set_extra(key, value)
        sentry_sdk.capture_exception(error)

    # Report critical errors to Honeybadger
    if getattr(error, "critical", False):
        honeybadger.notify(error, context=context)


# Usage
try:
    risky_operation()
except Exception as e:
    capture_error(e, {"user_id": user.id, "action": "risky_operation"})
    raise

Appwrite Usage

database.py

from appwrite.client import Client
from appwrite.services.databases import Databases
from appwrite.query import Query
from appwrite.id import ID


def get_appwrite_client():
    client = Client()
    client.set_endpoint(os.environ.get("APPWRITE_ENDPOINT"))
    client.set_project(os.environ.get("APPWRITE_PROJECT_ID"))
    client.set_key(os.environ.get("APPWRITE_API_KEY"))
    return client


def get_databases():
    return Databases(get_appwrite_client())


# Create document
def create_user(name: str, email: str):
    db = get_databases()
    return db.create_document(
        database_id="main",
        collection_id="users",
        document_id=ID.unique(),
        data={"name": name, "email": email}
    )


# Query documents
def get_users_by_name(name: str):
    db = get_databases()
    return db.list_documents(
        database_id="main",
        collection_id="users",
        queries=[Query.equal("name", name)]
    )

Environment Variables

# .env

# Sentry
SENTRY_DSN=https://key@sentry.io/project

# Honeybadger
HONEYBADGER_API_KEY=your_key

# DevCycle
DEVCYCLE_SERVER_SDK_KEY=server_key

# Appwrite
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
APPWRITE_PROJECT_ID=your_project
APPWRITE_API_KEY=your_api_key

# Environment
ENVIRONMENT=development

Testing

test_services.py

import pytest
from unittest.mock import Mock, patch


@pytest.fixture
def mock_devcycle():
    with patch("myapp.features.DevCycleLocalClient") as mock:
        client = Mock()
        client.variable_value.return_value = True
        mock.return_value = client
        yield client


def test_feature_flag(mock_devcycle):
    from myapp.features import get_feature_flag

    result = get_feature_flag("user-123", "new-feature")

    assert result is True
    mock_devcycle.variable_value.assert_called_once()

Web Scraping with Zyte

scraper.py

from zyte_api import ZyteAPI
import os


def scrape_page(url: str) -> dict:
    client = ZyteAPI(api_key=os.environ.get("ZYTE_API_KEY"))

    response = client.get({
        "url": url,
        "browserHtml": True,
    })

    return {
        "html": response.get("browserHtml"),
        "status": response.get("statusCode"),
    }


def scrape_product(url: str) -> dict:
    client = ZyteAPI(api_key=os.environ.get("ZYTE_API_KEY"))

    response = client.get({
        "url": url,
        "product": True,
    })

    return response.get("product", {})