Spinning up FastAPI

You are not logged in.

Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.
A Python Error Occurred:

Error on line 2 of Python tag (line 3 of source):
    student_servername =  BASE_SERVER+"/"+STUDENT_SERVERS[cs_username]['endpoint']

KeyError: 'None'

In 6.900, pretty much all of the projects we'll be working on will need some sort of distributed system where computation is both "on the edge" in embedded systems as well as centralized to some degree "in the cloud" aka on a server, with us using various network protocols to link everything together. The embedded side will get worked on lab 1, but we also need to focus on the server side. For this we'll use Python and in particular a web framework written in Python called FastAPI1. We chose FastAPI since it is new and fast and written in Python since you should all have some working knowledge of Python. It is also very well-documented and actively developed so you can lean on the internet and documentation to help develop things in your experimentation.

We'll set up a FastAPI application that can be run on your local laptop. This is great for development since you can use the tools you know and love (pick your poison, VScode, IDLE, I don't care) and since it is all local, the debug loop will be much faster. Eventually this framework can be migrated onto an actual server for long-term deployment with your projects as well.

Get Started

We're going to assume you have Python on your computer. What we're doing is pretty flexible to your development environment/framework, so we'll assume that you can navigate Python on your system. We would strongly encourage you to make a virtual Python environment rather than just install things on your system Python, which is a separate "clone" of your system Python. Why make a virtual environment and not just use the system Python? Well the main reason is just to keep things isolated. If we mess up the Python with an installation, we'd rather that be the standalone python rather than the one that much of the system might be depending on. It also allows us to run multiple apps on different Python environments and potentially not run into any big issues with conflicting libraries.

Making a virtual environment can be done with a command like the following (in a terminal/shell), though note you may just need to use python rather than python3. Here I'm making a virtual environment called "efi_venv" short for "engineering for impact virtual environment". You can call yours whatever you want. Run this command in the terminal, in whatever directory you want to create your virtual environment. It may take a little while to run.

python3 -m venv efi_venv

Now in order to "activate" that Python virtual environment we use this command:

source efi_venv/bin/activate

If you did that right, you'll see (efi_venv) prepending your terminal lines. That means this particular environment of Python is active. If you run deactivate. It'll exit you out of here.

With this virtual environment activated, any Python-related task...such as running Python or installing libraries will affect this version of Python and not the big system-wide one.2

OK so we need to install just one library within this virtual environment, the FastAPI framework. This can be done with the following command:

pip install "fastapi[standard]"

Ok you should be good. If, from the terminal you run python, it'll bring up a Python shell. Inside there do : import fastapi. If nothing pukes back at you, you're golden. Exit Python with exit().

Now let's write a basic FastAPI application now:

Basic Application

Make a subdirectory efi_test. Inside this efi_test directory make a new file and call it efi_test.py. This will be your "main" FastAPI application for this assignment which would eventually contain a lot of code. For now it'll be short and sweet. Anything that interfaces with your application will just respond with "hey there!"

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
  return "hey there"

Now in order to test this file we're not going to just run it like a normal Python file. Instead, fastAPI comes with a local development server that we can use to see how our stuff is working. It will spin up a little local webserver for you and host the application on your computer. To do this in a terminal with the virtual environment activated, run:

fastapi dev efi_test.py

You should see a whole bunch of stuff fly by. These are basically logs of your server working and it should look something like this:



   FastAPI   Starting development server 🚀

             Searching for package file structure from directories with __init__.py files
             Importing from /Users/jodalyst/fast_test

    module   🐍 efi_test.py

      code   Importing the FastAPI app object from the module with the following code:

             from efi_test import app

       app   Using import string: efi_test:app

    server   Server started at http://127.0.0.1:8000
    server   Documentation at http://127.0.0.1:8000/docs

       tip   Running in development mode, for production use: fastapi run

             Logs:

      INFO   Will watch for changes in these directories: ['/Users/jodalyst/fast_test']
      INFO   Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
      INFO   Started reloader process [19007] using WatchFiles
      INFO   Started server process [19009]
      INFO   Waiting for application startup.
      INFO   Application startup complete.

Among the lines that fly by you'll see one saying:

    server   Server started at http://127.0.0.1:8000

This is telling us that a development server is currently running at the IP address 127.0.0.1 and port 8000. We'll talk more about IP addresses and networking later in the term, but for now you can visit this address in a web browser, just like any other address. Go ahead. Open up a browser tab and type in 127.0.0.1:8000. You should get something like the following:

Visiting the simple web app in the browser at address `127.0.0.1:8000`

Note on most computers 127.0.0.1 is the internal address of the machine to itself and this usually has an aliased name localhost which you can also use directly:

aka `localhost:8000`

Just to convince yourself of the causality in the situation we find ourselves in, go ahead and make a change to the text that your application is returning. Then restart (control-C to kill) the web server (though it usually does auto-restart on changes.). For example, I changed the text that came back from

@app.get("/")
def root():
  return "I am excited."

and now on refreshing the web page, I get:

with a change

How about that.

Notice also in the shell that is running the Python development server, you should be getting readouts. These are logs of the server/application's behavior. For example, if I hit the page a few times with refreshes I get the following:

      INFO   Application startup complete.
      INFO   127.0.0.1:55188 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55188 - "GET /favicon.ico HTTP/1.1" 404
      INFO   127.0.0.1:55196 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55196 - "GET /favicon.ico HTTP/1.1" 404
      INFO   127.0.0.1:55197 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55197 - "GET /favicon.ico HTTP/1.1" 404
      INFO   127.0.0.1:55200 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55200 - "GET /favicon.ico HTTP/1.1" 404
      INFO   127.0.0.1:55201 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55201 - "GET /favicon.ico HTTP/1.1" 404
      INFO   127.0.0.1:55202 - "GET / HTTP/1.1" 200
      INFO   127.0.0.1:55202 - "GET /favicon.ico HTTP/1.1" 404

The line with the GET / HTTP/1.1 (With the 200 code which means success in HTTP) is us hitting the page and getting a response, and the line about the 404 is the fact that we don't have a favicon.ico specified (code 404 means "not found" in HTTP). Note that you may not get the 404 error line.

Doing Useful Things

FastAPI is a full-fledged web framework. It is well-documented and widely used, so there's little reason for us to spend a bunch of time rewriting documentation...instead we should just go to the source: FastAPI Documentation and numerous other websites will go over effectively how to do things with it.

As a starter assignment which will take a little research on your part and studying the docs and experimenting let's write an application that can respond to incoming query arguments in our HTTP request. These are the things that show up after the ? in your URL. They generally show up as key-value pairs like http://internet.com?name=None&school=mit with individual pairs separated by ampersands.

You can use them to provide inputs a web service and that's exactly how we'll do that here. Dig through the FastAPI documentation and find a way to have a sub-url called heat_index peform an operation where it looks for two incoming query arguments named rh and t that should be numbers (ints or floats) and return the corresponding heat index (the formula can be found here), rounded to the closest integer.

For example going to: localhost:8000/heat_index?rh=80&t=100 should yield 158 in the response. For other rh&t pairings, you can verify the appropriate heat index using this chart, but make sure t is at least 80 for the heat index to be valid.

Look it is working!

Look it is working with different numbers!

Feel free to ask for help on Piazza and/or office hours! The solution to this should not be more than about ten lines of additional code (if that). you can end up doing this...it will be very useful and you understand a good portion of FastAPI then!

In the next section, we'll add a little bit more infrastructure so that you can "tunnel" your development application to a world-viewable endpoint.

Documentation

A really nice feature of FastAPI is it automatically generates documentation for the application that you're writing. If you go and visit localhost:8000/docs, you should get a page that looks something like below. This can be useful in debugging and just remembering what you wrote in the first place/allowing other people to understand what you wrote.

The documentation of your functioning heat index web application


 
Footnotes

1In years past, we used the Flask framework, which really was a game-changer in the field as far Python-based web frameworks are concerned. (click to return to text)

2Using virtual environments is a good idea in general. If you're ever at a job and they want you to mess with the Python, do a virtual environment first...you'll look cooler. (click to return to text)