gui ml modal view
This commit is contained in:
@ -37,6 +37,8 @@ from traceback import format_exc
|
||||
import v2realbot.reporting.analyzer as ci
|
||||
import shutil
|
||||
from starlette.responses import JSONResponse
|
||||
import mlroom
|
||||
import mlroom.utils.mlutils as ml
|
||||
#from async io import Queue, QueueEmpty
|
||||
#
|
||||
# install()
|
||||
@ -841,6 +843,29 @@ def download_model(model_name: str):
|
||||
else:
|
||||
raise HTTPException(status_code=404, detail="Model not found.")
|
||||
|
||||
@app.get("/model/metadata/{model_name}", dependencies=[Depends(api_key_auth)])
|
||||
def get_metadata(model_name: str):
|
||||
try:
|
||||
model_instance = ml.load_model(file=model_name, directory=MODEL_DIR)
|
||||
try:
|
||||
metadata = model_instance.metadata
|
||||
except Exception as e:
|
||||
metadata = "No Metada" + str(e) + format_exc()
|
||||
return metadata
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=404, detail="Model not found."+str(e) + format_exc())
|
||||
|
||||
# model_path = os.path.join(MODEL_DIR, model_name)
|
||||
# if os.path.exists(model_path):
|
||||
# # Example: Retrieve metadata from a file or generate it
|
||||
# metadata = {
|
||||
# "name": model_name,
|
||||
# "size": os.path.getsize(model_path),
|
||||
# "last_modified": os.path.getmtime(model_path),
|
||||
# # ... other metadata fields ...
|
||||
# }
|
||||
|
||||
|
||||
# Thread function to insert data from the queue into the database
|
||||
def insert_queue2db():
|
||||
print("starting insert_queue2db thread")
|
||||
|
||||
@ -798,6 +798,30 @@
|
||||
<button type="submit" class="btn btn-outline-success btn-sm">Upload Model</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- modal na inspekci -->
|
||||
<div id="modelModal" class="modal fade" style="--bs-modal-width: 900px;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title_json"><i class="fa fa-plus"></i>Model metadata</h4>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="metadata-container" id="metadata_label" class="form-label">Metadata</label>
|
||||
<div id="metadata-container" style="height:700px;border:1px solid black;">
|
||||
<div id="toml-editor-container"></div>
|
||||
<div id="python-editor-container"></div>
|
||||
</div>
|
||||
<!-- <div id="metadata-container" style="height:200px;border:1px solid black;"></div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="TestListContainer" class="flex-items">
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
//ML Model GUI section
|
||||
|
||||
let model_editor_json
|
||||
let model_editor_python
|
||||
|
||||
$(document).ready(function() {
|
||||
function fetchModels() {
|
||||
$.ajax({
|
||||
@ -14,7 +19,8 @@ $(document).ready(function() {
|
||||
const models = response.models;
|
||||
models.forEach(function(model) {
|
||||
$('#model-list').append(`
|
||||
<p>${model}
|
||||
<p>${model}
|
||||
<span class="inspect-model" data-model="${model}">[🔍]</span>
|
||||
<span class="download-model" data-model="${model}">[↓]</span>
|
||||
<span class="delete-model" data-model="${model}">[x]</span>
|
||||
</p>
|
||||
@ -24,7 +30,7 @@ $(document).ready(function() {
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$('#model-list').html('An error occurred: ' + error);
|
||||
$('#model-list').html('An error occurred: ' + error + xhr.responseText + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -40,7 +46,7 @@ $(document).ready(function() {
|
||||
fetchModels(); // Refresh the list after deletion
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert('Error deleting model: ' + error);
|
||||
alert('Error deleting model: ' + error + xhr.responseText + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -60,7 +66,7 @@ $(document).ready(function() {
|
||||
alert('Model uploaded successfully');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert('Error uploading model: ' + error);
|
||||
alert('Error uploading model: ' + error + xhr.responseText + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -86,11 +92,53 @@ $(document).ready(function() {
|
||||
a.remove();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert('Error downloading model: ' + error);
|
||||
alert('Error downloading model: ' + error + xhr.responseText + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Function to fetch metadata
|
||||
function fetchMetadata(modelName) {
|
||||
$.ajax({
|
||||
url: '/model/metadata/' + modelName,
|
||||
type: 'GET',
|
||||
beforeSend: function (xhr) {
|
||||
xhr.setRequestHeader('X-API-Key', API_KEY);
|
||||
},
|
||||
success: function(response) {
|
||||
show_metadata(response, modelName)
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$('#metadata-container').html('Error fetching metadata: ' + error + xhr.responseText + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function show_metadata(response, name) {
|
||||
// var formattedMetadata = '<pre>cfg:' + JSON.stringify(response.cfg, null, 4) + '</pre>';
|
||||
// formattedMetadata += '<pre>arch_function:' + response.arch_function + '</pre>';
|
||||
// $('#metadata-container').html(formattedMetadata);
|
||||
//console.log(response)
|
||||
console.log(JSON.stringify(response,null,4))
|
||||
$('#metadata_label').html(name);
|
||||
|
||||
require(["vs/editor/editor.main"], () => {
|
||||
model_editor_json = monaco.editor.create(document.getElementById('toml-editor-container'), {
|
||||
value: response.cfg_toml,
|
||||
language: 'toml',
|
||||
theme: 'tomlTheme-dark',
|
||||
automaticLayout: true,
|
||||
readOnly: true
|
||||
});
|
||||
model_editor_python = monaco.editor.create(document.getElementById('python-editor-container'), {
|
||||
value: response.arch_function,
|
||||
language: 'python',
|
||||
theme: 'tomlTheme-dark',
|
||||
automaticLayout: true,
|
||||
readOnly: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch models on page load
|
||||
fetchModels();
|
||||
@ -119,6 +167,15 @@ $(document).ready(function() {
|
||||
uploadModel(formData);
|
||||
});
|
||||
|
||||
// Event handler for the inspect icon
|
||||
$('#model-list').on('click', '.inspect-model', function() {
|
||||
if (model_editor_json) {model_editor_json.dispose()}
|
||||
if (model_editor_python) {model_editor_python.dispose()}
|
||||
const modelName = $(this).data('model');
|
||||
fetchMetadata(modelName);
|
||||
window.$('#modelModal').modal('show');
|
||||
});
|
||||
|
||||
//Handler to download the model
|
||||
$('#model-list').on('click', '.download-model', function() {
|
||||
const modelName = $(this).data('model');
|
||||
|
||||
@ -88,6 +88,8 @@ $(document).ready(function () {
|
||||
|
||||
require(["vs/editor/editor.main"], () => {
|
||||
|
||||
monaco.languages.register({ id: 'python' });
|
||||
monaco.languages.register({ id: 'json' });
|
||||
// Register the TOML language
|
||||
monaco.languages.register({ id: 'toml' });
|
||||
|
||||
|
||||
@ -49,15 +49,36 @@
|
||||
}
|
||||
|
||||
.scrollable-div {
|
||||
width: 262px;
|
||||
width: 328px;
|
||||
height: 143px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #585858;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* #metadata-container {
|
||||
overflow-y: auto;
|
||||
height: 500px;
|
||||
} */
|
||||
|
||||
#metadata-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%; /* Adjust this as needed */
|
||||
}
|
||||
|
||||
#toml-editor-container {
|
||||
height: 60%; /* Adjust this as needed */
|
||||
}
|
||||
|
||||
#python-editor-container {
|
||||
height: 40%; /* Adjust this as needed */
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
|
||||
/* ... existing CSS ... */
|
||||
.download-model, .delete-model {
|
||||
.download-model, .delete-model, .inspect-model {
|
||||
cursor: pointer;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ class Strategy:
|
||||
if self.signal_stop:
|
||||
print(current_thread().name, "Stopping signal - internal")
|
||||
break
|
||||
if self.state.time is not None and self.state.time > self.state.today_market_close:
|
||||
if self.state.time is not None and self.state.today_market_close is not None and self.state.time > self.state.today_market_close:
|
||||
print(current_thread().name, "MARKET CLOSE - Stopping signal - internal")
|
||||
break
|
||||
#check signals - external signal stops also batch
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import os
|
||||
# import importlib
|
||||
# from v2realbot.strategyblocks.indicators.custom.opengap import opengap
|
||||
# Get the directory of the current file (__init__.py)
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
for filename in os.listdir("v2realbot/strategyblocks/indicators/custom"):
|
||||
for filename in os.listdir(current_dir):
|
||||
if filename.endswith(".py") and filename != "__init__.py":
|
||||
# __import__(filename[:-3])
|
||||
__import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}")
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
# import os
|
||||
# # import importlib
|
||||
# # from v2realbot.strategyblocks.indicators.custom.opengap import opengap
|
||||
# Get the directory of the current file (__init__.py)
|
||||
# current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# for filename in os.listdir("v2realbot/strategyblocks/indicators/custom"):
|
||||
# for filename in os.listdir(current_dir):
|
||||
# if filename.endswith(".py") and filename != "__init__.py":
|
||||
# # __import__(filename[:-3])
|
||||
# __import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}")
|
||||
|
||||
Reference in New Issue
Block a user