Skip to content

Commit

Permalink
feat: store writer framework IDE into project directory instead of ui…
Browse files Browse the repository at this point in the history
….json

* feat: add support for workflow
  • Loading branch information
FabienArcellier committed Sep 22, 2024
1 parent 7d287be commit 867c4f9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 46 deletions.
12 changes: 6 additions & 6 deletions src/writer/core_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,11 @@ def ingest_bmc_component_tree(component_tree: ComponentTree, components: Dict[st
component_tree.ingest(components, tree=Branch.bmc)


def lookup_page_for_component(components: Dict[str, ComponentDefinition], component_id: str) -> Optional[str]:
def lookup_parent_type_for_component(components: Dict[str, ComponentDefinition], component_id: str, parent_type: str) -> Optional[str]:
"""
Retrieves the page of a component
Retrieves the first parent of type {parent_type} for a component.
>>> lookup_page_for_component(components, "6a490318-239e-4fe9-a56b-f0f33d628c87")
>>> lookup_parent_type_for_component(components, "6a490318-239e-4fe9-a56b-f0f33d628c87", "page")
"""
component: Optional[ComponentDefinition] = components.get(component_id, None)
if component is None:
Expand All @@ -400,14 +400,14 @@ def lookup_page_for_component(components: Dict[str, ComponentDefinition], compon
if parent_id is None:
return None

if component['type'] == "page":
if component['type'] == parent_type:
return component['id']

if parent_id in components:
if components[parent_id]['type'] == "page":
if components[parent_id]['type'] == parent_type:
return parent_id
else:
return lookup_page_for_component(components, parent_id)
return lookup_parent_type_for_component(components, parent_id, parent_type)

return None

Expand Down
4 changes: 4 additions & 0 deletions src/writer/ss_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,7 @@ class ComponentDefinition(TypedDict):
handlers: Optional[Dict[str, str]]
visible: Optional[Union[bool, str]]
binding: Optional[Dict]
outs: Optional[Dict[str, str]]
x: Optional[int]
y: Optional[int]

89 changes: 53 additions & 36 deletions src/writer/wf_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,58 @@ def write_files(app_path: str, metadata: MetadataDefinition, components: dict[st
* the metadata.json file is written in json format
* a file for the root component written in jsonline format
* one file per page is created in the form `components-{id}.json` in jsonline format
* a file for the workflows_root component written in jsonline format
* one file per page is created in the form `components-page-{id}.json` in jsonline format
* one file per workflow is created in the form `components-workflows_workflow-{id}.json` in jsonline format
>>> wf_project.write_files('app/hello', metadata={"writer_version": "0.1" }, components=...)
"""
roots = ['root', 'workflows_root']
components_parts_root = ['page', 'workflows_workflow']

wf_directory = os.path.join(app_path, ".wf")
if not os.path.exists(wf_directory):
os.makedirs(wf_directory)

with io.open(os.path.join(wf_directory, "metadata.json"), "w") as f:
json.dump(metadata, f, indent=4)

root_component = components["root"]
with io.open(os.path.join(wf_directory, "components-root.jsonl"), "w") as f:
f.write(json.dumps(root_component))

list_pages = []
for c in components.values():
if c["type"] == "page":
list_pages.append(c["id"])
for root in roots:
root_component = components.get(root, None)
if root_component:
with io.open(os.path.join(wf_directory, f"components-{root}.jsonl"), "w") as f:
f.write(json.dumps(root_component))

for position, page_id in enumerate(list_pages):
page_components = []
page_components_ids = {page_id}
list_parts_root = []
for part_root_type in components_parts_root:
for c in components.values():
if core_ui.lookup_page_for_component(components, c['id']) in page_components_ids:
page_components.append(c)
page_components_ids.add(c["id"])
if c["type"] == part_root_type:
list_parts_root.append(c["id"])

for position, component_id in enumerate(list_parts_root):
part_components = []
part_components_ids = {component_id}
for c in components.values():
if core_ui.lookup_parent_type_for_component(components, c['id'], parent_type=part_root_type) in part_components_ids:
part_components.append(c)
part_components_ids.add(c["id"])

with io.open(os.path.join(wf_directory, f"components-{part_root_type}-{position}-{component_id}.jsonl"), "w") as f:
for p in part_components:
f.write(json.dumps(p) + "\n")

with io.open(os.path.join(wf_directory, f"components-page-{position}-{page_id}.jsonl"), "w") as f:
for p in page_components:
f.write(json.dumps(p) + "\n")

def read_files(app_path: str) -> Tuple[MetadataDefinition, dict[str, ComponentDefinition]]:
"""
Reads project files in the `.wf` folder.
The components are read in page order.
The components are read in page and workflows_workflow order.
>>> metadata, components = wf_project.read_files('app/hello')
"""
components: dict[str, ComponentDefinition] = {}
roots = ['root', 'workflows_root']
component_part_file_type = ['page', 'workflows_workflow']

meta_data_path = os.path.join(app_path, ".wf", "metadata.json")
try:
Expand All @@ -70,26 +81,32 @@ def read_files(app_path: str) -> Tuple[MetadataDefinition, dict[str, ComponentDe
except Exception as e:
raise ValueError(f"Error reading metadata file {meta_data_path} : {e}")

root_component_path = os.path.join(app_path, ".wf", "components-root.jsonl")
try:
with io.open(root_component_path, "r") as filep:
root_component: ComponentDefinition = json.loads(filep.read())
components.update({root_component["id"]: root_component})
except Exception as e:
raise ValueError(f"Error reading root component file {root_component_path} : {e}")

files = os.listdir(os.path.join(app_path, ".wf"))
page_files = [file for file in files if file.startswith("components-page-")]
sorted_page_files = sorted(page_files, key=lambda x: int(x.split("-")[2]))
for page_file in sorted_page_files:
page_file_path = os.path.join(app_path, ".wf", page_file)
# read ui files
for root in roots:
root_component_path = os.path.join(app_path, ".wf", f"components-{root}.jsonl")
if not os.path.exists(root_component_path):
continue

try:
with io.open(page_file_path, "r") as filep:
for line in filep:
component: ComponentDefinition = json.loads(line)
components.update({component["id"]: component})
with io.open(root_component_path, "r") as filep:
root_component: ComponentDefinition = json.loads(filep.read())
components.update({root_component["id"]: root_component})
except Exception as e:
raise ValueError(f"Error reading page component file {page_file_path} : {e}")
raise ValueError(f"Error reading root component file {root_component_path} : {e}")

files = os.listdir(os.path.join(app_path, ".wf"))
for file in files:
for part_file_type in component_part_file_type:
if file.startswith(f"components-{part_file_type}-"):
page_file_path = os.path.join(app_path, ".wf", file)
try:
with io.open(page_file_path, "r") as filep:
for line in filep:
component: ComponentDefinition = json.loads(line)
components.update({component["id"]: component})
except Exception as e:
raise ValueError(f"Error reading page component file {page_file_path} : {e}")

return metadata, components

Expand Down
8 changes: 4 additions & 4 deletions tests/backend/test_core_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@
from backend.fixtures import load_fixture_content


def test_lookup_page_for_component_should_retrieve_the_page_for_a_specific_component_id():
def test_lookup_parent_type_for_component_should_retrieve_the_page_for_a_specific_component_id():
# Given
components_list: List[ComponentDefinition] = load_fixture_content('components/components-page-1.jsonl')
components = {c['id']: c for c in components_list}

# When
page_id = core_ui.lookup_page_for_component(components, '42ab5c3d-21fc-4e88-befd-33e52fd15e8b')
page_id = core_ui.lookup_parent_type_for_component(components, '42ab5c3d-21fc-4e88-befd-33e52fd15e8b', parent_type="page")

# Then
assert page_id == '23bc1387-26ed-4ff2-8565-b027c2960c3c'


def test_lookup_page_for_component_should_return_nothing_when_the_component_match_nothing():
def test_lookup_parent_type_for_component_should_return_nothing_when_the_component_match_nothing():
# Given
components_list: List[ComponentDefinition] = load_fixture_content('components/components-page-1.jsonl')
components = {c['id']: c for c in components_list}

# When
page_id = core_ui.lookup_page_for_component(components, 'xxxxxxxxx-xxxxx-4e88-befd-33e52fd15e8b')
page_id = core_ui.lookup_parent_type_for_component(components, 'xxxxxxxxx-xxxxx-4e88-befd-33e52fd15e8b', parent_type="page")

# Then
assert page_id is None

0 comments on commit 867c4f9

Please sign in to comment.