A new and easy way to use FLAMA
Report Bug
·
Request Feature
flamapy-rest is a Flask REST API that wraps the
FLAMAPY framework for feature model analysis. It dynamically
exposes FLAMAPY operations (dead features, false-optional features, configurations, satisfiability,
diagnosis, …) as HTTP endpoints, with self-generated Swagger documentation.
Feature model analysis has a crucial role in software product line engineering, enabling us to understand, design, and validate the complex relationships among features in a software product line. These models can be complex and challenging to analyze due to their variability, making it difficult to identify conflicts, dead features, and potential optimizations. This REST API makes that analysis available to any tool or language that can speak HTTP.
Please note: this is a living document and we will continue to update and improve it as we release new versions of the plugins and receive feedback from our users. If there's anything you don't understand or if you have any suggestions for improvement, don't hesitate to open an issue. We're here to help!
There are three supported ways to run the API. Using the published Docker image is the easiest — nothing to build, and it already bundles FLAMAPY and all of its analysis plugins.
The CI publishes a multi-arch image (linux/amd64 and linux/arm64) to Docker Hub at
flamapy/flamapy-rest on every version tag.
# Pull and run the latest release
docker run --rm -p 8000:8000 flamapy/flamapy-restThen open:
- API home: http://localhost:8000/
- Swagger UI / API docs: http://localhost:8000/docs/
To pin a specific version, use its tag (matching a release, e.g. v2.6.0):
docker run --rm -p 8000:8000 flamapy/flamapy-rest:v2.6.0Run it detached and give the container a name so it's easy to stop later:
docker run -d --name flamapy-rest -p 8000:8000 flamapy/flamapy-rest
docker logs -f flamapy-rest # follow the logs
docker stop flamapy-rest # stop it
docker rm flamapy-rest # remove itIf you want to run your local changes, clone the repo and build the image yourself. A helper script is provided that builds, runs, and (on exit) cleans up the container and image:
# Linux / macOS
./start-server.sh
# Windows
start-server.cmdOr do it by hand:
docker build --tag flamapy-rest .
docker run --rm -p 8000:8000 flamapy-restThe API is also published on PyPI as flamapy-rest
(requires Python 3.11+). Because the WSGI entrypoint lives in app.py, clone the repo to get it:
git clone https://github.com/flamapy/flamapy-rest.git
cd flamapy-rest
pip install .
# Production server
gunicorn --bind 0.0.0.0:8000 app:app
# …or the Flask development server
python -m flask run --host=0.0.0.0Every public operation of FLAMAPY's FLAMAFeatureModel facade is exposed as a POST endpoint under
/api/v1/operations/<operation_name>. Each call uploads a feature model file (e.g. UVL) as
multipart form data; some operations also accept an optional feature or configuration parameter.
# Example: count the number of valid configurations of a model
curl -X POST http://localhost:8000/api/v1/operations/configurations_number \
-F "model=@resources/models/simple/valid_model.uvl"The full, interactive list of endpoints — with parameters and "try it out" support — is available in the Swagger UI at http://localhost:8000/docs/.
The API ships with per-IP rate limiting, a per-operation time budget, upload size limits and a
result cache, all configurable through environment variables (e.g. docker run -e FLAMAPY_...):
| Env var | Default | Meaning |
|---|---|---|
FLAMAPY_MAX_CONTENT_LENGTH |
16777216 |
Max upload size in bytes; larger requests get 413 |
FLAMAPY_RATELIMIT_ENABLED |
true |
Turn rate limiting on/off |
FLAMAPY_RATELIMIT_DEFAULT |
60 per minute |
Per-IP limit for cheap operations |
FLAMAPY_RATELIMIT_EXPENSIVE |
10 per minute |
Per-IP limit for enumeration/solver-heavy operations (configurations, configurations_number, sampling, …); exceeding a limit returns 429 |
FLAMAPY_RATELIMIT_STORAGE_URI |
memory:// |
Limiter storage; use redis://host:6379 when running several gunicorn workers so they share counters |
FLAMAPY_OPERATION_TIMEOUT |
60 |
Seconds an operation may run before it is killed and 504 is returned; 0 disables |
FLAMAPY_CACHE_TTL |
3600 |
Seconds a result stays cached (same model + operation + arguments); 0 disables. Responses carry an `X-Cache: HIT |
FLAMAPY_CACHE_MAXSIZE |
128 |
Max cached results per worker |
FLAMAPY_TRUST_PROXY |
false |
Set to true behind a reverse proxy so rate limits see the real client IP (X-Forwarded-For) |
WEB_CONCURRENCY |
2 |
gunicorn worker count (Docker image) |
GUNICORN_TIMEOUT |
120 |
gunicorn hard worker timeout; keep it above FLAMAPY_OPERATION_TIMEOUT |
Every request is logged to stdout (client IP, path, status, duration, upload size, cache result),
so docker logs is enough to spot heavy users.
All documentation is registered with Swagger UI and OAS 3.0, served at
/docs/. It is generated dynamically by
Flasgger from the route docstrings and method signatures, so
don't forget to document your code in the route files — new operations show up automatically.
Contributions are welcome. This repo enforces Conventional Commits on pull request titles, and runs Ruff, mypy, and pytest in CI.
pip install .[dev] # install dev tooling
ruff check . # lint
mypy -p flamapy # static type checking
pytest # tests