Skip to content

Commit

Permalink
Use click and add mesa run
Browse files Browse the repository at this point in the history
This runs the project in the same way a user typically would, by
changing to the project directory (so that resources can be located
using relative paths).  However, rather than executing the `run.py`
directly, it assumes that importing `run` will produce a module with a
`server` attribute.  For the moment, it calls `server.launch()` but it
could be modified to call other methods or pass parameters to that
server, such as to run "headless"
  • Loading branch information
djmitche committed May 14, 2018
1 parent f49fcc5 commit 304e9f1
Show file tree
Hide file tree
Showing 19 changed files with 90 additions and 17 deletions.
3 changes: 2 additions & 1 deletion examples/Schelling/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/bank_reserves/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from bank_reserves.server import server

server.launch()
if __name__ == "__main__":
server.launch()
5 changes: 3 additions & 2 deletions examples/boid-flockers/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from boidflockers.server import server
from flockers.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/boltzmann_wealth_model/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from wealth_model.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/boltzmann_wealth_model_network/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from wealth_model.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/color_patches/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from color_patches.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/conways_game_of_life/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from game_of_life.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/epstein_civil_violence/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from civil_violence.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/forest_fire/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from forest_fire.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/hex_snowflake/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from hex_snowflake.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/pd_grid/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pd_grid.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/shape_example/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from shape_model.server import launch_shape_model

launch_shape_model()
if __name__ == "__main__":
launch_shape_model()
3 changes: 2 additions & 1 deletion examples/sugarscape_cg/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from sugarscape.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/virus_on_network/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from virus_on_network.server import server

server.launch()
if __name__ == "__main__":
server.launch()
3 changes: 2 additions & 1 deletion examples/wolf_sheep/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from wolf_sheep.server import server

server.launch()
if __name__ == "__main__":
server.launch()
25 changes: 25 additions & 0 deletions mesa/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
import os
import importlib
import click

PROJECT_PATH = click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True)


@click.group()
def cli():
'Manage Mesa projects'


@cli.command()
@click.argument('project', type=PROJECT_PATH, default='.')
def run(project):
'''Run mesa project PROJECT
PROJECT is the path to the directory containing `run.py`, or the current
directory if not specified.
'''
sys.path.insert(0, project)
os.chdir(project)
run = importlib.import_module('run')
run.server.launch()
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ tornado==4.5.3
flake8==2.5.2
tqdm
networkx==2.1

click==6.7

5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
'numpy',
'pandas',
'tqdm',
'click',
]

version = ''
Expand Down Expand Up @@ -47,4 +48,8 @@
'Development Status :: 3 - Alpha',
'Natural Language :: English',
],
entry_points='''
[console_scripts]
mesa=mesa.main:cli
''',
)
28 changes: 28 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
import sys
import unittest
from unittest.mock import patch
from click.testing import CliRunner

from mesa.main import cli


class TestCli(unittest.TestCase):
'''
Test CLI commands
'''

def setUp(self):
self.old_sys_path = sys.path[:]
self.runner = CliRunner()

def tearDown(self):
sys.path[:] = self.old_sys_path

def test_run(self):
with patch('mesa.visualization.ModularVisualization.ModularServer') as ModularServer:
example_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../examples/wolf_sheep'))
with self.runner.isolated_filesystem():
result = self.runner.invoke(cli, ['run', example_dir])
assert result.exit_code == 0, result.output
assert ModularServer().launch.call_count == 1

0 comments on commit 304e9f1

Please sign in to comment.