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 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")
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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');
|
||||||
|
|||||||
@ -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' });
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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]}")
|
||||||
|
|||||||
@ -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]}")
|
||||||
|
|||||||
Reference in New Issue
Block a user