- Tactical Rashers API
This site is to represent capabilities with the Django Rest Framework. It should employ full Create, Read, Update, Delete (CRUD) functionality via DRF.
The assessment checklist is available to view in the
docs/
directory
of the project repository.
The needs within this project are not genuine and are made purely for the purpose of completing my Code Institute project.
Tactical Rashers : a backgammon players' site.
The site should allow users to play backgammon in a manner similar to "Chess by post". Users will be able to play private games, with dice rolls handled via the app, and comment with their intended moves. They should be able to update the main image of the game to the latest state of a board and should be able to declare a winner.
Full CRUD functionality should be available to allow users to interact appropriately with the various aspects of the finished application. This repo intends to provide a robust back-end API via the Django Rest Framework.
Some example user stories that will affect the design. Please consult the GitHub project board for a full list of user concerns written in the form of GitHub issues. Alternatively, a status graph can be viewed here.
Below is a non-exhaustive list of some of the user stories. Some of these are key user stories that must be achieved for an MVP to be considered complete:
"As a potential player, I would like to be able to read the rules of the game so that I know how to play"
"As a potential user, I would like to be able to create a profile so that I am able to play"
"As a returning user, I would like to quickly determine whether I am logged in so that I can log in / out as needed"
"As a returning user, I would like to log in to my account so that I can interact with the features of the site"
"As a returning user, I would like to view my currently active games so that I can track the progress of, and make new moves on, my games in play"
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
"As a returning user, I would like to comment on completed games so that I can interact with other users of the site"
The back-end API should provide robust, well-handled database management for the front-end application. It should allow user authentication, game management, dice rolling and winner tracking. An optional consideration of "Follow gamer" - a feature that allows users to follow completed games of particular gamers - may be considered dependent on time constraints.
-
Create account
"As a potential user, I would like to be able to create a profile so that I am able to play"
New users of the site can create a profile that enables the creation of, and participation in, games.
-
Log in
"As a returning user, I would like to log in to my account so that I can interact with the features of the site"
Existing users of the site can log in to their account.
-
Log out
"As a signed in user, I would like to log out of my account so that I can protect my account on shared devices"
Existing users of the site can log out of their accounts.
-
Create game
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Existing users can create games with other players.
-
Find relevant games
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
"As a returning user, I would like to view my currently active games so that I can track the progress of, and make new moves on, my games in play"
Games can be filtered and searched.
-
Roll dice
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Dice rolls can be made in games.
-
Make a move
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Moves can be noted in games.
-
Winner selection
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Game winners can be specified.
-
Mark completed game
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Games can be marked as active/complete.
-
Update game image
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Game images can be updated by players.
-
Profile editing
"As a potential user, I would like to be able to create a profile so that I am able to play"
Users can update their profile with some information about themself and an avatar.
-
Display games records
"As a returning user, I would like to view my currently active games so that I can track the progress of, and make new moves on, my games in play"
Games can be filtered and searched and winners and move counts are tracked.
-
Display game requests
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
Games can be initiated with any other player in the current iteration. It would be nice to implement a "request" feature that allows the requested player to accept/reject the invitation.
-
Comment on completed games
"As a returning user, I would like to comment on completed games so that I can interact with other users of the site"
This has not been worked on for this iteration. Adding this feature would encourage more social interaction with the site. A
Comment
model would be similar to theMove
model and would only be available on games that are marked as complete (not active). -
Mark game as public
"As a returning user, I would like to play a game with another player so that I can enjoy the game of backgammon"
"As a returning user, I would like to comment on completed games so that I can interact with other users of the site"
This feature would allow all site users to view currently active games and, depending on the features permitted by the players, allow comments from non-players during the game. For this iteration, games will only be available to public and non-player users once they are marked as not active.
-
Rules
"As a potential player, I would like to be able to read the rules of the game so that I know how to play"
This will be handled by the front-end application.
-
Log in status
"As a returning user, I would like to quickly determine whether I am logged in so that I can log in / out as needed"
This will be handled by the front-end application.
A PostgreSQL database has been used for storing the various data required for the API.
The database structure has been mapped out using an ERD diagram generated using
the drawio extension in VSCode. Many of the entities will
be linked back through the owner (Django auth's User
model) which allows the
database to have a straightforward structure. A few fields are missing from the
ERD that record creation times and update times.
During development, the SQLite3 database provisioned by Django has been used.
For the production build, an external PostgreSQL instance is necessary. Code
Institute has provided a tool for their students that provides such a database.
As the tool is only for students, and the steps are well defined within the
application, the procedure to create this has not been detailed here. The URL
provided via the tool meets the format required for the dj-database-url
package: postgres://<username>:<password>@<host>/<database_name>
Many other PostgreSQL hosts will provide a URL in this format if required.
This URL is used in any non-development environment and is set as the
DATABASE_URL
environment variable.
Some of the main packages used throughout the project:
Package | Use |
---|---|
django | web framework with effective PostgreSQL database handling methods |
djangorestframework | powerful and flexible toolkit for building Web APIs |
djangorestframework-simplejwt | JSON Web Token authentication plugin |
django-filter | allow QuerySet filtering from URL parameters |
cloudinary | easy uploading of media files to Cloudinary |
load-dotenv | reads key-value pairs from a .env file |
gunicon | Python WSGI HTTP Server for UNIX |
psycopg2 | PostgreSQL database adapter for Python |
For a full list of installed Python packages, see
requirements.txt
Most packages have relevant documentation hosted on the Python package index site.
A screenshot tool built into Windows. It allows quick, partial screenshots to be taken that can be saved as image files.
A free, streamlined code editor. The extensions available have allowed me to customize my workspace and become more efficient.
Links to the VSCode marketplace for each extension used throughout this project:
- Python
- Better Comments
- GitHub Pull Request and Issue Provider
- Highlight Matching Tag
- Markdown All in One
- markdownlint
- Reflow Markdown
- flake8
- Code Spell Checker
- Django
- Draw.io
Manual testing was performed during the development cycle. As the database is fairly straightforward, there were very few bugs identified during the process. Testing consisted of logically creating, reading, updating and deleting records where necessary.
- Multiple users were created to allow testing of various relationships between the models.
- Games can be created by the logged-in user with another user successfully.
- Games cannot be created by a logged-in user with themself.
- Games cannot be created by a logged-in user between two other users.
- Moves were only available to relevant players and at relevant times.
- Winners could only be selected by anticipated users.
- Dice rolls could not be manually determined.
- Profile access is limited to the appropriate level of CRUD depending on user login status.
- Users can log in and out.
The nature of the project allowed for fairly robust automated testing. Several
tests were written utilizing the APITestCase
class available through
rest_framework.test
. I was not aware of how straightforward the test-writing
procedure would be for the application and would consider a TDD approach for
future development. There were a few items that needed editing that were
identified during the writing of tests. Those items have been updated.
Tests were written in a logical order to allow the flow of the site to be incorporated during the process. This allowed functions to be used to create users and games, reducing the need to duplicate code. However, many lines of code are similar in the tests and this is done with intention. The tests are clear, thorough, and easily maintained separately from each other.
Please consult the test.py
files for the test code, and consult
the manage.py test
output file for all tests run.
As shown within that file, 83 tests have been run on the database covering a
wide range of functionality and defensive programming. The test time is fairly
long due to the DiceRolls
test that ensures dice rolls are random. I could not
think of a more efficient (or certain) way of testing this feature, so 25 dice
rolls are generated and compared for uniqueness and their correct parameters.
The Python files have all been checked using flake8. As
shown, the command flake8 . --exclude .venv/,__pycache__/,**/migrations/**
was
used to run a check on the entire project directory, excluding the directories
passed in as arguments. No other errors or warnings are reported.
Doc strings and comments are included where I feel the logic or code needs explaining beyond its implicit readability, with closing brackets clearly showing where arguments etc. are finished. The only exceptions to this are the migration files that were generated by Django.
No HTML, CSS or JavaScript validation has been carried out on the API front end as this will not be utilized in the final project and is not my own code.
At the time of deployment, no current bugs have been found. Some features are yet to be implemented, but all functionality is working as intended for this iteration.
- Winner relationships were incorrect
Commit - a925c74
During manual testing and the improvement of back-end defensive programming, it
became evident that the Winner
model was incorrectly configured. This was
resolved by implementing a ForeignKeyField
with unique=True
. This generates
a warning that a OneToOneField
is more appropriate, but that would not allow
for a Game
with no Winner
without allowing it the other way as well
(Winner
without a Game
).
The warning (fields.W342
) has been silenced in the settings.py
file [421eb47].
Commit - c64e2aa
During the creation of automated tests, it was identified that players could
potentially create games that did not include themselves as a participant.
Although this is not a breaking issue, and would likely require some front-end
code manipulation when submitting a request, it was simple enough to resolve
with the addition of a custom perform_create
method. The discovery of this bug
led to another few custom methods being written to prevent erroneous instances
from being created. The image below shows a Move
being added to a game in
which the author was not a participant.
A GitHub project was created for the site's development. The project is shared between the back-end API and the front-end React application. Labels have been used to help organize the tasks involved and can be filtered as needed. There are multiple views already available on the Project.
An Agile approach has been used to ensure an MVP has been created in time for release (project submission). Issues have sprint points assigned for their effort to complete and have been assigned to Milestones to reflect a sprint process. Sprints were started with a total story point availability of 20 and reviewed at the end of the sprint. The sprint point availability for my efforts was adjusted to allow a maximum of 25 within a sprint as the initial value was not reflective of my ability.
Separate views have been created for each sprint to allow a clear visual of the progress being made. Separate views for docs and user stories also exist for an overview.
The site was developed using git, GitHub and VSCode. The repository is available for cloning or forking but no additional contributions will be accepted at this time.
To clone the repo please see the steps below.
- Sign in to GitHub.
- Navigate to the repository at https://github.com/DaveyJH/backgammon-back-end, click <> Code ▾ and copy the URL provided.
- Proceed to your chosen method of cloning a repo and provide the copied URL when needed.
I have a number of extensions installed to aid my development in VSCode. The steps below work for me, but alternative methods are available. Please consult the relevant docs for various approaches.
- Open a
bash
terminal within VSCode and navigate to a parent directory for your repository.
- Enter
git clone https://github.com/DaveyJH/backgammon-back-end.git
(the URL copied from GitHub). This will clone the repository into a new directory calledbackgammon-back-end
.
- Enter the command
cd backgammon-back-end && code . -r
to open the repository in the current VSCode window.
- Create and activate a virtual environment within the directory. I use
venv
for this viapython -m venv .venv && . .venv/scripts/activate
.
- Install the requirements for the repository using
pip install -r requirements.txt
.
- Ensure you have created the necessary
env
variables in a.env
file.
As mentioned above in the Python packages section, I
utilized a .env
file for my environment variables. If you intend to run this
application from a clone of the repository, you will need your own file with the
following key-value pairs:
key | value |
---|---|
SECRET_KEY | a secret key - this can be generated using python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' within your terminal |
HOST | the IP address or host name where the server will be run |
CLOUDINARY_URL | a Cloudinary account API Environment variable, available from a Cloudinary account dashboard |
DEVELOPMENT | optional configures the authentication method of the django rest framework API and connects the django project to an db.sqlite3 instance for use in a development environment |
DEV | optional configures the response format of the django rest framework API to allow a front-end interactive representation |
CLIENT_ORIGIN_DEV | optional allows cross-site http requests from an alternate URL to the server |
Additional key-value pairs are required for a deployed application. Please see the section below for more detail
The API is deployed on Heroku; the steps below detail the process to achieve this.
- Run
pip freeze > requirements.txt
to ensure all Python packages are available for the production build. - Ensure you have a Procfile with the following content:
release: python manage.py makemigrations && python manage.py migrate web: gunicorn backgammon_drf.wsgi
- Navigate to your Heroku dashboard
- Click "New" and select "Create new app".
- Input a meaningful name for your app and choose the region best suited to
your location.
- Select "Settings" from the tabs.
- Click "Reveal Config Vars".
- Input the required key-value pairs from the
.env
file. Ensure DEBUG and DEVELOPMENT are not included. Keys to include:SECRET_KEY
(generate a new key for production)CLOUDINARY_URL
HOST
(for this value, right-click "Open app" and copy the link address, deleting "https://
")DATABASE_URL
(see Production Database section)CLIENT_ORIGIN
(production - this will be the URL of your front-end app)CLIENT_ORIGIN_DEV
(development - this will be the URL of your front-end development server)
- Select "Deploy" from the tabs.
- Select "GitHub - Connect to GitHub" from deployment methods.
- Click "Connect to GitHub" in the created section.
- Search for the GitHub repository by name.
- Click to connect to the relevant repo.
- Either click
Enable Automatic Deploys
for automatic deploys, orDeploy Branch
to deploy manually. Manually deployed branches will need re-deploying each time the repo is updated.
- Click
View
to view the deployed site.
The live site can also be accessed from your repo in GitHub from the Deployments section of the repo.
- The default profile image is Two dice image by rawpixel.com on Freepik
- The default game image was created by me in Microsoft Paint! (⌐■_■)
- The ERD diagram was made using drawio
Thanks to @CluelessBiker, my mentor for the project, as she helped me focus on the MVP and gave great support regarding the project planning process.
As always, the wonderful staff at Code Institute for introducing me to this framework and providing me with the foundations to start developing this API.
I am pleased with how quickly this project has gone together. I would enjoy working with the framework again and would approach things with a TDD mindset!