Skip to content

heroku/heroku-applink-python

Python SDK for Heroku AppLink

This library provides basic functionality for building Python apps that use Heroku AppLink to secure communication and credential sharing with a Salesforce org.

Though the interaction with AppLink is simple and easy to hand code, using the SDK will quickstart your project experience.

Use of this project with Salesforce is subject to the TERMS_OF_USE.md document.

Documentation for the SDK is available and is generated from the source code.

Generate Documentation

Install the doc dependency group.

$ uv sync --group docs

Generate the documentation.

$ uv run pdoc3 --template-dir templates/python heroku_applink -o docs --force

Development

Setting Up the Development Environment

  1. Clone the repository:

    git clone https://github.com/heroku/heroku-applink-python.git
    cd heroku-applink-python
  2. Install Dependencies:

    Install the uv package manager:

    curl -LsSf https://astral.sh/uv/install.sh | sh

    Sync all dependencies:

    uv sync --all-extras
  3. Sync Development Dependencies:

    uv sync --all-extras --dev

Running Tests

  1. Run the full test suite:

    # Run all tests
    uv run pytest
    
    # Run all tests with coverage
    uv run pytest --cov=heroku_applink.data_api --cov-report=term-missing -v
  2. Run a single test:

    # Run a specific test file
    uv run pytest <path_to_test_file>/test_specific_file.py
    
    # Run a specific test file with coverage
    uv run pytest tests/data_api/test_data_api_record.py::test_some_specific_case \
        --cov=heroku_applink.data_api
  3. Run tests with a specific Python version:

    pyenv shell 3.12.2  # Or any installed version
    uv venv
    source .venv/bin/activate
    uv sync --all-extras --dev
    uv run pytest
  4. Run tests across multiple Python versions with Tox:

    uv sync --all-extras --dev
    uv run tox

Linting and Code Quality

  1. Run the Ruff linter:

    # Check the code for issues
    uv run ruff check .
    
    # Automatically fix issues
    uv run ruff check . --fix
    
    # Check a specific directory (e.g., heroku_applink)
    uv run ruff check heroku_applink/
    
    # Format the codebase
    uv run ruff format .

Usage Examples

For more detailed information about the SDK's capabilities, please refer to the full documentation.

Basic Setup

Install the package.

$ uv pip install heroku_applink

Add the middleware to your web framework.

ASGI

If you are using an ASGI framework (like FastAPI), you can use the IntegrationAsgiMiddleware to automatically populate the client-context in the request scope.

# FastAPI example
import asyncio
import heroku_applink as sdk
from fastapi import FastAPI

config = sdk.Config(request_timeout=5)

app = FastAPI()
app.add_middleware(sdk.IntegrationAsgiMiddleware, config=config)


@app.get("/")
def get_root():
    return {"root": "page"}


@app.get("/accounts")
def get_accounts():
    data_api = sdk.client_context.get().data_api
    asyncio.run(query_accounts(data_api))
    return {"Some": "Accounts"}


async def query_accounts(data_api):
    query = "SELECT Id, Name FROM Account"
    result = await data_api.query(query)
    for record in result.records:
        print("===== account record", record)

WSGI

If you are using a WSGI framework (like Flask), you can use the IntegrationWsgiMiddleware to automatically populate the client-context in the request environment.

from flask import Flask, jsonify, request

import heroku_applink as sdk

config = sdk.Config(request_timeout=5)
app = Flask(__name__)
app.wsgi_app = sdk.IntegrationWsgiMiddleware(app.wsgi_app, config=config)


@app.route("/")
def index():
    return jsonify({"message": "Hello, World!"})


@app.route("/accounts")
def get_accounts():
    data_api = sdk.client_context.get().data_api
    query = "SELECT Id, Name FROM Account"
    result = data_api.query(query)

    return jsonify({"accounts": [record.get("Name") for record in result.records]})

Directly from the x-client-context header

If you are not using a framework, you can manually extract the x-client-context header and use the DataAPI class to query the Salesforce org.

from heroku_applink.data_api import DataAPI

header = request.headers.get("x-client-context")
decoded = base64.b64decode(header)
data = json.loads(decoded)

data_api = DataAPI(
    org_domain_url=data["orgDomainUrl"],
    api_version=data["apiVersion"],
    access_token=data["accessToken"],
)

result = data_api.query("SELECT Id, Name FROM Account")

About

Use the Salesforce SDK for Python to develop Heroku Applink managed apps that interact with Salesforce and Data Cloud orgs.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 5