|
1 | | -# DeltaStream Python SDK |
| 1 | +# DeltaStream Python SDK - AI Agent Guide |
2 | 2 |
|
3 | 3 | ## Project Context |
4 | 4 |
|
5 | | -A Python SDK for [DeltaStream](https://deltastream.io), built on the DeltaStream Connector Python library. It provides a Python API to manage a DeltaStream environment (control and data plane). |
| 5 | +A modern, async-first Python SDK for [DeltaStream](https://deltastream.io), built on the DeltaStream Connector Python library. It provides an ergonomic Python API to manage a DeltaStream environment (control and data plane) with full CRUD lifecycle for all DeltaStream resources. |
| 6 | + |
| 7 | +**Key Characteristics:** |
| 8 | +- Async/await native API (Python 3.11+) |
| 9 | +- Type-safe with comprehensive type hints |
| 10 | +- Built on `deltastream-connector >= 0.3` |
| 11 | +- Follows patterns similar to Databricks SDK for familiarity |
| 12 | + |
| 13 | +## Repository Structure |
| 14 | + |
| 15 | +``` |
| 16 | +. |
| 17 | +├── src/ |
| 18 | +│ └── deltastream_sdk/ # Main package (note: deltastream_sdk not deltastream/sdk/) |
| 19 | +│ ├── __init__.py # Package exports: DeltaStreamClient, exceptions, models, resources |
| 20 | +│ ├── client.py # Main DeltaStreamClient class |
| 21 | +│ ├── exceptions.py # Custom exceptions (DeltaStreamSDKError, ResourceNotFound, etc.) |
| 22 | +│ ├── models/ # Data models (Pydantic-based) |
| 23 | +│ └── resources/ # Resource managers (CRUD operations) |
| 24 | +├── tests/ |
| 25 | +│ └── sdk/ # SDK tests |
| 26 | +│ ├── conftest.py # Test fixtures and configuration |
| 27 | +├── examples/ # Usage examples |
| 28 | +├── docs/ # Documentation and RFCs |
| 29 | +└── pyproject.toml # Project configuration and dependencies |
| 30 | +``` |
6 | 31 |
|
7 | 32 | ## Code Style and Structure |
8 | 33 |
|
9 | | -- Write concise, technical Python, SQL or Jinja code with accurate examples |
10 | | -- Use functional and declarative programming patterns; avoid classes where possible |
| 34 | +### General Principles |
| 35 | +- Write concise, technical Python or SQL code with accurate examples |
| 36 | +- Use functional and declarative programming patterns; avoid classes where possible (except for resource managers and models) |
11 | 37 | - Prefer iteration and modularization over code duplication |
12 | | -- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError) |
13 | | -- Structure repository files as follows: |
14 | | -. |
15 | | -├── src/ # Source code root directory |
16 | | -│ └── deltastream/ # Main package namespace |
17 | | -│ └── sdk/ # SDK implementation |
18 | | -│ |
19 | | -└── tests/ # Test suite root directory |
20 | | - └── sdk/ # SDK tests |
21 | | - |
22 | | -## Build and project setup |
23 | | - |
24 | | -The project is using `uv` for dependency management. You can find the lockfile in `uv.lock`. |
25 | | -To run tests, use `uv run pytest <path_to_test>`. |
26 | | -To add dependencies use `uv add <package>`. |
27 | | -Dependency resolution is done using `uv sync`. |
28 | | -Dependencies are specified in `pyproject.toml`. |
29 | | -Dependencies are installed in `./.venv`. |
| 38 | +- Use descriptive variable names with auxiliary verbs (e.g., `is_connected`, `has_error`, `fetch_results`) |
| 39 | +- Follow PEP 8 naming conventions: `snake_case` for functions/variables, `PascalCase` for classes |
| 40 | + |
| 41 | +### Async Patterns |
| 42 | +- All I/O operations are async; use `async def` and `await` |
| 43 | +- Follow established async patterns from existing code |
| 44 | +- Example: `async def create(...) -> ModelType:` |
| 45 | + |
| 46 | +### Type Hints |
| 47 | +- Use comprehensive type hints throughout |
| 48 | +- Models are Pydantic-based for validation and serialization |
| 49 | +- Import from `typing` as needed: `Optional`, `List`, `Dict`, `Any`, `Union` |
| 50 | + |
| 51 | +### Error Handling |
| 52 | +- Use custom exceptions from `exceptions.py`: |
| 53 | + - `DeltaStreamSDKError` (base exception) |
| 54 | + - `ResourceNotFound` |
| 55 | + - `ResourceAlreadyExists` |
| 56 | + - `InvalidConfiguration` |
| 57 | + - `ConnectionError` |
| 58 | +- Always provide meaningful error messages |
| 59 | + |
| 60 | +## Development Environment |
| 61 | + |
| 62 | +### Package Manager |
| 63 | +- **Tool**: `uv` (fast Python package manager) |
| 64 | +- **Lockfile**: `uv.lock` (committed to repository) |
| 65 | +- **Config**: `pyproject.toml` |
| 66 | +- **Virtual Environment**: `./.venv` (auto-created by uv) |
| 67 | + |
| 68 | +### Python Version |
| 69 | +- **Required**: Python 3.11+ |
| 70 | +- Specified in `pyproject.toml`: `requires-python = ">=3.11"` |
| 71 | + |
| 72 | +### Dependencies |
| 73 | +- **Production**: `deltastream-connector >= 0.3` |
| 74 | +- **Dev**: pytest, pytest-cov, pytest-asyncio, mypy, ruff, python-dotenv, tox, flake8 |
| 75 | +- **Optional**: jupyter (for notebook examples) |
| 76 | + |
| 77 | +## Common Commands |
| 78 | + |
| 79 | +### Installation & Setup |
| 80 | +```bash |
| 81 | +uv sync # Install all dependencies (production + dev) |
| 82 | +uv sync --all-groups # Install all dependency groups including optional |
| 83 | +uv add <package> # Add a new dependency |
| 84 | +``` |
| 85 | + |
| 86 | +### Testing |
| 87 | +```bash |
| 88 | +uv run pytest # Run all tests |
| 89 | +uv run pytest <path_to_test> # Run specific test |
| 90 | +uv run pytest -m "not integration" # Skip integration tests |
| 91 | +uv run pytest --cov # Run with coverage report |
| 92 | +``` |
| 93 | + |
| 94 | +### Code Quality |
| 95 | +```bash |
| 96 | +uv run ruff check # Lint code |
| 97 | +uv run ruff check --fix # Lint and auto-fix issues |
| 98 | +uv run ruff format # Format code |
| 99 | +uv run ruff format --check # Check formatting without changes |
| 100 | +uv run mypy # Type checking |
| 101 | +``` |
| 102 | + |
| 103 | +### Building |
| 104 | +```bash |
| 105 | +uv build # Build distribution packages |
| 106 | +``` |
| 107 | + |
| 108 | +### Makefile Targets |
| 109 | +```bash |
| 110 | +make help # Show available targets |
| 111 | +make install # Install all dependencies |
| 112 | +make lint # Run linting |
| 113 | +make format # Format code |
| 114 | +make check-format # Check formatting |
| 115 | +make mypy # Type checking |
| 116 | +make test # Run all tests |
| 117 | +make unit-tests # Run unit tests only |
| 118 | +make build # Build package |
| 119 | +make ci # Run all CI checks (lint, format, mypy, unit-tests, build) |
| 120 | +make clean # Clean build artifacts |
| 121 | +make jupyter # Launch Jupyter Lab |
| 122 | +``` |
| 123 | + |
| 124 | +## Development Workflow |
| 125 | + |
| 126 | +### Standard Development Flow |
| 127 | +1. Make changes to relevant files in `src/deltastream_sdk/` |
| 128 | +2. Write or update corresponding tests in `tests/sdk/` |
| 129 | +3. Run tests: `uv run pytest` or `make test` |
| 130 | +4. Run linting: `uv run ruff check --fix` or `make lint` |
| 131 | +5. Run formatting: `uv run ruff format` or `make format` |
| 132 | +6. Run type checking: `uv run mypy` or `make mypy` |
| 133 | +7. Ensure all checks pass before committing |
| 134 | + |
| 135 | +### Pre-commit Checklist |
| 136 | +```bash |
| 137 | +make ci # Runs: lint, check-format, mypy, unit-tests, build |
| 138 | +``` |
| 139 | + |
| 140 | +### Adding New Resources |
| 141 | +When adding a new resource type (e.g., "widgets"): |
| 142 | + |
| 143 | +1. **Create Model** (`src/deltastream_sdk/models/widgets.py`): |
| 144 | + ```python |
| 145 | + from pydantic import BaseModel, Field |
| 146 | + |
| 147 | + class Widget(BaseModel): |
| 148 | + name: str |
| 149 | + description: Optional[str] = None |
| 150 | + # ... other fields |
| 151 | + ``` |
| 152 | + |
| 153 | +2. **Create Resource Manager** (`src/deltastream_sdk/resources/widgets.py`): |
| 154 | + ```python |
| 155 | + from .base import ResourceManager |
| 156 | + from ..models.widgets import Widget |
| 157 | + |
| 158 | + class WidgetManager(ResourceManager): |
| 159 | + async def list(self) -> List[Widget]: |
| 160 | + # Implementation |
| 161 | + |
| 162 | + async def get(self, name: str) -> Widget: |
| 163 | + # Implementation |
| 164 | + |
| 165 | + async def create(self, name: str, **kwargs) -> Widget: |
| 166 | + # Implementation |
| 167 | + ``` |
| 168 | + |
| 169 | +3. **Register in Client** (`src/deltastream_sdk/client.py`): |
| 170 | + ```python |
| 171 | + from .resources.widgets import WidgetManager |
| 172 | + |
| 173 | + class DeltaStreamClient: |
| 174 | + def __init__(self, ...): |
| 175 | + # ... |
| 176 | + self.widgets = WidgetManager(self) |
| 177 | + ``` |
| 178 | + |
| 179 | +4. **Write Tests** (`tests/sdk/test_widgets.py`): |
| 180 | + ```python |
| 181 | + import pytest |
| 182 | + |
| 183 | + @pytest.mark.asyncio |
| 184 | + async def test_widget_creation(client): |
| 185 | + widget = await client.widgets.create(name="test_widget") |
| 186 | + assert widget.name == "test_widget" |
| 187 | + ``` |
| 188 | + |
| 189 | +5. **Update Exports** (`src/deltastream_sdk/__init__.py` if needed) |
| 190 | + |
| 191 | +## Architecture Notes |
| 192 | + |
| 193 | +### Client Initialization Patterns |
| 194 | +The SDK supports three initialization patterns: |
| 195 | + |
| 196 | +1. **Environment-based** (recommended for most use cases): |
| 197 | + ```python |
| 198 | + client = DeltaStreamClient.from_environment() |
| 199 | + ``` |
| 200 | + |
| 201 | +2. **Programmatic** (explicit configuration): |
| 202 | + ```python |
| 203 | + client = DeltaStreamClient( |
| 204 | + server_url="https://api.deltastream.io/v2", |
| 205 | + token_provider=token_provider, |
| 206 | + organization_id="my_org" |
| 207 | + ) |
| 208 | + ``` |
| 209 | + |
| 210 | +3. **DSN-based** (connection string): |
| 211 | + ```python |
| 212 | + client = DeltaStreamClient( dsn="https://:[email protected]/v2") |
| 213 | + ``` |
| 214 | + |
| 215 | +### Resource Manager Pattern |
| 216 | +- Each resource type has a dedicated manager (e.g., `StreamManager`, `StoreManager`) |
| 217 | +- Managers are instantiated by `DeltaStreamClient` and accessible as attributes (e.g., `client.streams`, `client.stores`) |
| 218 | +- All managers extend `ResourceManager` base class |
| 219 | +- CRUD operations follow consistent naming: `list()`, `get()`, `create()`, `update()`, `delete()` |
| 220 | + |
| 221 | +### Context Management |
| 222 | +The client maintains state for current database, schema, and store: |
| 223 | +- `await client.use_database(name)` |
| 224 | +- `await client.use_schema(name)` |
| 225 | +- `await client.use_store(name)` |
| 226 | +- `await client.get_current_database()` |
| 227 | +- `await client.get_current_schema()` |
| 228 | +- `await client.get_current_store()` |
| 229 | + |
| 230 | +## Testing Guidelines |
| 231 | + |
| 232 | +### Test Organization |
| 233 | +- Use `pytest` with `pytest-asyncio` for async tests |
| 234 | +- Mark async tests with `@pytest.mark.asyncio` |
| 235 | +- Use fixtures from `conftest.py` for common setup |
| 236 | +- Separate unit tests from integration tests using markers |
| 237 | + |
| 238 | +### Test Coverage |
| 239 | +- Aim for high coverage (current target: comprehensive) |
| 240 | +- Run with coverage: `uv run pytest --cov` |
| 241 | +- Coverage reports generated in `htmlcov/` |
| 242 | + |
| 243 | +### Mocking |
| 244 | +- Mock external API calls in unit tests |
| 245 | +- Use integration tests for end-to-end scenarios |
| 246 | +- Keep integration tests separate with `@pytest.mark.integration` |
| 247 | + |
| 248 | +## Documentation |
| 249 | + |
| 250 | +### In-Code Documentation |
| 251 | +- Use docstrings for all public classes and methods |
| 252 | +- Follow Google-style docstring format |
| 253 | +- Include parameter types, return types, and examples where helpful |
| 254 | + |
| 255 | +### External Documentation |
| 256 | +- `README.md`: User-facing quickstart and examples |
| 257 | +- `docs/`: Architecture docs, RFCs, tutorials |
| 258 | +- `examples/`: Working code examples |
| 259 | + |
| 260 | +## Release Process |
| 261 | + |
| 262 | +1. Update version in `pyproject.toml` |
| 263 | +2. Update `CHANGELOG.md` with new version and changes |
| 264 | +3. Run full CI: `make ci` |
| 265 | +4. Build package: `uv build` |
| 266 | +5. Publish to PyPI: `uv publish` (requires credentials) |
| 267 | + |
| 268 | +## Useful References |
| 269 | + |
| 270 | +- **DeltaStream Docs**: https://docs.deltastream.io |
| 271 | +- **DeltaStream Connector**: https://github.com/deltastreaminc/deltastream-connector-python |
| 272 | +- **uv Documentation**: https://github.com/astral-sh/uv |
| 273 | +- **Pydantic**: https://docs.pydantic.dev |
0 commit comments