Skip to main content

Messaging connectors giving AI agents authenticated, normalized access to email and chat platforms

Project description

appif -- Application Interfaces

A Python library that gives AI agents authenticated, normalized access to external platforms -- email, chat, and work tracking systems.

Purpose

Agents need information that lives behind logins: email threads, Slack messages, Jira tickets. This library provides connectors and adapters that authenticate as you and return clean, structured domain objects suitable for agent reasoning -- platform-specific APIs are fully encapsulated behind shared protocols.

Two domains are supported:

  • Messaging -- Gmail, Outlook, Slack. Unified MessageEvent objects via the Connector protocol.
  • Work Tracking -- Jira. Unified WorkItem objects via the WorkTracker protocol. Multi-instance support with YAML config.

For the complete usage guide -- the unified model, per-connector mapping tables, code examples, and environment variable reference -- see docs/usage.md.

Quick Start

Messaging (Gmail, Outlook, Slack)

pip install appif
from appif.adapters.gmail import GmailConnector
from appif.domain.messaging.models import MessageEvent, MessageContent

class MyListener:
    def on_message(self, event: MessageEvent) -> None:
        print(f"[{event.connector}] {event.author.display_name}: {event.content.text}")

connector = GmailConnector()
connector.connect()
connector.register_listener(MyListener())

All three messaging connectors (Gmail, Outlook, Slack) follow this same pattern. The full model, per-connector setup, and examples are in docs/usage.md.

Work Tracking (Jira)

from appif.domain.work_tracking.service import WorkTrackingService
from appif.domain.work_tracking.models import CreateItemRequest, ItemCategory, SearchCriteria

service = WorkTrackingService()  # Loads from ~/.config/appif/jira/config.yaml

# Create a ticket using domain-level categories (adapter resolves to platform type)
item = service.create_item(CreateItemRequest(
    project="MYPROJECT",
    title="Fix login bug",
    item_type=ItemCategory.BUG,
    description="Users cannot log in after password reset",
))
print(f"Created: {item.key}")

# Search
results = service.search(SearchCriteria(project="MYPROJECT", status="To Do"))
for item in results.items:
    print(f"  {item.key}: {item.title}")

# List projects
for project in service.list_projects():
    print(f"  {project.key}: {project.name} ({project.project_type})")

# Get project details
project = service.get_project("MYPROJECT")
print(f"Lead: {project.lead.display_name if project.lead else 'unassigned'}")

See docs/design/work_tracking/setup.md for configuration.

Supported Platforms

Messaging Connectors

Service Connector Inbound Method Status
Gmail Google API (OAuth 2.0) history.list polling Active
Outlook / Microsoft 365 Microsoft Graph API Delta-query polling Active
Slack Slack API (Bolt + Socket Mode) Real-time Socket Mode Active

Work Tracking Adapters

Service Library Auth Method Status
Jira Cloud atlassian-python-api API token (YAML config) Active

CLI

Both Slack and Outlook adapters include command-line interfaces:

pip install appif

# Slack — identity-first commands (bot or user)
appif-slack bot status
appif-slack bot channels
appif-slack bot send general "Deploy complete"
appif-slack bot listen
appif-slack user channels

# Outlook — verify setup and exercise the connector
appif-outlook status
appif-outlook folders
appif-outlook inbox --limit 5
appif-outlook send user@example.com "Hello from appif"
appif-outlook consent

Installation

For development

uv venv .venv
source .venv/bin/activate
uv pip install -e ".[dev]"

As a library dependency

pip install appif

Prerequisites

  • Python 3.13.x
  • uv (for development)

Configuration

Messaging (environment variables)

Credentials are stored in ~/.env and loaded at runtime:

cp .env.example ~/.env
Variable Service Required
APPIF_GMAIL_CLIENT_ID Gmail Yes -- Google Cloud OAuth client ID
APPIF_GMAIL_CLIENT_SECRET Gmail Yes -- Google Cloud OAuth client secret
APPIF_GMAIL_ACCOUNT Gmail Yes -- Account email address
APPIF_OUTLOOK_CLIENT_ID Outlook Yes -- Azure AD app (client) ID
APPIF_OUTLOOK_TENANT_ID Outlook Optional -- Azure AD tenant (default: common)
APPIF_SLACK_BOT_OAUTH_TOKEN Slack Yes -- Bot user OAuth token (xoxb-...)
APPIF_SLACK_BOT_APP_LEVEL_TOKEN Slack Yes -- App-level token for Socket Mode (xapp-...)

See .env.example for the full template with all optional variables.

Work Tracking (YAML config)

Jira uses a YAML config file at ~/.config/appif/jira/config.yaml:

instances:
  personal:
    jira:
      url: https://your-domain.atlassian.net
      username: your-email@example.com
      api_token: your-api-token

default: personal

Override the config path with APPIF_JIRA_CONFIG env var. Multiple instances supported.

See docs/design/work_tracking/setup.md for the full setup guide.

Project Structure

appif/
├── src/
│   └── appif/                       # Top-level package (PyPI: appif)
│       ├── __init__.py              # Version via importlib.metadata
│       ├── domain/
│       │   ├── messaging/           # Connector protocol, canonical models, errors
│       │   └── work_tracking/       # WorkTracker protocol, models, service
│       ├── adapters/
│       │   ├── gmail/               # Gmail messaging connector
│       │   ├── outlook/             # Outlook messaging connector
│       │   ├── slack/               # Slack messaging connector
│       │   └── jira/                # Jira work tracking adapter
│       ├── cli/                     # CLI entry points (Slack)
│       └── infrastructure/          # Credential loading
├── tests/
│   ├── unit/                        # 323 unit tests
│   ├── integration/                 # Live API tests (Slack, Jira)
│   └── e2e/
├── scripts/                         # OAuth consent flows, cleanup utilities
├── docs/design/                     # Design documents per adapter
├── pyproject.toml
├── ADAPTERS.md                      # Detailed adapter documentation
├── .env.example
└── readme.md

Development

# Set up dev environment
uv venv .venv
source .venv/bin/activate
uv pip install -e ".[dev]"

# Run all unit tests (323 tests)
pytest tests/unit -v

# Run adapter-specific tests
pytest tests/unit/test_gmail_*.py -v
pytest tests/unit/test_outlook_*.py -v

# Run integration tests (requires live credentials)
pytest tests/integration/test_jira_integration.py -v
pytest tests/integration/test_slack_integration.py -v

# Clean up Jira test tickets
python scripts/jira_cleanup.py

# Lint and format
ruff check src/ tests/
ruff format src/ tests/

# Type check
mypy src/

Architecture

Messaging: Connector Protocol

All messaging connectors implement a shared Connector protocol (appif.domain.messaging.ports.Connector) -- a transport adapter that:

  • Connects to an external system and manages authentication
  • Emits normalized MessageEvent objects to registered listeners
  • Delivers outbound messages via send(target, content)
  • Supports historical backfill alongside realtime event ingestion
  • Advertises capabilities so upstream logic branches on what the connector supports, not which platform it is

All connectors produce identical canonical types (MessageEvent, ConversationRef, SendReceipt). Platform-specific SDK code is fully encapsulated -- zero Slack/Outlook/Gmail types leak through the public interface.

Work Tracking: WorkTracker Protocol

The Jira adapter implements the WorkTracker protocol (appif.domain.work_tracking.ports.WorkTracker):

  • CRUD operations: get, create, comment, transition, link, search, project management
  • Multi-instance support via InstanceRegistry protocol
  • WorkTrackingService routes operations to the correct adapter instance
  • Domain types (WorkItem, CreateItemRequest, ItemCategory, SearchCriteria) are platform-agnostic
  • ItemCategory enum (TASK, SUBTASK, STORY, BUG, EPIC) -- callers express intent, adapters resolve to platform-specific types
  • Per-project type discovery and caching via createmeta API

Internal Module Pattern

Each messaging adapter follows the same decomposition:

src/appif/adapters/<platform>/
├── __init__.py          # Public exports
├── connector.py         # Connector protocol implementation
├── _auth.py             # Authentication (protocol + implementation)
├── _normalizer.py       # Platform message -> MessageEvent
├── _message_builder.py  # MessageContent -> platform request (email adapters)
├── _poller.py           # Inbound message detection (email adapters)
└── _rate_limiter.py     # Retry + platform error -> domain error mapping

The Jira adapter uses a similar pattern with adapter.py (operations), _auth.py (YAML config + client), and _normalizer.py (API dicts to domain types).

Credential Setup

Adapter Auth Method Setup Guide
Gmail OAuth 2.0 (python scripts/gmail_consent.py <account>) docs/design/gmail/setup.md
Outlook OAuth 2.0 (python scripts/outlook_consent.py <account>) docs/design/outlook/setup.md
Slack Bot + App tokens from Slack app config docs/design/slack/setup.md
Jira API token in YAML config docs/design/work_tracking/setup.md

Documentation

Document Description
CHANGELOG.md Version history, breaking changes, and migration guides
API Reference Complete method signatures, domain models, and error types
ADAPTERS.md Detailed adapter documentation (all platforms)
docs/usage.md Unified messaging model and code examples
docs/design/gmail/ Gmail design, technical design, setup
docs/design/outlook/ Outlook design, technical design, setup
docs/design/slack/ Slack design, setup, CLI checklist
docs/design/work_tracking/ Jira requirements, design, technical design, setup
docs/adr/ Architecture decision records

License

GPL-3.0-or-later -- see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

appif-1.0.0.tar.gz (237.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

appif-1.0.0-py3-none-any.whl (89.3 kB view details)

Uploaded Python 3

File details

Details for the file appif-1.0.0.tar.gz.

File metadata

  • Download URL: appif-1.0.0.tar.gz
  • Upload date:
  • Size: 237.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for appif-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7115baa1cae4e4e926ffa4c6cc01c9daaa4b783db0c94c0a53577dfa5894f3ff
MD5 9749d3bf384894b83834b422ec42dff1
BLAKE2b-256 bf56fce96447b8ec85139c764c73b08973c6cc4aeeb56f11eefe29cfb18ae697

See more details on using hashes here.

Provenance

The following attestation bundles were made for appif-1.0.0.tar.gz:

Publisher: release.yml on dawsonlp/appif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file appif-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: appif-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 89.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for appif-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 80a2633e3ee236133811be0e44baf64cb559dbf86f00a532535b044a5db61bf3
MD5 40b70a3e28b70bd827877d3510ca4e2b
BLAKE2b-256 fe830800b4b5bcd545041ba5aef004990f6892259ac7494565da8bce368ac257

See more details on using hashes here.

Provenance

The following attestation bundles were made for appif-1.0.0-py3-none-any.whl:

Publisher: release.yml on dawsonlp/appif

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page