This project is the Device Registry Service, an example REST API web service for registering smart devices. It is written in Python using Flask, and it stores data in a SQLite database. Note that it is not a "real" web service, but rather one to use as a teaching example. This project also contains integration tests to test the REST API endpoints.
What does the Device Registry Service do? It stores records for all smart devices a user owns in one central place. A home could have multiple kinds of smart devices: WiFi routers, voice assistants, thermostats, light switches, and even appliances. This service stores information like name, location, type, model, and serial number for each device. Its API enables callers to practice CRUD (Create, Retrieve, Update, Delete) operations. In theory, a dashboard or monitoring app could use a registry service like this to quickly access devices.
Note: I originally developed this project for my book, The Way To Test Software. However, during development, I decided to rewrite this project using FastAPI. The repository for the new FastAPI project is device-registry-service.
The Device Registry Service is designed to run on your local machine. It should run on any operating system (Windows, macOS, Linux). To install it:
- Install Python 3.8 or higher.
- Clone the GitHub repository on to your local machine.
- Install dependency packages from the command line:
- Change directory to the project's root directory.
- Run
pip install -r requirements.txt
to install all dependencies.
The Device Registry Service is written using Flask.
Before running it from the command line,
set the FLASK_APP
environment variable to the name of the app's main module, registry
.
- Windows:
set FLASK_APP=registry
- macOS and Linux:
export FLASK_APP=registry
To run the web service, run flask run
.
You should see output like this from the command line:
$ flask run
* Serving Flask app 'registry' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
When running, the web service can be accessed at http://127.0.0.1:5000/
(the address printed by the flask run
output).
If you load that address in a web browser, you should see the status for the REST API service.
Out of the box, the Device Registry Service uses a SQLite database. SQLite is not meant to be a high-scale production database, but it works just fine for this small example web service.
There are two ways to manage the app's database:
- Testing: create a fresh, empty, in-memory SQLite database every time
flask run
is launched. - Development: create a SQLite database file named
registry_data.sqlite
with a few prepopulated devices.
Set the FLASK_CONFIG
environment variable to chose which database to use:
- For the Testing database, set
FLASK_CONFIG
totesting
. - For the Development database, set
FLASK_CONFIG
todevelopment
.
If FLASK_CONFIG
is not set, then the app uses the Testing database by default.
If you want to use the Development database,
you must create it before running the Flask app.
Run flask init-db
to create the initial registry_data.sqlite
file in the project's root directory.
Then, set FLASK_CONFIG
to development
and run flask run
to run the app with this database.
Any changes will persist, even after the app is restarted.
The Device Registry Service stores all its configuration options in config.py
.
The following configuration options have default values,
but they may optionally be overridden using environment variables:
SECRET_KEY
: the secret key used for app securityAUTH_USERNAME1
: the username for user 1AUTH_PASSWORD1
: the password for user 1AUTH_USERNAME2
: the username for user 2AUTH_PASSWORD2
: the password for user 2AUTH_TOKEN_EXPIRATION
: the expiration time in seconds for authentication tokens
Warning: Overriding these options is not recommended for most cases.
REST API integration tests are located in the tests
directory.
They are written using pytest.
The tests are not unit tests -
they send requests to a live version of the Device Registry Service.
If you try to run them without the following setup steps, they will fail.
The tests require a configuration file that specifies the web service's base URL and available users.
In the tests/integration
directory, create a file named inputs.json
with the following contents:
{
"base_url": "<base-url>",
"users" : [
{
"username": "<user1-username>",
"password": "<user1-password>"
},
{
"username": "<user2-username>",
"password": "<user2-password>"
}
]
}
You will need to substitute appropriate values for the "<...>"
values.
If you run the Device Registry Service with the default values from config.py
,
then tests/integration/inputs.json
should look like this:
{
"base_url": "http://127.0.0.1:5000",
"users" : [
{
"username": "pythonista",
"password": "I<3testing"
},
{
"username": "engineer",
"password": "Muh5devices"
}
]
}
Note: tests/integration/inputs.json
is not committed to the repository
because inputs and secrets should never be committed to a publicly-shared location.
(Nevertheless, this web service is a teaching example,
so values are pasted in the section above for convenience and clarity.)
Once the inputs file is ready, configure the app to use the Testing database and run flask run
.
Then, in another command line terminal, run python -m pytest tests
.
Note that the web app must be running before launching the tests.
Here's a condensed guide for running tests:
- Set the
FLASK_APP
environment variable toregistry
. - Set the
FLASK_CONFIG
environment variable totesting
. - Run
flask run
from the project root directory. - Create the
tests/integration/inputs.json
file. - Run
python -m pytest tests
from the project root directory.