loco-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- loco_sdk-0.1.0/CHANGELOG.md +46 -0
- loco_sdk-0.1.0/DEVELOPMENT.md +303 -0
- loco_sdk-0.1.0/MANIFEST.in +16 -0
- loco_sdk-0.1.0/PKG-INFO +152 -0
- loco_sdk-0.1.0/README.md +134 -0
- loco_sdk-0.1.0/pyproject.toml +69 -0
- loco_sdk-0.1.0/setup.cfg +4 -0
- loco_sdk-0.1.0/src/loco_sdk/__init__.py +44 -0
- loco_sdk-0.1.0/src/loco_sdk/auth/__init__.py +5 -0
- loco_sdk-0.1.0/src/loco_sdk/auth/context.py +152 -0
- loco_sdk-0.1.0/src/loco_sdk/core/__init__.py +33 -0
- loco_sdk-0.1.0/src/loco_sdk/core/base.py +221 -0
- loco_sdk-0.1.0/src/loco_sdk/core/exceptions.py +98 -0
- loco_sdk-0.1.0/src/loco_sdk/schemas/__init__.py +5 -0
- loco_sdk-0.1.0/src/loco_sdk/utils/__init__.py +5 -0
- loco_sdk-0.1.0/src/loco_sdk/version.py +3 -0
- loco_sdk-0.1.0/src/loco_sdk.egg-info/PKG-INFO +152 -0
- loco_sdk-0.1.0/src/loco_sdk.egg-info/SOURCES.txt +23 -0
- loco_sdk-0.1.0/src/loco_sdk.egg-info/dependency_links.txt +1 -0
- loco_sdk-0.1.0/src/loco_sdk.egg-info/requires.txt +10 -0
- loco_sdk-0.1.0/src/loco_sdk.egg-info/top_level.txt +1 -0
- loco_sdk-0.1.0/tests/conftest.py +61 -0
- loco_sdk-0.1.0/tests/test_auth_context.py +139 -0
- loco_sdk-0.1.0/tests/test_exceptions.py +102 -0
- loco_sdk-0.1.0/tests/test_node_plugin.py +106 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Loco SDK will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-01-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- NodePlugin base class for workflow nodes
|
|
13
|
+
- PluginBase abstract class
|
|
14
|
+
- ExtensionPlugin and TriggerPlugin base classes
|
|
15
|
+
- AuthContext helper for OAuth2, API key, and basic auth
|
|
16
|
+
- Exception hierarchy (PluginError, AuthenticationError, etc.)
|
|
17
|
+
- Comprehensive test suite with pytest
|
|
18
|
+
- Development tools: black, ruff, mypy
|
|
19
|
+
- uv support for dependency management
|
|
20
|
+
- DEVELOPMENT.md guide
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- N/A (initial release)
|
|
24
|
+
|
|
25
|
+
### Deprecated
|
|
26
|
+
- N/A
|
|
27
|
+
|
|
28
|
+
### Removed
|
|
29
|
+
- N/A
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- N/A
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
- N/A
|
|
36
|
+
|
|
37
|
+
## [Unreleased]
|
|
38
|
+
|
|
39
|
+
### Planned
|
|
40
|
+
- Pydantic schemas for manifest validation
|
|
41
|
+
- Manifest loader utilities
|
|
42
|
+
- OAuth provider configurations
|
|
43
|
+
- Backwards invocation client (call Loco services from plugins)
|
|
44
|
+
- File operation helpers
|
|
45
|
+
- HTTP client with retry logic
|
|
46
|
+
- More authentication methods
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Setup Development Environment
|
|
4
|
+
|
|
5
|
+
### Prerequisites
|
|
6
|
+
- Python 3.11+
|
|
7
|
+
- uv (recommended) or pip
|
|
8
|
+
|
|
9
|
+
### Install with uv (Recommended)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install uv if not already installed
|
|
13
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
14
|
+
|
|
15
|
+
# Navigate to SDK directory
|
|
16
|
+
cd packages/loco-plugin-sdk
|
|
17
|
+
|
|
18
|
+
# Create virtual environment and install dependencies
|
|
19
|
+
uv venv
|
|
20
|
+
source .venv/bin/activate # Linux/macOS
|
|
21
|
+
# or
|
|
22
|
+
.venv\Scripts\activate # Windows
|
|
23
|
+
|
|
24
|
+
# Install package with dev dependencies
|
|
25
|
+
uv pip install -e ".[dev]"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Install with pip
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
cd packages/loco-plugin-sdk
|
|
32
|
+
|
|
33
|
+
# Create virtual environment
|
|
34
|
+
python -m venv .venv
|
|
35
|
+
source .venv/bin/activate # Linux/macOS
|
|
36
|
+
.venv\Scripts\activate # Windows
|
|
37
|
+
|
|
38
|
+
# Install package with dev dependencies
|
|
39
|
+
pip install -e ".[dev]"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Running Tests
|
|
43
|
+
|
|
44
|
+
### Run all tests
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# With pytest
|
|
48
|
+
pytest
|
|
49
|
+
|
|
50
|
+
# With coverage
|
|
51
|
+
pytest --cov=loco_plugin_sdk --cov-report=html
|
|
52
|
+
|
|
53
|
+
# Verbose output
|
|
54
|
+
pytest -v
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Run specific tests
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Test specific file
|
|
61
|
+
pytest tests/test_auth_context.py
|
|
62
|
+
|
|
63
|
+
# Test specific function
|
|
64
|
+
pytest tests/test_auth_context.py::test_auth_context_oauth2_get_header
|
|
65
|
+
|
|
66
|
+
# Test with keyword
|
|
67
|
+
pytest -k "oauth"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Watch mode (requires pytest-watch)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install pytest-watch
|
|
74
|
+
ptw
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Code Quality
|
|
78
|
+
|
|
79
|
+
### Format code
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Format with black
|
|
83
|
+
black src tests
|
|
84
|
+
|
|
85
|
+
# Check formatting
|
|
86
|
+
black --check src tests
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Lint code
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Run ruff
|
|
93
|
+
ruff check src tests
|
|
94
|
+
|
|
95
|
+
# Auto-fix issues
|
|
96
|
+
ruff check --fix src tests
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Type checking
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Run mypy
|
|
103
|
+
mypy src
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### All checks
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Format, lint, and test
|
|
110
|
+
black src tests && ruff check src tests && pytest
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Project Structure
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
packages/loco-plugin-sdk/
|
|
117
|
+
├── src/
|
|
118
|
+
│ └── loco_plugin_sdk/
|
|
119
|
+
│ ├── __init__.py # Public API
|
|
120
|
+
│ ├── version.py # Version info
|
|
121
|
+
│ ├── core/ # Base classes
|
|
122
|
+
│ │ ├── base.py # NodePlugin
|
|
123
|
+
│ │ ├── exceptions.py # Exception hierarchy
|
|
124
|
+
│ │ └── __init__.py
|
|
125
|
+
│ ├── auth/ # Auth helpers
|
|
126
|
+
│ │ ├── context.py # AuthContext
|
|
127
|
+
│ │ └── __init__.py
|
|
128
|
+
│ ├── schemas/ # Future: Pydantic models
|
|
129
|
+
│ └── utils/ # Future: Utilities
|
|
130
|
+
├── tests/
|
|
131
|
+
│ ├── conftest.py # Pytest fixtures
|
|
132
|
+
│ ├── test_auth_context.py # AuthContext tests
|
|
133
|
+
│ ├── test_node_plugin.py # NodePlugin tests
|
|
134
|
+
│ └── test_exceptions.py # Exception tests
|
|
135
|
+
├── pyproject.toml # Package config
|
|
136
|
+
├── README.md # User documentation
|
|
137
|
+
└── DEVELOPMENT.md # This file
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Adding New Features
|
|
141
|
+
|
|
142
|
+
### 1. Create the feature
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# src/loco_plugin_sdk/myfeature.py
|
|
146
|
+
def my_function():
|
|
147
|
+
"""My new feature."""
|
|
148
|
+
pass
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 2. Export in __init__.py
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# src/loco_plugin_sdk/__init__.py
|
|
155
|
+
from loco_plugin_sdk.myfeature import my_function
|
|
156
|
+
|
|
157
|
+
__all__ = [
|
|
158
|
+
# ... existing
|
|
159
|
+
"my_function",
|
|
160
|
+
]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3. Add tests
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# tests/test_myfeature.py
|
|
167
|
+
def test_my_function():
|
|
168
|
+
"""Test my new feature."""
|
|
169
|
+
result = my_function()
|
|
170
|
+
assert result is not None
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 4. Update documentation
|
|
174
|
+
|
|
175
|
+
Update README.md with usage examples.
|
|
176
|
+
|
|
177
|
+
## Publishing
|
|
178
|
+
|
|
179
|
+
### Build package
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Install build tools
|
|
183
|
+
pip install build twine
|
|
184
|
+
|
|
185
|
+
# Build distributions
|
|
186
|
+
python -m build
|
|
187
|
+
|
|
188
|
+
# Check build
|
|
189
|
+
twine check dist/*
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Publish to PyPI
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Test PyPI (recommended first)
|
|
196
|
+
twine upload --repository testpypi dist/*
|
|
197
|
+
|
|
198
|
+
# Production PyPI
|
|
199
|
+
twine upload dist/*
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Version bumping
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Update version in src/loco_plugin_sdk/version.py
|
|
206
|
+
__version__ = "0.2.0"
|
|
207
|
+
|
|
208
|
+
# Update version in pyproject.toml
|
|
209
|
+
version = "0.2.0"
|
|
210
|
+
|
|
211
|
+
# Commit and tag
|
|
212
|
+
git commit -am "Bump version to 0.2.0"
|
|
213
|
+
git tag v0.2.0
|
|
214
|
+
git push && git push --tags
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Continuous Integration
|
|
218
|
+
|
|
219
|
+
### GitHub Actions (example)
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
name: Tests
|
|
223
|
+
|
|
224
|
+
on: [push, pull_request]
|
|
225
|
+
|
|
226
|
+
jobs:
|
|
227
|
+
test:
|
|
228
|
+
runs-on: ubuntu-latest
|
|
229
|
+
strategy:
|
|
230
|
+
matrix:
|
|
231
|
+
python-version: ["3.11", "3.12"]
|
|
232
|
+
|
|
233
|
+
steps:
|
|
234
|
+
- uses: actions/checkout@v3
|
|
235
|
+
- uses: actions/setup-python@v4
|
|
236
|
+
with:
|
|
237
|
+
python-version: ${{ matrix.python-version }}
|
|
238
|
+
|
|
239
|
+
- name: Install dependencies
|
|
240
|
+
run: |
|
|
241
|
+
pip install -e ".[dev]"
|
|
242
|
+
|
|
243
|
+
- name: Run tests
|
|
244
|
+
run: |
|
|
245
|
+
pytest --cov=loco_plugin_sdk --cov-report=xml
|
|
246
|
+
|
|
247
|
+
- name: Upload coverage
|
|
248
|
+
uses: codecov/codecov-action@v3
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Best Practices
|
|
252
|
+
|
|
253
|
+
### Code Style
|
|
254
|
+
- Follow PEP 8
|
|
255
|
+
- Use type hints
|
|
256
|
+
- Write docstrings for public APIs
|
|
257
|
+
- Keep functions small and focused
|
|
258
|
+
|
|
259
|
+
### Testing
|
|
260
|
+
- Write tests for new features
|
|
261
|
+
- Maintain >80% code coverage
|
|
262
|
+
- Use descriptive test names
|
|
263
|
+
- Test edge cases and errors
|
|
264
|
+
|
|
265
|
+
### Documentation
|
|
266
|
+
- Update README for user-facing changes
|
|
267
|
+
- Add inline comments for complex logic
|
|
268
|
+
- Keep CHANGELOG.md updated
|
|
269
|
+
|
|
270
|
+
### Version Control
|
|
271
|
+
- Use feature branches
|
|
272
|
+
- Write clear commit messages
|
|
273
|
+
- Squash commits before merging
|
|
274
|
+
- Tag releases
|
|
275
|
+
|
|
276
|
+
## Troubleshooting
|
|
277
|
+
|
|
278
|
+
### Import errors
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Reinstall in editable mode
|
|
282
|
+
pip install -e .
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Test failures
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Run with verbose output
|
|
289
|
+
pytest -vv
|
|
290
|
+
|
|
291
|
+
# Show print statements
|
|
292
|
+
pytest -s
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Coverage not working
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
# Ensure coverage installed
|
|
299
|
+
pip install pytest-cov
|
|
300
|
+
|
|
301
|
+
# Clear cache
|
|
302
|
+
pytest --cache-clear
|
|
303
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Package metadata
|
|
2
|
+
include README.md
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include DEVELOPMENT.md
|
|
5
|
+
include LICENSE
|
|
6
|
+
|
|
7
|
+
# Source code
|
|
8
|
+
recursive-include src/loco_plugin_sdk *.py
|
|
9
|
+
|
|
10
|
+
# Tests
|
|
11
|
+
recursive-include tests *.py
|
|
12
|
+
|
|
13
|
+
# Exclude
|
|
14
|
+
global-exclude __pycache__
|
|
15
|
+
global-exclude *.py[cod]
|
|
16
|
+
global-exclude .DS_Store
|
loco_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loco-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Loco SDK for building plugins and shared utilities
|
|
5
|
+
Author: Loco Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: pydantic>=2.0.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
13
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
14
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
15
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
16
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
17
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
18
|
+
|
|
19
|
+
# Loco Plugin SDK
|
|
20
|
+
|
|
21
|
+
Official SDK for building Loco workflow plugins.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
### For Plugin Development
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Using pip
|
|
29
|
+
pip install loco-plugin-sdk
|
|
30
|
+
|
|
31
|
+
# Using uv (recommended)
|
|
32
|
+
uv pip install loco-plugin-sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### For SDK Development
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Clone repository
|
|
39
|
+
cd packages/loco-plugin-sdk
|
|
40
|
+
|
|
41
|
+
# Install with dev dependencies using uv
|
|
42
|
+
uv venv
|
|
43
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
44
|
+
uv pip install -e ".[dev]"
|
|
45
|
+
|
|
46
|
+
# Or with pip
|
|
47
|
+
pip install -e ".[dev]"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from loco_plugin_sdk import NodePlugin
|
|
54
|
+
|
|
55
|
+
class MyNode(NodePlugin):
|
|
56
|
+
"""My custom node."""
|
|
57
|
+
|
|
58
|
+
async def execute(self, inputs: dict, context: dict) -> dict:
|
|
59
|
+
"""
|
|
60
|
+
Execute node logic.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
inputs: Node input values
|
|
64
|
+
context: Workflow execution context with auth, sys_vars, etc.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Output values dictionary
|
|
68
|
+
"""
|
|
69
|
+
# Get authentication if needed
|
|
70
|
+
auth = context.get("auth")
|
|
71
|
+
if auth:
|
|
72
|
+
headers = auth.get_header()
|
|
73
|
+
# Use headers for API calls
|
|
74
|
+
|
|
75
|
+
# Process inputs
|
|
76
|
+
result = do_something(inputs)
|
|
77
|
+
|
|
78
|
+
# Return outputs
|
|
79
|
+
return {"result": result}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Authentication Helper
|
|
83
|
+
|
|
84
|
+
The SDK provides `AuthContext` to easily work with credentials:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from loco_sdk import NodePlugin, AuthContext
|
|
88
|
+
|
|
89
|
+
class MyNode(NodePlugin):
|
|
90
|
+
async def execute(self, inputs: dict, context: dict) -> dict:
|
|
91
|
+
# Wrap auth dict with helper
|
|
92
|
+
auth = AuthContext(context.get("auth"))
|
|
93
|
+
|
|
94
|
+
# Get Authorization header
|
|
95
|
+
headers = auth.get_header()
|
|
96
|
+
# Returns: {"Authorization": "Bearer <token>"}
|
|
97
|
+
|
|
98
|
+
# Check token expiry
|
|
99
|
+
if auth.is_expired():
|
|
100
|
+
raise AuthenticationError("Token expired")
|
|
101
|
+
|
|
102
|
+
# Access properties
|
|
103
|
+
provider = auth.provider # e.g., "google"
|
|
104
|
+
scopes = auth.scopes # OAuth scopes
|
|
105
|
+
|
|
106
|
+
# Use in API calls
|
|
107
|
+
response = await client.get(url, headers=headers)
|
|
108
|
+
return {"data": response.json()}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Features
|
|
112
|
+
|
|
113
|
+
- **NodePlugin Base Class**: Simple interface for workflow nodes
|
|
114
|
+
- **AuthContext Helper**: Easy OAuth2/API key authentication
|
|
115
|
+
- **Type Safety**: Full Pydantic schema support (coming soon)
|
|
116
|
+
- **Manifest Loading**: Parse plugin.yaml files (coming soon)
|
|
117
|
+
- **Testing**: Comprehensive test suite with pytest
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed development guide including:
|
|
122
|
+
- Setting up development environment with uv
|
|
123
|
+
- Running tests with pytest
|
|
124
|
+
- Code formatting and linting
|
|
125
|
+
- Publishing to PyPI
|
|
126
|
+
|
|
127
|
+
### Quick Commands
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Run tests
|
|
131
|
+
pytest
|
|
132
|
+
|
|
133
|
+
# Run tests with coverage
|
|
134
|
+
pytest --cov=loco_plugin_sdk --cov-report=html
|
|
135
|
+
|
|
136
|
+
# Format code
|
|
137
|
+
black src tests
|
|
138
|
+
|
|
139
|
+
# Lint code
|
|
140
|
+
ruff check src tests
|
|
141
|
+
|
|
142
|
+
# Type check
|
|
143
|
+
mypy src
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
See [docs/](docs/) for detailed guides (coming soon).
|
|
149
|
+
|
|
150
|
+
## Version
|
|
151
|
+
|
|
152
|
+
0.1.0
|
loco_sdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Loco Plugin SDK
|
|
2
|
+
|
|
3
|
+
Official SDK for building Loco workflow plugins.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### For Plugin Development
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Using pip
|
|
11
|
+
pip install loco-plugin-sdk
|
|
12
|
+
|
|
13
|
+
# Using uv (recommended)
|
|
14
|
+
uv pip install loco-plugin-sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### For SDK Development
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Clone repository
|
|
21
|
+
cd packages/loco-plugin-sdk
|
|
22
|
+
|
|
23
|
+
# Install with dev dependencies using uv
|
|
24
|
+
uv venv
|
|
25
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
26
|
+
uv pip install -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
# Or with pip
|
|
29
|
+
pip install -e ".[dev]"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from loco_plugin_sdk import NodePlugin
|
|
36
|
+
|
|
37
|
+
class MyNode(NodePlugin):
|
|
38
|
+
"""My custom node."""
|
|
39
|
+
|
|
40
|
+
async def execute(self, inputs: dict, context: dict) -> dict:
|
|
41
|
+
"""
|
|
42
|
+
Execute node logic.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
inputs: Node input values
|
|
46
|
+
context: Workflow execution context with auth, sys_vars, etc.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Output values dictionary
|
|
50
|
+
"""
|
|
51
|
+
# Get authentication if needed
|
|
52
|
+
auth = context.get("auth")
|
|
53
|
+
if auth:
|
|
54
|
+
headers = auth.get_header()
|
|
55
|
+
# Use headers for API calls
|
|
56
|
+
|
|
57
|
+
# Process inputs
|
|
58
|
+
result = do_something(inputs)
|
|
59
|
+
|
|
60
|
+
# Return outputs
|
|
61
|
+
return {"result": result}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Authentication Helper
|
|
65
|
+
|
|
66
|
+
The SDK provides `AuthContext` to easily work with credentials:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from loco_sdk import NodePlugin, AuthContext
|
|
70
|
+
|
|
71
|
+
class MyNode(NodePlugin):
|
|
72
|
+
async def execute(self, inputs: dict, context: dict) -> dict:
|
|
73
|
+
# Wrap auth dict with helper
|
|
74
|
+
auth = AuthContext(context.get("auth"))
|
|
75
|
+
|
|
76
|
+
# Get Authorization header
|
|
77
|
+
headers = auth.get_header()
|
|
78
|
+
# Returns: {"Authorization": "Bearer <token>"}
|
|
79
|
+
|
|
80
|
+
# Check token expiry
|
|
81
|
+
if auth.is_expired():
|
|
82
|
+
raise AuthenticationError("Token expired")
|
|
83
|
+
|
|
84
|
+
# Access properties
|
|
85
|
+
provider = auth.provider # e.g., "google"
|
|
86
|
+
scopes = auth.scopes # OAuth scopes
|
|
87
|
+
|
|
88
|
+
# Use in API calls
|
|
89
|
+
response = await client.get(url, headers=headers)
|
|
90
|
+
return {"data": response.json()}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Features
|
|
94
|
+
|
|
95
|
+
- **NodePlugin Base Class**: Simple interface for workflow nodes
|
|
96
|
+
- **AuthContext Helper**: Easy OAuth2/API key authentication
|
|
97
|
+
- **Type Safety**: Full Pydantic schema support (coming soon)
|
|
98
|
+
- **Manifest Loading**: Parse plugin.yaml files (coming soon)
|
|
99
|
+
- **Testing**: Comprehensive test suite with pytest
|
|
100
|
+
|
|
101
|
+
## Development
|
|
102
|
+
|
|
103
|
+
See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed development guide including:
|
|
104
|
+
- Setting up development environment with uv
|
|
105
|
+
- Running tests with pytest
|
|
106
|
+
- Code formatting and linting
|
|
107
|
+
- Publishing to PyPI
|
|
108
|
+
|
|
109
|
+
### Quick Commands
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Run tests
|
|
113
|
+
pytest
|
|
114
|
+
|
|
115
|
+
# Run tests with coverage
|
|
116
|
+
pytest --cov=loco_plugin_sdk --cov-report=html
|
|
117
|
+
|
|
118
|
+
# Format code
|
|
119
|
+
black src tests
|
|
120
|
+
|
|
121
|
+
# Lint code
|
|
122
|
+
ruff check src tests
|
|
123
|
+
|
|
124
|
+
# Type check
|
|
125
|
+
mypy src
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Documentation
|
|
129
|
+
|
|
130
|
+
See [docs/](docs/) for detailed guides (coming soon).
|
|
131
|
+
|
|
132
|
+
## Version
|
|
133
|
+
|
|
134
|
+
0.1.0
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "loco-sdk"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Loco SDK for building plugins and shared utilities"
|
|
5
|
+
authors = [{name = "Loco Team"}]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
requires-python = ">=3.11"
|
|
8
|
+
license = {text = "MIT"}
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
"pydantic>=2.0.0",
|
|
12
|
+
"pyyaml>=6.0.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
dev = [
|
|
17
|
+
"pytest>=7.0.0",
|
|
18
|
+
"pytest-asyncio>=0.21.0",
|
|
19
|
+
"pytest-cov>=4.0.0",
|
|
20
|
+
"black>=23.0.0",
|
|
21
|
+
"ruff>=0.1.0",
|
|
22
|
+
"mypy>=1.0.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = ["setuptools>=68.0.0", "wheel"]
|
|
27
|
+
build-backend = "setuptools.build_meta"
|
|
28
|
+
|
|
29
|
+
[tool.setuptools.packages.find]
|
|
30
|
+
where = ["src"]
|
|
31
|
+
|
|
32
|
+
[tool.black]
|
|
33
|
+
line-length = 100
|
|
34
|
+
target-version = ['py311']
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
line-length = 100
|
|
38
|
+
target-version = "py311"
|
|
39
|
+
|
|
40
|
+
[tool.ruff.lint]
|
|
41
|
+
select = ["E", "F", "I", "N", "W", "UP"]
|
|
42
|
+
ignore = ["E501"]
|
|
43
|
+
|
|
44
|
+
[tool.pytest.ini_options]
|
|
45
|
+
testpaths = ["tests"]
|
|
46
|
+
python_files = ["test_*.py"]
|
|
47
|
+
python_classes = ["Test*"]
|
|
48
|
+
python_functions = ["test_*"]
|
|
49
|
+
asyncio_mode = "auto"
|
|
50
|
+
|
|
51
|
+
[tool.coverage.run]
|
|
52
|
+
source = ["src"]
|
|
53
|
+
omit = ["*/tests/*", "*/test_*.py"]
|
|
54
|
+
|
|
55
|
+
[tool.coverage.report]
|
|
56
|
+
exclude_lines = [
|
|
57
|
+
"pragma: no cover",
|
|
58
|
+
"def __repr__",
|
|
59
|
+
"raise AssertionError",
|
|
60
|
+
"raise NotImplementedError",
|
|
61
|
+
"if __name__ == .__main__.:",
|
|
62
|
+
"if TYPE_CHECKING:",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.mypy]
|
|
66
|
+
python_version = "3.11"
|
|
67
|
+
warn_return_any = true
|
|
68
|
+
warn_unused_configs = true
|
|
69
|
+
disallow_untyped_defs = true
|
loco_sdk-0.1.0/setup.cfg
ADDED