Web Development with Tornado and React

This is an example Jaffle configuration for the web development which uses Tornado and React to build the back-end API and the front-end web interface respectively.

It does:

  • Launch the Tornado application including HTTP server
  • Launch the Webpack dev server as an external process by executing yarn start
  • Launch Jest as an external process by executing yarn test
  • Restart the Tornado application when a related file is updated
  • Execute pytest when a related file is updated

This page assumes that you have already know the basic configuration for a pytest. If not, please read the section Auto-testing with pytest.

jaffle.hcl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
kernel "py_kernel" {}

app "watchdog" {
  class  = "jaffle.app.watchdog.WatchdogApp"
  kernel = "py_kernel"

  options {
    handlers = [
      {
        watch_path         = "tornado_spa"
        patterns           = ["*.py"]
        ignore_patterns    = ["*/tests/*.py"]
        ignore_directories = true
        clear_cache        = ["tornado_spa"]

        code_blocks = [
          "tornado_app.handle_watchdog_event({event})",
          "pytest.handle_watchdog_event({event})",
        ]
      },
      {
        watch_path         = "tornado_spa/tests"
        patterns           = ["*/test_*.py"]
        ignore_directories = true
        clear_cache        = ["tornado_spa.tests"]

        code_blocks = [
          "pytest.handle_watchdog_event({event})",
        ]
      },
    ]
  }
}

app "tornado_app" {
  class  = "jaffle.app.tornado.TornadoBridgeApp"
  kernel = "py_kernel"
  start  = "tornado_app.start()"

  options {
    app_class   = "tornado_spa.app.ExampleApp"
    args        = ["--port=9999"]
    clear_cache = []
  }
}

app "pytest" {
  class  = "jaffle.app.pytest.PyTestRunnerApp"
  kernel = "py_kernel"

  options {
    args = ["-s", "-v", "--color=yes"]

    auto_test = [
      "tornado_spa/tests/test_*.py",
    ]

    auto_test_map {
      "tornado_spa/**/*.py" = "tornado_spa/tests/{}/test_{}.py"
    }

    clear_cache = []
  }
}

process "frontend" {
  command = "yarn start"
  tty     = true

  env {
    BROWSER = "none"
  }
}

process "jest" {
  command = "yarn test"
  tty     = true
}

Clearing Module Cache

Since two applications tornado_app and pytest run in the same Jupyter kernel and share the same Python modules in memory, you should manually configure the cache clear. By default TornadoBridgeApp and PyTestRunnerApp clear the modules found under the current directory on receiving an Watchdog event. That causes duplicated cache clear on the same module. To prevent that, the configuration above has clear_cache = [] in both tornado_app and pytest to disable cache clear and has clear_cache = ["tornado_spa"] in watchdog to let WatchdogApp clear the module cache instead.

Note

If clear_cache configuration is incorrect, TornadoBridgeApp or PyTestRunnerApp may not reload Python modules.

Screenshot

../_images/tornado_example.gif

Note

The source package of Jaffle contains example projects in examples directory. You can see the latest version of them here: https://github.com/yatsu/jaffle/tree/master/examples

A Tornado and React example is here: https://github.com/yatsu/jaffle/tree/master/examples/tornado_spa