ganaka-sdk 0.1.2__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,52 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: write
8
+
9
+ jobs:
10
+ release:
11
+ runs-on: ubuntu-latest
12
+ concurrency:
13
+ group: release
14
+ cancel-in-progress: false
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - uses: astral-sh/setup-uv@v5
22
+ with:
23
+ enable-cache: true
24
+
25
+ - run: uv sync
26
+
27
+ - run: uv run pytest -v
28
+
29
+ - name: Verify baseline tag exists
30
+ run: |
31
+ git fetch --tags --force
32
+ if ! git tag -l 'v*' | grep -q .; then
33
+ echo "::error::No v* tag found. Seed baseline: git tag v0.1.0 <commit> && git push origin v0.1.0"
34
+ exit 1
35
+ fi
36
+ echo "Found tags: $(git tag -l 'v*' | tr '\n' ' ')"
37
+
38
+ - name: Semantic version release
39
+ id: release
40
+ uses: python-semantic-release/python-semantic-release@v10.5.3
41
+ with:
42
+ github_token: ${{ secrets.GITHUB_TOKEN }}
43
+ git_committer_name: "github-actions[bot]"
44
+ git_committer_email: "41898282+github-actions[bot]@users.noreply.github.com"
45
+
46
+ - name: Publish to PyPI
47
+ if: steps.release.outputs.released == 'true'
48
+ env:
49
+ UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }}
50
+ run: |
51
+ uv build
52
+ uv publish
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ .venv/
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .uv/
9
+ .pytest_cache/
10
+ .ruff_cache/
11
+ .mypy_cache/
12
+ .coverage
13
+ htmlcov/
@@ -0,0 +1,6 @@
1
+ repos:
2
+ - repo: https://github.com/commitizen-tools/commitizen
3
+ rev: v4.10.0
4
+ hooks:
5
+ - id: commitizen
6
+ stages: [commit-msg]
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,29 @@
1
+ {
2
+ "autorun": false,
3
+ "terminals": [
4
+ {
5
+ "name": "SDK: Sync",
6
+ "focus": true,
7
+ "onlySingle": true,
8
+ "command": "uv sync"
9
+ },
10
+ {
11
+ "name": "SDK: Test",
12
+ "focus": true,
13
+ "onlySingle": true,
14
+ "command": "uv run pytest -v"
15
+ },
16
+ {
17
+ "name": "SDK: Test Coverage",
18
+ "focus": true,
19
+ "onlySingle": true,
20
+ "command": "uv run pytest -v --cov=ganaka --cov-report=term-missing"
21
+ },
22
+ {
23
+ "name": "SDK: Build",
24
+ "focus": true,
25
+ "onlySingle": true,
26
+ "command": "uv build"
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,32 @@
1
+ # CHANGELOG
2
+
3
+ <!-- version list -->
4
+
5
+ ## v0.1.2 (2026-06-16)
6
+
7
+
8
+ ## v0.1.1 (2026-06-16)
9
+
10
+ ### Bug Fixes
11
+
12
+ - Remove unused build command from pyproject.toml and maintain semantic release configuration.
13
+ ([`106fa0c`](https://github.com/ganakadev/sdk/commit/106fa0c2dd3db1f16dfad8accdf8abdf576e4090))
14
+
15
+ - Update GitHub Actions workflow to fetch all tags and improve error messaging for baseline tag
16
+ verification.
17
+ ([`76127f9`](https://github.com/ganakadev/sdk/commit/76127f9a441dc4d3afe3dcc4553d743f345b02c0))
18
+
19
+ - Update GitHub Actions workflow to fetch tags and clean up VSCode terminal configurations by
20
+ removing unused commands.
21
+ ([`8be3351`](https://github.com/ganakadev/sdk/commit/8be33513fbc749c4424558f817721585ce353fcf))
22
+
23
+ ### Chores
24
+
25
+ - Add initial test suite for Ganaka SDK, including version check, client instantiation, and error
26
+ handling for unknown brokers.
27
+ ([`e286115`](https://github.com/ganakadev/sdk/commit/e286115387ea828f98add39c4d37cca576f31e5f))
28
+
29
+
30
+ ## v0.1.0 (2026-06-16)
31
+
32
+ - Initial Release
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ganaka Dev
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,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: ganaka-sdk
3
+ Version: 0.1.2
4
+ Summary: Python SDK for Ganaka - broker access and strategy tracking
5
+ Project-URL: Homepage, https://github.com/ganakadev/sdk
6
+ Project-URL: Repository, https://github.com/ganakadev/sdk
7
+ Project-URL: Issues, https://github.com/ganakadev/sdk/issues
8
+ Author-email: Ganaka Dev <dev@ganaka.dev>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: broker,dhan,sdk,strategy,trading
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Office/Business :: Financial :: Investment
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: httpx>=0.27
20
+ Description-Content-Type: text/markdown
21
+
22
+ # Ganaka Python SDK
23
+
24
+ Python SDK for [Ganaka](https://github.com/ganakadev/sdk) — trade through brokers like Dhan, track strategy execution on the Ganaka platform, and store run results for analysis.
25
+
26
+ ## Requirements
27
+
28
+ - Python 3.11+
29
+ - [uv](https://docs.astral.sh/uv/) (recommended) or pip
30
+
31
+ ## Install
32
+
33
+ From this repository (development):
34
+
35
+ ```bash
36
+ cd sdk
37
+ uv sync
38
+ ```
39
+
40
+ Editable install:
41
+
42
+ ```bash
43
+ uv pip install -e .
44
+ ```
45
+
46
+ ## Configuration
47
+
48
+ | Variable / argument | Description |
49
+ |---------------------|-------------|
50
+ | `api_key` | Ganaka platform API key (Bearer token) |
51
+ | `broker` | Broker adapter name (`dhan`) |
52
+ | `broker_config.client_id` | Dhan client ID |
53
+ | `broker_config.access_token` | Dhan access token (refreshed daily) |
54
+ | `base_url` | Ganaka API URL (default: `http://localhost:3000`) |
55
+
56
+ ## Usage
57
+
58
+ ```python
59
+ import asyncio
60
+
61
+ from ganaka import Ganaka
62
+
63
+
64
+ async def main() -> None:
65
+ async with Ganaka(
66
+ api_key="gk_your_key",
67
+ broker="dhan",
68
+ broker_config={
69
+ "client_id": "1100000001",
70
+ "access_token": "eyJ...",
71
+ },
72
+ ) as client:
73
+ # Broker: portfolio and orders
74
+ positions = await client.broker.get_positions()
75
+ holdings = await client.broker.get_holdings()
76
+
77
+ order = await client.broker.place_order(
78
+ security_id="1333",
79
+ exchange_segment="NSE_EQ",
80
+ transaction_type="BUY",
81
+ quantity=1,
82
+ product_type="INTRADAY",
83
+ order_type="LIMIT",
84
+ price=2500.0,
85
+ )
86
+
87
+ # Strategy tracking: log the flow of a run
88
+ run_id = await client.strategy.start_run(
89
+ strategy_id="breakout-nifty",
90
+ metadata={"timeframe": "5m"},
91
+ )
92
+ await client.strategy.log_entry(
93
+ signal="BUY",
94
+ instrument="RELIANCE",
95
+ reason="breakout above resistance",
96
+ extra={"price": 2500.0},
97
+ )
98
+ await client.strategy.end_run(status="completed")
99
+
100
+ # Persist final results to Ganaka database
101
+ await client.results.save(
102
+ strategy_id="breakout-nifty",
103
+ pnl=1200.50,
104
+ run_id=run_id,
105
+ trades=[{"symbol": "RELIANCE", "side": "BUY", "qty": 1}],
106
+ metrics={"win_rate": 0.62},
107
+ )
108
+
109
+
110
+ if __name__ == "__main__":
111
+ asyncio.run(main())
112
+ ```
113
+
114
+ ## Project layout
115
+
116
+ ```
117
+ src/ganaka/
118
+ ├── client.py # Ganaka main client
119
+ ├── broker/ # Broker adapters (Dhan)
120
+ ├── strategy/ # Strategy run tracking
121
+ ├── storage/ # Result persistence
122
+ └── exceptions.py # SDK error types
123
+ ```
124
+
125
+ ## Development
126
+
127
+ ```bash
128
+ uv sync
129
+ uv run pre-commit install --hook-type commit-msg
130
+ ```
131
+
132
+ If hook install fails with `core.hooksPath` set (e.g. after removing Husky), run `git config --local --unset-all core.hooksPath` and retry.
133
+
134
+ ```bash
135
+ uv run python -c "from ganaka import Ganaka; print(Ganaka)"
136
+ ```
137
+
138
+ ### Commit messages
139
+
140
+ This project uses [Conventional Commits](https://www.conventionalcommits.org/). After installing pre-commit hooks, every commit message is validated locally:
141
+
142
+ ```bash
143
+ feat: add Dhan order book helper
144
+ fix: handle expired access token
145
+ chore: update dependencies
146
+ ```
147
+
148
+ Dry-run a release locally (no changes made):
149
+
150
+ ```bash
151
+ uv run semantic-release -v --noop version
152
+ ```
153
+
154
+ ## Releasing
155
+
156
+ Releases are triggered manually via the **Release** GitHub Actions workflow (`workflow_dispatch`).
157
+
158
+ 1. Seed a baseline tag before the first release: `git tag v0.1.0 && git push origin v0.1.0`
159
+ 2. Merge conventional commits to `main`
160
+ 3. Run the **Release** workflow in GitHub Actions
161
+
162
+ The workflow uses [python-semantic-release](https://python-semantic-release.readthedocs.io/) to bump `pyproject.toml`, update `CHANGELOG.md`, create a git tag and GitHub Release, then publish to PyPI with `uv publish`.
163
+
164
+ ### GitHub secrets
165
+
166
+ | Secret | Purpose |
167
+ |--------|---------|
168
+ | `GITHUB_TOKEN` | Auto-provided; tags and GitHub Releases |
169
+ | `UV_PUBLISH_TOKEN` | PyPI API token for `uv publish` |
170
+
171
+ Optional: configure [PyPI Trusted Publisher](https://docs.pypi.org/trusted-publishers/) to avoid storing a token.
172
+
173
+ ## License
174
+
175
+ MIT
@@ -0,0 +1,154 @@
1
+ # Ganaka Python SDK
2
+
3
+ Python SDK for [Ganaka](https://github.com/ganakadev/sdk) — trade through brokers like Dhan, track strategy execution on the Ganaka platform, and store run results for analysis.
4
+
5
+ ## Requirements
6
+
7
+ - Python 3.11+
8
+ - [uv](https://docs.astral.sh/uv/) (recommended) or pip
9
+
10
+ ## Install
11
+
12
+ From this repository (development):
13
+
14
+ ```bash
15
+ cd sdk
16
+ uv sync
17
+ ```
18
+
19
+ Editable install:
20
+
21
+ ```bash
22
+ uv pip install -e .
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ | Variable / argument | Description |
28
+ |---------------------|-------------|
29
+ | `api_key` | Ganaka platform API key (Bearer token) |
30
+ | `broker` | Broker adapter name (`dhan`) |
31
+ | `broker_config.client_id` | Dhan client ID |
32
+ | `broker_config.access_token` | Dhan access token (refreshed daily) |
33
+ | `base_url` | Ganaka API URL (default: `http://localhost:3000`) |
34
+
35
+ ## Usage
36
+
37
+ ```python
38
+ import asyncio
39
+
40
+ from ganaka import Ganaka
41
+
42
+
43
+ async def main() -> None:
44
+ async with Ganaka(
45
+ api_key="gk_your_key",
46
+ broker="dhan",
47
+ broker_config={
48
+ "client_id": "1100000001",
49
+ "access_token": "eyJ...",
50
+ },
51
+ ) as client:
52
+ # Broker: portfolio and orders
53
+ positions = await client.broker.get_positions()
54
+ holdings = await client.broker.get_holdings()
55
+
56
+ order = await client.broker.place_order(
57
+ security_id="1333",
58
+ exchange_segment="NSE_EQ",
59
+ transaction_type="BUY",
60
+ quantity=1,
61
+ product_type="INTRADAY",
62
+ order_type="LIMIT",
63
+ price=2500.0,
64
+ )
65
+
66
+ # Strategy tracking: log the flow of a run
67
+ run_id = await client.strategy.start_run(
68
+ strategy_id="breakout-nifty",
69
+ metadata={"timeframe": "5m"},
70
+ )
71
+ await client.strategy.log_entry(
72
+ signal="BUY",
73
+ instrument="RELIANCE",
74
+ reason="breakout above resistance",
75
+ extra={"price": 2500.0},
76
+ )
77
+ await client.strategy.end_run(status="completed")
78
+
79
+ # Persist final results to Ganaka database
80
+ await client.results.save(
81
+ strategy_id="breakout-nifty",
82
+ pnl=1200.50,
83
+ run_id=run_id,
84
+ trades=[{"symbol": "RELIANCE", "side": "BUY", "qty": 1}],
85
+ metrics={"win_rate": 0.62},
86
+ )
87
+
88
+
89
+ if __name__ == "__main__":
90
+ asyncio.run(main())
91
+ ```
92
+
93
+ ## Project layout
94
+
95
+ ```
96
+ src/ganaka/
97
+ ├── client.py # Ganaka main client
98
+ ├── broker/ # Broker adapters (Dhan)
99
+ ├── strategy/ # Strategy run tracking
100
+ ├── storage/ # Result persistence
101
+ └── exceptions.py # SDK error types
102
+ ```
103
+
104
+ ## Development
105
+
106
+ ```bash
107
+ uv sync
108
+ uv run pre-commit install --hook-type commit-msg
109
+ ```
110
+
111
+ If hook install fails with `core.hooksPath` set (e.g. after removing Husky), run `git config --local --unset-all core.hooksPath` and retry.
112
+
113
+ ```bash
114
+ uv run python -c "from ganaka import Ganaka; print(Ganaka)"
115
+ ```
116
+
117
+ ### Commit messages
118
+
119
+ This project uses [Conventional Commits](https://www.conventionalcommits.org/). After installing pre-commit hooks, every commit message is validated locally:
120
+
121
+ ```bash
122
+ feat: add Dhan order book helper
123
+ fix: handle expired access token
124
+ chore: update dependencies
125
+ ```
126
+
127
+ Dry-run a release locally (no changes made):
128
+
129
+ ```bash
130
+ uv run semantic-release -v --noop version
131
+ ```
132
+
133
+ ## Releasing
134
+
135
+ Releases are triggered manually via the **Release** GitHub Actions workflow (`workflow_dispatch`).
136
+
137
+ 1. Seed a baseline tag before the first release: `git tag v0.1.0 && git push origin v0.1.0`
138
+ 2. Merge conventional commits to `main`
139
+ 3. Run the **Release** workflow in GitHub Actions
140
+
141
+ The workflow uses [python-semantic-release](https://python-semantic-release.readthedocs.io/) to bump `pyproject.toml`, update `CHANGELOG.md`, create a git tag and GitHub Release, then publish to PyPI with `uv publish`.
142
+
143
+ ### GitHub secrets
144
+
145
+ | Secret | Purpose |
146
+ |--------|---------|
147
+ | `GITHUB_TOKEN` | Auto-provided; tags and GitHub Releases |
148
+ | `UV_PUBLISH_TOKEN` | PyPI API token for `uv publish` |
149
+
150
+ Optional: configure [PyPI Trusted Publisher](https://docs.pypi.org/trusted-publishers/) to avoid storing a token.
151
+
152
+ ## License
153
+
154
+ MIT
@@ -0,0 +1,59 @@
1
+ [project]
2
+ name = "ganaka-sdk"
3
+ version = "0.1.2"
4
+ description = "Python SDK for Ganaka - broker access and strategy tracking"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ requires-python = ">=3.11"
8
+ authors = [{ name = "Ganaka Dev", email = "dev@ganaka.dev" }]
9
+ keywords = ["trading", "broker", "dhan", "strategy", "sdk"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Topic :: Office/Business :: Financial :: Investment",
17
+ ]
18
+ dependencies = ["httpx>=0.27"]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/ganakadev/sdk"
22
+ Repository = "https://github.com/ganakadev/sdk"
23
+ Issues = "https://github.com/ganakadev/sdk/issues"
24
+
25
+ [build-system]
26
+ requires = ["hatchling"]
27
+ build-backend = "hatchling.build"
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src/ganaka"]
31
+
32
+ [dependency-groups]
33
+ dev = [
34
+ "pytest>=8.0",
35
+ "pytest-asyncio>=0.23",
36
+ "pytest-cov>=4.0",
37
+ "python-semantic-release>=10.5",
38
+ "pre-commit>=4.0",
39
+ ]
40
+
41
+ [tool.pytest.ini_options]
42
+ asyncio_mode = "auto"
43
+ testpaths = ["tests"]
44
+
45
+ [tool.semantic_release]
46
+ version_toml = ["pyproject.toml:project.version"]
47
+ commit_parser = "conventional"
48
+ allow_zero_version = true
49
+
50
+ [tool.semantic_release.branches.main]
51
+ match = "main"
52
+ prerelease = false
53
+
54
+ [tool.semantic_release.changelog.default_templates]
55
+ changelog_file = "CHANGELOG.md"
56
+ output_format = "md"
57
+
58
+ [tool.semantic_release.changelog.environment]
59
+ keep_trailing_newline = true
@@ -0,0 +1,42 @@
1
+ """Ganaka Python SDK — broker access and strategy tracking.
2
+
3
+ Install::
4
+
5
+ pip install ganaka
6
+
7
+ Quick start::
8
+
9
+ from ganaka import Ganaka
10
+
11
+ client = Ganaka(
12
+ api_key="gk_...",
13
+ broker="dhan",
14
+ broker_config={
15
+ "client_id": "1100000001",
16
+ "access_token": "eyJ...",
17
+ },
18
+ )
19
+
20
+ positions = await client.broker.get_positions()
21
+ """
22
+
23
+ from ganaka.client import Ganaka
24
+ from ganaka.exceptions import (
25
+ AuthenticationError,
26
+ BrokerAPIError,
27
+ ConfigurationError,
28
+ GanakaError,
29
+ ResultStorageError,
30
+ StrategyTrackingError,
31
+ )
32
+
33
+ __all__ = [
34
+ "Ganaka",
35
+ "GanakaError",
36
+ "ConfigurationError",
37
+ "AuthenticationError",
38
+ "BrokerAPIError",
39
+ "StrategyTrackingError",
40
+ "ResultStorageError",
41
+ ]
42
+ __version__ = "0.1.0"