FastAPI over HTTPS for development on Windows
Tags: python, fastapi, https, windows
Published: 2021-04-03 14:23:01

Today we'll implement FastAPI over HTTPS using mkcert and setup our own Certificate Authority(CA) on our localhost. 

Note: since this is a self-signed certificate you might get a warning before accessing your API depending on which browser you're using.

We'll get started with the code right away so if your boss has told you "Cool get this running over https by EOD" you are in the right place.


+ Open cmd and make a directory for our app.
```
-> mkdir fastapi-https
-> cd fastapi-https
```

+ Create and activate a virtual environment for your project and install fastapi and uvicorn in our virtual environment.
```
-> python -m venv ./venv
-> .\venv\Scripts\activate
(venv) -> pip install fastapi uvicorn 
```
It's always a good practice to create [virtual environments](https://realpython.com/python-virtual-environments-a-primer/) 

+ Open the _fastapi-https_ folder in VSCode and create a directory _app_ which will contain our FastAPI application in *app/main.py*. Also create a file *server.py* to run our [Uvicorn](https://www.uvicorn.org/) server and use it to serve our FastAPI app.
So your directory structure should look like this:
    ![Alt Directory Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qgnuj7wrrgsvs9u3ewck.PNG)

+ Paste the following code in *app/main.py* which will create a FastAPI route for us.
```python
    from fastapi import FastAPI

    app = FastAPI()

    @app.get('/')
    def read_main():
        return { "message" : "Hello World of FastAPI HTTPS"}
```

+ Since FastAPI doesn't come with a built-in web server like Flask and Django, we will be using Uvicorn which is an ASGI server. In the file *server.py* paste the following code -
```python
import uvicorn

if __name__ == '__main__':
    uvicorn.run("app.main:app",
                host="0.0.0.0",
                port=8432,
                reload=True,
                )
```

In this code in the main function we essentially tell the uvicorn server "Dude! Go to app.main and run whatever this 'app' is" and then we mention the host and port and yeah we do want to reload and all those things.

+ Now its run the server.py file with `python server.py` and go to this link http://localhost:8432/
    ![Alt It worked!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w74pzvouv5fjau3y3m8q.PNG)

+ It works! But over "http" 🙄 this won't do in production. We need HTTPS in production. If you want to learn more about how HTTPS works, I will be writing another article here.
To get HTTPS we need to install [mkcert](https://github.com/FiloSottile/mkcert). Mkcert is a free way to get a self signed certificate for your app so it can run over HTTPS.
Install mkcert using [Chocolatey](https://chocolatey.org/install)
```
-> choco install mkcert
```

+ You need to generate the certificate and add to your CA with the mkcert utility
```
-> mkcert -install
-> mkcert localhost 127.0.0.1 ::1
```

+ The certificate is at "localhost+2.pem" and the key at "localhost+2-key.pem" in our project folder. I like to rename the files as "cert.pem" and "key.pem" so its a bit easier on the eyes.

+ Now we just need to tell Uvicorn the location of these files and Uvicorn will do all the HTTPS heavy-lifting for us. In *server.py* add the ssl arguemnts
```python
import uvicorn

if __name__ == '__main__':
    uvicorn.run("app.main:app",
                host="0.0.0.0",
                port=8432,
                reload=True,
                ssl_keyfile="./key.pem", 
                ssl_certfile="./cert.pem"
                )
```

+ Voila! Go to https://localhost:8432/docs and we now have the sweet green text
    ![Alt Connection Secure!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atzp9y7fbhf8tp00dpyt.png)