a9dfe686db | ||
---|---|---|
.ebextensions | ||
api | ||
babybuddy | ||
core | ||
dashboard | ||
etc | ||
gulpfile.js | ||
reports | ||
.coveragerc | ||
.gitignore | ||
.travis.yml | ||
Dockerfile | ||
LICENSE | ||
Pipfile | ||
Pipfile.lock | ||
Procfile | ||
README.md | ||
app.json | ||
boxfile.yml | ||
docker-compose.yml | ||
docker.env.example | ||
manage.py | ||
package-lock.json | ||
package.json | ||
screenshot.png | ||
screenshot_mobile.png |
README.md
Baby Buddy
A buddy for babies! Helps caregivers track sleep, feedings, diaper changes, and tummy time to learn about and predict baby's needs without (as much) guess work.
Table of Contents
Demo
A demo of Baby Buddy is available on Heroku. The demo instance resets every hour. Login credentials are:
- Username:
admin
- Password:
admin
Deployment
The default user name and password for Baby Buddy is admin
/admin
. For any
deployment, log in and change the default admin password immediately.
Many of Baby Buddy's configuration settings can be controlled using environment variables - see Configuration for detailed information.
AWS Elastic Beanstalk
A basic Elastic Beanstalk
configuration is provided in .ebextensions/babybuddy.config
. The steps
below are a rough guide to deployment. See Working with Python
for detailed information.
-
Clone/download the Baby Buddy repo
git clone https://github.com/cdubz/babybuddy.git
-
Enter the cloned/downloaded directory
cd babybuddy
-
Change the
SECRET_KEY
value to something random in.ebextensions/babybuddy.config
-
Create an IAM user in AWS with EB, EC2, RDS and S3 privileges.
-
Initialize the Elastic Bean application (using the IAM user from the previous step)
eb init -p python-3.6
-
Create/deploy the environment! 🚀
eb create -db -db.engine postgres
The create command will also do an initial deployment. Run eb deploy
to
redeploy the app (e.g. if there are errors or settings are changed).
Docker
A Docker deploy requires Docker and Docker Compose to create two containers - one for the database and one for the application. Baby Buddy uses a multi-stage build, which requires Docker version 17.05 or newer.
-
Copy the
docker.env.example
todocker.env
and set theALLOWED_HOSTS
andSECRET_KEY
variables withincp docker.env.example docker.env editor docker.env
See Configuration for other settings that can be controlled by environment variables added to the
docker.env
file. -
Build/run the application
docker-compose up -d
-
Initialize the database (first run/after updates)
docker-compose exec app python manage.py migrate
-
Initialize static assets (first run/after updates)
docker-compose exec app python manage.py collectstatic
The app should now be locally available at http://127.0.0.1:8000. See Get Started, Part 6: Deploy your app for detailed information about how to deployment methods with Docker.
Nanobox
An example Nanobox configuration, boxfile.yml
, is
provided with Baby Buddy. The steps below are a rough guide to deployment. See
Create and Deploy a Custom Django App
for detailed information about Nanobox's deployment and configuration process.
-
Clone/download the Baby Buddy repo
git clone https://github.com/cdubz/babybuddy.git
-
Enter the cloned/downloaded directory
cd babybuddy
-
Add the
SECRET_KEY
andDJANGO_SETTINGS_MODULE
environment variablesnanobox evar add DJANGO_SETTINGS_MODULE=babybuddy.settings.nanobox nanobox evar add SECRET_KEY=<CHANGE TO SOMETHING RANDOM>
See Configuration for other settings that can be controlled by environment variables.
-
Deploy! 🚀
nanobox deploy
Heroku
For manual deployments to Heroku without using the deploy button, make sure to
create two settings before pushing using heroku config:set
:
heroku config:set DJANGO_SETTINGS_MODULE=babybuddy.settings.heroku
heroku config:set SECRET_KEY=<CHANGE TO SOMETHING RANDOM>
See Configuration for other settings that can be controlled
by heroku config:set
.
Manual
There are a number of ways to deploy Baby Buddy manually to any server/VPS. The application can run fine in low memory (below 1GB) situations, however a 32-bit operating system is recommended in such cases. This is primarily because the build process can be memory intensive and cause excessive memory usage on 64-bit systems. If all fails, assets can be built on a local machine and then uploaded to a server.
Requirements
- Python 3.4+, pip, pipenv
- Web server (nginx, Apache, etc.)
- Application server (uwsgi, gunicorn, etc.)
- Database (sqlite, Postgres, MySQL, etc.)
- NodeJS 8.x and NPM 5.x (for building assets)
- Gulp (for building assets)
Example deployment
This example assumes a 512MB VPS instance with Ubuntu 16.04 x32. It uses Python 3.x, nginx, uwsgi and sqlite and should be sufficient for a few users (e.g. two parents and 1+ child).
-
Install Python 3.x, pip, nginx and uwsgi
sudo apt-get install python3 python3-pip nginx uwsgi uwsgi-plugin-python3
-
Install pipenv
sudo -H pip install pipenv
-
Install NodeJS, NPM and Gulp
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs sudo npm install -g gulp-cli
-
Set up directories and files
sudo mkdir /var/www/babybuddy sudo chown user:user /var/www/babybuddy mkdir -p /var/www/babybuddy/data/media sudo chown -R www-data:www-data /var/www/babybuddy/data git clone https://github.com/cdubz/babybuddy.git /var/www/babybuddy/public
-
Move in to the application folder
cd /var/www/babybuddy/public
-
Initiate the Python environment
pipenv --three --dev
-
Build static assets
npm install gulp build
-
Create a production settings file and set the
SECRET_KEY
andALLOWED_HOSTS
valuescp babybuddy/settings/production.example.py babybuddy/settings/production.py editor babybuddy/settings/production.py
-
Initiate the application
export DJANGO_SETTINGS_MODULE=babybuddy.settings.production gulp collectstatic gulp migrate
-
Set appropriate permissions on the database and data folder
sudo chown www-data:www-data /var/www/babybuddy/data/db.sqlite3 sudo chmod 640 /var/www/babybuddy/data/db.sqlite3 sudo chmod 750 /var/www/babybuddy/data
-
Create and configure the uwsgi app
sudo editor /etc/uwsgi/apps-available/babybuddy.ini sudo ln -s /etc/uwsgi/apps-available/babybuddy.ini /etc/uwsgi/apps-enabled/babybuddy.ini sudo service uwsgi restart
Example config:
[uwsgi] plugins = python3 project = babybuddy base_dir = /var/www/babybuddy virtualenv = /home/user/.local/share/virtualenvs/babybuddy-XXXXXXXX chdir = %(base_dir)/babybuddy module = %(project).wsgi:application env = DJANGO_SETTINGS_MODULE=%(project).settings.production master = True vacuum = True
See the uWSGI documentation for more advanced configuration details.
Note: Find the location of the pipenv virtual environment with the command
pipenv --venv
. -
Create and configure the nginx server
sudo vim /etc/nginx/sites-available/babybuddy sudo ln -s /etc/nginx/sites-available/babybuddy /etc/nginx/sites-enabled/babybuddy sudo service nginx restart
Example config:
upstream babybuddy { server unix:///var/run/uwsgi/app/babybuddy/socket; } server { listen 80; server_name babybuddy.example.com; location / { uwsgi_pass babybuddy; include uwsgi_params; } }
See the nginx documentation for more advanced configuration details.
-
That's it (hopefully)! 🎉
Configuration
Environment variables can be used to define a number of configuration settings.
Baby Buddy will check the application directory structure for an .env
file or
take these variables from the system environment. System environment variables
take precedence over the contents of an .env
file.
ALLOWED_HOSTS
Default: * (any)
This option may be set to a single host or comma-separated list of hosts (without spaces). This should always be set to a specific host or hosts in production deployments.
See also: Django's documentation on the ALLOWED_HOSTS setting
ALLOW_UPLOADS
Default: True
Whether or not to allow uploads (e.g. of Child photos). For some deployments (AWS, Heroku, Nanobox) this setting will default to False due to the lack of available persistent storage.
DEBUG
Default: False
When in debug mode, Baby Buddy will print much more detailed error information for exceptions. This setting should be False in production deployments.
See also Django's documentation on the DEBUG setting.
NAP_START_MAX
Default: 18:00
The maximum start time (in the instance's time zone) before which a sleep entry is consider a nap. Expects the format %H:%M.
NAP_START_MIN
Default: 06:00
The minimum start time (in the instance's time zone) after which a sleep entry is considered a nap. Expects the format %H:%M.
SECRET_KEY
Default: None
A random, unique string must be set as the "secret key" before Baby Buddy can be deployed and run.
See also Django's documentation on the SECRET_KEY setting.
TIME_ZONE
Default: Etc/UTC
The time zone to use for the instance. See List of tz database time zones for all possible values.
API
Baby Buddy uses the Django REST Framework (DRF) to provide a REST API.
The only requirement for (most) requests is that the Authorization
header is
set as described in the Authentication section. The one
exception is the /api
endpoint, which lists all available endpoints.
Currently, the following endpoints are available for GET
, OPTIONS
, and
POST
requests:
/api/children/
/api/changes/
(Diaper Changes)/api/feedings/
/api/notes/
/api/sleep/
/api/timers/
/api/tummy-times/
/api/weight/
Authentication
By default, the TokenAuthentication and SessionAuthentication classes are enabled. Session authentication covers local API requests made by the application itself. Token authentication allows external requests to be made.
❗ In a production environment, token authentication should only
be used for API calls to an https
endpoint. ❗
Each user is automatically assigned an API key that can be used for token
authentication. This key can be found on the User Settings page for the logged
in the user. To use a key for an API request, set the request Authorization
header to Token <user-key>
. E.g.
Authorization: Token 2h23807gd72h7hop382p98hd823dw3g665g56
If the Authorization
header is not set or the key is not valid, the API will
return 403 Forbidden
with additional details in the response body.
GET
Method
Request
The limit
and offset
request parameters can be used to limit
and offset the results set respectively. For example, the following request
will return five diaper changes starting from the 10th diaper change entry:
curl -X GET 'https://[...]/api/changes/?limit=5&offset=10' -H 'Authorization: Token [...]'
{
"count": <int>,
"next": "https://[...]/api/changes/?limit=5&offset=15",
"previous": "https://[...]/api/changes/?limit=5&offset=5",
"results": [...]
}
Field-based filters for specific endpoints can be found the in the filters
field of the OPTIONS
response for specific endpoints.
Response
Returns JSON data in the response body in the following format:
{
"count":<int>,
"next":<url>,
"previous":<url>,
"results":[{...}]
}
count
: Total number of records (in the database, not just the response).next
: URL for the next set of results.previous
: URL for the previous set of results.results
: An array of the results of the request.
OPTIONS
Method
Request
All endpoints will respond to an OPTIONS
request with detailed information
about the endpoint's purpose, parameters, filters, etc.
Response
Returns JSON data in the response body describing the endpoint, available
options for POST
requests, and available filters for GET
requests. The
following example describes the /api/children
endpoint:
{
"name": "Child List",
"renders": [
"application/json",
"text/html"
],
"parses": [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"
],
"actions": {
"POST": {
"id": {
"type": "integer",
"required": false,
"read_only": true,
"label": "ID"
},
[...]
}
},
"filters": [
"first_name",
"last_name",
"slug"
]
}
POST
Method
Request
To add new entries for a particular endpoint, send a POST
request with the
entry data in JSON format in the request body. The Content-Type
header for
POST
request must be set to application/json
.
Regular sanity checks will be performed on relevant data. See the OPTIONS
response for a particular endpoint for details on required fields and data
formats.
Response
Returns JSON data in the response body describing the added/updated instance or error details if errors exist. Errors are keyed by either the field in error or the general string "non_field_errors" (usually when validation incorporates multiple fields).
Development
Requirements
- Python 3.4+, pip, pipenv
- NodeJS 8.x and NPM 5.x
- Gulp
Installation
-
Install pipenv
pip install pipenv
-
Install required Python packages, including dev packages
pipenv install --dev
-
Install Gulp CLI
npm install -g gulp-cli
-
Install required Node packages
npm install
-
Set, at least, the
DJANGO_SETTINGS_MODULE
environment variableexport DJANGO_SETTINGS_MODULE=babybuddy.settings.development
This process will differ based on the host OS. The above example is for Linux-based systems. See Configuration for other settings and methods for defining them.
-
Migrate the database
gulp migrate
-
Build assets and run the server
gulp
This command will also watch for file system changes to rebuild assets and restart the server as needed.
Open http://127.0.0.1:8000 and log in with the default
user name and password (admin
/admin
).
Gulp commands
Baby Buddy's Gulp commands are defined and configured by files in the
gulpfile.js
folder. Django's management commands are defined
in the babybuddy/management/commands
folder.
gulp
gulp build
gulp collectstatic
gulp compress
gulp coverage
gulp extras
gulp fake
gulp lint
gulp makemigrations
gulp migrate
gulp reset
gulp runserver
gulp scripts
gulp styles
gulp test
gulp
Executes the build
and watch
commands and runs Django's development server.
build
Creates all script, style and "extra" assets and places them in the
babybuddy/static
folder.
collectstatic
Executes Django's collectstatic
management task. This task relies on files in
the babybuddy/static
folder, so generally gulp build
should be run before
this command for production deployments. Gulp also passes along
non-overlapping arguments for this command, e.g. --no-input
.
compress
❗ DEPRECATED ❗
Compresses built scripts and styles. This command has been deprecated in favor
of WhiteNoise's compression as part of the collectstatic
command.
coverage
Create a test coverage report. See .coveragerc
for default
settings information.
extras
Copies "extra" files (fonts, images and server root contents) to the build folder.
fake
Adds some fake data to the database. By default, fake
creates one child and
31 days of random data. Use the --children
and --days
flags to change the
default values, e.g. gulp fake --children 5 --days 7
to generate five fake
children and seven days of data for each.
lint
Executes Python and SASS linting for all relevant source files.
makemigrations
Executes Django's makemigrations
management task. Gulp also passes along
non-overlapping arguments for this command.
migrate
Executes Django's migrate
management task. In addition to migrating the
database, this command creates the default admin
user. Gulp also passes along
non-overlapping arguments for this command.
reset
Resets the database to a default state with one fake child and 31 days of fake data.
runserver
Executes Django's runserver
management task. Gulp also passes along
non-overlapping arguments for this command.
scripts
Builds and combines relevant application scripts. Generally this command does
not need to be executed independently - see the build
command.
styles
Builds and combines SASS styles in to CSS files. Generally this command does
not need to be executed independently - see the build
command.
test
Executes Baby Buddy's suite of tests.
Gulp also passes along non-overlapping arguments for this command, however
individual tests cannot be run with this command. python manage.py test
can be
used for individual test execution.