ivoryos 1.2.0b1__py3-none-any.whl → 1.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +22 -1
- ivoryos/config.py +1 -0
- ivoryos/optimizer/ax_optimizer.py +164 -0
- ivoryos/optimizer/base_optimizer.py +65 -0
- ivoryos/optimizer/baybe_optimizer.py +183 -0
- ivoryos/optimizer/registry.py +9 -0
- ivoryos/routes/auth/auth.py +3 -1
- ivoryos/routes/data/data.py +2 -0
- ivoryos/routes/design/design.py +4 -4
- ivoryos/routes/library/library.py +4 -4
- ivoryos/utils/script_runner.py +1 -1
- ivoryos/utils/serilize.py +4 -6
- ivoryos/utils/utils.py +2 -1
- ivoryos/version.py +1 -1
- {ivoryos-1.2.0b1.dist-info → ivoryos-1.2.2.dist-info}/METADATA +60 -35
- ivoryos-1.2.2.dist-info/RECORD +47 -0
- {ivoryos-1.2.0b1.dist-info → ivoryos-1.2.2.dist-info}/WHEEL +1 -1
- {ivoryos-1.2.0b1.dist-info → ivoryos-1.2.2.dist-info}/top_level.txt +0 -1
- ivoryos/routes/auth/templates/login.html +0 -25
- ivoryos/routes/auth/templates/signup.html +0 -32
- ivoryos/routes/control/templates/controllers.html +0 -166
- ivoryos/routes/control/templates/controllers_new.html +0 -112
- ivoryos/routes/data/templates/components/step_card.html +0 -13
- ivoryos/routes/data/templates/workflow_database.html +0 -109
- ivoryos/routes/data/templates/workflow_view.html +0 -130
- ivoryos/routes/design/templates/components/action_form.html +0 -53
- ivoryos/routes/design/templates/components/actions_panel.html +0 -25
- ivoryos/routes/design/templates/components/autofill_toggle.html +0 -10
- ivoryos/routes/design/templates/components/canvas.html +0 -5
- ivoryos/routes/design/templates/components/canvas_footer.html +0 -9
- ivoryos/routes/design/templates/components/canvas_header.html +0 -75
- ivoryos/routes/design/templates/components/canvas_main.html +0 -34
- ivoryos/routes/design/templates/components/deck_selector.html +0 -10
- ivoryos/routes/design/templates/components/edit_action_form.html +0 -38
- ivoryos/routes/design/templates/components/instruments_panel.html +0 -66
- ivoryos/routes/design/templates/components/modals/drop_modal.html +0 -17
- ivoryos/routes/design/templates/components/modals/json_modal.html +0 -22
- ivoryos/routes/design/templates/components/modals/new_script_modal.html +0 -17
- ivoryos/routes/design/templates/components/modals/rename_modal.html +0 -23
- ivoryos/routes/design/templates/components/modals/saveas_modal.html +0 -27
- ivoryos/routes/design/templates/components/modals.html +0 -6
- ivoryos/routes/design/templates/components/python_code_overlay.html +0 -39
- ivoryos/routes/design/templates/components/sidebar.html +0 -15
- ivoryos/routes/design/templates/components/text_to_code_panel.html +0 -20
- ivoryos/routes/design/templates/experiment_builder.html +0 -41
- ivoryos/routes/execute/templates/components/error_modal.html +0 -20
- ivoryos/routes/execute/templates/components/logging_panel.html +0 -31
- ivoryos/routes/execute/templates/components/progress_panel.html +0 -27
- ivoryos/routes/execute/templates/components/run_panel.html +0 -9
- ivoryos/routes/execute/templates/components/run_tabs.html +0 -17
- ivoryos/routes/execute/templates/components/tab_bayesian.html +0 -399
- ivoryos/routes/execute/templates/components/tab_configuration.html +0 -98
- ivoryos/routes/execute/templates/components/tab_repeat.html +0 -14
- ivoryos/routes/execute/templates/experiment_run.html +0 -294
- ivoryos/routes/library/templates/library.html +0 -91
- ivoryos/routes/main/templates/help.html +0 -141
- ivoryos/routes/main/templates/home.html +0 -103
- ivoryos/static/favicon.ico +0 -0
- ivoryos/static/gui_annotation/Slide1.png +0 -0
- ivoryos/static/gui_annotation/Slide2.PNG +0 -0
- ivoryos/static/js/action_handlers.js +0 -213
- ivoryos/static/js/db_delete.js +0 -23
- ivoryos/static/js/overlay.js +0 -12
- ivoryos/static/js/script_metadata.js +0 -39
- ivoryos/static/js/socket_handler.js +0 -125
- ivoryos/static/js/sortable_card.js +0 -24
- ivoryos/static/js/sortable_design.js +0 -138
- ivoryos/static/js/ui_state.js +0 -113
- ivoryos/static/logo.webp +0 -0
- ivoryos/static/style.css +0 -211
- ivoryos/templates/base.html +0 -157
- ivoryos-1.2.0b1.dist-info/RECORD +0 -105
- tests/__init__.py +0 -0
- tests/conftest.py +0 -133
- tests/integration/__init__.py +0 -0
- tests/integration/test_route_auth.py +0 -80
- tests/integration/test_route_control.py +0 -94
- tests/integration/test_route_database.py +0 -61
- tests/integration/test_route_design.py +0 -36
- tests/integration/test_route_main.py +0 -35
- tests/integration/test_sockets.py +0 -26
- {ivoryos-1.2.0b1.dist-info → ivoryos-1.2.2.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from ivoryos.utils.db_models import User, db
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_get_signup(client):
|
|
5
|
-
"""
|
|
6
|
-
GIVEN a client
|
|
7
|
-
WHEN a GET request is made to /ivoryos/auth/signup
|
|
8
|
-
THEN check that signup page loads with 200 status and contains "Signup" text
|
|
9
|
-
"""
|
|
10
|
-
response = client.get("/ivoryos/auth/signup", follow_redirects=True)
|
|
11
|
-
assert response.status_code == 200
|
|
12
|
-
assert b"Signup" in response.data
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_route_auth_signup(client):
|
|
16
|
-
"""
|
|
17
|
-
GIVEN a client
|
|
18
|
-
WHEN a POST request is made to /ivoryos/auth/signup with valid credentials
|
|
19
|
-
THEN check that signup succeeds with 200 status and the user is created in database
|
|
20
|
-
"""
|
|
21
|
-
response = client.post("/ivoryos/auth/signup",
|
|
22
|
-
data={
|
|
23
|
-
"username": "second_testuser",
|
|
24
|
-
"password": "password"
|
|
25
|
-
},
|
|
26
|
-
follow_redirects=True
|
|
27
|
-
)
|
|
28
|
-
assert response.status_code == 200
|
|
29
|
-
assert b"Login" in response.data
|
|
30
|
-
|
|
31
|
-
# Verify user was created
|
|
32
|
-
with client.application.app_context():
|
|
33
|
-
user = db.session.query(User).filter(User.username == 'second_testuser').first()
|
|
34
|
-
assert user is not None
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def test_duplicate_user_signup(client, init_database):
|
|
38
|
-
"""
|
|
39
|
-
GIVEN a client and init_database fixture
|
|
40
|
-
WHEN a POST request is made to signup with an existing username
|
|
41
|
-
THEN check that signup fails with 409 status and appropriate error message
|
|
42
|
-
"""
|
|
43
|
-
client.post('/ivoryos/auth/signup', data={
|
|
44
|
-
'username': 'existinguser',
|
|
45
|
-
'password': 'anotherpass'
|
|
46
|
-
})
|
|
47
|
-
# Try to create duplicate
|
|
48
|
-
response = client.post('/ivoryos/auth/signup', data={
|
|
49
|
-
'username': 'existinguser',
|
|
50
|
-
'password': 'anotherpass'
|
|
51
|
-
})
|
|
52
|
-
assert response.status_code == 409
|
|
53
|
-
assert b"Signup" in response.data
|
|
54
|
-
assert b"User already exists" in response.data
|
|
55
|
-
|
|
56
|
-
# Verify user was created
|
|
57
|
-
users = db.session.query(User).filter(User.username == 'existinguser').all()
|
|
58
|
-
assert len(users) == 1
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def test_failed_login(client):
|
|
62
|
-
"""
|
|
63
|
-
GIVEN a client and invalid login credentials
|
|
64
|
-
WHEN a POST request is made to /ivoryos/auth/login
|
|
65
|
-
THEN check that login fails with 401 status and the appropriate error message
|
|
66
|
-
"""
|
|
67
|
-
response = client.post('/ivoryos/auth/login', data={
|
|
68
|
-
'username': 'nonexistent',
|
|
69
|
-
'password': 'wrongpass'
|
|
70
|
-
})
|
|
71
|
-
assert response.status_code == 401
|
|
72
|
-
|
|
73
|
-
def test_logout(auth):
|
|
74
|
-
"""
|
|
75
|
-
GIVEN an authenticated client
|
|
76
|
-
WHEN a GET request is made to /ivoryos/auth/logout
|
|
77
|
-
THEN check that logout succeeds with 302 status and redirects to login
|
|
78
|
-
"""
|
|
79
|
-
response = auth.get('/ivoryos/auth/logout')
|
|
80
|
-
assert response.status_code == 302 # Redirect to login
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
from unittest.mock import patch, Mock
|
|
2
|
-
|
|
3
|
-
from ivoryos.utils.db_models import Script
|
|
4
|
-
from ivoryos import db
|
|
5
|
-
|
|
6
|
-
def test_control_panel_redirects_anonymous(client):
|
|
7
|
-
"""
|
|
8
|
-
GIVEN an anonymous user
|
|
9
|
-
WHEN the control panel is accessed
|
|
10
|
-
THEN they should be redirected to the login page
|
|
11
|
-
"""
|
|
12
|
-
response = client.get('/ivoryos/control/home/deck', follow_redirects=True)
|
|
13
|
-
assert response.status_code == 200
|
|
14
|
-
assert b'Login' in response.data
|
|
15
|
-
|
|
16
|
-
def test_deck_control_for_auth_user(auth):
|
|
17
|
-
"""
|
|
18
|
-
GIVEN an authenticated user
|
|
19
|
-
WHEN the control panel is accessed
|
|
20
|
-
THEN the page should load successfully
|
|
21
|
-
"""
|
|
22
|
-
response = auth.get('/ivoryos/control/home/deck', follow_redirects=True)
|
|
23
|
-
assert response.status_code == 200
|
|
24
|
-
assert b'<title>IvoryOS | Devices</title>' in response.data # Assuming this text exists on the page
|
|
25
|
-
|
|
26
|
-
def test_temp_control_for_auth_user(auth):
|
|
27
|
-
"""
|
|
28
|
-
GIVEN an authenticated user
|
|
29
|
-
WHEN the control panel is accessed
|
|
30
|
-
THEN the page should load successfully
|
|
31
|
-
"""
|
|
32
|
-
response = auth.get('/ivoryos/control/home/temp', follow_redirects=True)
|
|
33
|
-
assert response.status_code == 200
|
|
34
|
-
# assert b'<title>IvoryOS | Devices</title>' in response.data # Assuming this text exists on the page
|
|
35
|
-
|
|
36
|
-
def test_new_controller_page(auth):
|
|
37
|
-
"""Test new controller page loads"""
|
|
38
|
-
response = auth.get('/ivoryos/control/new/')
|
|
39
|
-
assert response.status_code == 200
|
|
40
|
-
|
|
41
|
-
def test_download_proxy(self, auth_headers):
|
|
42
|
-
"""Test proxy download functionality"""
|
|
43
|
-
with patch('ivoryos.routes.control.control.global_config') as mock_config:
|
|
44
|
-
mock_config.deck_snapshot = {'test_instrument': {'test_method': {'signature': 'test()'}}}
|
|
45
|
-
response = auth_headers.get('/ivoryos/control/download')
|
|
46
|
-
assert response.status_code == 200
|
|
47
|
-
assert response.headers['Content-Disposition'].startswith('attachment')
|
|
48
|
-
|
|
49
|
-
def test_backend_control_get(self, auth_headers):
|
|
50
|
-
"""Test backend control GET endpoint"""
|
|
51
|
-
with patch('ivoryos.routes.control.control.global_config') as mock_config:
|
|
52
|
-
mock_config.deck_snapshot = {'test_instrument': {'test_method': {'signature': 'test()'}}}
|
|
53
|
-
response = auth_headers.get('/ivoryos/api/control/')
|
|
54
|
-
assert response.status_code == 200
|
|
55
|
-
assert response.is_json
|
|
56
|
-
|
|
57
|
-
@patch('ivoryos.routes.control.control.runner')
|
|
58
|
-
@patch('ivoryos.routes.control.control.find_instrument_by_name')
|
|
59
|
-
@patch('ivoryos.routes.control.control.create_form_from_module')
|
|
60
|
-
def test_backend_control_post(self, mock_form, mock_find, mock_runner, auth_headers):
|
|
61
|
-
"""Test backend control POST endpoint"""
|
|
62
|
-
# Setup mocks
|
|
63
|
-
mock_instrument = Mock()
|
|
64
|
-
mock_find.return_value = mock_instrument
|
|
65
|
-
mock_field = Mock()
|
|
66
|
-
mock_field.name = 'test_param'
|
|
67
|
-
mock_field.data = 'test_value'
|
|
68
|
-
mock_form_instance = Mock()
|
|
69
|
-
mock_form_instance.__iter__ = Mock(return_value=iter([mock_field]))
|
|
70
|
-
mock_form.return_value = {'test_method': mock_form_instance}
|
|
71
|
-
mock_runner.run_single_step.return_value = 'success'
|
|
72
|
-
response = auth_headers.post('/ivoryos/api/control/test_instrument', data={
|
|
73
|
-
'hidden_name': 'test_method',
|
|
74
|
-
'hidden_wait': 'true'
|
|
75
|
-
})
|
|
76
|
-
assert response.status_code == 200
|
|
77
|
-
|
|
78
|
-
# def test_control(auth, app):
|
|
79
|
-
# """
|
|
80
|
-
# GIVEN an authenticated user and an existing script
|
|
81
|
-
# WHEN a POST request is made to run the script
|
|
82
|
-
# THEN the user should be redirected and a success message shown
|
|
83
|
-
# """
|
|
84
|
-
# # We need to create a script in the database first
|
|
85
|
-
# with app.app_context():
|
|
86
|
-
# script = Script(name='My Test Script', author='testuser', content='print("hello")')
|
|
87
|
-
# db.session.add(script)
|
|
88
|
-
# db.session.commit()
|
|
89
|
-
# script_id = script.id
|
|
90
|
-
#
|
|
91
|
-
# # Simulate running the script
|
|
92
|
-
# response = auth.post(f'/ivoryos/control/run/{script_id}', follow_redirects=True)
|
|
93
|
-
# assert response.status_code == 200
|
|
94
|
-
# assert b'has been initiated' in response.data # Check for a flash message
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
|
|
3
|
-
from ivoryos.utils.db_models import Script, WorkflowRun, WorkflowStep
|
|
4
|
-
from ivoryos import db
|
|
5
|
-
|
|
6
|
-
def test_database_scripts_page(auth):
|
|
7
|
-
"""
|
|
8
|
-
GIVEN an authenticated user
|
|
9
|
-
WHEN they access the script database page
|
|
10
|
-
THEN the page should load and show their scripts
|
|
11
|
-
"""
|
|
12
|
-
# First, create a script so the page has something to render
|
|
13
|
-
with auth.application.app_context():
|
|
14
|
-
script = Script(name='test_script', author='testuser')
|
|
15
|
-
db.session.add(script)
|
|
16
|
-
db.session.commit()
|
|
17
|
-
|
|
18
|
-
response = auth.get('/ivoryos/database/scripts/', follow_redirects=True)
|
|
19
|
-
assert response.status_code == 200
|
|
20
|
-
# assert b'Scripts Database' in response.data
|
|
21
|
-
assert b'<title>IvoryOS | Design Database</title>' in response.data
|
|
22
|
-
|
|
23
|
-
def test_database_workflows_page(auth):
|
|
24
|
-
"""
|
|
25
|
-
GIVEN an authenticated user
|
|
26
|
-
WHEN they access the workflow database page
|
|
27
|
-
THEN the page should load and show past workflow runs
|
|
28
|
-
"""
|
|
29
|
-
# Create a workflow run to display
|
|
30
|
-
with auth.application.app_context():
|
|
31
|
-
run = WorkflowRun(name="untitled", platform="deck",start_time=datetime.now())
|
|
32
|
-
db.session.add(run)
|
|
33
|
-
db.session.commit()
|
|
34
|
-
run_id = run.id
|
|
35
|
-
|
|
36
|
-
response = auth.get('/ivoryos/database/workflows/', follow_redirects=True)
|
|
37
|
-
assert response.status_code == 200
|
|
38
|
-
assert b'Workflow ID' in response.data
|
|
39
|
-
# assert b'run_id' in response.data
|
|
40
|
-
|
|
41
|
-
def test_view_specific_workflow(auth):
|
|
42
|
-
"""
|
|
43
|
-
GIVEN an authenticated user and an existing workflow run
|
|
44
|
-
WHEN they access the specific URL for that workflow
|
|
45
|
-
THEN the detailed view for that run should be displayed
|
|
46
|
-
"""
|
|
47
|
-
with auth.application.app_context():
|
|
48
|
-
run = WorkflowRun(name='test_workflow', platform='test_platform', start_time=datetime.now())
|
|
49
|
-
db.session.add(run)
|
|
50
|
-
db.session.commit()
|
|
51
|
-
run_id = run.id
|
|
52
|
-
|
|
53
|
-
step = WorkflowStep(method_name='test_step', workflow_id=run_id, phase="main", run_error=False, start_time=datetime.now())
|
|
54
|
-
db.session.add(step)
|
|
55
|
-
db.session.commit()
|
|
56
|
-
# run_id = run.id
|
|
57
|
-
|
|
58
|
-
response = auth.get(f'/ivoryos/database/workflows/{run_id}', follow_redirects=True)
|
|
59
|
-
assert response.status_code == 200
|
|
60
|
-
# assert b'test_step' in response.data # Check for a title on the view page
|
|
61
|
-
assert b'test_workflow' in response.data
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
def test_design_page_loads_for_auth_user(auth):
|
|
2
|
-
"""
|
|
3
|
-
GIVEN an authenticated user
|
|
4
|
-
WHEN the design page is accessed
|
|
5
|
-
THEN the page should load successfully
|
|
6
|
-
"""
|
|
7
|
-
response = auth.get('/ivoryos/design/script/', follow_redirects=True)
|
|
8
|
-
assert response.status_code == 200
|
|
9
|
-
assert b'<title>IvoryOS | Design</title>' in response.data # Assuming this text exists
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_clear_canvas(auth):
|
|
13
|
-
"""
|
|
14
|
-
Tests clearing the design canvas.
|
|
15
|
-
"""
|
|
16
|
-
response = auth.get('/ivoryos/design/clear', follow_redirects=True)
|
|
17
|
-
assert response.status_code == 200
|
|
18
|
-
# assert b'Operations' in response.data
|
|
19
|
-
|
|
20
|
-
# def test_add_action(auth, test_deck):
|
|
21
|
-
# """
|
|
22
|
-
# Tests adding an action to the design canvas.
|
|
23
|
-
# """
|
|
24
|
-
# response = auth.post('/ivoryos/design/script/deck.dummy/', data={
|
|
25
|
-
# 'hidden_name': 'int_method',
|
|
26
|
-
# 'arg': '10'
|
|
27
|
-
# }, follow_redirects=True)
|
|
28
|
-
# assert response.status_code == 200
|
|
29
|
-
|
|
30
|
-
def test_experiment_run_page(auth):
|
|
31
|
-
"""
|
|
32
|
-
Tests the experiment run page.
|
|
33
|
-
"""
|
|
34
|
-
response = auth.get('/ivoryos/design/campaign')
|
|
35
|
-
assert response.status_code == 200
|
|
36
|
-
assert b'Run Panel' in response.data
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
from flask_login import current_user
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_home_page_authenticated(auth, app):
|
|
5
|
-
"""
|
|
6
|
-
GIVEN an authenticated user (using the 'auth' fixture)
|
|
7
|
-
WHEN the home page is accessed
|
|
8
|
-
THEN check that they see the main application page
|
|
9
|
-
"""
|
|
10
|
-
with auth.application.test_request_context('/ivoryos/'):
|
|
11
|
-
# Manually trigger the before_request functions that Flask-Login uses
|
|
12
|
-
app.preprocess_request()
|
|
13
|
-
|
|
14
|
-
# Assert that the `current_user` proxy is now populated and authenticated
|
|
15
|
-
assert current_user.is_authenticated
|
|
16
|
-
assert current_user.username == 'testuser'
|
|
17
|
-
|
|
18
|
-
def test_help_page(client):
|
|
19
|
-
"""
|
|
20
|
-
GIVEN an unauthenticated user
|
|
21
|
-
WHEN they access the help page
|
|
22
|
-
THEN check that the page loads successfully and contains documentation content
|
|
23
|
-
"""
|
|
24
|
-
response = client.get('/ivoryos/help')
|
|
25
|
-
assert response.status_code == 200
|
|
26
|
-
assert b'Documentations' in response.data
|
|
27
|
-
|
|
28
|
-
def test_prefix_redirect(auth):
|
|
29
|
-
"""
|
|
30
|
-
GIVEN an authenticated user (using the 'auth' fixture)
|
|
31
|
-
WHEN the home page is accessed without prefix
|
|
32
|
-
THEN check that they see the main application page
|
|
33
|
-
"""
|
|
34
|
-
response = auth.get('/', follow_redirects=True)
|
|
35
|
-
assert response.status_code == 200
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
def test_socket_connection(socketio_client):
|
|
2
|
-
"""
|
|
3
|
-
Test that a client can successfully connect to the Socket.IO server.
|
|
4
|
-
"""
|
|
5
|
-
assert socketio_client.is_connected()
|
|
6
|
-
socketio_client.disconnect()
|
|
7
|
-
assert not socketio_client.is_connected()
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# def test_logger_socket_event(socketio_client):
|
|
11
|
-
# """
|
|
12
|
-
# Test the custom logging event handler.
|
|
13
|
-
# (This assumes you have a handler like `@socketio.on('start_log')`)
|
|
14
|
-
# """
|
|
15
|
-
# # Connect the client
|
|
16
|
-
# socketio_client.connect()
|
|
17
|
-
#
|
|
18
|
-
# # Emit an event from the client to the server
|
|
19
|
-
# socketio_client.emit('start_log', {'logger_name': 'my_test_logger'})
|
|
20
|
-
#
|
|
21
|
-
# # Check what the server sent back to the client
|
|
22
|
-
# received = socketio_client.get_received()
|
|
23
|
-
#
|
|
24
|
-
# assert len(received) > 0
|
|
25
|
-
# assert received[0]['name'] == 'log_message' # Check for the event name
|
|
26
|
-
# assert 'Logger my_test_logger started' in received[0]['args'][0]['data']
|
|
File without changes
|