This is a monorepo for barista, a companion tool for UCLA's CS 131. It helps students create and debug test cases for the course's quarter-wide project, building an interpreter for the "Brewin" language.
Overall, barista is a small "web wrapper" around the core project interpreter code; it has
- a small Flask server that runs arbitrary Brewin code and returns the result/error
- a tiny React app that provides an interface to use the server
Broadly, we package the React app as a static HTML page with Create React App, and then serve that HTML with Flask as a root.
This is nothing fancy (or bleeding-edge), and it's probably not the best way to do this --- but, it works :)
Have any questions or concerns? Open an issue or shoot matt an email at matt@matthewwang.me.
This project blends a typical Python and Node workflow. To run the entire app locally, you'll need both. As of writing, we require at least Python 3.9 and Node 16.
First, set up the environment; we've added some npm
helpers:
$ npm install
# sets up a venv and installs with pip
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
To run the Flask server in dev mode,
$ source venv/bin/activate # activate the venv
$ npm run start-api
To then run the frontend,
$ npm start
A flag in the React app hard-codes a development path to ping, which relies on the port; if you change ports, make sure to change the code there too!
There are a few ways to deploy this app; since it's so small, a variety of solutions work (ex Heroku / Fly / EC2 / running your own server). Since no state is necessary, you can probably even run this as a lambda!
We've deployed a copy of barista at https://barista.fly.dev, using Fly. The included Dockerfile
is a self-contained build process for the entire application: it builds the React app first, copies it into the next stage, and then builds and serves the Flask server with gunicorn.
src
roots the React app; all of the logic lives insrc/App.js
, and the React app's public folder ispublic
(this gets copied into the Flask static serve)app.py
is the root of the Flask server, and only handles parameter parsing and "general" webserver stuffinterpreters
has all the code related to execution- we've added an
executor.py
that wraps the entire interpreter run process (init, validate program, run) - the other code can be directly copy-pasted from a canonical solution; ensure that imports to be relative to filepath (ex
from . import intbase
)
- we've added an
We recommend using venv to manage your local Python installation.
After adding a new library to the venv, add it to requirements.txt
:
$ pip freeze -l > requirements.txt
You're probably right 😅. This is more of a quick-and-dirty solution than a thoroughly thought-through production app.
There's some low-hanging fruit:
- the
Dockerfile
stages are not as efficient/slim as they could be - the
interpreters
structure is not well-designed; making it a module is probably a good first step - we haven't configured web vitals, manifests, etc.
- the site is not mobile-friendly :(
And bigger picture,
- React is overkill for the frontend; we could certainly accomplish the same thing with preact or Flask templates, both of which would significantly reduce the bundle size and complexity of the build
- and, if we did stick with React, using a framework that's a bit more powerful/customizable than Create React App would let us eke out better performance / bundle size / ergonomics
- the code editing experience could be better -- for example, if we wrote a custom syntax highlighter for the language
- it may be possible to do all of this in WASM instead!
If you have any ideas, a PR is always welcome!