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/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: 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" +} 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, +)