gui ml modal view

This commit is contained in:
David Brazda
2023-12-08 19:11:08 +01:00
parent ac11c37e77
commit 523905ece6
8 changed files with 144 additions and 12 deletions

View File

@ -37,6 +37,8 @@ from traceback import format_exc
import v2realbot.reporting.analyzer as ci import v2realbot.reporting.analyzer as ci
import shutil import shutil
from starlette.responses import JSONResponse from starlette.responses import JSONResponse
import mlroom
import mlroom.utils.mlutils as ml
#from async io import Queue, QueueEmpty #from async io import Queue, QueueEmpty
# #
# install() # install()
@ -841,6 +843,29 @@ def download_model(model_name: str):
else: else:
raise HTTPException(status_code=404, detail="Model not found.") 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 # Thread function to insert data from the queue into the database
def insert_queue2db(): def insert_queue2db():
print("starting insert_queue2db thread") print("starting insert_queue2db thread")

View File

@ -798,6 +798,30 @@
<button type="submit" class="btn btn-outline-success btn-sm">Upload Model</button> <button type="submit" class="btn btn-outline-success btn-sm">Upload Model</button>
</form> </form>
</div> </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>
<div id="TestListContainer" class="flex-items"> <div id="TestListContainer" class="flex-items">

View File

@ -1,3 +1,8 @@
//ML Model GUI section
let model_editor_json
let model_editor_python
$(document).ready(function() { $(document).ready(function() {
function fetchModels() { function fetchModels() {
$.ajax({ $.ajax({
@ -14,7 +19,8 @@ $(document).ready(function() {
const models = response.models; const models = response.models;
models.forEach(function(model) { models.forEach(function(model) {
$('#model-list').append(` $('#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="download-model" data-model="${model}">[↓]</span>
<span class="delete-model" data-model="${model}">[x]</span> <span class="delete-model" data-model="${model}">[x]</span>
</p> </p>
@ -24,7 +30,7 @@ $(document).ready(function() {
} }
}, },
error: function(xhr, status, error) { 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 fetchModels(); // Refresh the list after deletion
}, },
error: function(xhr, status, error) { 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'); alert('Model uploaded successfully');
}, },
error: function(xhr, status, error) { 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(); a.remove();
}, },
error: function(xhr, status, error) { 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 // Fetch models on page load
fetchModels(); fetchModels();
@ -119,6 +167,15 @@ $(document).ready(function() {
uploadModel(formData); 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 //Handler to download the model
$('#model-list').on('click', '.download-model', function() { $('#model-list').on('click', '.download-model', function() {
const modelName = $(this).data('model'); const modelName = $(this).data('model');

View File

@ -88,6 +88,8 @@ $(document).ready(function () {
require(["vs/editor/editor.main"], () => { require(["vs/editor/editor.main"], () => {
monaco.languages.register({ id: 'python' });
monaco.languages.register({ id: 'json' });
// Register the TOML language // Register the TOML language
monaco.languages.register({ id: 'toml' }); monaco.languages.register({ id: 'toml' });

View File

@ -49,15 +49,36 @@
} }
.scrollable-div { .scrollable-div {
width: 262px; width: 328px;
height: 143px; height: 143px;
overflow-y: auto; overflow-y: auto;
border: 1px solid #585858; border: 1px solid #585858;
padding: 10px; 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 ... */ /* ... existing CSS ... */
.download-model, .delete-model { .download-model, .delete-model, .inspect-model {
cursor: pointer; cursor: pointer;
padding: 0 5px; padding: 0 5px;
} }

View File

@ -435,7 +435,7 @@ class Strategy:
if self.signal_stop: if self.signal_stop:
print(current_thread().name, "Stopping signal - internal") print(current_thread().name, "Stopping signal - internal")
break 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") print(current_thread().name, "MARKET CLOSE - Stopping signal - internal")
break break
#check signals - external signal stops also batch #check signals - external signal stops also batch

View File

@ -1,8 +1,10 @@
import os import os
# import importlib # import importlib
# from v2realbot.strategyblocks.indicators.custom.opengap import opengap # 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": if filename.endswith(".py") and filename != "__init__.py":
# __import__(filename[:-3]) # __import__(filename[:-3])
__import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}") __import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}")

View File

@ -1,8 +1,9 @@
# import os # import os
# # import importlib # # 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": # if filename.endswith(".py") and filename != "__init__.py":
# # __import__(filename[:-3]) # # __import__(filename[:-3])
# __import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}") # __import__(f"v2realbot.strategyblocks.indicators.custom.{filename[:-3]}")