Metadata-Version: 2.4
Name: openconn
Version: 0.1.0
Summary: Pre-built action connectors for 3rd-party services — bring your own credentials
Project-URL: Homepage, https://github.com/mys1erious/openconn
Project-URL: Repository, https://github.com/mys1erious/openconn
Project-URL: Bug Tracker, https://github.com/mys1erious/openconn/issues
Author: mys1erious
License: MIT
License-File: LICENSE
Keywords: ai-agents,automation,connectors,github,integrations,notion,slack,tools
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 :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.13
Provides-Extra: airtable
Requires-Dist: pyairtable>=2.0; extra == 'airtable'
Provides-Extra: all
Requires-Dist: atlassian-python-api>=3.0; extra == 'all'
Requires-Dist: google-api-python-client>=2.0; extra == 'all'
Requires-Dist: google-auth-oauthlib>=1.0; extra == 'all'
Requires-Dist: google-auth>=2.0; extra == 'all'
Requires-Dist: httpx>=0.25; extra == 'all'
Requires-Dist: notion-client>=2.0; extra == 'all'
Requires-Dist: pyairtable>=2.0; extra == 'all'
Requires-Dist: pygithub>=2.0; extra == 'all'
Requires-Dist: slack-sdk>=3.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-mock>=3.12; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: discord
Requires-Dist: httpx>=0.25; extra == 'discord'
Provides-Extra: github
Requires-Dist: pygithub>=2.0; extra == 'github'
Provides-Extra: gmail
Requires-Dist: google-api-python-client>=2.0; extra == 'gmail'
Requires-Dist: google-auth-oauthlib>=1.0; extra == 'gmail'
Requires-Dist: google-auth>=2.0; extra == 'gmail'
Provides-Extra: google-drive
Requires-Dist: google-api-python-client>=2.0; extra == 'google-drive'
Requires-Dist: google-auth-oauthlib>=1.0; extra == 'google-drive'
Requires-Dist: google-auth>=2.0; extra == 'google-drive'
Provides-Extra: google-sheets
Requires-Dist: google-api-python-client>=2.0; extra == 'google-sheets'
Requires-Dist: google-auth-oauthlib>=1.0; extra == 'google-sheets'
Requires-Dist: google-auth>=2.0; extra == 'google-sheets'
Provides-Extra: jira
Requires-Dist: atlassian-python-api>=3.0; extra == 'jira'
Provides-Extra: linear
Requires-Dist: httpx>=0.25; extra == 'linear'
Provides-Extra: notion
Requires-Dist: notion-client>=2.0; extra == 'notion'
Provides-Extra: slack
Requires-Dist: slack-sdk>=3.0; extra == 'slack'
Description-Content-Type: text/markdown

# openconn

[![CI](https://github.com/YOUR_USERNAME/openconn/actions/workflows/ci.yml/badge.svg)](https://github.com/YOUR_USERNAME/openconn/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Pre-built action connectors for 3rd-party services. Bring your own credentials.**

## Why openconn?

- **No cloud, no lock-in** — runs entirely in your own process with credentials you supply
- **Action-oriented** — discrete, named actions (`send_message`, `upload_file`) rather than data sync primitives
- **Framework-agnostic** — plain async Python, no coupling to LangChain, pydantic-ai, or any agent framework
- **Installable per-connector** — only pull in the SDKs you actually use

## Install

```bash
uv add openconn[slack]
uv add openconn[google-drive]
uv add openconn[slack,google-drive]
uv add openconn[all]
```

## Quick start

```python
import asyncio
from openconn import ConnectorRegistry

async def main():
    # Instantiate a connector
    slack = ConnectorRegistry.create("slack")

    # Connect with your credentials
    await slack.connect({"bot_token": "xoxb-your-token-here"})

    # Execute an action
    result = await slack.execute_action("send_message", {
        "channel": "C12345678",
        "text": "Hello from openconn!",
    })

    # Use the result
    print(result.text)           # "Message sent to channel C12345678."
    print(result.data["ts"])     # "1234567890.123456"

asyncio.run(main())
```

## Connector support

| Connector | Extra | Status |
|-----------|-------|--------|
| Slack | `[slack]` | Done |
| Google Drive | `[google-drive]` | Done |
| GitHub | `[github]` | Soon |
| Gmail | `[gmail]` | Soon |
| Google Sheets | `[google-sheets]` | Soon |
| Notion | `[notion]` | Soon |
| Jira | `[jira]` | Soon |
| Linear | `[linear]` | Soon |
| Airtable | `[airtable]` | Soon |
| Discord | `[discord]` | Soon |

## Credential schemas

### Slack

```python
{
    "bot_token": "xoxb-..."   # OAuth & Permissions page in your Slack App dashboard
}
```

### Google Drive

```python
{
    "token":          "ya29.a...",
    "refresh_token":  "1//...",
    "client_id":      "....apps.googleusercontent.com",
    "client_secret":  "...",
    "token_uri":      "https://oauth2.googleapis.com/token",   # optional
}
```

## Docs

- [Connector reference](docs/connectors.md) — credential schemas and full action tables
- [Adding a connector](docs/adding-a-connector.md) — step-by-step guide for contributors

## License

MIT
