moved config related services into separated package
This commit is contained in:
@ -1,4 +1,3 @@
|
|||||||
from v2realbot.config import DATA_DIR
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import queue
|
import queue
|
||||||
import threading
|
import threading
|
||||||
@ -9,6 +8,7 @@ import orjson
|
|||||||
from v2realbot.utils.utils import json_serial, send_to_telegram, zoneNY
|
from v2realbot.utils.utils import json_serial, send_to_telegram, zoneNY
|
||||||
import v2realbot.controller.services as cs
|
import v2realbot.controller.services as cs
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
from v2realbot.config import DATA_DIR
|
||||||
|
|
||||||
sqlite_db_file = DATA_DIR + "/v2trading.db"
|
sqlite_db_file = DATA_DIR + "/v2trading.db"
|
||||||
# Define the connection pool
|
# Define the connection pool
|
||||||
|
|||||||
@ -3,11 +3,14 @@ from v2realbot.enums.enums import Mode, Account, FillCondition
|
|||||||
from appdirs import user_data_dir
|
from appdirs import user_data_dir
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import os
|
import os
|
||||||
|
from collections import defaultdict
|
||||||
# Global flag to track if the ml module has been imported (solution for long import times of tensorflow)
|
# Global flag to track if the ml module has been imported (solution for long import times of tensorflow)
|
||||||
#the first occurence of using it will load it globally
|
#the first occurence of using it will load it globally
|
||||||
_ml_module_loaded = False
|
_ml_module_loaded = False
|
||||||
|
|
||||||
|
#TBD - konfiguracni dict issue #148
|
||||||
|
#CFG: defaultdict = defaultdict(None)
|
||||||
|
|
||||||
#directory for generated images and basic reports
|
#directory for generated images and basic reports
|
||||||
MEDIA_DIRECTORY = Path(__file__).parent.parent.parent / "media"
|
MEDIA_DIRECTORY = Path(__file__).parent.parent.parent / "media"
|
||||||
RUNNER_DETAIL_DIRECTORY = Path(__file__).parent.parent.parent / "runner_detail"
|
RUNNER_DETAIL_DIRECTORY = Path(__file__).parent.parent.parent / "runner_detail"
|
||||||
|
|||||||
108
v2realbot/controller/configs.py
Normal file
108
v2realbot/controller/configs.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import config as cfg
|
||||||
|
from v2realbot.common.db import pool
|
||||||
|
from v2realbot.common.model import RunDay, StrategyInstance, Runner, RunRequest, RunArchive, RunArchiveView, RunArchiveViewPagination, RunArchiveDetail, RunArchiveChange, Bar, TradeEvent, TestList, Intervals, ConfigItem, InstantIndicator, DataTablesRequest
|
||||||
|
import orjson
|
||||||
|
|
||||||
|
# region CONFIG db services
|
||||||
|
#TODO vytvorit modul pro dotahovani z pythonu (get_from_config(var_name, def_value) {)- stejne jako v js
|
||||||
|
#TODO zvazit presunuti do TOML z JSONu
|
||||||
|
def get_all_config_items():
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT id, item_name, json_data FROM config_table')
|
||||||
|
config_items = [{"id": row[0], "item_name": row[1], "json_data": row[2]} for row in cursor.fetchall()]
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
return 0, config_items
|
||||||
|
|
||||||
|
# Function to get a config item by ID
|
||||||
|
def get_config_item_by_id(item_id):
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT item_name, json_data FROM config_table WHERE id = ?', (item_id,))
|
||||||
|
row = cursor.fetchone()
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
if row is None:
|
||||||
|
return -2, "not found"
|
||||||
|
else:
|
||||||
|
return 0, {"item_name": row[0], "json_data": row[1]}
|
||||||
|
|
||||||
|
# Function to get a config item by ID
|
||||||
|
def get_config_item_by_name(item_name):
|
||||||
|
#print(item_name)
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = f"SELECT item_name, json_data FROM config_table WHERE item_name = '{item_name}'"
|
||||||
|
#print(query)
|
||||||
|
cursor.execute(query)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
#print(row)
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
if row is None:
|
||||||
|
return -2, "not found"
|
||||||
|
else:
|
||||||
|
return 0, {"item_name": row[0], "json_data": row[1]}
|
||||||
|
|
||||||
|
# Function to create a new config item
|
||||||
|
def create_config_item(config_item: ConfigItem):
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('INSERT INTO config_table (item_name, json_data) VALUES (?, ?)', (config_item.item_name, config_item.json_data))
|
||||||
|
item_id = cursor.lastrowid
|
||||||
|
conn.commit()
|
||||||
|
print(item_id)
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
|
||||||
|
return 0, {"id": item_id, "item_name":config_item.item_name, "json_data":config_item.json_data}
|
||||||
|
except Exception as e:
|
||||||
|
return -2, str(e)
|
||||||
|
|
||||||
|
# Function to update a config item by ID
|
||||||
|
def update_config_item(item_id, config_item: ConfigItem):
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('UPDATE config_table SET item_name = ?, json_data = ? WHERE id = ?', (config_item.item_name, config_item.json_data, item_id))
|
||||||
|
conn.commit()
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
return 0, {"id": item_id, **config_item.dict()}
|
||||||
|
except Exception as e:
|
||||||
|
return -2, str(e)
|
||||||
|
|
||||||
|
# Function to delete a config item by ID
|
||||||
|
def delete_config_item(item_id):
|
||||||
|
conn = pool.get_connection()
|
||||||
|
try:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('DELETE FROM config_table WHERE id = ?', (item_id,))
|
||||||
|
conn.commit()
|
||||||
|
finally:
|
||||||
|
pool.release_connection(conn)
|
||||||
|
return 0, {"id": item_id}
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
#Example of using config directive
|
||||||
|
# config_directive = "overrides"
|
||||||
|
# ret, res = get_config_item_by_name(config_directive)
|
||||||
|
# if ret < 0:
|
||||||
|
# print(f"CONFIG OVERRIDE {config_directive} Error {res}")
|
||||||
|
# else:
|
||||||
|
# config = orjson.loads(res["json_data"])
|
||||||
|
|
||||||
|
# print("OVERRIDN CFG:", config)
|
||||||
|
# for key, value in config.items():
|
||||||
|
# if hasattr(cfg, key):
|
||||||
|
# print(f"Overriding {key} with {value}")
|
||||||
|
# setattr(cfg, key, value)
|
||||||
|
|
||||||
@ -1851,95 +1851,6 @@ def delete_indicator_byName(id: UUID, indicator: InstantIndicator):
|
|||||||
print(str(e) + format_exc())
|
print(str(e) + format_exc())
|
||||||
return -2, str(e)
|
return -2, str(e)
|
||||||
|
|
||||||
# region CONFIG db services
|
|
||||||
#TODO vytvorit modul pro dotahovani z pythonu (get_from_config(var_name, def_value) {)- stejne jako v js
|
|
||||||
#TODO zvazit presunuti do TOML z JSONu
|
|
||||||
def get_all_config_items():
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('SELECT id, item_name, json_data FROM config_table')
|
|
||||||
config_items = [{"id": row[0], "item_name": row[1], "json_data": row[2]} for row in cursor.fetchall()]
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
return 0, config_items
|
|
||||||
|
|
||||||
# Function to get a config item by ID
|
|
||||||
def get_config_item_by_id(item_id):
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('SELECT item_name, json_data FROM config_table WHERE id = ?', (item_id,))
|
|
||||||
row = cursor.fetchone()
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
if row is None:
|
|
||||||
return -2, "not found"
|
|
||||||
else:
|
|
||||||
return 0, {"item_name": row[0], "json_data": row[1]}
|
|
||||||
|
|
||||||
# Function to get a config item by ID
|
|
||||||
def get_config_item_by_name(item_name):
|
|
||||||
#print(item_name)
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
query = f"SELECT item_name, json_data FROM config_table WHERE item_name = '{item_name}'"
|
|
||||||
#print(query)
|
|
||||||
cursor.execute(query)
|
|
||||||
row = cursor.fetchone()
|
|
||||||
#print(row)
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
if row is None:
|
|
||||||
return -2, "not found"
|
|
||||||
else:
|
|
||||||
return 0, {"item_name": row[0], "json_data": row[1]}
|
|
||||||
|
|
||||||
# Function to create a new config item
|
|
||||||
def create_config_item(config_item: ConfigItem):
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('INSERT INTO config_table (item_name, json_data) VALUES (?, ?)', (config_item.item_name, config_item.json_data))
|
|
||||||
item_id = cursor.lastrowid
|
|
||||||
conn.commit()
|
|
||||||
print(item_id)
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
|
|
||||||
return 0, {"id": item_id, "item_name":config_item.item_name, "json_data":config_item.json_data}
|
|
||||||
except Exception as e:
|
|
||||||
return -2, str(e)
|
|
||||||
|
|
||||||
# Function to update a config item by ID
|
|
||||||
def update_config_item(item_id, config_item: ConfigItem):
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('UPDATE config_table SET item_name = ?, json_data = ? WHERE id = ?', (config_item.item_name, config_item.json_data, item_id))
|
|
||||||
conn.commit()
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
return 0, {"id": item_id, **config_item.dict()}
|
|
||||||
except Exception as e:
|
|
||||||
return -2, str(e)
|
|
||||||
|
|
||||||
# Function to delete a config item by ID
|
|
||||||
def delete_config_item(item_id):
|
|
||||||
conn = pool.get_connection()
|
|
||||||
try:
|
|
||||||
cursor = conn.cursor()
|
|
||||||
cursor.execute('DELETE FROM config_table WHERE id = ?', (item_id,))
|
|
||||||
conn.commit()
|
|
||||||
finally:
|
|
||||||
pool.release_connection(conn)
|
|
||||||
return 0, {"id": item_id}
|
|
||||||
|
|
||||||
# endregion
|
|
||||||
|
|
||||||
#returns b
|
#returns b
|
||||||
def get_alpaca_history_bars(symbol: str, datetime_object_from: datetime, datetime_object_to: datetime, timeframe: TimeFrame):
|
def get_alpaca_history_bars(symbol: str, datetime_object_from: datetime, datetime_object_to: datetime, timeframe: TimeFrame):
|
||||||
"""Returns Bar object
|
"""Returns Bar object
|
||||||
@ -1990,4 +1901,11 @@ def get_alpaca_history_bars(symbol: str, datetime_object_from: datetime, datetim
|
|||||||
# change_archived_runner
|
# change_archived_runner
|
||||||
# delete_archived_runner_details
|
# delete_archived_runner_details
|
||||||
|
|
||||||
|
#Example of using config directive
|
||||||
|
# config_directive = "python"
|
||||||
|
# ret, res = get_config_item_by_name(config_directive)
|
||||||
|
# if ret < 0:
|
||||||
|
# print(f"Error {res}")
|
||||||
|
# else:
|
||||||
|
# config = orjson.loads(res["json_data"])
|
||||||
|
# print(config)
|
||||||
@ -10,6 +10,7 @@ from fastapi.security import APIKeyHeader
|
|||||||
import uvicorn
|
import uvicorn
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import v2realbot.controller.services as cs
|
import v2realbot.controller.services as cs
|
||||||
|
import v2realbot.controller.configs as cf
|
||||||
from v2realbot.utils.ilog import get_log_window
|
from v2realbot.utils.ilog import get_log_window
|
||||||
from v2realbot.common.model import RunManagerRecord, StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveView, RunArchiveViewPagination, RunArchiveDetail, Bar, RunArchiveChange, TestList, ConfigItem, InstantIndicator, DataTablesRequest, AnalyzerInputs
|
from v2realbot.common.model import RunManagerRecord, StrategyInstance, RunnerView, RunRequest, Trade, RunArchive, RunArchiveView, RunArchiveViewPagination, RunArchiveDetail, Bar, RunArchiveChange, TestList, ConfigItem, InstantIndicator, DataTablesRequest, AnalyzerInputs
|
||||||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
||||||
@ -771,7 +772,7 @@ def delete_testlist(record_id: str):
|
|||||||
# Get all config items
|
# Get all config items
|
||||||
@app.get("/config-items/", dependencies=[Depends(api_key_auth)])
|
@app.get("/config-items/", dependencies=[Depends(api_key_auth)])
|
||||||
def get_all_items() -> list[ConfigItem]:
|
def get_all_items() -> list[ConfigItem]:
|
||||||
res, sada = cs.get_all_config_items()
|
res, sada = cf.get_all_config_items()
|
||||||
if res == 0:
|
if res == 0:
|
||||||
return sada
|
return sada
|
||||||
else:
|
else:
|
||||||
@ -781,7 +782,7 @@ def get_all_items() -> list[ConfigItem]:
|
|||||||
# Get a config item by ID
|
# Get a config item by ID
|
||||||
@app.get("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
@app.get("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
||||||
def get_item(item_id: int)-> ConfigItem:
|
def get_item(item_id: int)-> ConfigItem:
|
||||||
res, sada = cs.get_config_item_by_id(item_id)
|
res, sada = cf.get_config_item_by_id(item_id)
|
||||||
if res == 0:
|
if res == 0:
|
||||||
return sada
|
return sada
|
||||||
else:
|
else:
|
||||||
@ -790,7 +791,7 @@ def get_item(item_id: int)-> ConfigItem:
|
|||||||
# Get a config item by Name
|
# Get a config item by Name
|
||||||
@app.get("/config-items-by-name/", dependencies=[Depends(api_key_auth)])
|
@app.get("/config-items-by-name/", dependencies=[Depends(api_key_auth)])
|
||||||
def get_item(item_name: str)-> ConfigItem:
|
def get_item(item_name: str)-> ConfigItem:
|
||||||
res, sada = cs.get_config_item_by_name(item_name)
|
res, sada = cf.get_config_item_by_name(item_name)
|
||||||
if res == 0:
|
if res == 0:
|
||||||
return sada
|
return sada
|
||||||
else:
|
else:
|
||||||
@ -799,7 +800,7 @@ def get_item(item_name: str)-> ConfigItem:
|
|||||||
# Create a new config item
|
# Create a new config item
|
||||||
@app.post("/config-items/", dependencies=[Depends(api_key_auth)], status_code=status.HTTP_200_OK)
|
@app.post("/config-items/", dependencies=[Depends(api_key_auth)], status_code=status.HTTP_200_OK)
|
||||||
def create_item(config_item: ConfigItem) -> ConfigItem:
|
def create_item(config_item: ConfigItem) -> ConfigItem:
|
||||||
res, sada = cs.create_config_item(config_item)
|
res, sada = cf.create_config_item(config_item)
|
||||||
if res == 0: return sada
|
if res == 0: return sada
|
||||||
else:
|
else:
|
||||||
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not created: {res}:{id} {sada}")
|
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not created: {res}:{id} {sada}")
|
||||||
@ -808,7 +809,7 @@ def create_item(config_item: ConfigItem) -> ConfigItem:
|
|||||||
# Update a config item by ID
|
# Update a config item by ID
|
||||||
@app.put("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
@app.put("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
||||||
def update_item(item_id: int, config_item: ConfigItem) -> ConfigItem:
|
def update_item(item_id: int, config_item: ConfigItem) -> ConfigItem:
|
||||||
res, sada = cs.get_config_item_by_id(item_id)
|
res, sada = cf.get_config_item_by_id(item_id)
|
||||||
if res != 0:
|
if res != 0:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No data found")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No data found")
|
||||||
|
|
||||||
@ -821,11 +822,11 @@ def update_item(item_id: int, config_item: ConfigItem) -> ConfigItem:
|
|||||||
# Delete a config item by ID
|
# Delete a config item by ID
|
||||||
@app.delete("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
@app.delete("/config-items/{item_id}", dependencies=[Depends(api_key_auth)])
|
||||||
def delete_item(item_id: int) -> dict:
|
def delete_item(item_id: int) -> dict:
|
||||||
res, sada = cs.get_config_item_by_id(item_id)
|
res, sada = cf.get_config_item_by_id(item_id)
|
||||||
if res != 0:
|
if res != 0:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No data found")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No data found")
|
||||||
|
|
||||||
res, sada = cs.delete_config_item(item_id)
|
res, sada = cf.delete_config_item(item_id)
|
||||||
if res == 0: return sada
|
if res == 0: return sada
|
||||||
else:
|
else:
|
||||||
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not created: {res}:{id}")
|
raise HTTPException(status_code=status.HTTP_406_NOT_ACCEPTABLE, detail=f"Error not created: {res}:{id}")
|
||||||
|
|||||||
Reference in New Issue
Block a user