Preperations...
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
creds.toml
|
||||||
23
main.py
Normal file
23
main.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import tomllib
|
||||||
|
import paho.mqtt.client as paho
|
||||||
|
import time
|
||||||
|
from utils import load_config, authenticate
|
||||||
|
|
||||||
|
config = load_config()
|
||||||
|
#client = paho.Client(paho.CallbackAPIVersion.VERSION2)
|
||||||
|
#client.username_pw_set(username=config.mqtt.username,password=config.mqtt.password)
|
||||||
|
|
||||||
|
#if client.connect("proliant.lan", 1883, 60) != 0:
|
||||||
|
#print("Couldn't connect to the mqtt broker")
|
||||||
|
#sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#client.publish("SP500", json.dumps({"value":6349}), 0)
|
||||||
|
#time.sleep(0.5)
|
||||||
|
|
||||||
|
|
||||||
|
#client.disconnect()
|
||||||
|
|
||||||
|
authenticate()
|
||||||
0
producers/sp500.py
Normal file
0
producers/sp500.py
Normal file
89
utils.py
Normal file
89
utils.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
from typing import NamedTuple
|
||||||
|
import tomllib
|
||||||
|
def dict_to_namedtuple(name, dictionary):
|
||||||
|
fields = {}
|
||||||
|
for key, value in dictionary.items():
|
||||||
|
if isinstance(value, dict):
|
||||||
|
fields[key] = dict_to_namedtuple(key.capitalize(), value)
|
||||||
|
else:
|
||||||
|
fields[key] = value
|
||||||
|
return NamedTuple(name, [(k, type(v)) for k, v in fields.items()])(**fields)
|
||||||
|
|
||||||
|
|
||||||
|
def load_config():
|
||||||
|
with open("creds.toml", "rb") as f:
|
||||||
|
config_dict = tomllib.load(f)
|
||||||
|
config = dict_to_namedtuple("Config", config_dict)
|
||||||
|
return config
|
||||||
|
import webbrowser
|
||||||
|
import requests
|
||||||
|
import threading
|
||||||
|
from flask import Flask, request
|
||||||
|
|
||||||
|
def authenticate(client_id, client_secret, scopes=None, port=5000):
|
||||||
|
"""
|
||||||
|
Opens the browser for OAuth authorization and returns token data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
client_id (str): Your Tastytrade client ID
|
||||||
|
client_secret (str): Your Tastytrade client secret
|
||||||
|
scopes (list[str]): Optional list of scopes (default: None)
|
||||||
|
port (int): Port for local callback server (default: 5000)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Token response JSON (access_token, refresh_token, etc.)
|
||||||
|
"""
|
||||||
|
redirect_uri = f"http://127.0.0.1:{port}/callback"
|
||||||
|
auth_url = "https://api.tastytrade.com/oauth/authorize"
|
||||||
|
token_url = "https://api.tastytrade.com/oauth/token"
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
auth_code_container = {}
|
||||||
|
|
||||||
|
@app.route("/callback")
|
||||||
|
def callback():
|
||||||
|
code = request.args.get("code")
|
||||||
|
auth_code_container["code"] = code
|
||||||
|
return "Authorization successful. You may close this window."
|
||||||
|
|
||||||
|
# Start local server in background
|
||||||
|
def run_server():
|
||||||
|
app.run(port=port, debug=False, use_reloader=False)
|
||||||
|
threading.Thread(target=run_server, daemon=True).start()
|
||||||
|
|
||||||
|
# Build auth URL
|
||||||
|
params = {
|
||||||
|
"response_type": "code",
|
||||||
|
"client_id": client_id,
|
||||||
|
"redirect_uri": redirect_uri
|
||||||
|
}
|
||||||
|
if scopes:
|
||||||
|
params["scope"] = " ".join(scopes)
|
||||||
|
|
||||||
|
# Open browser
|
||||||
|
webbrowser.open(f"{auth_url}?{requests.compat.urlencode(params)}")
|
||||||
|
|
||||||
|
# Wait for code
|
||||||
|
print("Waiting for authorization...")
|
||||||
|
while "code" not in auth_code_container:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exchange code for token
|
||||||
|
token_resp = requests.post(token_url, data={
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
"code": auth_code_container["code"],
|
||||||
|
"redirect_uri": redirect_uri,
|
||||||
|
"client_id": client_id,
|
||||||
|
"client_secret": client_secret
|
||||||
|
})
|
||||||
|
token_resp.raise_for_status()
|
||||||
|
|
||||||
|
return token_resp.json()
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
if __name__ == "__main__":
|
||||||
|
client_id = "YOUR_CLIENT_ID"
|
||||||
|
client_secret = "YOUR_CLIENT_SECRET"
|
||||||
|
token_data = authenticate(client_id, client_secret, scopes=["accounts", "orders"])
|
||||||
|
print(token_data)
|
||||||
|
|
||||||
Reference in New Issue
Block a user