Setting up the Backend for Athena, my Personal Assistant
Tags: python, flask, heroku
Published: 2019-07-03 00:22:01

---
title: Setting up the Backend for Athena, my Personal Assistant
published: true
description: Before getting into the code, here's how I set up the backend for the api that powers Athena
tags: python, flask, Heroku
---


If I'm going to build a full-featured, AI-powered, totally-awesome personal assistant bot, I need to start off with a solid foundation. Here's a post that outlines all of the involved technologies and my initial flask app set up. If you would like to see how the project looked at different stages of the process, click on the Code Checkpoint link to head to the commit in Github.

## Contents
* [Tech Stack](#stack)
* [Initial Commit](#start)
* [Deployment with Heroku](#deployment)
* [Testing... 1, 2, 3](#testing)
* [Athena, Tell Me More about Yourself](#add-intro)


<a name = "stack"></a>
### Current Tech Stack
* [Github Repo](https://github.com/TaylorFacen/Athena)
* Heroku
* Python (Flask)

<a name = "start"></a>


### Initial Commit
[Code Checkpoint](https://github.com/TaylorFacen/Athena/tree/9404bf53f03e240d0614a34c6d3963632f4f3e19)

Ahh, who doesn't love typing `Initial Commit` to get a project going? To kick things off, I started with a basic Hello World flask app with Swagger documentation via flask-restplus. Although restplus isn't a requirement for deploying flask app, I find it much simpler to have the service provide the documentation for me. Also, it allows for testing endpoints without having to use curl or an IDE. 

**Virtualenv**
As with any Python project, I start off by adding a virtual environment. This step is crucial in making sure that what I see on my computer is the same thing I'll see when deployed (and so that people like you can copy my code with ease). 

**Flask Application Factory**
Flask suggests to use the application factory for two main reasons:
* Easy Testing
* Having multiple instances of the same (or slightly tweaked) app

You can read more about this method [here](http://flask.pocoo.org/docs/1.0/patterns/appfactories/). 

**Folder Hierarchy and App Structure**
To be honest, I'm still learning about the best organization method for flask so that projects are easy to follow and update. Here's the structure that I have at this point:

.
├── athena
|   ├── __init__.py
|   ├── app.py
|   └── general
|       ├── __init__.py
|       └── general.py
├── env
|   └── (insert all of the hidden magic of virtualenv)...
├── .gitignore
├── requirements.txt
└── run.py

Because Athena will have multiple components (because no one's life only pertains to one area), the api will have multiple namespaces (think folders) that will organize similar endpoints. I'm starting off with a "general" section to house all foundational api calls and activities..

After getting the project set up, this is what the app looks like when deployed locally
```python
python run.py
```
![Swagger Documentation](https://thepracticaldev.s3.amazonaws.com/i/qox06ksfoi6bb4vyxgtc.png)

And heading to /athena/intro in the browser shows the following response
![Hello World](https://thepracticaldev.s3.amazonaws.com/i/qpqt3morigtf2zeck8ph.png)

<a name = "deployment"></a>


### Deployment with Heroku
[Code Checkpoint](https://github.com/TaylorFacen/Athena/tree/a403eeac3627b5991d63026996121f7e0e81a289)

Alright, now it's time to push this out to the public. I'm using Heroku to host my app for the following reasons:
* I can connect a branch to my app so that whenever code is push to remote, a new app with the new changes is deployed
* Automated testing
* App pipelines
* The interface is amazingly user-friendly
* When there's a pull request, Heroku can automatically deploy a one-off version of the app with the code in the pr 
* plus a million more reasons

**Pipeline**
I went ahead and created a pipeline with two apps for my two development environments: 
* production: this is what I'll interact with every day
* staging: this is where I'll deploy code that's finished with development but may not be 100% ready to go public (e.g. completed sub-features that need another sub-feature to be finished before the entire section is complete)

![Athena Pipeline](https://thepracticaldev.s3.amazonaws.com/i/hragi0jf3ux020r7n8js.png)

The entire pipeline is connected to my project repo, and my prod app is connected specifically to my master branch. Once the staging branch is created down the line, I'll go ahead and connect that branch to the staging app (don't want to get ahead of myself).

![Deployment Settings](https://thepracticaldev.s3.amazonaws.com/i/yzdtbx4u1e2po45304jd.png)

The prod app is set to automatically deploy with each push. However, before the first deployment, I need to add a few things to the app to make it Heroku-ready.

**Changes** 
* Added Procfile (file)
* Installed gunicorn (package)
* Created app instance in run.py

After adding these changes, I ran `heroku local` in my terminal to make sure I had everything set up right.

Within seconds of pushing my changes to Github, Heroku started to deploy my changes to the app. 

![Automatic Deployment](https://thepracticaldev.s3.amazonaws.com/i/m9is98hr5invv29rxn2x.png)

![Public Deployment](https://thepracticaldev.s3.amazonaws.com/i/op1163r44f2z5kk2v41i.png)

And voila! Athena is public!

<a name = "testing"></a>


### Testing... 1, 2, 3
[Code Checkpoint](https://github.com/TaylorFacen/Athena/tree/8663a8a54f7cef33ffba387ad8c66db1e91b2e4e)

One thing I've learned along my coding journey is that sooo much time can be saved by starting off a project with testing in mind. Heroku and pytest make it easy to make sure that each push is a fully functioning application. 

First up, let's add a test to make sure that the app works. 

**Changes**
* Installed pytest (package)
* Added test folder with test
* Enabled CI in pipeline
* Added app.json file for test configuration
* Added pytest.ini (file)

After getting pytest installed, I added a simple test to check to see if the app is running. One quick way to do this is to check to see if a GET request to '/' returns with a status code of 200.

`test_app.py`

```python
from athena import create_app

import pytest

@pytest.fixture
def app():
    app = create_app()
    return app

def test_app(app):
    client = app.test_client()

    resp = client.get('/')
    assert resp.status_code == 200
```

**Tip**
 If you've used pytest with a Python 3.# virtualenv before, you've probably seen the following error:

```
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
    from collections import Hashable
```

To make sure that DeprecationWarnings like this don't halt the entire app, you can add a `pytest.ini` file with the following:

```
[pytest]
filterwarnings = ignore::DeprecationWarning
```

After running `pytest` in the terminal, the following output is displayed.
![Pytest results](https://thepracticaldev.s3.amazonaws.com/i/2r946hc52m0c80oxzzt5.png)

Next step is to add the app.json file so that Heroku knows how to test the app. Afterwards, I can enable CI on the pipeline and then deploy the changes for testing. Here's what's displayed on the screen after pushing to remote.

![Automatic Testing](https://thepracticaldev.s3.amazonaws.com/i/rhbvpjvlcnt5gbp0jct1.png)

And here's what's displayed when all tests pass.
![Tests passed](https://thepracticaldev.s3.amazonaws.com/i/k9gbbxwrr5jltwx4wai5.png)


<a name = "add-intro"></a>


### Athena, Tell Me More about Yourself
[Code Checkpoint](https://github.com/TaylorFacen/Athena/tree/8dcdad7983f239e89f88ecb9dfecedf3c3f7a4eb)
Okay, the set up is basically done. We have automatic deployment and testing and a solid application organization structure. To finish things out, I'll go ahead and create a staging application for any future features. Also, just to add a little spice to this tutorial, let's try to commit the first feature change so that we can get a glimpse into the power of Heroku's Review Apps. 

**Changes**
* Added staging branch
* Connected staging branch to staging app with automatic deployment
* Added more details to the GET /athena/intro request

After enabling Review Apps (inheriting config vars from the staging application), changing the response to the intro request, and submitting a pull request, an app was created and launched for me to see the changes in real time. The pull request page shows that all tests passed and gives a link to view the deployment (can also see from the heroku dashboard). 
![pull request page](https://thepracticaldev.s3.amazonaws.com/i/wyn8cufrnb2566788yx1.png)

Wooh! All tests passed and my intro text was updated. Time to accept the pr, push the changes up to master, and release v0.1 of my app! 

![Updated intro text](https://thepracticaldev.s3.amazonaws.com/i/ozv8qheq760fcu96rwyn.png)

Thanks for reading along! Next, I'll program Athena to give me a wake up call every morning.

[Athena v0.1](https://github.com/TaylorFacen/Athena/releases/tag/v0.1)