Metadata-Version: 2.4
Name: appif
Version: 0.1.0
Summary: Messaging connectors giving AI agents authenticated, normalized access to email and chat platforms
Project-URL: Homepage, https://github.com/dawsonlp/application_interfaces
Project-URL: Repository, https://github.com/dawsonlp/application_interfaces
Project-URL: Issues, https://github.com/dawsonlp/application_interfaces/issues
Author: ldawson
License: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.13
Requires-Dist: httpx<1.0,>=0.28
Requires-Dist: python-dotenv>=1.0
Requires-Dist: structlog>=24.4
Requires-Dist: tenacity>=9.0
Provides-Extra: all
Requires-Dist: azure-identity>=1.19; extra == 'all'
Requires-Dist: google-api-python-client>=2.160; extra == 'all'
Requires-Dist: google-auth-oauthlib>=1.2; extra == 'all'
Requires-Dist: msal>=1.31; extra == 'all'
Requires-Dist: msgraph-sdk>=1.14; extra == 'all'
Requires-Dist: slack-bolt>=1.21; extra == 'all'
Requires-Dist: slack-sdk>=3.33; extra == 'all'
Provides-Extra: dev
Requires-Dist: black>=25.1; extra == 'dev'
Requires-Dist: mypy>=1.14; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.25; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Provides-Extra: gmail
Requires-Dist: google-api-python-client>=2.160; extra == 'gmail'
Requires-Dist: google-auth-oauthlib>=1.2; extra == 'gmail'
Provides-Extra: outlook
Requires-Dist: azure-identity>=1.19; extra == 'outlook'
Requires-Dist: msal>=1.31; extra == 'outlook'
Requires-Dist: msgraph-sdk>=1.14; extra == 'outlook'
Provides-Extra: slack
Requires-Dist: slack-bolt>=1.21; extra == 'slack'
Requires-Dist: slack-sdk>=3.33; extra == 'slack'
Description-Content-Type: text/markdown

# appif -- Application Interfaces

A Python library of messaging connectors that give AI agents authenticated, normalized access to email and chat platforms.

## Purpose

Agents need information that lives behind logins: email threads, Slack messages, team conversations. This library provides a set of connectors that authenticate as you and return clean, structured `MessageEvent` objects suitable for agent reasoning -- platform-specific APIs are fully encapsulated behind a shared `Connector` protocol.

## Quick Start

```bash
# Create dev environment
uv venv .venv
source .venv/bin/activate
uv pip install -e ".[dev,gmail,outlook]"

# Set up credentials
cp .env.example ~/.env    # then edit ~/.env with your values

# Run consent flow for Gmail
python scripts/gmail_consent.py my-account

# Run tests
pytest tests/unit -v
```

## Supported 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 |

For detailed documentation of all adapters, see [ADAPTERS.md](ADAPTERS.md).

## Installation

### For development

```bash
uv venv .venv
source .venv/bin/activate

# Core + dev tools
uv pip install -e ".[dev]"

# With specific adapter dependencies
uv pip install -e ".[dev,gmail]"
uv pip install -e ".[dev,outlook]"
uv pip install -e ".[dev,slack]"
uv pip install -e ".[dev,all]"
```

### As a library dependency

```bash
pip install appif
pip install "appif[gmail]"
pip install "appif[outlook]"
pip install "appif[all]"
```

### Prerequisites

- Python 3.13.x
- uv (for development)

## Configuration

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

```bash
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](.env.example) for the full template with all optional variables.

## Project Structure

```
application_interfaces/
├── src/
│   └── appif/                       # Top-level package (PyPI: appif)
│       ├── __init__.py              # Version via importlib.metadata
│       ├── domain/
│       │   └── messaging/           # Connector protocol, canonical models, errors
│       ├── adapters/
│       │   ├── gmail/               # Gmail messaging connector
│       │   ├── outlook/             # Outlook messaging connector
│       │   └── slack/               # Slack messaging connector
│       └── infrastructure/          # Credential loading
├── tests/
│   ├── unit/                        # 241 unit tests
│   ├── integration/
│   └── e2e/
├── scripts/                         # OAuth consent flows
├── docs/design/                     # Design documents per adapter
├── pyproject.toml
├── ADAPTERS.md                      # Detailed adapter documentation
├── .env.example
└── readme.md
```

## Development

```bash
# Set up dev environment
uv venv .venv
source .venv/bin/activate
uv pip install -e ".[dev,gmail,outlook]"

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

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

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

# Type check
mypy src/
```

## Architecture

### 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.

### Internal Module Pattern

Each 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
```

### Credential Setup

| Adapter | Consent Script | Setup Guide |
|---------|---------------|-------------|
| Gmail | `python scripts/gmail_consent.py <account>` | [docs/design/gmail/setup.md](docs/design/gmail/setup.md) |
| Outlook | `python scripts/outlook_consent.py <account>` | [docs/design/outlook/setup.md](docs/design/outlook/setup.md) |
| Slack | N/A (tokens from Slack app) | [docs/design/slack/setup.md](docs/design/slack/setup.md) |

### Related: appif-ext

Content adapters (The Economist, Irish Times, Foreign Affairs), CLI entry point, and browser infrastructure live in the private [appif-ext](https://github.com/dawsonlp/appif_ext) package, which depends on `appif>=0.1.0`.

## License

MIT -- see [LICENSE](LICENSE).