Skip to content

Commit 6a495d2

Browse files
authoredFeb 22, 2023
Arrows Config Support (#6)
* WIP Simplification update to use arrows only for generator assignment & config * Mappings tabbed replaced with auto generated mappings from specially formatted arrows.app json files * Generator search and code copy in design tab added * Config tab removed * Import, Generate, and Export tabs combined into new Generate tab * Design tab updated with new instructions * Clean up and instructions added
1 parent 4dd11ef commit 6a495d2

26 files changed

+1728
-286
lines changed
 

‎mock_generators/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
__version__ = "0.1.0"

‎mock_generators/app.py

+12-35
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
import streamlit as st
22
from constants import *
3-
from tabs.config_tab import config_tab
4-
from tabs.generators_tab import generators_tab
5-
from tabs.new_generator_tab import create_tab
6-
from tabs.mapping_tab import mapping_tab
7-
from tabs.generate_tab import generate_tab
8-
from tabs.export_tab import export_tab
93
from tabs.importing_tab import import_tab
104
from tabs.design_tab import design_tab
115
from tabs.data_importer import data_importer_tab
12-
from models.mapping import Mapping
13-
6+
from config import load_generators
147

158
# SETUP
169
st.set_page_config(layout="wide")
@@ -42,9 +35,9 @@
4235
if CODE_TEMPLATE_FILE not in st.session_state:
4336
st.session_state[CODE_TEMPLATE_FILE] = DEFAULT_CODE_TEMPLATES_FILE
4437
if MAPPINGS not in st.session_state:
45-
st.session_state[MAPPINGS] = Mapping(
46-
nodes={},
47-
relationships={})
38+
st.session_state[MAPPINGS] = None
39+
40+
load_generators()
4841

4942
# UI
5043
st.title("Mock Graph Data Generator")
@@ -54,31 +47,15 @@
5447
imported_file = None
5548

5649
# Streamlit runs from top-to-bottom from tabs 1 through 8. This is essentially one giant single page app. Earlier attempt to use Streamlit's multi-page app functionality resulted in an inconsistent state between pages.
57-
tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(["Config >", "Design >", "Import >", "Mapping >", "Search Generators >", "Add New Generator >", "Generate >", "Export >", "Data Importer"])
58-
59-
with tab1:
60-
config_tab()
6150

62-
with tab2:
51+
t1, t2, t5 = st.tabs([
52+
"① Design",
53+
"② Generate",
54+
"③ Data Importer"
55+
])
56+
with t1:
6357
design_tab()
64-
65-
with tab3:
58+
with t2:
6659
import_tab()
67-
68-
with tab4:
69-
mapping_tab()
70-
71-
with tab5:
72-
generators_tab()
73-
74-
with tab6:
75-
create_tab()
76-
77-
with tab7:
78-
generate_tab()
79-
80-
with tab8:
81-
export_tab()
82-
83-
with tab9:
60+
with t5:
8461
data_importer_tab()

‎mock_generators/config.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import streamlit as st
2+
from constants import *
3+
from file_utils import load_json, load_string
4+
from models.generator import Generator, generators_from_json
5+
import os
6+
import sys
7+
import logging
8+
from widgets.folder_files import folder_files_expander
9+
10+
def load_generators():
11+
12+
spec_filepath = st.session_state[SPEC_FILE]
13+
generators = st.session_state[GENERATORS]
14+
try:
15+
with open(spec_filepath) as input:
16+
# generators_file = input.read()
17+
generators_json = load_json(spec_filepath)
18+
new_generators = generators_from_json(generators_json)
19+
if generators != new_generators:
20+
st.session_state[GENERATORS] = new_generators
21+
22+
except FileNotFoundError:
23+
st.error('File not found.')

‎mock_generators/constants.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import streamlit as st
22

33
# Default local filepaths
4-
DEFAULT_GENERATORS_SPEC_FILE = "mock_generators/generators.json"
4+
DEFAULT_GENERATORS_SPEC_FILE = "mock_generators/named_generators.json"
55
DEFAULT_GENERATORS_CODE_PATH = "mock_generators/generators"
66
DEFAULT_ARROWS_SAMPLE_PATH = "mock_generators/samples/arrows.json"
77
DEFAULT_IMPORTS_PATH = "mock_generators/imports"

‎mock_generators/generate.py

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import streamlit as st
2+
from constants import *
3+
from models.mapping import Mapping
4+
from logic.generate_csv import generate_csv
5+
from logic.generate_data_import import generate_data_importer_json
6+
import os
7+
import logging
8+
import sys
9+
import zipfile
10+
from datetime import datetime
11+
12+
def generate_data(mapping: Mapping):
13+
14+
export_folder = st.session_state[EXPORTS_PATH]
15+
zips_folder = st.session_state[ZIPS_PATH]
16+
imported_filename = st.session_state[IMPORTED_FILENAME]
17+
18+
# TODO: Implement better filename cleaning
19+
# TODO: Breaks when using a copy and pasted file
20+
export_zip_filename = f'{imported_filename}'.lower()
21+
export_zip_filename = export_zip_filename.replace(".json", "")
22+
export_zip_filename.replace(" ", "_")
23+
export_zip_filename.replace(".", "_")
24+
25+
# Stop if no mapping data available
26+
if len(mapping.nodes) == 0:
27+
st.error('No nodes to generate data for. Map at least one noded.')
28+
st.stop()
29+
return
30+
31+
# Generate values from mappings
32+
for _, node in mapping.nodes.items():
33+
# logging.info(f'Generating data for node: {node}')
34+
if len(node.properties) == 0:
35+
st.error(f'Node {node.caption} has no properties. Add at least one property to generate data.')
36+
st.stop()
37+
return
38+
node.generate_values()
39+
40+
for _, rel in mapping.relationships.items():
41+
rel.generate_values()
42+
43+
# Delete all files in export folder first
44+
dir = export_folder
45+
for f in os.listdir(dir):
46+
os.remove(os.path.join(dir, f))
47+
48+
# Data Importer Options
49+
success = generate_csv(
50+
mapping,
51+
export_folder=export_folder)
52+
53+
# Check that data was generated
54+
if success == False:
55+
st.error('Error generating data. Check console for details.')
56+
# st.stop()
57+
# return
58+
59+
success = generate_data_importer_json(
60+
mapping,
61+
export_folder=export_folder,
62+
export_filename=DEFAULT_DATA_IMPORTER_FILENAME)
63+
64+
# Check that data-import data was generated
65+
if success == False:
66+
st.error('Error generating data-import json. Check console for details.')
67+
# st.stop()
68+
# return
69+
70+
# Only attempt to zip files if data generation was successful
71+
if success:
72+
try:
73+
# Create zip file, appended with time created
74+
# now = str(datetime.now().isoformat())
75+
zip_path = f'{zips_folder}/{export_zip_filename}.zip'
76+
logging.info(f'generate_tab: Creating zip file: {zip_path}')
77+
with zipfile.ZipFile(f'{zip_path}', 'w', zipfile.ZIP_DEFLATED) as zipf:
78+
# zipdir(export_folder, zipf)
79+
path = export_folder
80+
for root, dirs, files in os.walk(path):
81+
for file in files:
82+
if file[0] =='.':
83+
# Skip hidden files
84+
continue
85+
zipf.write(os.path.join(root, file),
86+
os.path.relpath(os.path.join(root, file),
87+
os.path.join(path, '..')))
88+
except:
89+
st.error(f'Error creating zip file: {sys.exc_info()[0]}')
90+
# st.stop()
91+
return
92+
93+
if success == True:
94+
st.success('Data generated successfully.')

0 commit comments

Comments
 (0)