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.
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+