diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b7d900 --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +# 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): + +```Bash +virtualenv venv +``` + +Once the virtual environment has been created, activate it using the +following command: + +```Bash +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: + +```Bash +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: + +```Nix +with import {}; + +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: + +```Bash +export DB_LOC=database.sqlite +``` + +Additionally, Flask uses the `FLASK_APP` environment variable to determine the entry point +of a web application + +```Bash +# 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: + +```Python +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: + +```Bash +flask run +``` + +## Next Steps +Once the server is up and running, consider setting up the +[app](https://dev.danilafe.com/CS-46X/app), which is able +interact with this API server. Additionally, check out the +[cow description language](https://dev.danilafe.com/CS-46X/cdl) +if you want to generate mock data for the API server's database.