Skip to content

Commit

Permalink
Websockets/codemirror implementation, execution interruption, bug fix…
Browse files Browse the repository at this point in the history
…es (#113)

* initial codemirror

* All cells saving on keyup, Finish completions in code cells

* added text component import to layout

* got view to work

* fixed type errors on code component and moved stuff to setup

* ctrl enter fixed

* websocket runcode

* nice

* completions with cell_id

* code completions working

* Model Fix and more

* remove ace

* Typo

* Fixes and built files

* Remove

* update save cell to not save on ctrl+enter

* App mode with stdout bug

* LFG

* frontend build

* Hide add cell in app, run request queue lock state, no extra websocket in execute

* Remove user state

* test fix

* ws connection fix

---------

Co-authored-by: Red-Giuliano <red.giuliano@zero-true.com>
  • Loading branch information
Carson-Shaar and Red-Giuliano authored Dec 7, 2023
1 parent ac7ac1e commit b9aff77
Show file tree
Hide file tree
Showing 59 changed files with 1,823 additions and 4,025 deletions.
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include_package_data = true
packages = find:
install_requires =
fastapi
uvicorn
uvicorn[standard]
pydantic
toml
pytest
Expand All @@ -28,6 +28,7 @@ install_requires =
lock-requirements
pyyaml
rtoml
jedi

[options.entry_points]
console_scripts =
Expand Down
188 changes: 188 additions & 0 deletions zt_backend/dist_app/assets/index-67be79b0.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,608 changes: 0 additions & 1,608 deletions zt_backend/dist_app/assets/index-d25ef89f.js

This file was deleted.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions zt_backend/dist_app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Zero-True</title>
<script type="module" crossorigin src="./assets/index-d25ef89f.js"></script>
<link rel="stylesheet" href="./assets/index-9d4f0e04.css">
<script type="module" crossorigin src="./assets/index-67be79b0.js"></script>
<link rel="stylesheet" href="./assets/index-b4b3b1e9.css">
</head>

<body>
Expand Down
188 changes: 188 additions & 0 deletions zt_backend/dist_dev/assets/index-608d348b.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,608 changes: 0 additions & 1,608 deletions zt_backend/dist_dev/assets/index-f89dedf6.js

This file was deleted.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions zt_backend/dist_dev/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Zero-True</title>
<script type="module" crossorigin src="./assets/index-f89dedf6.js"></script>
<link rel="stylesheet" href="./assets/index-9d4f0e04.css">
<script type="module" crossorigin src="./assets/index-608d348b.js"></script>
<link rel="stylesheet" href="./assets/index-b4b3b1e9.css">
</head>

<body>
Expand Down
2 changes: 2 additions & 0 deletions zt_backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import OrderedDict
from zt_backend.models.notebook import Notebook, CodeCell
from zt_backend.config import settings
from zt_backend.utils import get_notebook
import zt_backend.router as router
import os
import uuid
Expand Down Expand Up @@ -55,6 +56,7 @@ def open_project():
with open('requirements.txt', 'w') as file:
file.write('zero-true')
subprocess.run("lock requirements.txt")
get_notebook()
except Exception as e:
logger.error("Error creating new files on startup: %s", traceback.format_exc())

Expand Down
23 changes: 12 additions & 11 deletions zt_backend/models/components/autocomplete.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
from pydantic import Field, validator, field_validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.validations import validate_color
from typing import List, Union
from zt_backend.models.state import component_values
from typing import List, Optional, Union
from zt_backend.runner.user_state import UserContext

class Autocomplete(ZTComponent):
"""A class for Autocomplete components inheriting from ZTComponent."""

component: str = Field("v-autocomplete", description="Vue component name.")
items: List[Union[str, int]] = Field(..., description="Options for the autocomplete box. Can be a list of strings or integers.")
value: Union[str, int,None] = Field("", description="Selected option for the autocomplete box. Can be a string or integer.")
label: str = Field(None, description="Label for the autocomplete box.")
multiple: bool = Field(False, description="Determines if multiple selections are allowed.")
clearable: bool = Field(None, description="Determines if the autocomplete box has a clearable option.")
disabled: bool = Field(None, description="Determines if the autocomplete box is disabled.")
readonly: bool = Field(None, description="Determines if the autocomplete box is read-only.")
color: str = Field(None, pre=True, description="Color of the autocomplete component. Can be custom or standard Material color.")
value: Union[str, int, None] = Field("", description="Selected option for the autocomplete box. Can be a string or integer.")
label: Optional[str] = Field(None, description="Label for the autocomplete box.")
multiple: Optional[bool] = Field(None, description="Determines if multiple selections are allowed.")
clearable: Optional[bool] = Field(None, description="Determines if the autocomplete box has a clearable option.")
disabled: Optional[bool] = Field(None, description="Determines if the autocomplete box is disabled.")
readonly: Optional[bool] = Field(None, description="Determines if the autocomplete box is read-only.")
color: Optional[str] = Field(None, pre=True, description="Color of the autocomplete component. Can be custom or standard Material color.")
triggerEvent: str = Field('update:modelValue',description="Trigger event for when to run based on the selected value")

@field_validator('color')
Expand All @@ -25,9 +25,10 @@ def validate_color(cls, color):
@validator('value', always=True) #TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
7 changes: 4 additions & 3 deletions zt_backend/models/components/button.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pydantic import Field, validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.state import component_values
from zt_backend.runner.user_state import UserContext

class Button(ZTComponent):
"""A class for Button components inheriting from ZTComponent."""
Expand All @@ -15,9 +15,10 @@ class Button(ZTComponent):
@validator('value', always=True)
def get_label_from_global_state(cls, value, values):
id = values.get('id') # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
pass # Handle exception as needed
return (value) # If id doesn't exist in global_state, return the original value
12 changes: 6 additions & 6 deletions zt_backend/models/components/card.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from pydantic import Field
from typing import List
from typing import List, Optional
from zt_backend.models.components.zt_component import ZTComponent

class Card(ZTComponent):
"""A class for Card components inheriting from ZTComponent."""

component: str = Field("v-card", description="Vue component name.")
cardChildren: List[str] = Field([], description="List of child components within the card.")
color: str = Field(None, description="Background color of the card.")
elevation: int = Field(None, ge=0, le=24, description="Elevation level of the card. Must be between 0 and 24.")
density: str = Field(None, enum=['default','comfortable','compact'], description="Density of the component")
width: int = Field(None, description="Width of the card.")
location: str = Field(None, enum=['center'])
color: Optional[str] = Field(None, description="Background color of the card.")
elevation: Optional[int] = Field(None, ge=0, le=24, description="Elevation level of the card. Must be between 0 and 24.")
density: Optional[str] = Field(None, enum=['default','comfortable','compact'], description="Density of the component")
width: Optional[int] = Field(None, description="Width of the card.")
location: Optional[str] = Field(None, enum=['center'])
2 changes: 1 addition & 1 deletion zt_backend/models/components/dataframe.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pandas as pd
from pydantic import Field, validator, BaseModel
from pydantic import Field, BaseModel
import numpy as np
from zt_backend.models.components.zt_component import ZTComponent
from typing import List, Dict,Any
Expand Down
7 changes: 4 additions & 3 deletions zt_backend/models/components/layout.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pydantic import BaseModel,Field
from typing import ForwardRef,Union
from zt_backend.models.state import current_cell_layout,context_globals
from typing import List
from zt_backend.runner.user_state import UserContext

Row = ForwardRef('Row')
Column = ForwardRef('Column')
Expand All @@ -21,5 +21,6 @@ class Layout(BaseModel):

def __init__(self, **data):
super().__init__(**data)
if context_globals['exec_mode']:
current_cell_layout.append(self)
execution_state = UserContext.get_state()
if execution_state and execution_state.context_globals['exec_mode']:
execution_state.current_cell_layout.append(self)
27 changes: 14 additions & 13 deletions zt_backend/models/components/multiselect.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from pydantic import Field, validator,field_validator
from pydantic import Field, validator, field_validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.validations import validate_color
from typing import List, Union
from zt_backend.models.state import component_values
from typing import List, Union, Optional
from zt_backend.runner.user_state import UserContext

class MultiSelectBox(ZTComponent):
"""A class for SelectBox components inheriting from ZTComponent."""
Expand All @@ -11,14 +11,14 @@ class MultiSelectBox(ZTComponent):

items: List[Union[str, int]] = Field(..., description="Options for the select box. Can be a list of strings or integers.")
value: Union[List[Union[str, int,None]],None,str,int] = Field(None, description="Selected option for the select box. Can be a string or integer.")
label: str = Field(None, description="Label for the select box.")
multiple: bool = Field(False, description="Determines if multiple selections are allowed.")
dense: bool = Field(None, description="Determines if the select box is dense.")
outlined: bool = Field(None, description="Determines if the select box has an outlined style.")
clearable: bool = Field(None, description="Determines if the select box has a clearable option.")
disabled: bool = Field(None, description="Determines if the select box is disabled.")
readonly: bool = Field(None, description="Determines if the select box is read-only.")
color: str = Field(None, pre=True, description="Color of the range slider. Can be custom or standard Material color.")
label: Optional[str] = Field(None, description="Label for the select box.")
multiple: Optional[bool] = Field(None, description="Determines if multiple selections are allowed.")
dense: Optional[bool] = Field(None, description="Determines if the select box is dense.")
outlined: Optional[bool] = Field(None, description="Determines if the select box has an outlined style.")
clearable: Optional[bool] = Field(None, description="Determines if the select box has a clearable option.")
disabled: Optional[bool] = Field(None, description="Determines if the select box is disabled.")
readonly: Optional[bool] = Field(None, description="Determines if the select box is read-only.")
color: Optional[str] = Field(None, pre=True, description="Color of the range slider. Can be custom or standard Material color.")
triggerEvent: str = Field('update:modelValue',description="Trigger event for when to run the slider")
multiple: str = ''
@field_validator('color')
Expand All @@ -28,9 +28,10 @@ def validate_color(cls, color):
@validator('value', always=True) #TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
17 changes: 9 additions & 8 deletions zt_backend/models/components/number_input.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from pydantic import Field, field_validator, validator
from pydantic import Field, validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.state import component_values
from typing import Union,Optional
from zt_backend.runner.user_state import UserContext

class NumberInput(ZTComponent):
"""A class for TextInput components inheriting from ZTComponent."""
component: str = Field("v-number-field", description="Vue component name.")
value: Union[int,float,None] = Field (None,description="The input text value")
placeholder: str = Field(None, description="Placeholder text.")
label: str = Field(None, description="Label for the text input.")
readonly: bool = Field(None, description="If true, the input is read-only.")
disabled: bool = Field(None, description="If true, the input is disabled.")
placeholder: Optional[str] = Field(None, description="Placeholder text.")
label: Optional[str] = Field(None, description="Label for the text input.")
readonly: Optional[bool] = Field(None, description="If true, the input is read-only.")
disabled: Optional[bool] = Field(None, description="If true, the input is disabled.")
type: str = Field('number',description="Ensures that only numbers are accepted on the frontend")
triggerEvent: str = Field('input',description="Trigger event to send code to the backend")

Expand All @@ -19,9 +19,10 @@ def get_value_from_global_state(cls, value, values):
if value=="":
return None
id = values['id'] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
9 changes: 4 additions & 5 deletions zt_backend/models/components/range_slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pydantic import Field, field_validator, validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.validations import validate_color
from zt_backend.models.state import component_values
from zt_backend.runner.user_state import UserContext

class RangeSlider(ZTComponent):
"""A range slider component that allows you to capture numeric input from a user.
Expand All @@ -24,7 +24,6 @@ class RangeSlider(ZTComponent):
color: str = Field('primary', pre=True, description="Color of the range slider. Can be custom or standard Material color.")
size: str = Field('large', description="Size of the slider.")
label: Optional[str] = Field(None,description= 'A label for your slider')

rounded: bool = Field(True, description="Determines if the slider has rounded edges.")
triggerEvent: str = Field('end',description="Trigger event for when to run the slider")

Expand All @@ -35,10 +34,10 @@ def validate_color(cls, color):
@validator('value', always=True) #TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values

execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
Expand Down
28 changes: 14 additions & 14 deletions zt_backend/models/components/selectbox.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
from pydantic import Field, validator,field_validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.validations import validate_color
from typing import List, Union
from zt_backend.models.state import component_values
from typing import List, Union, Optional
from zt_backend.runner.user_state import UserContext

class SelectBox(ZTComponent):
"""A class for SelectBox components inheriting from ZTComponent."""

component: str = Field("v-select", description="Vue component name.")

items: List[Union[str, int]] = Field(..., description="Options for the select box. Can be a list of strings or integers.")
value: Union[str, int,None] = Field(None, description="Selected option for the select box. Can be a string or integer.")
label: str = Field(None, description="Label for the select box.")
multiple: bool = Field(False, description="Determines if multiple selections are allowed.")
dense: bool = Field(None, description="Determines if the select box is dense.")
outlined: bool = Field(None, description="Determines if the select box has an outlined style.")
clearable: bool = Field(None, description="Determines if the select box has a clearable option.")
disabled: bool = Field(None, description="Determines if the select box is disabled.")
readonly: bool = Field(None, description="Determines if the select box is read-only.")
color: str = Field(None, pre=True, description="Color of the range slider. Can be custom or standard Material color.")
value: Union[str, int, None] = Field(None, description="Selected option for the select box. Can be a string or integer.")
label: Optional[str] = Field(None, description="Label for the select box.")
multiple: Optional[bool] = Field(None, description="Determines if multiple selections are allowed.")
dense: Optional[bool] = Field(None, description="Determines if the select box is dense.")
outlined: Optional[bool] = Field(None, description="Determines if the select box has an outlined style.")
clearable: Optional[bool] = Field(None, description="Determines if the select box has a clearable option.")
disabled: Optional[bool] = Field(None, description="Determines if the select box is disabled.")
readonly: Optional[bool] = Field(None, description="Determines if the select box is read-only.")
color: Optional[str] = Field(None, pre=True, description="Color of the range slider. Can be custom or standard Material color.")
triggerEvent: str = Field('update:modelValue',description="Trigger event for when to run the slider")

@field_validator('color')
Expand All @@ -28,9 +27,10 @@ def validate_color(cls, color):
@validator('value', always=True) #TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if id and id in component_values: # Check if id exists in global_state
return component_values[id] # Return the value associated with id in global_state
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
Loading

0 comments on commit b9aff77

Please sign in to comment.