Thank you for your interest in contributing! This guide will help you get started.
- Python 3.8+
- pip
- Docker & docker-compose (optional, recommended)
We welcome contributions in these areas:
- bug fixes
- documentation improvements
- tests
- performance improvements with evidence
- better error handling
- API consistency improvements
- support for new upstream API features
- refactoring that reduces maintenance burden without changing behavior
We are more cautious about:
- breaking public API changes
- large stylistic rewrites
- new dependencies
- “helper” abstractions that hide important API behavior
- speculative features that the upstream API does not support
The reason is simple: SDK users usually value stability and clarity more than novelty.
git checkout -b your-feature-branchAll SDK source lives under signnow/. Each API domain is a sub-package under
signnow/api/ with request/ and response/ directories.
make lint # check formatting + Flake8
make format # auto-format with Blackmake test # all unit tests
make test-cov # with coverage report (htmlcov/)
make test-api # only mock-API integration testsOr run the full CI check in one command:
make check # lint + typecheck + testsTests do not require a .env file — they use mocked HTTP responses.
make docker-build
make docker-test- Formatter: Black with default 88-char line length.
- Linter: Flake8 (E203/W503/E501 ignored).
- Type hints: Use them on all public APIs. Run
make typecheck(mypy) to verify.
| Item | Convention | Example |
|---|---|---|
| Request class | {Entity}{Method}Request |
DocumentPostRequest |
| Response class | {Entity}{Method}Response |
DocumentPostResponse |
| Request file | {entity}_{method}_request.py |
document_post_request.py |
| Response file | {entity}_{method}_response.py |
document_post_response.py |
| Test file | test_{domain}.py |
test_document.py |
Every API endpoint is a pair of request + response classes:
# signnow/api/example/request/thing_get_request.py
from signnow.core.request import RequestInterface, api_endpoint
@api_endpoint(
name="getThing",
url="/thing/{thing_id}",
method="get",
auth="bearer",
namespace="example",
entity="thing",
)
class ThingGetRequest(RequestInterface):
def __init__(self):
self._uri_params = {}
def with_thing_id(self, thing_id: str) -> "ThingGetRequest":
self._uri_params["thing_id"] = thing_id
return self
def uri_params(self):
return dict(self._uri_params)
def payload(self):
return {}- One test file per API domain in
tests/api/. - Test request creation, response structure, and mock API calls.
- Use the
mock_api_clientfixture fromconftest.pyfor API-call tests.
- Ensure
make checkpasses. - Write or update tests for your changes.
- Keep commits focused — one logical change per commit.
- Open a PR against
masterwith a clear description.
Open an issue on GitHub with:
- Minimal reproduction steps
- Full traceback if applicable