Skip to content

Commit b101857

Browse files
authored
Google cloud run (#32)
* Google Cloud Run supporting files added * Ideate load sample without openai key option removed * Additiona openai env setting added * Readme updated
1 parent de1b112 commit b101857

File tree

7 files changed

+131
-34
lines changed

7 files changed

+131
-34
lines changed

Dockerfile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM python:3.11-slim
2+
3+
WORKDIR /app
4+
5+
COPY requirements.txt .
6+
COPY secrets.toml /app/.streamlit/secrets.toml
7+
RUN pip install -r requirements.txt
8+
9+
COPY . .
10+
11+
CMD ["streamlit", "run", "graph_data_generator_streamlit/app.py", "--server.enableCORS", "false", "--browser.serverAddress", "0.0.0.0", "--browser.gatherUsageStats", "false", "--server.port", "8080"]

README.md

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# MOCK GRAPH DATA GENERATOR
2-
Applet using [Streamlit](https://streamlit.io) to conveniently design and generate interwoven mock data.
2+
Applet using [Streamlit](https://streamlit.io) to conveniently design and generate interwoven mock data. A running cloud instance of this can be found [here](https://dev.neo4j.com/mock-graph-data-generator)
33

44
## Install Poetry
55
This applet uses [Poetry](https://python-poetry.org) for dependency management.
@@ -9,11 +9,25 @@ This applet uses several packages that will auto-install if you use either the p
99
1. [graph-data-generator](https://pypi.org/project/graph-data-generator/) for generating the actual mock data from a .json configuration
1010
2. [neo4j-uploader](https://pypi.org/project/neo4j-uploader/) for uploading generated .json output to a [Neo4j](https://neo4j.com/developer/) graph database instance
1111

12-
## Running
12+
## Local Running
1313
```
1414
poetry update
1515
poetry run streamlit run graph_data_generator_streamlit/app.py
1616
```
1717

1818
## Testing with local packages
1919
`poetry add --editable /path/to/package`
20+
21+
## Running in Google Cloud
22+
- Set up a [Google Cloud account](https://cloud.google.com)
23+
- Create a [Google Cloud Project](https://developers.google.com/workspace/guides/create-project)
24+
- [Enable billing](https://cloud.google.com/billing/docs/how-to/modify-project) for that project
25+
- Temporarily move any .streamlit/secret.toml file to the root folder director (same level as Dockerfile)
26+
- Install [glcoud cli](https://cloud.google.com/sdk/docs/install)
27+
- Run the following commands from the terminal of your local dev machine:
28+
```
29+
gcloud builds submit --tag gcr.io/<google_cloud_project_id>/mock-graph-generator
30+
gcloud run deploy --image gcr.io/<google_cloud_project_id>/mock-graph-generator --platform managed --allow-unauthenticated
31+
32+
When completed, can move secrets.toml file back to .streamlit/ - that or maintain a separate external secrets.toml file just for Google Cloud
33+
```

app.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
runtime: python311
2+
3+
entrypoint: streamlit run graph_data_generator_streamlit/app.py --server.enableCORS false --browser.serverAddress 0.0.0.0 --browser.gatherUsageStats false --server.port $PORT

graph_data_generator_streamlit/app.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import streamlit as st
22
from ui.instructions_ui import instructions_ui
33
from ui.generate_ui import generate_ui
4-
from ui.config_ui import config_ui
54
from ui.design_ui import arrows_ui, generators_ui
65
from ui.ideate_ui import ideate_ui
76
from ui.export_ui import export_ui
87
from ui.samples_ui import samples_list
9-
from graph_data_generator import start_logging
108
import logging
119

1210
# SETUP
@@ -17,17 +15,25 @@
1715
# Uncomment to start graph_data_generator logging
1816
# start_logging()
1917

20-
# LOAD any env
21-
neo4j_uri = st.secrets.get("NEO4J_URI", None)
18+
# LOAD optional env data
19+
try:
20+
neo4j_uri = st.secrets.get("NEO4J_URI", None)
21+
neo4j_user = st.secrets.get("NEO4J_USER", None)
22+
open_ai_key = st.secrets.get("OPENAI_API_KEY", None)
23+
neo4j_pass = st.secrets.get("NEO4J_PASSWORD", None)
24+
except:
25+
neo4j_uri = None
26+
neo4j_user = None
27+
neo4j_pass = None
28+
open_ai_key = None
29+
pass
30+
2231
if "NEO4J_URI" not in st.session_state:
2332
st.session_state["NEO4J_URI"] = neo4j_uri
24-
neo4j_user = st.secrets.get("NEO4J_USER", None)
2533
if "NEO4J_USER" not in st.session_state:
2634
st.session_state["NEO4J_USER"] = neo4j_user
27-
password = st.secrets.get("NEO4J_PASSWORD", None)
2835
if "NEO4J_PASSWORD" not in st.session_state:
29-
st.session_state["NEO4J_PASSWORD"] = password
30-
open_ai_key = st.secrets.get("OPENAI_API_KEY", None)
36+
st.session_state["NEO4J_PASSWORD"] = neo4j_pass
3137
if "OPENAI_API_KEY" not in st.session_state:
3238
st.session_state["OPENAI_API_KEY"] = open_ai_key
3339

graph_data_generator_streamlit/ui/export_ui.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11

22

33
import streamlit as st
4-
from graph_data_generator import generators
54
import graph_data_generator as gdg
6-
from neo4j_uploader import upload, start_logging, stop_logging, UploadResult
5+
from neo4j_uploader import upload, start_logging
76
import json
87

98
def export_ui():

graph_data_generator_streamlit/ui/ideate_ui.py

+15-22
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import streamlit as st
44
from streamlit_agraph import agraph, Node, Edge, Config
5-
import streamlit.components.v1 as components
65
import logging
76
import openai
87
import json
98
import random
109
import base64
1110
import ast
11+
import os
1212

1313
# Yes yes - move all the non-ui stuff into a controller or something already
1414

@@ -330,22 +330,19 @@ def ideate_ui():
330330
# OPENAI TEXTFIELD
331331
new_open_ai_key = st.text_input(f'OpenAI KEY', type="password", value=st.session_state["OPENAI_API_KEY"])
332332

333+
if new_open_ai_key is None or new_open_ai_key == "":
334+
st.warning(f'OpenAI API Key required to use this feature')
335+
return
336+
333337
# Set openAI key
334-
openai.api_key = new_open_ai_key
338+
openai.api_key = new_open_ai_key # This doesn't work in a Google Cloud Run instance
339+
os.environ["OPENAI_API_KEY"] = new_open_ai_key
335340

336341
# Display prompt for user input
337342
sample_prompt = "Sharks eat big fish. Big fish eat small fish. Small fish eat bugs."
338-
run_openai = True
339343

340-
b1, b2 = st.columns(2)
341-
with b1:
342-
if st.button('Load Sample', key="graphgpt_sample"):
343-
st.session_state["SAMPLE_PROMPT"] = sample_prompt
344-
345-
with b2:
346-
if st.button('Load Sample without OpenAI', key="graphgpt_sample_no_key"):
347-
st.session_state["SAMPLE_PROMPT"] = sample_prompt
348-
run_openai = False
344+
if st.button('Load Sample', key="graphgpt_sample"):
345+
st.session_state["SAMPLE_PROMPT"] = sample_prompt
349346

350347
prompt = st.text_area("Prompt", value=st.session_state["SAMPLE_PROMPT"])
351348
if prompt is None or prompt == "":
@@ -354,13 +351,9 @@ def ideate_ui():
354351
nodes = None
355352
edges = None
356353

357-
if run_openai == False:
358-
# Load vetted response to save on hitting openai for the same thing
359-
response = [["Sharks", "eat", "big fish"], ["Big fish", "eat", "small fish"], ["Small fish", "eat", "bugs"]]
360-
else:
361-
# Send completion request to openAI
362-
full_prompt = triples_prompt(prompt)
363-
response = generate_openai_response(full_prompt)
354+
# Send completion request to openAI
355+
full_prompt = triples_prompt(prompt)
356+
response = generate_openai_response(full_prompt)
364357

365358
# Convert response to agraph nodes and edges
366359
try:
@@ -376,8 +369,8 @@ def ideate_ui():
376369

377370
# Display data
378371
st.write('Graph Viewer')
379-
agraph(nodes=nodes,
380-
edges=edges,
372+
agraph(nodes=nodes,
373+
edges=edges,
381374
config=config)
382375

383376
# For displaying JSON schema. This can be quite long though
@@ -399,4 +392,4 @@ def ideate_ui():
399392
st.session_state["ARROWS_URI"] = uri
400393
with b2:
401394
if st.button("Push to Generator"):
402-
st.session_state["ARROWS_DICT"] = arrows_dict
395+
st.session_state["ARROWS_DICT"] = arrows_dict

requirements.txt

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
altair==5.2.0 ; python_version >= "3.11" and python_version < "4.0"
2+
annotated-types==0.6.0 ; python_version >= "3.11" and python_version < "4.0"
3+
anyio==4.2.0 ; python_version >= "3.11" and python_version < "4.0"
4+
attrs==23.1.0 ; python_version >= "3.11" and python_version < "4.0"
5+
blinker==1.7.0 ; python_version >= "3.11" and python_version < "4.0"
6+
cachetools==5.3.2 ; python_version >= "3.11" and python_version < "4.0"
7+
certifi==2023.11.17 ; python_version >= "3.11" and python_version < "4.0"
8+
charset-normalizer==3.3.2 ; python_version >= "3.11" and python_version < "4.0"
9+
click==8.1.7 ; python_version >= "3.11" and python_version < "4.0"
10+
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows"
11+
distro==1.9.0 ; python_version >= "3.11" and python_version < "4.0"
12+
faker==19.13.0 ; python_version >= "3.11" and python_version < "4.0"
13+
gitdb==4.0.11 ; python_version >= "3.11" and python_version < "4.0"
14+
gitpython==3.1.40 ; python_version >= "3.11" and python_version < "4.0"
15+
graph-data-generator==0.4.1 ; python_version >= "3.11" and python_version < "4.0"
16+
h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0"
17+
httpcore==1.0.2 ; python_version >= "3.11" and python_version < "4.0"
18+
httpx==0.26.0 ; python_version >= "3.11" and python_version < "4.0"
19+
idna==3.6 ; python_version >= "3.11" and python_version < "4.0"
20+
importlib-metadata==6.11.0 ; python_version >= "3.11" and python_version < "4.0"
21+
isodate==0.6.1 ; python_version >= "3.11" and python_version < "4.0"
22+
jinja2==3.1.2 ; python_version >= "3.11" and python_version < "4.0"
23+
jsonschema-specifications==2023.12.1 ; python_version >= "3.11" and python_version < "4.0"
24+
jsonschema==4.20.0 ; python_version >= "3.11" and python_version < "4.0"
25+
lorem-text==2.1 ; python_version >= "3.11" and python_version < "4.0"
26+
markdown-it-py==3.0.0 ; python_version >= "3.11" and python_version < "4.0"
27+
markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "4.0"
28+
mdurl==0.1.2 ; python_version >= "3.11" and python_version < "4.0"
29+
neo4j-uploader==0.4.1 ; python_version >= "3.11" and python_version < "4.0"
30+
neo4j==5.16.0 ; python_version >= "3.11" and python_version < "4.0"
31+
networkx==3.2.1 ; python_version >= "3.11" and python_version < "4.0"
32+
numpy==1.26.2 ; python_version >= "3.11" and python_version < "4.0"
33+
openai==1.6.1 ; python_version >= "3.11" and python_version < "4.0"
34+
opencv-python==4.8.1.78 ; python_version >= "3.11" and python_version < "4.0"
35+
packaging==23.2 ; python_version >= "3.11" and python_version < "4.0"
36+
pandas==2.1.4 ; python_version >= "3.11" and python_version < "4.0"
37+
pasteboard==0.3.3 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Darwin"
38+
pillow==10.1.0 ; python_version >= "3.11" and python_version < "4.0"
39+
protobuf==4.25.1 ; python_version >= "3.11" and python_version < "4.0"
40+
pyarrow==14.0.2 ; python_version >= "3.11" and python_version < "4.0"
41+
pyclip==0.7.0 ; python_version >= "3.11" and python_version < "4.0"
42+
pydantic-core==2.14.6 ; python_version >= "3.11" and python_version < "4.0"
43+
pydantic==2.5.3 ; python_version >= "3.11" and python_version < "4.0"
44+
pydeck==0.8.0 ; python_version >= "3.11" and python_version < "4.0"
45+
pygments==2.17.2 ; python_version >= "3.11" and python_version < "4.0"
46+
pyparsing==3.1.1 ; python_version >= "3.11" and python_version < "4.0"
47+
python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "4.0"
48+
pytz==2023.3.post1 ; python_version >= "3.11" and python_version < "4.0"
49+
pywin32==306 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows"
50+
rdflib==7.0.0 ; python_version >= "3.11" and python_version < "4.0"
51+
referencing==0.32.0 ; python_version >= "3.11" and python_version < "4.0"
52+
requests==2.31.0 ; python_version >= "3.11" and python_version < "4.0"
53+
rich==13.7.0 ; python_version >= "3.11" and python_version < "4.0"
54+
rpds-py==0.16.2 ; python_version >= "3.11" and python_version < "4.0"
55+
six==1.16.0 ; python_version >= "3.11" and python_version < "4.0"
56+
smmap==5.0.1 ; python_version >= "3.11" and python_version < "4.0"
57+
sniffio==1.3.0 ; python_version >= "3.11" and python_version < "4.0"
58+
streamlit-agraph==0.0.45 ; python_version >= "3.11" and python_version < "4.0"
59+
streamlit==1.29.0 ; python_version >= "3.11" and python_version < "4.0"
60+
tenacity==8.2.3 ; python_version >= "3.11" and python_version < "4.0"
61+
toml==0.10.2 ; python_version >= "3.11" and python_version < "4.0"
62+
toolz==0.12.0 ; python_version >= "3.11" and python_version < "4.0"
63+
tornado==6.4 ; python_version >= "3.11" and python_version < "4.0"
64+
tqdm==4.66.1 ; python_version >= "3.11" and python_version < "4.0"
65+
typing-extensions==4.9.0 ; python_version >= "3.11" and python_version < "4.0"
66+
tzdata==2023.4 ; python_version >= "3.11" and python_version < "4.0"
67+
tzlocal==5.2 ; python_version >= "3.11" and python_version < "4.0"
68+
urllib3==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
69+
validators==0.22.0 ; python_version >= "3.11" and python_version < "4.0"
70+
watchdog==3.0.0 ; python_version >= "3.11" and python_version < "4.0" and platform_system != "Darwin"
71+
zipp==3.17.0 ; python_version >= "3.11" and python_version < "4.0"

0 commit comments

Comments
 (0)