Skip to content

Commit 7bd20ff

Browse files
authored
Rework the SDK internal and API to make it more future proof (#7)
* Correct the store creation and DSN documentation * Enhance entity creation examples and improve parameter handling in the SDK * Updated entity creation examples in README.md to include default and custom Kafka configurations. * Removed unnecessary use of EntityCreateParams in example scripts, directly using the SDK's create method. * Added a new method in EntityManager to format parameters for SQL queries, improving readability and maintainability. * Refactor to simplify the store code * Refactor models to use properties instead of dataclass fields * Updated `Changelog`, `ComputePool`, `Database`, `DescriptorSource`, `Entity`, `FunctionSource`, `Function`, `Schema`, and `Store` models to utilize properties for accessing attributes instead of using dataclass fields. * Removed unused parameters such as `comment` from various model classes and their corresponding create/update parameters. * Adjusted the `BaseResourceManager` to ensure resource names are handled in PascalCase. * Updated tests to reflect changes in model structure and ensure compatibility with the new property-based access. * Removed comments from SQL generation methods in resource managers where comments are no longer supported. * Update README.md for improved clarity and consistency in examples * Refactor parameter naming from "params" to "parameters" for consistency across SDK models and examples * Remove unused files and directories from the project structure for improved clarity and maintainability * review changes
1 parent 97c3eed commit 7bd20ff

34 files changed

+1498
-835
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Features
2+
body: Rework the different constructor and SDK API to make it more future proof
3+
time: 2025-10-18T01:40:58.600389+02:00
4+
custom:
5+
Author: Kayrnt
6+
Issue: ""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Fixes
2+
body: Correct the store creation and DSN documentation
3+
time: 2025-10-16T21:40:49.8561+02:00
4+
custom:
5+
Author: Kayrnt
6+
Issue: ""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Under the Hood
2+
body: Add more unit tests to create entities and stores
3+
time: 2025-10-16T22:06:39.725486+02:00
4+
custom:
5+
Author: Kayrnt
6+
Issue: ""
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Under the Hood
2+
body: Enhance entity creation examples and improve parameter handling in the SDK
3+
time: 2025-10-16T23:28:35.603992+02:00
4+
custom:
5+
Author: Kayrnt
6+
Issue: ""

AGENTS.md

Lines changed: 266 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,273 @@
1-
# DeltaStream Python SDK
1+
# DeltaStream Python SDK - AI Agent Guide
22

33
## Project Context
44

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+
```
631

732
## Code Style and Structure
833

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)
1137
- 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

Comments
 (0)