spgroup 1.0.3__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.
Files changed (70) hide show
  1. spgroup-1.0.3/.gitattributes +27 -0
  2. spgroup-1.0.3/.github/dependabot.yml +19 -0
  3. spgroup-1.0.3/.github/workflows/release.yml +113 -0
  4. spgroup-1.0.3/.github/workflows/semantic-release.yml +37 -0
  5. spgroup-1.0.3/.gitignore +10 -0
  6. spgroup-1.0.3/.postman/resources.yaml +7 -0
  7. spgroup-1.0.3/.pre-commit-config.yaml +17 -0
  8. spgroup-1.0.3/AGENTS.md +85 -0
  9. spgroup-1.0.3/CHANGELOG.md +58 -0
  10. spgroup-1.0.3/LICENSE +21 -0
  11. spgroup-1.0.3/MANIFEST.in +2 -0
  12. spgroup-1.0.3/PKG-INFO +52 -0
  13. spgroup-1.0.3/README.md +36 -0
  14. spgroup-1.0.3/docs/adr/adr-two-mode-sdk-vendoring.md +248 -0
  15. spgroup-1.0.3/docs/api/README.md +88 -0
  16. spgroup-1.0.3/docs/api/auth-profile-parity-inventory.md +63 -0
  17. spgroup-1.0.3/docs/api/auth0-api.md +231 -0
  18. spgroup-1.0.3/docs/api/auth0-flow.md +191 -0
  19. spgroup-1.0.3/docs/api/content-api.md +64 -0
  20. spgroup-1.0.3/docs/api/ev-api.md +102 -0
  21. spgroup-1.0.3/docs/api/frieza-api.md +159 -0
  22. spgroup-1.0.3/docs/api/greenup-api.md +74 -0
  23. spgroup-1.0.3/docs/api/jarvis-api.md +318 -0
  24. spgroup-1.0.3/docs/api/jarvis-parity-inventory.md +59 -0
  25. spgroup-1.0.3/docs/api/live-e2e.md +132 -0
  26. spgroup-1.0.3/docs/api/models.md +235 -0
  27. spgroup-1.0.3/docs/api/network-layer.md +133 -0
  28. spgroup-1.0.3/docs/api/payment-api.md +268 -0
  29. spgroup-1.0.3/docs/api/queries.md +198 -0
  30. spgroup-1.0.3/docs/api/response-schemas.md +306 -0
  31. spgroup-1.0.3/docs/api/sdk-foundations.md +83 -0
  32. spgroup-1.0.3/docs/api/skalbox-api.md +133 -0
  33. spgroup-1.0.3/docs/api/utility-apis.md +85 -0
  34. spgroup-1.0.3/docs/api/yggdrasil-api.md +219 -0
  35. spgroup-1.0.3/docs/context-tracker.md +69 -0
  36. spgroup-1.0.3/docs/dev-workflow.md +709 -0
  37. spgroup-1.0.3/docs/plans/sdk-vendoring.md +534 -0
  38. spgroup-1.0.3/docs/postman-collection.json +543 -0
  39. spgroup-1.0.3/docs/sdk-parity-roadmap.md +204 -0
  40. spgroup-1.0.3/docs/sp-mobile-api.postman_collection.json +1246 -0
  41. spgroup-1.0.3/mise.toml +30 -0
  42. spgroup-1.0.3/postman/collections/energy-monitoring-api.json +577 -0
  43. spgroup-1.0.3/postman/collections/sp-mobile-api.json +1395 -0
  44. spgroup-1.0.3/postman/environments/local.json +91 -0
  45. spgroup-1.0.3/pyproject.toml +64 -0
  46. spgroup-1.0.3/setup.cfg +4 -0
  47. spgroup-1.0.3/src/spgroup/__init__.py +23 -0
  48. spgroup-1.0.3/src/spgroup/auth.py +14 -0
  49. spgroup-1.0.3/src/spgroup/client.py +17 -0
  50. spgroup-1.0.3/src/spgroup/mobile/__init__.py +31 -0
  51. spgroup-1.0.3/src/spgroup/mobile/auth.py +336 -0
  52. spgroup-1.0.3/src/spgroup/mobile/constants.py +51 -0
  53. spgroup-1.0.3/src/spgroup/mobile/errors.py +65 -0
  54. spgroup-1.0.3/src/spgroup/mobile/jarvis.py +302 -0
  55. spgroup-1.0.3/src/spgroup/mobile/models.py +26 -0
  56. spgroup-1.0.3/src/spgroup/mobile/profile.py +178 -0
  57. spgroup-1.0.3/src/spgroup/mobile/request.py +201 -0
  58. spgroup-1.0.3/src/spgroup/mobile/resource.py +116 -0
  59. spgroup-1.0.3/src/spgroup/mobile/session.py +213 -0
  60. spgroup-1.0.3/src/spgroup/mobile/transport.py +96 -0
  61. spgroup-1.0.3/src/spgroup/mobile/yggdrasil.py +235 -0
  62. spgroup-1.0.3/src/spgroup/models.py +16 -0
  63. spgroup-1.0.3/src/spgroup/py.typed +1 -0
  64. spgroup-1.0.3/src/spgroup.egg-info/PKG-INFO +52 -0
  65. spgroup-1.0.3/src/spgroup.egg-info/SOURCES.txt +68 -0
  66. spgroup-1.0.3/src/spgroup.egg-info/dependency_links.txt +1 -0
  67. spgroup-1.0.3/src/spgroup.egg-info/requires.txt +1 -0
  68. spgroup-1.0.3/src/spgroup.egg-info/scm_file_list.json +77 -0
  69. spgroup-1.0.3/src/spgroup.egg-info/scm_version.json +8 -0
  70. spgroup-1.0.3/src/spgroup.egg-info/top_level.txt +1 -0
@@ -0,0 +1,27 @@
1
+ # Auto-detect text files and normalize line endings
2
+ * text=auto
3
+
4
+ # Python source
5
+ *.py text diff=python
6
+
7
+ # Markdown
8
+ *.md text diff=markdown
9
+
10
+ # YAML
11
+ *.yml text
12
+ *.yaml text
13
+
14
+ # TOML
15
+ *.toml text
16
+
17
+ # JSON
18
+ *.json text
19
+
20
+ # Binary files — keep as-is
21
+ *.png binary
22
+ *.jpg binary
23
+ *.ico binary
24
+ *.apk binary
25
+ *.keystore binary
26
+ *.jar binary
27
+ *.idsig binary
@@ -0,0 +1,19 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ day: "monday"
8
+ open-pull-requests-limit: 5
9
+ labels:
10
+ - "dependencies"
11
+
12
+ - package-ecosystem: "github-actions"
13
+ directory: "/"
14
+ schedule:
15
+ interval: "weekly"
16
+ day: "monday"
17
+ open-pull-requests-limit: 5
18
+ labels:
19
+ - "dependencies"
@@ -0,0 +1,113 @@
1
+ name: Publish spgroup to PyPI
2
+ run-name: ${{ github.actor }} is publishing spgroup to PyPI
3
+
4
+ on: [push]
5
+
6
+ jobs:
7
+ build:
8
+ name: Build distribution
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - name: Set up Python
14
+ uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.13"
17
+ - name: Install build tools
18
+ run: |
19
+ python -m pip install build
20
+ python -m pip install -e . pytest
21
+ - name: Build a binary wheel and a source tarball
22
+ run: python -m build
23
+ - name: Verify wheel and sdist integrity
24
+ run: python -m pytest tests/test_sdk_packaging.py -v
25
+ - name: Store the distribution packages
26
+ uses: actions/upload-artifact@v4
27
+ with:
28
+ name: python-package-distributions
29
+ path: dist/
30
+
31
+ publish-to-testpypi:
32
+ name: Publish to TestPyPI
33
+ if: github.ref_name == 'main' && !startsWith(github.ref, 'refs/tags/')
34
+ needs: [build]
35
+ runs-on: ubuntu-latest
36
+
37
+ environment:
38
+ name: testpypi
39
+ url: https://test.pypi.org/p/spgroup
40
+
41
+ permissions:
42
+ id-token: write
43
+
44
+ steps:
45
+ - name: Download all the dists
46
+ uses: actions/download-artifact@v4
47
+ with:
48
+ name: python-package-distributions
49
+ path: dist/
50
+ - name: Publish distribution to TestPyPI
51
+ uses: pypa/gh-action-pypi-publish@release/v1
52
+ with:
53
+ repository-url: https://test.pypi.org/legacy/
54
+
55
+ publish-to-pypi:
56
+ name: Publish to PyPI
57
+ if: startsWith(github.ref, 'refs/tags/')
58
+ needs: [build]
59
+ runs-on: ubuntu-latest
60
+
61
+ environment:
62
+ name: pypi
63
+ url: https://pypi.org/p/spgroup
64
+
65
+ permissions:
66
+ id-token: write
67
+
68
+ steps:
69
+ - name: Download all the dists
70
+ uses: actions/download-artifact@v4
71
+ with:
72
+ name: python-package-distributions
73
+ path: dist/
74
+ - name: Publish distribution to PyPI
75
+ uses: pypa/gh-action-pypi-publish@release/v1
76
+
77
+ github-release:
78
+ name: Sign and upload to GitHub Release
79
+ if: startsWith(github.ref, 'refs/tags/')
80
+ needs: [publish-to-pypi]
81
+ runs-on: ubuntu-latest
82
+
83
+ permissions:
84
+ contents: write
85
+ id-token: write
86
+
87
+ steps:
88
+ - name: Download all the dists
89
+ uses: actions/download-artifact@v4
90
+ with:
91
+ name: python-package-distributions
92
+ path: dist/
93
+ - name: Sign the dists with Sigstore
94
+ uses: sigstore/gh-action-sigstore-python@v2.1.1
95
+ with:
96
+ inputs: >-
97
+ ./dist/*.tar.gz
98
+ ./dist/*.whl
99
+ - name: Create GitHub Release
100
+ env:
101
+ GITHUB_TOKEN: ${{ github.token }}
102
+ run: >-
103
+ gh release create
104
+ '${{ github.ref_name }}'
105
+ --repo '${{ github.repository }}'
106
+ --notes ""
107
+ - name: Upload artifact signatures to GitHub Release
108
+ env:
109
+ GITHUB_TOKEN: ${{ github.token }}
110
+ run: >-
111
+ gh release upload
112
+ '${{ github.ref_name }}' dist/**
113
+ --repo '${{ github.repository }}'
@@ -0,0 +1,37 @@
1
+ name: Semantic Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ concurrency: release
11
+ permissions:
12
+ contents: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0
18
+ # Use the PAT for checkout so git push triggers downstream workflows.
19
+ # GITHUB_TOKEN pushes are intentionally blocked from cascading.
20
+ token: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v5
24
+ with:
25
+ python-version: "3.13"
26
+
27
+ - name: Install python-semantic-release
28
+ run: python -m pip install python-semantic-release
29
+
30
+ - name: Run semantic release
31
+ env:
32
+ GH_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
33
+ run: |
34
+ git config user.name "semantic-release"
35
+ git config user.email "semantic-release"
36
+ semantic-release version
37
+ semantic-release publish
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .DS_Store
7
+ node_modules/
8
+ .runtime/
9
+ .pytest_cache/
10
+ prototype/
@@ -0,0 +1,7 @@
1
+ workspace:
2
+ id: 030fd6da-c0cc-428e-8c68-0b63593aa702
3
+ collections:
4
+ - path: postman/collections/energy-monitoring-api.json
5
+ - path: postman/collections/sp-mobile-api.json
6
+ environments:
7
+ - path: postman/environments/local.json
@@ -0,0 +1,17 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.15.21
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v5.0.0
11
+ hooks:
12
+ - id: check-yaml
13
+ - id: check-toml
14
+ - id: check-added-large-files
15
+ - id: trailing-whitespace
16
+ - id: end-of-file-fixer
17
+ - id: check-merge-conflict
@@ -0,0 +1,85 @@
1
+ # spgroup SDK — Repository Guidelines
2
+
3
+ Async Python SDK for SP Group mobile APIs, reverse-engineered from the
4
+ Android app (v15.9.0). Published as `spgroup` on PyPI.
5
+
6
+ Consumed by the HA integration in
7
+ [energy-monitoring](../energy-monitoring/).
8
+
9
+ ---
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ git clone https://github.com/ashe0047/spgroup.git
15
+ cd spgroup
16
+ mise run python:install
17
+ mise run python:test
18
+ mise run python:lint
19
+ ```
20
+
21
+ ## Commands
22
+
23
+ | Command | Purpose |
24
+ |---|---|
25
+ | `mise run python:install` | Editable install + pinned dev deps |
26
+ | `mise run python:test` | Hermetic test suite (77 tests) |
27
+ | `mise run python:test:e2e` | Opt-in live e2e tests (needs session) |
28
+ | `mise run python:lint` | Ruff check + mypy |
29
+ | `mise run python:build` | Build wheel + sdist |
30
+ | `mise run python:publish:testpypi` | Upload to TestPyPI via twine |
31
+ | `mise run python:publish` | Upload to production PyPI via twine |
32
+
33
+ ---
34
+
35
+ ## Key Docs
36
+
37
+ | Doc | What it covers |
38
+ |---|---|
39
+ | [`docs/dev-workflow.md`](docs/dev-workflow.md) | Full dev-to-release process: setup, test strategy, CI/CD pipeline, environment gating, publishing, troubleshooting |
40
+ | [`docs/sdk-parity-roadmap.md`](docs/sdk-parity-roadmap.md) | SDK coverage plan, APK parity milestones |
41
+ | [`docs/context-tracker.md`](docs/context-tracker.md) | Decision log and discovery trail |
42
+ | [`docs/api/`](docs/api/) | Reverse-engineered API reference |
43
+ | [`.github/workflows/release.yml`](.github/workflows/release.yml) | CI/CD pipeline (4 jobs: Build, TestPyPI, PyPI, GitHub Release) |
44
+
45
+ ## Publishing
46
+
47
+ **CI/CD (recommended):** Push a `vX.Y.Z` tag. The pipeline publishes via
48
+ Trusted Publishing (OIDC) — no tokens needed. See
49
+ [docs/dev-workflow.md](docs/dev-workflow.md) for the full walkthrough.
50
+
51
+ **Local:** `mise run python:build` → `mise run python:publish:testpypi` →
52
+ verify → `mise run python:publish`. Never run `twine upload` directly without
53
+ first confirming via TestPyPI.
54
+
55
+ ## Project Structure
56
+
57
+ | Path | Contents |
58
+ |---|---|
59
+ | `src/spgroup/` | SDK source (17 files, public API in `__init__.py`) |
60
+ | `tests/` | Hermetic tests (3 test files) |
61
+ | `tests/e2e/` | Opt-in live tests (9 tests, skipped by default) |
62
+ | `docs/` | API reference, roadmaps, dev workflow guide |
63
+ | `postman/` | Postman collections + environment |
64
+ | `prototype/` | TypeScript harness (local only, not tracked) |
65
+
66
+ ## Conventions
67
+
68
+ - Use `python`, not `python3`, when invoking Python directly.
69
+ - All source files use `from __future__ import annotations`.
70
+ - Follow [Conventional Commits](https://www.conventionalcommits.org/) for all
71
+ commit messages. See [`docs/dev-workflow.md`](docs/dev-workflow.md) for the
72
+ full type reference.
73
+ - Do not hardcode credentials — use `transport.redact_json()` for safe output.
74
+ - New sensitive response fields go in `SENSITIVE_KEYS` in
75
+ `src/spgroup/mobile/transport.py`.
76
+ - Hermetic tests go in `tests/`, e2e tests in `tests/e2e/`.
77
+ - Packaging changes require updating `tests/test_sdk_packaging.py`.
78
+ - Pushing to `main` triggers automatic version bumping via
79
+ `python-semantic-release`. No manual tag creation is needed for releases.
80
+
81
+ ## Agent Instructions
82
+
83
+ Append discoveries and decisions to `docs/context-tracker.md`. For detailed
84
+ development workflow, CI/CD pipeline layout, and release steps, refer to
85
+ `docs/dev-workflow.md`.
@@ -0,0 +1,58 @@
1
+ # CHANGELOG
2
+
3
+ <!-- version list -->
4
+
5
+ ## v1.0.3 (2026-07-18)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Pass PAT as checkout token so git push triggers downstream workflows
10
+ ([`2b04bab`](https://github.com/ashe0047/spgroup/commit/2b04bab8dc2a7f0cc6a9ea893714ebb1ada323a0))
11
+
12
+
13
+ ## v1.0.2 (2026-07-18)
14
+
15
+ ### Bug Fixes
16
+
17
+ - Verify PAT cascade for release pipeline
18
+ ([`90c4c05`](https://github.com/ashe0047/spgroup/commit/90c4c0501d76b2b1f65ef7f6b351c7dcec24cb46))
19
+
20
+
21
+ ## v1.0.1 (2026-07-18)
22
+
23
+ ### Bug Fixes
24
+
25
+ - Correct version_variables format for semantic-release (needs :__version__)
26
+ ([`51e8b5b`](https://github.com/ashe0047/spgroup/commit/51e8b5b47cc84fce18ed93fc8a4e408a9ce9bcee))
27
+
28
+ - Trigger full CI pipeline verify with PAT cascade
29
+ ([`579117a`](https://github.com/ashe0047/spgroup/commit/579117a4b2247e9e9ae1f44c5772a43b698b0ae9))
30
+
31
+ ### Chores
32
+
33
+ - Add __version__, .gitattributes, fix lint issues, configure semantic-release version management
34
+ ([`0ade9c4`](https://github.com/ashe0047/spgroup/commit/0ade9c42c95be7cded641fa71433e05d5f4ddf48))
35
+
36
+ - Add pre-commit hooks, dependabot config, register live pytest marker, document in dev-workflow
37
+ ([`8256df1`](https://github.com/ashe0047/spgroup/commit/8256df19ae7ff702a7ddb731c258af1866b525ef))
38
+
39
+ - Remove root resources.yaml (duplicate of .postman/resources.yaml)
40
+ ([`1a16cbd`](https://github.com/ashe0047/spgroup/commit/1a16cbd733643410cedf698a9f55e2ea4dd416b7))
41
+
42
+ ### Documentation
43
+
44
+ - Document devN pre-release versions in version management and TestPyPI sections
45
+ ([`c003c7b`](https://github.com/ashe0047/spgroup/commit/c003c7bf04f474e3d1dae7706a273a9e7e18a621))
46
+
47
+
48
+ ## v1.0.0 (2026-07-18)
49
+
50
+ ### Features
51
+
52
+ - **ci**: Setup conventional commits and python-semantic-release for automatic version bumping
53
+ ([`b627880`](https://github.com/ashe0047/spgroup/commit/b627880f67ef3e89c0d124ec285b523b5ba1fa25))
54
+
55
+
56
+ ## v0.1.0 (2026-07-17)
57
+
58
+ - Initial Release
spgroup-1.0.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Aw Sheng Xiang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ exclude tests
2
+ recursive-exclude tests *
spgroup-1.0.3/PKG-INFO ADDED
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.4
2
+ Name: spgroup
3
+ Version: 1.0.3
4
+ Summary: Async Python SDK scaffold for SP Group APIs
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/ashe0047/spgroup
7
+ Project-URL: Source, https://github.com/ashe0047/spgroup
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: aiohttp>=3.9
15
+ Dynamic: license-file
16
+
17
+ # spgroup
18
+
19
+ Async Python SDK for SP Group (Singapore Power) utility APIs.
20
+
21
+ Reverse-engineered from the SP Group Android mobile app (v15.9.0).
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install spgroup
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```python
32
+ import asyncio
33
+ from spgroup import MobileAuthClient, JarvisClient
34
+
35
+ async def main():
36
+ auth = MobileAuthClient(session=None)
37
+ print(f"Client ID: {auth._client_id}")
38
+
39
+ asyncio.run(main())
40
+ ```
41
+
42
+ ## Documentation
43
+
44
+ API reference and usage guides are available on
45
+ [GitHub](https://github.com/ashe0047/spgroup).
46
+
47
+ For developers working on the SDK: see `docs/`, `prototype/`, and `postman/`
48
+ in the [GitHub repository](https://github.com/ashe0047/spgroup).
49
+
50
+ ## License
51
+
52
+ MIT
@@ -0,0 +1,36 @@
1
+ # spgroup
2
+
3
+ Async Python SDK for SP Group (Singapore Power) utility APIs.
4
+
5
+ Reverse-engineered from the SP Group Android mobile app (v15.9.0).
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install spgroup
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ import asyncio
17
+ from spgroup import MobileAuthClient, JarvisClient
18
+
19
+ async def main():
20
+ auth = MobileAuthClient(session=None)
21
+ print(f"Client ID: {auth._client_id}")
22
+
23
+ asyncio.run(main())
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ API reference and usage guides are available on
29
+ [GitHub](https://github.com/ashe0047/spgroup).
30
+
31
+ For developers working on the SDK: see `docs/`, `prototype/`, and `postman/`
32
+ in the [GitHub repository](https://github.com/ashe0047/spgroup).
33
+
34
+ ## License
35
+
36
+ MIT