Skip to content

anders617/michigan-dining-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

michigan-dining-api

Build Status

michigan-dining-api.tendiesti.me
michigan-dining-api.herokuapp.com

A system for scraping and serving information from the University of Michigan dining API. This repository contains the code for fetching, analyzing and serving dining information. For how to make use of this service, see the usage section or visit the mdining-proto repository for protobuf service definitions.

Data is scraped from the University of Michigan's MDining API, formatted and stored in a database to be served. This allows for data structures and formats that are easier to work with than the original API and for historical data to be retrieved past what the MDining API offers (2019-11-02 is the earliest date available through the tendies time michigan dining api service). Check out the MDining statistics page of tendies time for examples made using this historical data.

Setup
Executables
Deployment
Usage

Setup

Clone this repo

git clone https://github.com/anders617/michigan-dining-api.git

Install the Bazel build system

Executables

This project uses the glog library for logging. The --alsologtostderr flag can be specified to send log output to stderr.

Run the web server:

bazel run //cmd:web -- --alsologtostderr

Run the fetch executable to fill the DiningHalls/Foods/Menus tables:

bazel run //cmd:fetch -- --alsologtostderr

Run the analyze executable to fill the FoodStats table (depends on data from running //cmd:fetch above):

bazel run //cmd:analyze -- --alsologtostderr

Run the db executable to create tables:

bazel run //cmd:db -- --alsologtostderr --create

Run the db executable to delete tables:

bazel run //cmd:db -- --alsologtostderr --delete

Run the testing client executable to connect to a instance of the web server:

bazel run //cmd:client -- --alsologtostderr --address=michigan-dining-api.tendiesti.me:443 --use_credentials

Deployment

Containers
AWS
Heroku

Containers

The //cmd:web, //cmd:fetch, and //cmd:analyze executables all have rules for creating distroless docker images:

  • //cmd/web:web_image
  • //cmd:fetch:fetch_image
  • //cmd:analyze:analyze_image

There are also rules for pushing these container images to container registries:

  • //cmd/web:web_image_publish
  • //cmd/fetch:fetch_image_publish
  • //cmd/analyze:analyze_image_publish

Note that each target above needs to be run with the --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 flag set to ensure the binaries are built for running in a linux container. Alternatively, you can specify --config=container to use the config set in the .bazelrc to avoid having to remember the long platform name.

Currently these rules are configures to push the images to gcr.io/michigandiningapi but can be easily configured to publish to other container registries by editing the rules in the BUILD files.

This means that the latest container image builds for each executable are available at:

  • gcr.io/michigandiningapi/web:latest
  • gcr.io/michigandiningapi/fetch:latest
  • gcr.io/michigandiningapi/analyze:latest

Note that these container images need to have the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY set when run for the AWS account which will host the dynamodb data tables.

Note that since these are distroless docker images, only the bare minimum for running the executable is included so no shells or other standard Linux programs are included. This means that traditional Docker healthchecks that depend on shell commands will not work and should not be used for determining container health.

AWS

Currently michigan-dining-api is deployed and hosted on AWS using the Elastic Container Service at michigan-dining-api.tendiesti.me.

There is a task definition for each executable container image (listed above). Within each task definition, the AWS_SECRET_ACCESS_KEY and AWS_SECRET_ACCESS_KEY environment variables must be specified for the AWS account hosting the dynamodb tables. The analyze and web tasks have 0.5GiB memory and 0.25vCPU allocated. The fetch task requires more memory and is allocated 1.0GiB memory and 0.25vCPU.

There is a Service defined for the web server using the web task definition. This service is deployed on a Fargate cluster. The web service is configured to include load balancing using a network load balancer. The network load balancer is configured with an SSL/TLS certificate on its :443 listener and decrypts HTTPS traffic before it is forwarded to the web server. It is important this is a network load balancer instead of an application load balancer since AWS application load balancers do not handle grpc style HTTP/2 traffic correctly.

There are scheduled tasks for the fetch and analyze tasks to run once daily in order to update the dynamodb tables.

Heroku

Currently michigan-dining-api is deployed and hosted on Heroku at https://michigan-dining-api.herokuapp.com.

Heroku is not optimal for hosting grpc servers since it does not support HTTP/2. Therefore, if you plan to take advantage of grpc, I recommend you use a different provider such as AWS.

In order to deploy your own server:

  • Setup the Heroku application to point to this repository
  • Add the custom heroku-buildpack-bazel buildpack to allow building with bazel
  • Setup the HerokuScheduler add on to run the command cmd/fetch/fetch and cmd/analyze/analyze daily in order to fill the data tables
  • Set the following Heroku config vars:
    • AWS_ACCESS_KEY_ID - Access key used for AWS DynamoDB access
    • AWS_SECRET_ACCESS_KEY - Secret used for AWS DynamoDB access
    • BAZEL_BUILD_PATH - //cmd:all
    • BAZEL_VERSION - 1.1.0 (or later version)
    • BUILD_CACHE_LOCATION - Address of a bazel remote cache server (optional)
  • Go to the deploy tab and click deploy branch

Usage

There are examples of grpc usage and client libraries in the mdining-proto library. This library also contains the proto definitions of messages and services provided by this service.

REST Endpoints

You can try out the following queries to get a sense of what is available through the api.
Additionally, the homepage for the tendies time michigan dining api service has longer descriptions of the purpose of each query.

/v1/items
/v1/diningHalls
/v1/filterableEntries
/v1/all
/v1/menus?date={yyyy-MM-dd}&diningHall={DINING_HALL}&meal={MEAL}
/v1/foods?name={LOWERCASE_FOOD_NAME}&date={yyyy-MM-dd}&meal={MEAL}
/v1/summarystats
/v1/stats
/v1/hearts