Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google cloud run #32

Merged
merged 4 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
COPY secrets.toml /app/.streamlit/secrets.toml
RUN pip install -r requirements.txt

COPY . .

CMD ["streamlit", "run", "graph_data_generator_streamlit/app.py", "--server.enableCORS", "false", "--browser.serverAddress", "0.0.0.0", "--browser.gatherUsageStats", "false", "--server.port", "8080"]
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# MOCK GRAPH DATA GENERATOR
Applet using [Streamlit](https://streamlit.io) to conveniently design and generate interwoven mock data.
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)

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

## Running
## Local Running
```
poetry update
poetry run streamlit run graph_data_generator_streamlit/app.py
```

## Testing with local packages
`poetry add --editable /path/to/package`

## Running in Google Cloud
- Set up a [Google Cloud account](https://cloud.google.com)
- Create a [Google Cloud Project](https://developers.google.com/workspace/guides/create-project)
- [Enable billing](https://cloud.google.com/billing/docs/how-to/modify-project) for that project
- Temporarily move any .streamlit/secret.toml file to the root folder director (same level as Dockerfile)
- Install [glcoud cli](https://cloud.google.com/sdk/docs/install)
- Run the following commands from the terminal of your local dev machine:
```
gcloud builds submit --tag gcr.io/<google_cloud_project_id>/mock-graph-generator
gcloud run deploy --image gcr.io/<google_cloud_project_id>/mock-graph-generator --platform managed --allow-unauthenticated

When completed, can move secrets.toml file back to .streamlit/ - that or maintain a separate external secrets.toml file just for Google Cloud
```
3 changes: 3 additions & 0 deletions app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
runtime: python311

entrypoint: streamlit run graph_data_generator_streamlit/app.py --server.enableCORS false --browser.serverAddress 0.0.0.0 --browser.gatherUsageStats false --server.port $PORT
22 changes: 14 additions & 8 deletions graph_data_generator_streamlit/app.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import streamlit as st
from ui.instructions_ui import instructions_ui
from ui.generate_ui import generate_ui
from ui.config_ui import config_ui
from ui.design_ui import arrows_ui, generators_ui
from ui.ideate_ui import ideate_ui
from ui.export_ui import export_ui
from ui.samples_ui import samples_list
from graph_data_generator import start_logging
import logging

# SETUP
Expand All @@ -17,17 +15,25 @@
# Uncomment to start graph_data_generator logging
# start_logging()

# LOAD any env
neo4j_uri = st.secrets.get("NEO4J_URI", None)
# LOAD optional env data
try:
neo4j_uri = st.secrets.get("NEO4J_URI", None)
neo4j_user = st.secrets.get("NEO4J_USER", None)
open_ai_key = st.secrets.get("OPENAI_API_KEY", None)
neo4j_pass = st.secrets.get("NEO4J_PASSWORD", None)
except:
neo4j_uri = None
neo4j_user = None
neo4j_pass = None
open_ai_key = None
pass

if "NEO4J_URI" not in st.session_state:
st.session_state["NEO4J_URI"] = neo4j_uri
neo4j_user = st.secrets.get("NEO4J_USER", None)
if "NEO4J_USER" not in st.session_state:
st.session_state["NEO4J_USER"] = neo4j_user
password = st.secrets.get("NEO4J_PASSWORD", None)
if "NEO4J_PASSWORD" not in st.session_state:
st.session_state["NEO4J_PASSWORD"] = password
open_ai_key = st.secrets.get("OPENAI_API_KEY", None)
st.session_state["NEO4J_PASSWORD"] = neo4j_pass
if "OPENAI_API_KEY" not in st.session_state:
st.session_state["OPENAI_API_KEY"] = open_ai_key

Expand Down
3 changes: 1 addition & 2 deletions graph_data_generator_streamlit/ui/export_ui.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@


import streamlit as st
from graph_data_generator import generators
import graph_data_generator as gdg
from neo4j_uploader import upload, start_logging, stop_logging, UploadResult
from neo4j_uploader import upload, start_logging
import json

def export_ui():
Expand Down
37 changes: 15 additions & 22 deletions graph_data_generator_streamlit/ui/ideate_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import streamlit as st
from streamlit_agraph import agraph, Node, Edge, Config
import streamlit.components.v1 as components
import logging
import openai
import json
import random
import base64
import ast
import os

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

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

if new_open_ai_key is None or new_open_ai_key == "":
st.warning(f'OpenAI API Key required to use this feature')
return

# Set openAI key
openai.api_key = new_open_ai_key
openai.api_key = new_open_ai_key # This doesn't work in a Google Cloud Run instance
os.environ["OPENAI_API_KEY"] = new_open_ai_key

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

b1, b2 = st.columns(2)
with b1:
if st.button('Load Sample', key="graphgpt_sample"):
st.session_state["SAMPLE_PROMPT"] = sample_prompt

with b2:
if st.button('Load Sample without OpenAI', key="graphgpt_sample_no_key"):
st.session_state["SAMPLE_PROMPT"] = sample_prompt
run_openai = False
if st.button('Load Sample', key="graphgpt_sample"):
st.session_state["SAMPLE_PROMPT"] = sample_prompt

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

if run_openai == False:
# Load vetted response to save on hitting openai for the same thing
response = [["Sharks", "eat", "big fish"], ["Big fish", "eat", "small fish"], ["Small fish", "eat", "bugs"]]
else:
# Send completion request to openAI
full_prompt = triples_prompt(prompt)
response = generate_openai_response(full_prompt)
# Send completion request to openAI
full_prompt = triples_prompt(prompt)
response = generate_openai_response(full_prompt)

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

# Display data
st.write('Graph Viewer')
agraph(nodes=nodes,
edges=edges,
agraph(nodes=nodes,
edges=edges,
config=config)

# For displaying JSON schema. This can be quite long though
Expand All @@ -399,4 +392,4 @@ def ideate_ui():
st.session_state["ARROWS_URI"] = uri
with b2:
if st.button("Push to Generator"):
st.session_state["ARROWS_DICT"] = arrows_dict
st.session_state["ARROWS_DICT"] = arrows_dict
71 changes: 71 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
altair==5.2.0 ; python_version >= "3.11" and python_version < "4.0"
annotated-types==0.6.0 ; python_version >= "3.11" and python_version < "4.0"
anyio==4.2.0 ; python_version >= "3.11" and python_version < "4.0"
attrs==23.1.0 ; python_version >= "3.11" and python_version < "4.0"
blinker==1.7.0 ; python_version >= "3.11" and python_version < "4.0"
cachetools==5.3.2 ; python_version >= "3.11" and python_version < "4.0"
certifi==2023.11.17 ; python_version >= "3.11" and python_version < "4.0"
charset-normalizer==3.3.2 ; python_version >= "3.11" and python_version < "4.0"
click==8.1.7 ; python_version >= "3.11" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows"
distro==1.9.0 ; python_version >= "3.11" and python_version < "4.0"
faker==19.13.0 ; python_version >= "3.11" and python_version < "4.0"
gitdb==4.0.11 ; python_version >= "3.11" and python_version < "4.0"
gitpython==3.1.40 ; python_version >= "3.11" and python_version < "4.0"
graph-data-generator==0.4.1 ; python_version >= "3.11" and python_version < "4.0"
h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0"
httpcore==1.0.2 ; python_version >= "3.11" and python_version < "4.0"
httpx==0.26.0 ; python_version >= "3.11" and python_version < "4.0"
idna==3.6 ; python_version >= "3.11" and python_version < "4.0"
importlib-metadata==6.11.0 ; python_version >= "3.11" and python_version < "4.0"
isodate==0.6.1 ; python_version >= "3.11" and python_version < "4.0"
jinja2==3.1.2 ; python_version >= "3.11" and python_version < "4.0"
jsonschema-specifications==2023.12.1 ; python_version >= "3.11" and python_version < "4.0"
jsonschema==4.20.0 ; python_version >= "3.11" and python_version < "4.0"
lorem-text==2.1 ; python_version >= "3.11" and python_version < "4.0"
markdown-it-py==3.0.0 ; python_version >= "3.11" and python_version < "4.0"
markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "4.0"
mdurl==0.1.2 ; python_version >= "3.11" and python_version < "4.0"
neo4j-uploader==0.4.1 ; python_version >= "3.11" and python_version < "4.0"
neo4j==5.16.0 ; python_version >= "3.11" and python_version < "4.0"
networkx==3.2.1 ; python_version >= "3.11" and python_version < "4.0"
numpy==1.26.2 ; python_version >= "3.11" and python_version < "4.0"
openai==1.6.1 ; python_version >= "3.11" and python_version < "4.0"
opencv-python==4.8.1.78 ; python_version >= "3.11" and python_version < "4.0"
packaging==23.2 ; python_version >= "3.11" and python_version < "4.0"
pandas==2.1.4 ; python_version >= "3.11" and python_version < "4.0"
pasteboard==0.3.3 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Darwin"
pillow==10.1.0 ; python_version >= "3.11" and python_version < "4.0"
protobuf==4.25.1 ; python_version >= "3.11" and python_version < "4.0"
pyarrow==14.0.2 ; python_version >= "3.11" and python_version < "4.0"
pyclip==0.7.0 ; python_version >= "3.11" and python_version < "4.0"
pydantic-core==2.14.6 ; python_version >= "3.11" and python_version < "4.0"
pydantic==2.5.3 ; python_version >= "3.11" and python_version < "4.0"
pydeck==0.8.0 ; python_version >= "3.11" and python_version < "4.0"
pygments==2.17.2 ; python_version >= "3.11" and python_version < "4.0"
pyparsing==3.1.1 ; python_version >= "3.11" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "4.0"
pytz==2023.3.post1 ; python_version >= "3.11" and python_version < "4.0"
pywin32==306 ; python_version >= "3.11" and python_version < "4.0" and platform_system == "Windows"
rdflib==7.0.0 ; python_version >= "3.11" and python_version < "4.0"
referencing==0.32.0 ; python_version >= "3.11" and python_version < "4.0"
requests==2.31.0 ; python_version >= "3.11" and python_version < "4.0"
rich==13.7.0 ; python_version >= "3.11" and python_version < "4.0"
rpds-py==0.16.2 ; python_version >= "3.11" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.11" and python_version < "4.0"
smmap==5.0.1 ; python_version >= "3.11" and python_version < "4.0"
sniffio==1.3.0 ; python_version >= "3.11" and python_version < "4.0"
streamlit-agraph==0.0.45 ; python_version >= "3.11" and python_version < "4.0"
streamlit==1.29.0 ; python_version >= "3.11" and python_version < "4.0"
tenacity==8.2.3 ; python_version >= "3.11" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.11" and python_version < "4.0"
toolz==0.12.0 ; python_version >= "3.11" and python_version < "4.0"
tornado==6.4 ; python_version >= "3.11" and python_version < "4.0"
tqdm==4.66.1 ; python_version >= "3.11" and python_version < "4.0"
typing-extensions==4.9.0 ; python_version >= "3.11" and python_version < "4.0"
tzdata==2023.4 ; python_version >= "3.11" and python_version < "4.0"
tzlocal==5.2 ; python_version >= "3.11" and python_version < "4.0"
urllib3==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
validators==0.22.0 ; python_version >= "3.11" and python_version < "4.0"
watchdog==3.0.0 ; python_version >= "3.11" and python_version < "4.0" and platform_system != "Darwin"
zipp==3.17.0 ; python_version >= "3.11" and python_version < "4.0"