Working with products
Table of contents
- Introduction
- What a product looks like
- Declaring features
- A day of development
- Choosing the environment
- Running in production
- Command sections
Introduction
A product is a Flask application made of features. It declares them in pyproject.toml, and has its own Docker setup, database and deployment. Its features are a valid configuration of an SPL’s UVL model.
splent product:select my_first_app
splent product:derive --dev
Those two commands take a product from its pyproject.toml to a running app.
What a product looks like
my_product/
├── pyproject.toml ← declares features, version, metadata
├── src/my_product/ ← application source
├── docker/ ← Compose files and Dockerfiles per environment
├── entrypoints/ ← entrypoint scripts (dev/prod)
└── features/ ← links to the features it uses
Features are never copied into the product. A pinned feature links to its release in .splent_cache/features/, an editable one to its checkout at the workspace root, and both are installed as editable pip packages.
The UVL model lives outside the product too. [tool.splent].spl names the SPL, and [tool.splent.spl_model] pins its DOI on UVLHub (see spl:pin).
Declaring features
[tool.splent]
features = [
"splent-io/splent_feature_notes@v1.2.7",
"splent-io/splent_feature_cache@v1.2.7",
"splent-io/splent_feature_mailer@v1.2.7",
]
Features for one environment go in features_dev and features_prod. product:resolve clones the missing ones from the forge and links them.
A day of development
product:select <name> → set the active product
product:configure → choose the features (optional)
product:derive --dev → validate, resolve, generate env, start and run
product:logs → follow container output
product:shell → open a shell in the main container
product:down → stop all services
product:derive --dev runs these steps for you. You can also run them one by one.
product:resolve → clone and link all declared features
product:env --generate --all --dev → generate the .env files
product:env --merge --dev → merge them into the product .env
product:up --dev → start Docker Compose services
product:run --dev → execute the entrypoint inside the container
Every command above works on the selected product, and stops with SPLENT_APP not set without one. SPLENT_APP=<name> splent <command> runs one command on another product and leaves the selection alone (see Another product for one command).
Detached mode (product:deselect) is only for product:create and the spl:* commands. spl:pin works on the selected product, and spl:publish runs either way.
Choosing the environment
Most product commands accept --dev or --prod. Without either they use SPLENT_ENV, and dev when that is unset too. product:env and product:derive require --dev or --prod, and product:up requires one of them or SPLENT_ENV.
Each environment has its own Compose file.
docker/docker-compose.dev.yml
docker/docker-compose.prod.yml
Most commands read SPLENT_ENV as the framework does. Case and surrounding spaces do not matter, and development, production and testing mean dev, prod and test. product:validate, product:test, product:config and product:routes read it literally, so give them dev, prod or test.
Running in production
In production a product runs as a deployment, built with product:build and started with product:deploy as the Compose project <product>_deploy.
product:up --prod starts another stack, <product>_prod, from docker-compose.prod.yml, with the same container names. product:down --prod stops both. product:shell --prod and product:restart --prod look in <product>_prod first, then in the deployment’s <product>_web_deploy container.
Command sections
| Section | Description |
|---|---|
| Product Setup | Create, select, configure and derive products |
| Product Runtime | Start, stop, watch and work inside a running product |
| Product Inspection | Read its configuration, routes and signals, validate it and test it |
| Product Release & Deploy | Build, deploy and release products |