Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# This workflow builds the documentation and creates an artifact

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

Comment on lines +3 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "docs.yml" -path ".github/workflows/*" -type f

Repository: ably/ably-python

Length of output: 42


🏁 Script executed:

ls -la .github/workflows/ 2>/dev/null || echo "Directory not found"

Repository: ably/ably-python

Length of output: 469


🏁 Script executed:

cat -n .github/workflows/docs.yml

Repository: ably/ably-python

Length of output: 2005


Skip AWS publish steps on PRs to avoid secret/role failures.

This job runs on pull_request, but the AWS credentials (lines 47–52) and upload steps (lines 54–59) will fail for forks (no secrets available) and shouldn't publish from unmerged code. Gate those steps to non‑PR events.

🛠️ Proposed fix
       - name: Configure AWS Credentials
         uses: aws-actions/configure-aws-credentials@v4
+        if: github.event_name != 'pull_request'
         with:
           aws-region: eu-west-2
           role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}:role/ably-sdk-builds-ably-chat-kotlin
           role-session-name: "${{ github.run_id }}-${{ github.run_number }}"

       - name: Upload Documentation
         uses: ably/sdk-upload-action@v2
+        if: github.event_name != 'pull_request'
         with:
           sourcePath: site/
           githubToken: ${{ secrets.GITHUB_TOKEN }}
           artifactName: docs
🤖 Prompt for AI Agents
In @.github/workflows/docs.yml around lines 3 - 9, The workflow currently
triggers on pull_request, push and workflow_dispatch, but the AWS credential
configuration and upload steps run for PRs (causing secret/role failures for
forks); update the job or those specific steps (the AWS credential setup and the
S3/upload steps referenced in the PR comment) to only execute when the event is
not a pull_request by adding a conditional such as if: github.event_name !=
'pull_request' (or if: github.event.pull_request == null) on the steps or job,
so AWS secrets are only used on push/workflow_dispatch events.

jobs:
docs:
runs-on: ubuntu-22.04
permissions:
deployments: write
id-token: write
contents: read

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Set up Python 3.12
uses: actions/setup-python@v5
id: setup-python
with:
python-version: '3.12'

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- uses: actions/cache@v4
name: Define a cache for the virtual environment based on the dependencies lock file
id: cache
with:
path: ./.venv
key: venv-${{ runner.os }}-3.12-${{ hashFiles('uv.lock') }}

- name: Install dependencies
run: uv sync --extra docs

- name: Build documentation
run: uv run mkdocs build

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-west-2
role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}:role/ably-sdk-builds-ably-python
role-session-name: "${{ github.run_id }}-${{ github.run_number }}"

- name: Upload Documentation
uses: ably/sdk-upload-action@v2
with:
sourcePath: site/
githubToken: ${{ secrets.GITHUB_TOKEN }}
artifactName: docs
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ test/ably/restsetup.py.orig
.idea/**/*
ably/sync/**
test/ably/sync/**
site/
52 changes: 52 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Documentation

This directory contains the source files for the Ably Python SDK documentation, built using [MkDocs](https://www.mkdocs.org/) and [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/).

## Building the Documentation

### Prerequisites

- Python 3.8 or higher (documentation tools require Python 3.8+)
- Install documentation dependencies: `uv sync --extra docs`

### Build HTML Documentation

```bash
# Build the documentation
uv run mkdocs build

# The generated HTML will be in the site/ directory
```

### Serve Documentation Locally

```bash
# Start a local development server
uv run mkdocs serve

# Open http://127.0.0.1:8000/ in your browser
```

The development server automatically rebuilds the documentation when you make changes to the source files.

## Documentation Structure

- `docs/` - Documentation source files (Markdown)
- `index.md` - Home page
- `api/` - API reference documentation
- `mkdocs.yml` - MkDocs configuration
- `site/` - Generated HTML documentation (gitignored)

## How It Works

The documentation uses [mkdocstrings](https://mkdocstrings.github.io/) to automatically generate API documentation from Python docstrings. The special `:::` syntax in Markdown files tells mkdocstrings to extract and render documentation from Python modules:

```markdown
::: ably.rest.rest.AblyRest
```

This automatically generates formatted documentation including:
- Class and method signatures
- Docstrings
- Type hints
- Parameters and return types
19 changes: 19 additions & 0 deletions docs/api/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Authentication

The Auth class handles authentication with Ably, supporting API keys, tokens, and token generation.

## Auth

::: ably.rest.auth.Auth

## Token Details

::: ably.types.tokendetails.TokenDetails

## Token Request

::: ably.types.tokenrequest.TokenRequest

## Capability

::: ably.types.capability.Capability
27 changes: 27 additions & 0 deletions docs/api/channels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Channels

Channels provide the interface for publishing and subscribing to messages in Ably.

## REST Channels

### Channels Collection

::: ably.rest.channel.Channels

### REST Channel

::: ably.rest.channel.Channel

## Realtime Channels

### Channels Collection

::: ably.realtime.realtime_channel.Channels

### Realtime Channel

::: ably.realtime.realtime_channel.RealtimeChannel

## Presence

::: ably.realtime.realtimepresence.RealtimePresence
37 changes: 37 additions & 0 deletions docs/api/messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Messages

Message types represent the data sent through Ably channels.

## Message

The core message type for pub/sub messaging.

::: ably.types.message.Message

## Message Operations

Support for mutable messages (update, delete, append operations).

### MessageVersion

::: ably.types.message.MessageVersion

### MessageAction

::: ably.types.message.MessageAction

### MessageOperation

::: ably.types.operations.MessageOperation

### PublishResult

::: ably.types.operations.PublishResult

### UpdateDeleteResult

::: ably.types.operations.UpdateDeleteResult

## Presence Message

::: ably.types.presence.PresenceMessage
82 changes: 82 additions & 0 deletions docs/api/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# API Reference Overview

The Ably Python SDK provides two main client interfaces:

## Core Clients

### [REST Client](rest.md)

The REST client (`AblyRest`) provides synchronous access to Ably's REST API:

- Publish messages to channels
- Query message history
- Manage channel lifecycle
- Retrieve statistics
- Token authentication

Use the REST client when you need simple request/response operations without maintaining a persistent connection.

### [Realtime Client](realtime.md)

The Realtime client (`AblyRealtime`) maintains a persistent connection to Ably:

- Subscribe to channels and receive messages in real-time
- Publish messages
- Monitor connection state
- Track presence
- Receive live updates

Use the Realtime client for applications that need live updates and bidirectional communication.

## Key Components

### [Authentication](auth.md)

The `Auth` class handles authentication with Ably, supporting:

- API key authentication
- Token authentication
- Token generation and renewal

### [Channels](channels.md)

Channel interfaces provide access to messaging functionality:

- REST channels for publishing and history
- Realtime channels for subscribing to messages
- Channel state management

### [Messages](messages.md)

Message types represent the data sent through Ably:

- `Message` - Standard pub/sub messages
- `PresenceMessage` - Presence state changes
- Encoding and encryption support

### [Types](types.md)

Core data types and configuration:

- `ClientOptions` - Client configuration
- `TokenDetails` - Authentication tokens
- `Stats` - Usage statistics
- Channel and connection options

### [Utilities](util.md)

Utility functions and helpers:

- Exception types
- Encoding/decoding utilities
- Cryptographic functions

## Client Capabilities

Both clients share common capabilities:

- **Auto-reconnection**: Automatic connection recovery
- **Message queueing**: Queues messages during disconnection
- **Type safety**: Full type hints for IDE support
- **Async/await support**: Native async support in Realtime client
- **Error handling**: Comprehensive error types
19 changes: 19 additions & 0 deletions docs/api/realtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Realtime Client

The Realtime client maintains a persistent connection to Ably, enabling you to subscribe to channels and receive messages in real-time.

## AblyRealtime

::: ably.realtime.realtime.AblyRealtime

## Realtime Channels

::: ably.realtime.realtime_channel.Channels

## Realtime Channel

::: ably.realtime.realtime_channel.RealtimeChannel

## Connection

::: ably.realtime.connection.Connection
59 changes: 59 additions & 0 deletions docs/api/rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# REST Client

The REST client provides synchronous access to Ably's REST API for publishing messages, querying history, and managing channels.

## AblyRest

::: ably.rest.rest.AblyRest

## REST Channels

::: ably.rest.channel.Channels

## REST Channel

::: ably.rest.channel.Channel

## Examples

### Basic Usage

```python
from ably import AblyRest

# Initialize the REST client
rest = AblyRest('your-api-key')

# Get a channel
channel = rest.channels.get('test-channel')

# Publish a message
channel.publish('event-name', {'key': 'value'})

# Get channel history
history = channel.history()
for message in history.items:
print(f'Message: {message.data}')
```

### Publishing Multiple Messages

```python
# Publish multiple messages at once
channel.publish([
{'name': 'event-1', 'data': 'first message'},
{'name': 'event-2', 'data': 'second message'},
])
```

### Using Channel Options

```python
from ably.types.options import ChannelOptions
from ably.util.crypto import CipherParams

# Get a channel with encryption
cipher_params = CipherParams(secret_key='your-secret-key')
options = ChannelOptions(cipher=cipher_params)
channel = rest.channels.get('encrypted-channel', options)
```
Comment on lines +17 to +59
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the CipherParams class and its constructor parameters

echo "=== Checking for crypto module ==="
fd -e py 'crypto' --type f

echo "=== Checking CipherParams class definition ==="
rg -n "class CipherParams" --type py -A 10

echo "=== Checking ChannelOptions class ==="
rg -n "class ChannelOptions" --type py -A 10

echo "=== Checking channel.publish method signature ==="
rg -n "def publish" --type py -A 5 | head -50

echo "=== Checking channel.history method signature ==="
rg -n "def history" --type py -A 5 | head -50

Repository: ably/ably-python

Length of output: 6247


🏁 Script executed:

#!/bin/bash
# Check for ChannelOptions in types/options
echo "=== Checking for ably/types/options.py ==="
fd -n "options.py" --type f

echo "=== Checking ChannelOptions imports in examples/docs ==="
rg -n "from ably.*options import" --type py

echo "=== Checking if ChannelOptions exists in multiple locations ==="
rg -n "class ChannelOptions" --type py

echo "=== Checking REST client for synchronous vs async ==="
rg -n "class AblyRest" --type py -A 20

echo "=== Checking publish method more thoroughly ==="
rg -B5 -A15 "async def publish" ably/rest/channel.py

Repository: ably/ably-python

Length of output: 4534


🏁 Script executed:

#!/bin/bash
echo "=== Checking REST channel.get() method ==="
rg -B5 -A10 "def get" ably/rest/channels.py | head -50

echo "=== Checking if REST ChannelOptions is used ==="
rg -n "ChannelOptions" ably/rest/ --type py

echo "=== Checking test examples for REST channel usage ==="
rg -B3 -A3 "channels.get" test/ably/rest/ --type py | head -60

echo "=== Checking if publish/history work in sync context ==="
rg -B2 -A2 "rest_channel_publish_test" test/ --type py | head -30

Repository: ably/ably-python

Length of output: 4984


🏁 Script executed:

#!/bin/bash
echo "=== Finding channels implementation ==="
fd "channels" --type f --path "*/rest/*" | grep -v test

echo "=== Checking channels class ==="
rg -n "class.*[Cc]hannels" ably/rest/ --type py -A 10

echo "=== Checking get method in channels ==="
rg -n "def get" ably/rest/ --type py -B 2 -A 8

Repository: ably/ably-python

Length of output: 4519


🏁 Script executed:

#!/bin/bash
echo "=== Checking Channel class constructor ==="
rg -B5 -A15 "class Channel:" ably/rest/channel.py | head -50

echo "=== Checking Channel __init__ ==="
rg -B2 -A20 "def __init__" ably/rest/channel.py | head -40

Repository: ably/ably-python

Length of output: 2239


Fix code examples to use async/await and remove incorrect ChannelOptions usage.

The documentation examples have several API accuracy issues:

  1. Both channel.publish() and channel.history() are async methods but examples don't use await—this will cause runtime errors.
  2. The import from ably.types.options import ChannelOptions is incorrect—ChannelOptions only exists in the Realtime module and isn't available in the REST API.
  3. For REST channels with encryption, pass cipher directly to channels.get(), not wrapped in ChannelOptions:
# Correct pattern for encryption with REST channels
cipher_params = CipherParams(secret_key='your-secret-key')
channel = rest.channels.get('encrypted-channel', cipher=cipher_params)

# Use await for async methods
await channel.publish('event-name', {'key': 'value'})
history = await channel.history()

The CipherParams import path and constructor parameter are correct.

🤖 Prompt for AI Agents
In `@docs/api/rest.md` around lines 17 - 59, Update the REST examples to use
async/await for async methods and remove the incorrect ChannelOptions usage:
change all calls to channel.publish(...) and channel.history() to await
channel.publish(...) and history = await channel.history(); remove the import
and use of ChannelOptions (it belongs to Realtime) and instead pass cipher
directly to rest.channels.get by using cipher=CipherParams(...), e.g. channel =
rest.channels.get('encrypted-channel', cipher=cipher_params), keeping the
existing CipherParams import/constructor.

Loading
Loading