Fenceless Grazing API Server.
Go to file
2020-05-15 21:44:00 -07:00
fgs Add 'needs_push' field 2020-05-15 17:04:04 -07:00
.gitignore add gitignore 2020-05-13 02:40:44 +01:00
README.md Add README 2020-05-14 01:56:12 -07:00
requirements.txt Update requirements 2020-05-14 01:38:10 -07:00
REVIEW.md Add code review remarks. 2020-05-15 21:44:00 -07:00
run.sh add inlets back 2020-05-15 20:46:28 +01:00

Fenceless Grazing System API Server

This is the repository for the API server component of the Fenceless Grazing System. This server is written in Python using the Flask microframework, and uses the SQLAlchemy ORM to interact with the SQLite database.

Getting the Dependencies

The API server depends on several packages to operate properly, which will likely not be installed by default on your system. There are two ways to get the required dependencies: using Python's virtualenv (standard in the Python ecosystem), or using Nix (only if you are into that kind of thing).

Getting the Dependencies with virtualenv

First, create a virtual environment (this only has to be done once):

virtualenv venv

Once the virtual environment has been created, activate it using the following command:

source venv/bin/activate

This effectively creates an independent Python environment, into which you can install packages without affecting your entire system. You can now install the packages from the requirements.txt file:

pip install -r requirements.txt

With this, you should have all the necessary dependencies.

Getting the Dependencies with Nix

Below is the Nix expression I use daily to work on this application:

with import <nixpkgs> {};

mkShell {
    buildInputs = [ (python3.withPackages (ps: with ps; [ flask flask_sqlalchemy pyjwt bcrypt geopy pip ])) ];
}

Note that some packages (geopy in particular) are currently unstable; the expressions from stable Nixpkgs may not provide a working derivation. When using the nixpkgs-unstable, I have no such issues.

Setting Up

The application requires the DB_LOC environment variable to be set to indicate the location of the database that the server should use:

export DB_LOC=database.sqlite

Additionally, Flask uses the FLASK_APP environment variable to determine the entry point of a web application

# Here, fgs represents the fgs/ directory in the repository's root.
export FLASK_APP=fgs

Finally, on first run, you need to create the tables in the application's database. This can be done as follows:

flask shell
# Imports, among other things, the db variable, which is the handle for the SQLAlchemy ORM.
from fgs import *

# SQLAlchemy needs to be aware of the various tables in our database
from fgs.model import *

# Creates all tables
db.create_all()

# It also helps to set up a user and a couple of collars:
user = User(username='user', password='password')
collar1 = Collar(name='Sample Collar', active=True)
collar2 = Collar(name='Another Collar', active=True)

# To add the newly created objects to the database, use
# db.session.add and db.session.commit
db.session.add(user)
db.session.add(collar1)
db.session.add(collar2)
db.session.commit()

# You can now press Ctrl-D to exit the Flask shell. 

Once the database has been created, you can start the server with:

flask run

Next Steps

Once the server is up and running, consider setting up the app, which is able interact with this API server. Additionally, check out the cow description language if you want to generate mock data for the API server's database.