mybuddy/README.md

535 lines
17 KiB
Markdown
Raw Normal View History

2018-04-17 13:19:06 +00:00
<img src="babybuddy/static_src/logo/icon.png" height="150" align="left">
2018-04-16 12:45:23 +00:00
2017-10-22 20:00:29 +00:00
# Baby Buddy
[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause)
[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/babybuddy/Lobby)
2020-01-19 16:49:45 +00:00
A buddy for babies! Helps caregivers track sleep, feedings, diaper changes,
tummy time and more to learn about and predict baby's needs without (*as much*)
guess work.
![Baby Buddy desktop view](screenshot.png)
![Baby Buddy mobile views](screenshot_mobile.png)
2017-10-22 20:00:29 +00:00
2017-11-15 18:08:13 +00:00
**Table of Contents**
- [Demo](#demo)
- [Deployment](#deployment)
- [AWS Elastic Beanstalk](#aws-elastic-beanstalk)
- [Docker](#docker)
- [Heroku](#heroku)
2017-11-20 16:12:09 +00:00
- [Manual](#manual)
- [Configuration](#configuration)
2019-05-04 13:05:36 +00:00
- [Languages](#languages)
2017-12-05 21:46:15 +00:00
- [API](#api)
- [Authentication](#authentication)
2017-12-06 00:43:57 +00:00
- [`GET` Method](#get-method)
- [`OPTIONS` Method](#options-method)
- [`POST` Method](#post-method)
- [Contributing](#contributing)
2017-11-15 18:08:13 +00:00
2017-10-23 09:25:56 +00:00
## Demo
2017-11-30 00:28:43 +00:00
A [demo of Baby Buddy](http://demo.baby-buddy.net) is available on Heroku.
The demo instance resets every hour. Login credentials are:
- Username: `admin`
- Password: `admin`
2017-10-23 09:25:56 +00:00
2017-10-24 00:33:28 +00:00
## Deployment
The default user name and password for Baby Buddy is `admin`/`admin`. For any
2017-11-30 00:28:43 +00:00
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](#configuration) for detailed information.
2017-11-15 18:08:13 +00:00
### AWS Elastic Beanstalk
2017-10-24 00:33:28 +00:00
A basic [Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/)
configuration is provided in `.ebextensions/babybuddy.config`. The steps
2020-01-19 16:49:45 +00:00
below are a rough guide to deployment. See [Working with Python](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-apps.html)
for detailed information.
2017-10-24 00:33:28 +00:00
1. Clone/download the Baby Buddy repo
2017-11-15 18:08:13 +00:00
2020-02-07 06:16:57 +00:00
git clone https://github.com/babybuddy/babybuddy.git
1. Enter the cloned/downloaded directory
cd babybuddy
1. Set (at least) the `SECRET_KEY` environment value in `.ebextensions/babybuddy.config`
*See [Configuration](#configuration) for other settings that can be
controlled by environment variables.
1. [Create an IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) in AWS with EB, EC2, RDS and S3 privileges.
1. Initialize the Elastic Bean application (using the IAM user from the previous step)
eb init -p python-3.6
1. Create/deploy the environment! :rocket:
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).
2017-11-15 18:08:13 +00:00
### Docker
A Docker deployment requires [Docker Engine](https://www.docker.com/) v18.06.0+
and [Docker Compose](https://docs.docker.com/compose/) v1.22.0+ to create two
containers: one for the database and one for the application.
2017-12-01 03:33:51 +00:00
The example `docker-compose.example.yml` file provided in this repository is
intended for production deployments. Baby Buddy is deployed to Docker Hub as
2020-02-07 19:55:36 +00:00
[babybuddy/babybuddy](https://hub.docker.com/r/babybuddy/babybuddy) so this is
the only file needed for a Docker deployment with Docker Compose.
1. Copy the contents of `docker-compose.example.yml` as `docker-compose.yml`
and set, at least, the `ALLOWED_HOSTS` and `SECRET_KEY` variables under
`services:app:environment`.
*See [Configuration](#configuration) for other settings that can be
controlled by environment variables.*
1. Build/run the application
docker-compose up -d
1. Initialize the database *(first run/after migrations updates)*
docker-compose exec app python manage.py migrate
1. Initialize cache table *(first run/after cache configuration updates)*
docker-compose exec app python manage.py createcachetable
The app should now be locally available at
[http://127.0.0.1:8000](http://127.0.0.1:8000). See
2020-01-19 16:49:45 +00:00
[Docker's "Get Started" documentation](https://docs.docker.com/get-started/)
for detailed information about deployment methods with Docker.
### Heroku
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
For manual deployments to Heroku without using the deploy button, make sure to
create the following settings before pushing:
heroku config:set DJANGO_SETTINGS_MODULE=babybuddy.settings.heroku
heroku config:set SECRET_KEY=<CHANGE TO SOMETHING RANDOM>
heroku config:set DISABLE_COLLECTSTATIC=1
2020-01-31 04:46:23 +00:00
heroku config:set TIME_ZONE=<YOUR DESIRED TIMEZONE>
See [Configuration](#configuration) for other settings that can be controlled
2017-11-30 00:28:43 +00:00
by `heroku config:set`.
2020-01-31 04:46:23 +00:00
And after an initial push, execute the following commands:
heroku run python manage.py migrate
heroku run python manage.py createcachetable
2017-11-20 16:12:09 +00:00
### Manual
2018-10-21 15:19:57 +00:00
There are many ways to deploy Baby Buddy manually to any server/VPS. The basic
requirements are Python, a web server, an application server, and a database.
2017-11-20 16:12:09 +00:00
#### Requirements
- Python 3.6+, pip, pipenv
2017-11-20 16:12:09 +00:00
- Web server ([nginx](http://nginx.org/), [Apache](http://httpd.apache.org/), etc.)
- Application server ([uwsgi](http://projects.unbit.it/uwsgi), [gunicorn](http://gunicorn.org/), etc.)
- Database ([sqlite](https://sqlite.org/), [Postgres](https://www.postgresql.org/), [MySQL](https://www.mysql.com/), etc.)
#### Example deployment
*This example assumes a 512MB VPS instance with Ubuntu 18.04.* It uses
Python 3.6+, nginx, uwsgi and sqlite and should be sufficient for a few users
2017-11-20 16:12:09 +00:00
(e.g. two parents and 1+ child).
2018-10-21 15:19:57 +00:00
1. Install system packages
2017-11-20 16:12:09 +00:00
2018-05-08 04:54:21 +00:00
sudo apt-get install python3 python3-pip nginx uwsgi uwsgi-plugin-python3 git libopenjp2-7-dev
2017-11-20 16:12:09 +00:00
2018-05-05 19:29:02 +00:00
1. Default python3 to python for this session
2018-05-04 09:20:31 +00:00
alias python=python3
2017-11-20 16:12:09 +00:00
1. Install pipenv
sudo -H pip3 install pipenv
2017-11-20 16:12:09 +00:00
1. Set up directories and files
sudo mkdir /var/www/babybuddy
sudo chown user:user /var/www/babybuddy
mkdir -p /var/www/babybuddy/data/media
2020-02-07 06:16:57 +00:00
git clone https://github.com/babybuddy/babybuddy.git /var/www/babybuddy/public
2017-11-20 16:12:09 +00:00
1. Move in to the application folder
cd /var/www/babybuddy/public
1. Set pipenv to install locally.
export PIPENV_VENV_IN_PROJECT=1
2017-11-20 16:12:09 +00:00
2018-10-21 15:19:57 +00:00
1. Initiate and enter the Python environment
2017-11-20 16:12:09 +00:00
2018-10-21 15:19:57 +00:00
pipenv install --three
pipenv shell
**Note:** Python dependencies are locked on x86-64 architecture. Installs
on other architectures (like Raspberry Pi's ARM) may result in a
``THESE PACKAGES DO NOT MATCH THE HASHES FROM Pipfile.lock!`` error. Add
the ``--skip-lock`` flag to the above command to suppress this error
(i.e.: ``pipenv install --three --dev --skip-lock``).
2017-11-20 16:12:09 +00:00
1. Create a production settings file and set the ``SECRET_KEY`` and ``ALLOWED_HOSTS`` values
cp babybuddy/settings/production.example.py babybuddy/settings/production.py
editor babybuddy/settings/production.py
1. Initiate the application
export DJANGO_SETTINGS_MODULE=babybuddy.settings.production
2018-10-21 15:19:57 +00:00
python manage.py migrate
python manage.py createcachetable
2017-11-20 16:12:09 +00:00
1. Set appropriate permissions on the database and data folder
sudo chown -R www-data:www-data /var/www/babybuddy/data
2017-11-20 16:12:09 +00:00
sudo chmod 640 /var/www/babybuddy/data/db.sqlite3
sudo chmod 750 /var/www/babybuddy/data
1. Create and configure the uwsgi app
sudo editor /etc/uwsgi/apps-available/babybuddy.ini
2017-11-20 16:12:09 +00:00
Example config:
2017-11-20 16:12:09 +00:00
[uwsgi]
plugins = python3
project = babybuddy
base_dir = /var/www/babybuddy
chdir = %(base_dir)/public
virtualenv = %(chdir)/.venv
2017-11-20 16:12:09 +00:00
module = %(project).wsgi:application
env = DJANGO_SETTINGS_MODULE=%(project).settings.production
master = True
vacuum = True
See the [uWSGI documentation](http://uwsgi-docs.readthedocs.io/en/latest/)
2017-11-20 16:12:09 +00:00
for more advanced configuration details.
2018-05-08 04:50:55 +00:00
1. Symlink config and restart uWSGI:
2018-05-07 21:02:03 +00:00
sudo ln -s /etc/uwsgi/apps-available/babybuddy.ini /etc/uwsgi/apps-enabled/babybuddy.ini
sudo service uwsgi restart
2017-11-20 16:12:09 +00:00
1. Create and configure the nginx server
sudo editor /etc/nginx/sites-available/babybuddy
2017-11-20 16:12:09 +00:00
Example config:
upstream babybuddy {
server unix:///var/run/uwsgi/app/babybuddy/socket;
}
2017-11-20 16:12:09 +00:00
server {
listen 80;
server_name babybuddy.example.com;
2017-11-20 16:12:09 +00:00
location / {
uwsgi_pass babybuddy;
include uwsgi_params;
}
2018-10-21 15:19:57 +00:00
location /media {
alias /var/www/babybuddy/data/media;
}
2017-11-20 16:12:09 +00:00
}
See the [nginx documentation](https://nginx.org/en/docs/) for more advanced
configuration details.
2018-05-08 04:51:26 +00:00
1. Symlink config and restart NGINX:
sudo ln -s /etc/nginx/sites-available/babybuddy /etc/nginx/sites-enabled/babybuddy
sudo service nginx restart
2017-11-20 16:12:09 +00:00
1. That's it (hopefully)! :tada:
## 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`](#allowed_hosts)
- [`ALLOW_UPLOADS`](#allow_uploads)
- [`AWS_ACCESS_KEY_ID`](#aws_access_key_id)
- [`AWS_SECRET_ACCESS_KEY`](#aws_secret_access_key)
- [`AWS_STORAGE_BUCKET_NAME`](#aws_storage_bucket_name)
- [`DEBUG`](#debug)
- [`NAP_START_MAX`](#nap_start_max)
- [`NAP_START_MIN`](#nap_start_min)
- [`SECRET_KEY`](#secret_key)
- [`TIME_ZONE`](#time_zone)
### `ALLOWED_HOSTS`
2017-11-30 00:28:43 +00:00
*Default: * (any)*
This option may be set to a single host or comma-separated list of hosts
2017-11-30 00:28:43 +00:00
(without spaces). This should *always* be set to a specific host or hosts in
production deployments.
2020-01-19 16:49:45 +00:00
See also: [Django's documentation on the ALLOWED_HOSTS setting](https://docs.djangoproject.com/en/3.0/ref/settings/#allowed-hosts)
### `ALLOW_UPLOADS`
2017-11-30 00:28:43 +00:00
*Default: True*
Whether or not to allow uploads (e.g. of Child photos). For some deployments
2020-01-19 16:49:45 +00:00
(AWS, Heroku) this setting will default to False due to the lack of available
persistent storage.
### `AWS_ACCESS_KEY_ID`
*Default: None*
Required to access your AWS S3 bucket, should be uniquely generated per bucket
for security.
See also: [`AWS_STORAGE_BUCKET_NAME`](#aws_storage_bucket_name)
### `AWS_SECRET_ACCESS_KEY`
*Default: None*
Required to access your AWS S3 bucket, should be uniquely generated per bucket
for security.
See also: [`AWS_STORAGE_BUCKET_NAME`](#aws_storage_bucket_name)
### `AWS_STORAGE_BUCKET_NAME`
*Default: None*
If you would like to use AWS S3 for storage on ephemeral storage platforms like
Heroku you will need to create a bucket and add it's name. See django-storages'
2020-01-19 16:49:45 +00:00
[Amazon S3 documentation](https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html).
### `DEBUG`
2017-11-30 00:28:43 +00:00
*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.
2020-01-19 16:49:45 +00:00
See also [Django's documentation on the DEBUG setting](https://docs.djangoproject.com/en/3.0/ref/settings/#debug).
### `NAP_START_MAX`
2017-11-30 00:28:43 +00:00
*Default: 18:00*
2017-11-30 00:28:43 +00:00
The maximum *start* time (in the instance's time zone) before which a sleep
2020-01-19 16:49:45 +00:00
entry is consider a nap. Expects the 24-hour format %H:%M.
### `NAP_START_MIN`
2017-11-30 00:28:43 +00:00
*Default: 06:00*
2017-11-30 00:28:43 +00:00
The minimum *start* time (in the instance's time zone) after which a sleep
2020-01-19 16:49:45 +00:00
entry is considered a nap. Expects the 24-hour format %H:%M.
### `SECRET_KEY`
2017-11-30 00:28:43 +00:00
*Default: None*
A random, unique string must be set as the "secret key" before Baby Buddy can
2017-11-30 00:28:43 +00:00
be deployed and run.
2020-01-19 16:49:45 +00:00
See also [Django's documentation on the SECRET_KEY setting](https://docs.djangoproject.com/en/3.0/ref/settings/#secret-key).
### `TIME_ZONE`
*Default: Etc/UTC*
2017-11-30 00:28:43 +00:00
The time zone to use for the instance. See [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
for all possible values.
2019-05-04 13:05:36 +00:00
## Languages
2020-01-19 16:49:45 +00:00
Baby Buddy includes translation support as of v1.2.2. Language can be set on a
per-user basis from the user settings page (`/user/settings/`). See
[CONTRIBUTING.md](CONTRIBUTING.md#translation) for information about how to
create/update translations.
2019-05-04 13:05:36 +00:00
### Available languages
2020-01-19 16:49:45 +00:00
2019-05-04 13:05:36 +00:00
:us: English (U.S.) *(base)*
:fr: French
2019-06-07 14:38:59 +00:00
:de: German
2020-01-17 03:14:22 +00:00
:mexico: :es: Spanish
2019-05-04 13:05:36 +00:00
:sweden: Swedish
2020-01-17 03:42:49 +00:00
:tr: Turkish
2017-12-05 21:46:15 +00:00
## API
2020-01-19 16:49:45 +00:00
Baby Buddy uses the [Django REST Framework](https://www.django-rest-framework.org/)
2017-12-05 21:46:15 +00:00
(DRF) to provide a REST API.
2017-12-06 00:43:57 +00:00
The only requirement for (most) requests is that the `Authorization` header is
set as described in the [Authentication](#authentication) section. The one
2017-12-06 00:43:57 +00:00
exception is the `/api` endpoint, which lists all available endpoints.
Currently, the following endpoints are available for `GET`, `OPTIONS`, and
2017-12-06 00:43:57 +00:00
`POST` requests:
- `/api/children/`
- `/api/changes/` (Diaper Changes)
- `/api/feedings/`
- `/api/notes/`
- `/api/sleep/`
- `/api/temperature/`
2017-12-06 00:43:57 +00:00
- `/api/timers/`
- `/api/tummy-times/`
- `/api/weight/`
2017-12-05 21:46:15 +00:00
### Authentication
2020-01-19 16:49:45 +00:00
By default, the [TokenAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication)
and [SessionAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication)
2017-12-05 21:46:15 +00:00
classes are enabled. Session authentication covers local API requests made by
the application itself. Token authentication allows external requests to be
2017-12-05 21:46:15 +00:00
made.
:exclamation: **In a production environment, token authentication should only
2017-12-05 21:46:15 +00:00
be used for API calls to an `https` endpoint.** :exclamation:
Each user is automatically assigned an API key that can be used for token
2017-12-05 21:46:15 +00:00
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
2017-12-05 21:46:15 +00:00
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.
2017-12-06 00:43:57 +00:00
### `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`
2017-12-06 00:43:57 +00:00
field of the `OPTIONS` response for specific endpoints.
2017-12-05 21:46:15 +00:00
2017-12-06 00:43:57 +00:00
#### Response
2017-12-05 21:46:15 +00:00
Returns JSON data in the response body in the following format:
{
"count":<int>,
"next":<url>,
"previous":<url>,
"results":[{...}]
}
2017-12-05 21:46:15 +00:00
- `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.
2017-12-06 00:43:57 +00:00
### `OPTIONS` Method
2017-12-05 21:46:15 +00:00
2017-12-06 00:43:57 +00:00
#### 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
2017-12-06 00:43:57 +00:00
following example describes the `/api/children` endpoint:
2017-12-05 21:46:15 +00:00
{
"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"
},
[...]
}
2017-12-06 00:43:57 +00:00
},
"filters": [
"first_name",
"last_name",
"slug"
]
2017-12-05 21:46:15 +00:00
}
2017-12-06 00:43:57 +00:00
### `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
2017-12-06 00:43:57 +00:00
`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
2017-12-06 00:43:57 +00:00
formats.
#### Response
2017-12-05 21:46:15 +00:00
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
2020-01-19 16:49:45 +00:00
the general string `non_field_errors` (usually when validation involves
2017-12-05 21:46:15 +00:00
multiple fields).
## Contributing
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed
2020-01-19 16:49:45 +00:00
information about how to contribute to Baby Buddy.