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.txtto 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 runis launched. - Development: create a SQLite database file named
registry_data.sqlitewith a few prepopulated devices.
Set the FLASK_CONFIG environment variable to chose which database to use:
- For the Testing database, set
FLASK_CONFIGtotesting. - For the Development database, set
FLASK_CONFIGtodevelopment.
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_APPenvironment variable toregistry. - Set the
FLASK_CONFIGenvironment variable totesting. - Run
flask runfrom the project root directory. - Create the
tests/integration/inputs.jsonfile. - Run
python -m pytest testsfrom the project root directory.