├── .gitignore ├── Procfile ├── README.md ├── requirements.txt ├── runtime.txt ├── some_unique_string.png ├── test.png └── webapp.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | readme_assets 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | .hypothesis/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # IPython Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # dotenv 82 | .env 83 | 84 | # virtualenv 85 | venv/ 86 | ENV/ 87 | 88 | # Spyder project settings 89 | .spyderproject 90 | 91 | # Rope project settings 92 | .ropeproject 93 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: waitress-serve --port=$PORT webapp:app 2 | #$PORT 3 | #%PORT% -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | credit to https://github.com/datademofun/heroku-basic-flask for the base framework 2 | 3 | git push heroku master to push to heroku -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | waitress 3 | bs4 4 | requests 5 | ghhops_server 6 | matplotlib 7 | pandas 8 | seaborn -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.10.7 -------------------------------------------------------------------------------- /some_unique_string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timonielsen/grasshopperWebApp/1ef320df41d3431dc02e74b71b51e9a52147e2d8/some_unique_string.png -------------------------------------------------------------------------------- /test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timonielsen/grasshopperWebApp/1ef320df41d3431dc02e74b71b51e9a52147e2d8/test.png -------------------------------------------------------------------------------- /webapp.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask import send_file 3 | from flask import send_from_directory 4 | from datetime import datetime 5 | import ghhops_server as hs 6 | import requests 7 | from bs4 import BeautifulSoup 8 | 9 | import io 10 | import random 11 | from flask import Response 12 | from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas 13 | from matplotlib.figure import Figure 14 | import matplotlib.pyplot as plt 15 | import base64 16 | import seaborn as sns 17 | import numpy as np 18 | 19 | app = Flask(__name__) 20 | hops: hs.HopsFlask = hs.Hops(app) 21 | 22 | 23 | 24 | @hops.component( 25 | "/plot20", 26 | inputs=[ 27 | hs.HopsNumber("X", "X", "description", hs.HopsParamAccess.LIST), 28 | hs.HopsNumber("Y", "Y", "description", hs.HopsParamAccess.LIST), 29 | hs.HopsNumber("c", "c", "description", hs.HopsParamAccess.LIST), 30 | hs.HopsNumber("s", "s", "description", hs.HopsParamAccess.LIST) 31 | ], 32 | outputs=[hs.HopsString("base64img")], 33 | ) 34 | def BinaryMultiply(x,y,c,s): 35 | return create_figure(x,y,c,s) 36 | 37 | 38 | @hops.component( 39 | "/windspeed5", 40 | inputs=[hs.HopsString("T")], 41 | outputs=[hs.HopsString("w")], 42 | ) 43 | def getWindSpeed(city): 44 | return wind(city) 45 | 46 | 47 | def wind(city): 48 | headers = { 49 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} 50 | city = city+" weather" 51 | city = city.replace(" ", "+") 52 | res = requests.get(f'https://www.google.com/search?q={city}&oq={city}&aqs=chrome.0.35i39l2j0l4j46j69i60.6128j1j7&sourceid=chrome&ie=UTF-8', headers=headers) 53 | soup = BeautifulSoup(res.text, 'html.parser') 54 | wind = soup.select('#wob_ws')[0].getText().strip() 55 | return wind 56 | 57 | def create_figure(x,y,c,s): 58 | # Change color with c and transparency with alpha. 59 | # I map the color to the X axis value. 60 | plt.scatter(x, y, s=s, c=c, cmap="turbo") 61 | 62 | # Add titles (main and on axis) 63 | plt.xlabel("the X axis") 64 | plt.ylabel("the Y axis") 65 | plt.title("A colored bubble plot") 66 | plt.axis('equal') 67 | 68 | # Show the graph 69 | my_stringIObytes = io.BytesIO() #https://stackoverflow.com/a/38061400/7866788 70 | plt.savefig(my_stringIObytes, format='jpg', dpi=300) 71 | my_stringIObytes.seek(0) 72 | my_base64_jpgData = base64.b64encode(my_stringIObytes.read()) 73 | plt.close() 74 | return str(my_base64_jpgData) 75 | 76 | if __name__ == '__main__': 77 | app.run(debug=True, use_reloader=True) 78 | 79 | --------------------------------------------------------------------------------