Contributing¶
Contributing to fabias¶
Thank you for your interest in contributing to fabias! This document provides guidelines and instructions for contributing.
Development Setup¶
Prerequisites¶
- Python 3.9 or higher
- Git
Installation¶
-
Clone the repository:
-
Create a virtual environment:
-
Install in development mode with dev dependencies:
-
(Optional) Install documentation dependencies:
Project Structure¶
fabias/
├── src/fabias/ # Source code
│ ├── _shared/ # Internal shared utilities (auth, client, exceptions)
│ ├── fabric/ # Microsoft Fabric API
│ ├── datafactory/ # Azure Data Factory API
│ ├── teams/ # Microsoft Teams API
│ ├── secrets/ # Azure Key Vault API
│ └── cards/ # Adaptive Cards builder
├── tests/ # Test files
├── docs/ # Documentation (MkDocs)
└── pyproject.toml # Project configuration
Code Style¶
Naming Conventions¶
- Methods: camelCase (e.g.,
workspace.pipelines(),role.toJson()) - Properties: snake_case (e.g.,
workspace.capacity_id,connection.privacy_level) - Classes: PascalCase (e.g.,
FabricClient,ServicePrincipalAuth) - Module functions: snake_case (e.g.,
fabric.workspace())
Type Hints¶
All public APIs must have type annotations:
def workspace(workspace_id: Optional[str] = None) -> Workspace:
"""Get a workspace by name or ID."""
...
Docstrings¶
Use Google-style docstrings with Args, Returns, Raises, and Examples:
def pipeline(self, identifier: str) -> Pipeline:
"""
Get a specific pipeline by name or ID.
Args:
identifier: Pipeline name or GUID
Returns:
Pipeline: The pipeline object
Raises:
NotFoundError: If pipeline not found
Examples:
>>> pipeline = workspace.pipeline("Daily ETL")
>>> job = pipeline.run()
"""
Testing¶
Running Tests¶
# Run all unit tests (integration tests excluded by default)
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/test_fabric_unit.py
# Run integration tests (requires credentials)
pytest -m integration
# Run with coverage
pytest --cov=src/fabias --cov-report=term-missing
Test Organization¶
- Unit tests: Use
responseslibrary to mock HTTP calls. Fast and safe. - Integration tests: Real API calls. Marked with
@pytest.mark.integration.
Writing Tests¶
import pytest
import responses
import fabias.fabric as fabric
class TestMyFeature:
@responses.activate
def test_my_feature_works(self, mock_auth):
"""Test that my feature works correctly."""
# Mock the API response
responses.add(
responses.GET,
"https://api.fabric.microsoft.com/v1/workspaces",
json={"value": [{"id": "ws-1", "displayName": "Test"}]},
status=200
)
fabric.client(auth=mock_auth)
workspaces = fabric.workspaces()
assert len(workspaces) == 1
assert workspaces[0].name == "Test"
Type Checking¶
Run mypy to check type hints:
Pull Request Process¶
- Fork the repository and create a feature branch
- Write tests for any new functionality
- Run the test suite and ensure all tests pass
- Run mypy and fix any type errors
- Update documentation if needed
- Submit a pull request with a clear description
PR Checklist¶
- [ ] Tests added for new functionality
- [ ] All tests passing (
pytest) - [ ] Type hints added (
mypypasses) - [ ] Docstrings added for public APIs
- [ ] CHANGELOG.md updated (if applicable)
API Design Patterns¶
Pattern 1: Single Retrieval¶
Pattern 2: List Retrieval¶
Pattern 3: Create via Accessor¶
Lazy Loading¶
All resource objects should support lazy loading:
class MyResource:
def __init__(self, client, identifier=None, resource_data=None):
self._client = client
self._data_fetched = False
if resource_data:
# Pre-populated - no API call needed
self._populate_from_data(resource_data)
self._data_fetched = True
elif GUID.valid(identifier):
# GUID provided - store, don't fetch yet
self._id = identifier
else:
# Name provided - resolve now
self._resolve_identifier(identifier)
Questions?¶
Open an issue on GitHub or reach out to the maintainers.