From 321b0e5664e4ae6b417dc775004517ac2f8ccadd Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Fri, 23 Oct 2020 10:51:27 +0200 Subject: [PATCH 1/6] Prepare for heroku app --- Procfile | 1 + requirements.txt | 3 +-- run.py | 5 ++++- server.py | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..6cb02d5 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: python run.py -p=$PORT diff --git a/requirements.txt b/requirements.txt index b699870..1e054bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ -jupyter==1.0.0 -Mesa==0.7.6 +Mesa \ No newline at end of file diff --git a/run.py b/run.py index a25f3b1..2829e28 100644 --- a/run.py +++ b/run.py @@ -1,3 +1,6 @@ from server import server +import os -server.launch() +port= int(os.getenv("PORT", 4200)) + +server.launch(port=port, open_browser=False) diff --git a/server.py b/server.py index 62b2313..b7662e7 100644 --- a/server.py +++ b/server.py @@ -34,4 +34,6 @@ def schelling_draw(agent): server = ModularServer(SchellingModel, [canvas_element, happy_element, happy_chart], "Schelling’s Segregation Model", - 20, 20, 0.8, 0.2, 4) + {"height": 20, "width": 20, "density": 0.8, "minority_pc": 0.2, "homophily": 4}, + + ) From 4c016b4ecbf4891e3dc4b592dd176f83b0b58950 Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Fri, 23 Oct 2020 10:54:46 +0200 Subject: [PATCH 2/6] include usersettable parameters --- server.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/server.py b/server.py index b7662e7..6d82d1e 100644 --- a/server.py +++ b/server.py @@ -1,22 +1,23 @@ from mesa.visualization.ModularVisualization import ModularServer from mesa.visualization.modules import CanvasGrid, ChartModule, TextElement +from mesa.visualization.UserParam import UserSettableParameter from model import SchellingModel class HappyElement(TextElement): - ''' + """ Display a text count of how many happy agents there are. - ''' + """ def render(self, model): return "Happy agents: " + str(model.happy) def schelling_draw(agent): - ''' + """ Portrayal Method for canvas - ''' + """ if agent is None: return portrayal = {"Shape": "circle", "r": 0.5, "Filled": "true", "Layer": 0} @@ -27,13 +28,21 @@ def schelling_draw(agent): portrayal["Color"] = "Blue" return portrayal + happy_element = HappyElement() canvas_element = CanvasGrid(schelling_draw, 20, 20, 500, 500) happy_chart = ChartModule([{"Label": "happy", "Color": "Black"}]) -server = ModularServer(SchellingModel, - [canvas_element, happy_element, happy_chart], - "Schelling’s Segregation Model", - {"height": 20, "width": 20, "density": 0.8, "minority_pc": 0.2, "homophily": 4}, - - ) +model_params = { + "height": 20, + "width": 20, + "density": UserSettableParameter("slider", "Agent density", 0.8, 0.1, 1.0, 0.1), + "minority_pc": UserSettableParameter( + "slider", "Fraction minority", 0.2, 0.00, 1.0, 0.05 + ), + "homophily": UserSettableParameter("slider", "Homophily", 3, 0, 8, 1), +} + +server = ModularServer( + Schelling, [canvas_element, happy_element, happy_chart], "Schelling", model_params +) From fa0f0f9f3e299568e3ff5901657be55a1a264425 Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Fri, 23 Oct 2020 11:23:34 +0200 Subject: [PATCH 3/6] Make ready for heroku deployment * add procfile * fix model * update requirements --- Procfile | 1 + requirements.txt | 3 +-- run.py | 5 ++++- server.py | 30 ++++++++++++++++++++++-------- 4 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..6cb02d5 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: python run.py -p=$PORT diff --git a/requirements.txt b/requirements.txt index b699870..1e054bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ -jupyter==1.0.0 -Mesa==0.7.6 +Mesa \ No newline at end of file diff --git a/run.py b/run.py index a25f3b1..517658f 100644 --- a/run.py +++ b/run.py @@ -1,3 +1,6 @@ from server import server +import os -server.launch() +port = int(os.getenv("PORT", 4200)) + +server.launch(port=port, open_browser=False) diff --git a/server.py b/server.py index 62b2313..1da7dd7 100644 --- a/server.py +++ b/server.py @@ -1,22 +1,23 @@ from mesa.visualization.ModularVisualization import ModularServer from mesa.visualization.modules import CanvasGrid, ChartModule, TextElement +from mesa.visualization.UserParam import UserSettableParameter from model import SchellingModel class HappyElement(TextElement): - ''' + """ Display a text count of how many happy agents there are. - ''' + """ def render(self, model): return "Happy agents: " + str(model.happy) def schelling_draw(agent): - ''' + """ Portrayal Method for canvas - ''' + """ if agent is None: return portrayal = {"Shape": "circle", "r": 0.5, "Filled": "true", "Layer": 0} @@ -27,11 +28,24 @@ def schelling_draw(agent): portrayal["Color"] = "Blue" return portrayal + happy_element = HappyElement() canvas_element = CanvasGrid(schelling_draw, 20, 20, 500, 500) happy_chart = ChartModule([{"Label": "happy", "Color": "Black"}]) -server = ModularServer(SchellingModel, - [canvas_element, happy_element, happy_chart], - "Schelling’s Segregation Model", - 20, 20, 0.8, 0.2, 4) +model_params = { + "height": 20, + "width": 20, + "density": UserSettableParameter("slider", "Agent density", 0.8, 0.1, 1.0, 0.1), + "minority_pc": UserSettableParameter( + "slider", "Fraction minority", 0.2, 0.00, 1.0, 0.05 + ), + "homophily": UserSettableParameter("slider", "Homophily", 3, 0, 8, 1), +} + +server = ModularServer( + SchellingModel, + [canvas_element, happy_element, happy_chart], + "Schelling", + model_params, +) From 30f892f7a5070e431c6504db85a434bffefcc2c3 Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Mon, 9 Nov 2020 20:57:45 +0100 Subject: [PATCH 4/6] Fix model name --- run.py | 2 +- server.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/run.py b/run.py index 2829e28..517658f 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,6 @@ from server import server import os -port= int(os.getenv("PORT", 4200)) +port = int(os.getenv("PORT", 4200)) server.launch(port=port, open_browser=False) diff --git a/server.py b/server.py index 6d82d1e..1da7dd7 100644 --- a/server.py +++ b/server.py @@ -44,5 +44,8 @@ def schelling_draw(agent): } server = ModularServer( - Schelling, [canvas_element, happy_element, happy_chart], "Schelling", model_params + SchellingModel, + [canvas_element, happy_element, happy_chart], + "Schelling", + model_params, ) From 8d0a131cbaac11f7f218052bd090d243ba45cfb2 Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Mon, 9 Nov 2020 21:02:55 +0100 Subject: [PATCH 5/6] Create app.json Needed for deploy to heroku button --- app.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app.json diff --git a/app.json b/app.json new file mode 100644 index 0000000..c8df664 --- /dev/null +++ b/app.json @@ -0,0 +1,5 @@ +{ + "name": "Mesa Schelling Segregation Model", + "description": "An example model ready to be deployed on the web", + "repository": "https://github.com/Corvince/mesa-schelling-example" +} From 81c3cdebd0493e48f56233b8d706aec007b116ab Mon Sep 17 00:00:00 2001 From: Corvince <13568919+Corvince@users.noreply.github.com> Date: Tue, 10 Nov 2020 08:48:08 +0100 Subject: [PATCH 6/6] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index fc62366..f5a2ac4 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,35 @@ To view and run some example model analyses, launch the IPython Notebook and ope * ``server.py``: Defines classes for visualizing the model in the browser via Mesa's modular server, and instantiates a visualization server. * ``analysis.ipybn``: Notebook demonstrating how to run experiments and parameter sweeps on the model. +## How to run on the web using Heroku + +If you already have a free Heroku account you can deploy this example as a web app by using the following button + +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy). + +Otherwise refer to the [Getting Started on Heroku with Python](https://devcenter.heroku.com/articles/getting-started-with-python) to learn about the basics of hosting a web app on Heroku. + +If you already set up your model as a git repository you basically only need to create a `Procfile` with the following content + +```bash +web: python run.py -p=$PORT +``` + +This tells heroku to launch your model as a web application by running the file `run.py` and specify Herokus default port from the environmental variable `$PORT` + +Make sure your models ModularServer is also launched with the same port by using the following snippet inside your `run.py` (if you don't specify the port, future versions of mesa will use this by default) + +```python +from server import server +import os + +port = int(os.getenv("PORT", 4200)) + +server.launch(port=port, open_browser=False) +``` + +That's it! You can view the Schelling model from this repo at https://mesa-schelling-example.herokuapp.com/ + ## Further Reading Schelling's original paper describing the model: