ctrader-oauth-fetcher 1.0.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,14 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # IDE-specific files
13
+ .idea/
14
+ .vscode/
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Elio Anthony Chukri
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,79 @@
1
+ Metadata-Version: 2.4
2
+ Name: ctrader-oauth-fetcher
3
+ Version: 1.0.0
4
+ Summary: One-time OAuth token fetcher for cTrader Open API
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.14
7
+ Description-Content-Type: text/markdown
8
+
9
+ # ctrader-oauth-fetcher
10
+
11
+ A command-line utility for obtaining OAuth tokens from the cTrader Open API. This tool automates the OAuth 2.0 authorization code flow, handling browser-based authorization and token exchange.
12
+
13
+ ## Requirements
14
+
15
+ - Python 3.14+
16
+ - A cTrader Open API application (client ID and secret)
17
+
18
+ ## Usage
19
+
20
+ Run directly without installation using uvx:
21
+
22
+ ```bash
23
+ uvx ctrader-oauth-fetcher --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
24
+ ```
25
+
26
+ With all options:
27
+
28
+ ```bash
29
+ ctrader-oauth-fetcher \
30
+ --client-id YOUR_CLIENT_ID \
31
+ --client-secret YOUR_CLIENT_SECRET \
32
+ --scope trading \
33
+ --redirect-uri http://localhost:8080
34
+ ```
35
+
36
+ ### Options
37
+
38
+ | Option | Required | Default | Description |
39
+ |-------------------|----------|-------------------------|-------------------------------------------|
40
+ | `--client-id` | Yes | - | OAuth application client ID |
41
+ | `--client-secret` | Yes | - | OAuth application client secret |
42
+ | `--scope` | No | `trading` | Permission scope: `trading` or `accounts` |
43
+ | `--redirect-uri` | No | `http://localhost:8080` | OAuth callback URL |
44
+
45
+ ### Scopes
46
+
47
+ - `trading` - Full trading permissions (place orders, manage positions)
48
+ - `accounts` - Read-only access to account information
49
+
50
+ ## How It Works
51
+
52
+ 1. The tool constructs an authorization URL and opens it in your default browser
53
+ 2. A local HTTP server starts to listen for the OAuth callback
54
+ 3. After you authorize the application in your browser, cTrader redirects back to the local server
55
+ 4. The tool exchanges the authorization code for access and refresh tokens
56
+ 5. Tokens are displayed in the terminal
57
+
58
+ ## Output
59
+
60
+ On success, the tool outputs the token response:
61
+
62
+ ```
63
+ Tokens Received successfully.
64
+
65
+ Access token: <TOKEN>
66
+ Refresh token: <TOKEN>
67
+ Expires in: <SECONDS> seconds
68
+ ```
69
+
70
+ ## Getting cTrader API Credentials
71
+
72
+ 1. Go to [cTrader Open API](https://openapi.ctrader.com/)
73
+ 2. Register or log in to your account
74
+ 3. Create a new application
75
+ 4. Note your client ID and client secret
76
+
77
+ ## License
78
+
79
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,71 @@
1
+ # ctrader-oauth-fetcher
2
+
3
+ A command-line utility for obtaining OAuth tokens from the cTrader Open API. This tool automates the OAuth 2.0 authorization code flow, handling browser-based authorization and token exchange.
4
+
5
+ ## Requirements
6
+
7
+ - Python 3.14+
8
+ - A cTrader Open API application (client ID and secret)
9
+
10
+ ## Usage
11
+
12
+ Run directly without installation using uvx:
13
+
14
+ ```bash
15
+ uvx ctrader-oauth-fetcher --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
16
+ ```
17
+
18
+ With all options:
19
+
20
+ ```bash
21
+ ctrader-oauth-fetcher \
22
+ --client-id YOUR_CLIENT_ID \
23
+ --client-secret YOUR_CLIENT_SECRET \
24
+ --scope trading \
25
+ --redirect-uri http://localhost:8080
26
+ ```
27
+
28
+ ### Options
29
+
30
+ | Option | Required | Default | Description |
31
+ |-------------------|----------|-------------------------|-------------------------------------------|
32
+ | `--client-id` | Yes | - | OAuth application client ID |
33
+ | `--client-secret` | Yes | - | OAuth application client secret |
34
+ | `--scope` | No | `trading` | Permission scope: `trading` or `accounts` |
35
+ | `--redirect-uri` | No | `http://localhost:8080` | OAuth callback URL |
36
+
37
+ ### Scopes
38
+
39
+ - `trading` - Full trading permissions (place orders, manage positions)
40
+ - `accounts` - Read-only access to account information
41
+
42
+ ## How It Works
43
+
44
+ 1. The tool constructs an authorization URL and opens it in your default browser
45
+ 2. A local HTTP server starts to listen for the OAuth callback
46
+ 3. After you authorize the application in your browser, cTrader redirects back to the local server
47
+ 4. The tool exchanges the authorization code for access and refresh tokens
48
+ 5. Tokens are displayed in the terminal
49
+
50
+ ## Output
51
+
52
+ On success, the tool outputs the token response:
53
+
54
+ ```
55
+ Tokens Received successfully.
56
+
57
+ Access token: <TOKEN>
58
+ Refresh token: <TOKEN>
59
+ Expires in: <SECONDS> seconds
60
+ ```
61
+
62
+ ## Getting cTrader API Credentials
63
+
64
+ 1. Go to [cTrader Open API](https://openapi.ctrader.com/)
65
+ 2. Register or log in to your account
66
+ 3. Create a new application
67
+ 4. Note your client ID and client secret
68
+
69
+ ## License
70
+
71
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,6 @@
1
+ def main():
2
+ print("Hello from ctrader-oauth-fetcher!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,14 @@
1
+ [project]
2
+ name = "ctrader-oauth-fetcher"
3
+ version = "1.0.0"
4
+ readme = "README.md"
5
+ description = "One-time OAuth token fetcher for cTrader Open API"
6
+ requires-python = ">=3.14"
7
+ dependencies = []
8
+
9
+ [project.scripts]
10
+ ctrader-oauth-fetcher = "ctrader_oauth_fetcher.cli:main"
11
+
12
+ [build-system]
13
+ requires = ["hatchling"]
14
+ build-backend = "hatchling.build"
@@ -0,0 +1,107 @@
1
+ import argparse
2
+ import webbrowser
3
+ import json
4
+ import sys
5
+ from http.server import HTTPServer, BaseHTTPRequestHandler
6
+ from urllib.parse import urlparse, parse_qs, urlencode
7
+ from urllib.request import urlopen
8
+ from urllib.error import HTTPError
9
+
10
+ def eprint(msg: str) -> None:
11
+ print(msg, file=sys.stderr)
12
+
13
+ def main():
14
+ parser = argparse.ArgumentParser()
15
+ parser.add_argument(
16
+ "--client-id", required=True, help="Client ID used to authorize the application"
17
+ )
18
+ parser.add_argument(
19
+ "--client-secret",
20
+ required=True,
21
+ help="Client Secret used to authorize the application",
22
+ )
23
+ parser.add_argument(
24
+ "--scope", default="trading", help="The scope of the permissions to authorize for the application. Must be one of 'accounts' or 'trading'",
25
+ )
26
+ parser.add_argument(
27
+ "--redirect-uri",
28
+ default="http://localhost:8080",
29
+ help="Redirect URI registered with your application. Defaults to http://localhost:8080",
30
+ )
31
+ args = parser.parse_args()
32
+
33
+ if args.scope not in ["accounts", "trading"]:
34
+ eprint("Invalid scope. Must be one of 'accounts' or 'trading'")
35
+ sys.exit(1)
36
+
37
+ auth_code = None
38
+ auth_error = None
39
+
40
+ class Handler(BaseHTTPRequestHandler):
41
+ def do_GET(self):
42
+ nonlocal auth_code, auth_error
43
+ params = parse_qs(urlparse(self.path).query)
44
+ if "error" in params:
45
+ auth_error = params["error"][0]
46
+ elif "code" in params:
47
+ auth_code = params["code"][0]
48
+ else:
49
+ auth_error = "No code or error returned in redirect"
50
+ self.send_response(200)
51
+ self.end_headers()
52
+ self.wfile.write(b"Authorization complete. You can close this tab.")
53
+
54
+ def log_message(self, format: str, *args):
55
+ pass
56
+
57
+ auth_url = (
58
+ f"https://id.ctrader.com/my/settings/openapi/grantingaccess/"
59
+ f"?client_id={args.client_id}"
60
+ f"&redirect_uri={args.redirect_uri}"
61
+ f"&scope={args.scope}"
62
+ f"&product=web"
63
+ )
64
+
65
+ parsed = urlparse(args.redirect_uri)
66
+ host = parsed.hostname
67
+ port = parsed.port or 80
68
+
69
+ opened = webbrowser.open(auth_url)
70
+ if not opened:
71
+ print(f"Could not open browser. Visit this URL manually:\n{auth_url}")
72
+ else:
73
+ print("Browser opened. Complete the authorization in your browser.")
74
+
75
+ print("Waiting for authorization...")
76
+ HTTPServer((host, int(port)), Handler).handle_request()
77
+
78
+ if auth_error:
79
+ eprint(f"Authorization failed: {auth_error}")
80
+ sys.exit(1)
81
+
82
+ print("Authorization code received. Exchanging for tokens...")
83
+ url_params = urlencode(
84
+
85
+ {
86
+ "grant_type": "authorization_code",
87
+ "code": auth_code,
88
+ "redirect_uri": args.redirect_uri,
89
+ "client_id": args.client_id,
90
+ "client_secret": args.client_secret,
91
+ }
92
+ )
93
+
94
+ try:
95
+ with urlopen(
96
+ f"https://openapi.ctrader.com/apps/token?{url_params}"
97
+ ) as response:
98
+ tokens = json.loads(response.read())
99
+ except HTTPError as e:
100
+ body = e.read().decode()
101
+ eprint(f"Token exchange failed ({e.code}): {body}")
102
+ sys.exit(1)
103
+
104
+ print("Tokens received successfully.\n")
105
+ print(f"Access token: {tokens['accessToken']}")
106
+ print(f"Refresh token: {tokens['refreshToken']}")
107
+ print(f"Expires in: {tokens['expiresIn']} seconds")
@@ -0,0 +1,8 @@
1
+ version = 1
2
+ revision = 3
3
+ requires-python = ">=3.14"
4
+
5
+ [[package]]
6
+ name = "ctrader-oauth-fetcher"
7
+ version = "0.1.0"
8
+ source = { editable = "." }