Metadata-Version: 2.4
Name: glueco-sdk
Version: 0.2.0
Summary: Python SDK for Glueco Gateway - PoP-authenticated access to LLM providers
Project-URL: Homepage, https://github.com/glueco/python-sdk
Project-URL: Documentation, https://docs.glueco.io/sdk-python
Project-URL: Repository, https://github.com/glueco/python-sdk
Author-email: Glueco <dev@glueco.io>
License: MIT
Keywords: ai,gateway,gemini,groq,llm,openai,proxy
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.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24.0
Requires-Dist: pynacl>=1.5.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# Glueco SDK for Python

Python SDK for the Glueco Gateway with PoP (Proof-of-Possession) authentication.

## Installation

```bash
pip install glueco-sdk
```

Or install from source:

```bash
pip install -e path/to/glueco-sdk
```

## Quick Start

### Option 1: Dynamic Connection (Recommended for User-Facing Apps)

```python
import streamlit as st
from glueco_sdk import (
    connect, handle_callback, create_session,
    GatewayClient, AppInfo, PermissionRequest,
)

# 1. User enters pairing string
pairing_string = st.text_input("Pairing String")

# 2. Initiate connection
if st.button("Connect"):
    result = connect(
        pairing_string=pairing_string,
        app=AppInfo(name="My App", description="Example app"),
        requested_permissions=[
            PermissionRequest(resource_id="llm:openai", actions=["chat.completions"]),
            PermissionRequest(resource_id="llm:groq", actions=["chat.completions"]),
        ],
        redirect_uri=f"{st.get_script_run_ctx().session_id}/callback",
    )
    # Store pending connection
    st.session_state.pending_keypair = result.keypair
    st.session_state.pending_proxy_url = result.proxy_url
    # Redirect to approval
    st.markdown(f'<meta http-equiv="refresh" content="0;url={result.approval_url}">')

# 3. Handle callback (when user returns)
params = st.query_params
callback = handle_callback(params.get("status"), params.get("app_id"), params.get("expires_at"))

if callback.approved:
    session = create_session(
        proxy_url=st.session_state.pending_proxy_url,
        app_id=callback.app_id,
        keypair=st.session_state.pending_keypair,
        expires_at=callback.expires_at,
    )
    st.session_state.gateway_session = session

# 4. Make requests
session = st.session_state.get("gateway_session")
if session and session.is_valid():
    client = GatewayClient.from_session(session)
    response = client.chat_completion(
        provider="openai",
        model="gpt-4o",
        messages=[{"role": "user", "content": "Hello!"}],
    )
    print(response.content)
```

### Option 2: Static Configuration (Server-Side Apps)

```python
from glueco_sdk import GatewayClient

# Uses GATEWAY_PROXY_URL, GATEWAY_APP_ID, GATEWAY_PRIVATE_KEY env vars
client = GatewayClient.from_env()

response = client.chat_completion(
    provider="openai",
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.content)
```

## Session Management

```python
from glueco_sdk import GatewaySession

session = st.session_state.gateway_session

# Check validity
if session.is_valid():
    print(f"Session expires in: {session.time_remaining_formatted()}")
    
# Check available resources
llm_resources = session.get_resources_by_type("llm")
for resource in llm_resources:
    print(f"Provider: {resource.provider}, Actions: {resource.actions}")
    
# Serialize for storage
data = session.to_dict()
restored = GatewaySession.from_dict(data)
```

## Supported Providers

| Provider | Resource ID | Status |
|----------|-------------|--------|
| OpenAI | `llm:openai` | ✅ Ready |
| Groq | `llm:groq` | ✅ Ready |
| Gemini | `llm:gemini` | ✅ Ready |
| Anthropic | `llm:anthropic` | ⏳ Plugin needed |
| xAI Grok | `llm:grok` | ⏳ Plugin needed |

## API Reference

### Connection Flow

- `parse_pairing_string(str)` → `PairingInfo`
- `generate_keypair()` → `KeyPair`
- `connect(...)` → `ConnectResult`
- `handle_callback(status, app_id, expires_at)` → `CallbackResult`
- `create_session(...)` → `GatewaySession`

### Client

- `GatewayClient.from_env()` → client from env vars
- `GatewayClient.from_session(session)` → client from session
- `client.chat_completion(provider, model, messages, ...)` → `ChatCompletion`

### Session

- `session.is_valid()` → bool
- `session.is_expired()` → bool
- `session.time_remaining_seconds()` → int
- `session.time_remaining_formatted()` → str (MM:SS)
- `session.get_resources_by_type(type)` → list of resources
- `session.to_dict()` / `GatewaySession.from_dict(data)`

## License

MIT
