API Documentation
Build and Deploy
Configuration
The configuration profiles are held in idmanager/config.py, and combine configuration settings with secrets passed through environment variables as needed.
Set the FLASK_CONFIGURATION environment variable on the app's host to be the name of the desired profile (testing/development/production).
The 'testing' profile does not load any information from environment variables, and does not require an external database.
The 'development' and 'production' profiles load database secrets from the DATABASE environment variable. It should be expressed as a SQLAlchemy database URI, for example:
DATABASE=sqlite://
or
DATABASE=postgres+psycopg2://username:password@host:port/database
Logging
The default configuration is for all loggers (that inherit from the root logger) to put all logs to stdout, and for logging.ERROR or logging.CRITICAL to also be logged to stderr. This is to allow Datadog to filter and view errors without parsing the logs for information.
The level is controlled by the environment variable DEBUG_LEVEL (logging level - INFO, DEBUG, etc). If unset, this will default to INFO.
Authentication for the API
Currently, the authentication pattern uses JWT, with a simple credential handshake (similar to 2 legged OAuth 2.0 client credentials).
POST a JSON {} body to '/auth' containing 'username' and 'password' key-values pairs:
{ "username": "dummy", "password": "foo" }
(Currently, the username is 'dummy', and the password is drawn from the environment variable "MAGIC_KEY" on the host.)
The service will respond with an authorization token if correctly authenticated.
{ "access_token": "eyJ0eXAiO ... 1owoMs" }
Pass this as a header value 'Authorization: Bearer eyJ0....' token when using the privileged portion of the API.
LDAP
LDAP can be used for the username/password authentication system. It requires the following environment variables to be set:
LDAP_HOST- The host for the LDAP service. E.g. ldaps://directory.example.com
LDAP_PORT- Port for the service, e.g. 636
LDAP_SEARCH- This is the LDAP Search Root used for the username lookup. This is of the form
ou=Users,ou=.... The LDAP administrator should be able to provide the search root details.
- This is the LDAP Search Root used for the username lookup. This is of the form
LDAP_USERandLDAP_PASS- This should hold the username and password for the LDAP account that has permission to connect to the service, and search for the roles, cn/dn and attributes for users logging in using the search root.
If any of these cannot be found, a warning message will be displayed in the idmanager logs when starting an instance.
Remote Short ID generation
While one instance of the ID manager software can generate unique numbers that it will not reuse, there may be circumstances where there are multiple ID Managers deployed in their own environments. If it is desired, one of these instances can be used as the source of the unique numbers, so that no short ID (slug) number is reused between any system. To enable this, add the credentials for the chosen ID Manager to:
REMOTE_IDM_URL=
REMOTE_IDM_USERNAME=
REMOTE_IDM_PASSWORD=
If this is enabled, the slug id generation functionality will use this remote system as its source of unique numbers, and will not supply its own.
Local Development
Using Docker
Build the container
docker build --build-arg NEXUS_USER=%NEXUS_USER% --build-arg NEXUS_PASSWORD=%NEXUS_PASSWORD% -t id-manager:latest .
The NEXUS credentials are required to get a package from the Getty nexus PyPi.
Run the container image, overriding the command by calling the Flask debug server.
docker run --rm -it --env-file=.env -p 5001:5001/tcp id-manager:latest flask run --host=0.0.0.0 --port=5001
It can also be run with the local testing configuration:
docker run --rm -e FLASK_CONFIGURATION=testing -p 5001:5001/tcp id-manager:latest flask run --host=0.0.0.0 --port=5001
Testing with docker
There is a convenience script test_locally.sh that will build an id-manager test image, start a small local network, start CircleCI's version of Postgres along with the id-manager container, and run pytest on this. It will then remove the containers and the test network it used afterwards.
Running with docker compose
There are some helper scripts start_docker_compose.sh/.bat which will build, setup and run the docker compose stack and get the system in a working state. This expects the NEXUS credentials to be present in a .env.build file (.env.build.example file shows what it should look like).
The default subpath is 'shortids', so the system will be available on http://localhost:5001/shortids once this is up and working.
CLI tools
All commandline commands will be run through the flask CLI pattern:
DB commands
Standard Flask-Migrate:
flask db upgrade- run all the unperformed migrations. This can be safely run on a database, even if it is already up to date as no action will be taken in that caseflask db downgrade- this will undo the last migration and is usually a destructive process. Whatever data the migration supported will be deleted.flask db migrate- (development use only) compare the current database structure with the declared models and generate a migration that will alter the database to support the new model structure. For example,flask db upgradethen add a property to a model and runflask db migrateto generate a migration that will add the column to the database.
Link commands
flask links addrandom X- this adds X randomly generated links to the database, tagging them with the 'testdata' group_id. This is primarily useful in development either against this codebase or when testing clients against a local instance of the IDM.
Collections commands
flask collections list - this will list the accession identifiers registered as part of the 'getty' collection. These will be cached in full, and transformed into JSON-LD for in the LOD Gateway L2.
flask collections add urn:getty-local:XXXXXX add an accession identifier to the set.
flask collections remove urn:getty-local:XXXXXX remove an accession identifier from the set.
Deployment
For deployment, we should not override the command, and instead just use the startup.sh file that's use in the Dockerfile.
docker run --rm -it --env-file=.env -p 5001:5001/tcp id-manager:latest
Technical Architecture
Health Check
The API endpoint /health will return 200 when the application is running properly and can connect to the database.