Skip to content

DAFNI Workflow Enhancements #299

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5dc3d27
remove variables from entry-point
f-allian Dec 6, 2024
b929564
update sample dag file to include the variables as node attributes
f-allian Dec 6, 2024
354fd3e
update Dockerfile for dafni image
f-allian Dec 6, 2024
0e53b47
update dafni model definition
f-allian Dec 6, 2024
4497da2
update README.md
f-allian Dec 6, 2024
fb83d65
turned main_dafni.py into a module
f-allian Dec 6, 2024
5b736b8
final touches to main_dafni.py
f-allian Dec 10, 2024
ea46bdc
add: tests for main_dafni.py
f-allian Dec 10, 2024
005d2da
update: tests to dafni workflow
f-allian Dec 10, 2024
9a45392
fix: typo in Dockerfile
f-allian Dec 10, 2024
456048c
fix: default in ignore_cycles tests_main_dafni.py
f-allian Dec 10, 2024
029fdfc
updated causal_tests_results.json
f-allian Dec 10, 2024
802e274
update: file names
f-allian Dec 10, 2024
05a85fd
update: README.md metadata
f-allian Dec 13, 2024
3cd85ae
update: README
f-allian Jan 21, 2025
a03a807
Merge remote-tracking branch 'origin/main' into dafni-dev
f-allian Mar 6, 2025
5202034
Merge branch 'main' into dafni-dev
f-allian Apr 2, 2025
66cb0e7
remove: main_dafni.py and related files
f-allian Apr 2, 2025
233a49c
update: Docker image and config file
f-allian Apr 2, 2025
4a34334
update: DAFNI model_definition.yaml
f-allian Apr 2, 2025
5742985
update: example DAFNI test and results
f-allian Apr 2, 2025
60b3c7f
update: README.md
f-allian Apr 2, 2025
8977c0f
remove project tags for now
f-allian Apr 3, 2025
28aa53e
Merge branch 'main' into dafni-dev
f-allian Apr 29, 2025
a26c051
update: docker-compose.yaml
f-allian May 1, 2025
74c6f2f
update: publish-to-dafni.yaml
f-allian May 1, 2025
40faa83
Merge branch 'main' into dafni-dev
f-allian May 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions .github/workflows/publish-to-dafni.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ jobs:
- name: Get release version
id: get_release
run: |
export VERSION=$(curl -sSL https://api.github.com/repos/CITCOM-project/CausalTestingFramework/releases/latest | jq -r '.tag_name' | head -c 2)
echo "::set-output name=version::$VERSION"
# Extract the version without the 'v' prefix using regex
export VERSION=$(curl -sSL https://api.github.com/repos/CITCOM-project/CausalTestingFramework/releases/latest | jq -r '.tag_name' | sed -E 's/^v?([0-9]+(\.[0-9]+)?).*/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT

build_and_upload:
name: Docker Build
Expand All @@ -38,17 +39,28 @@ jobs:
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install causal-testing-framework -e .[dev]
python -m pip install dafni-cli

- name: Check if unit tests are passing first
id: tests
uses: ./.github/workflows/ci-tests.yml

- name: Build the container
if: success() && steps.tests.outcome == 'success'
run: |
docker build -t ctf:${{ env.VERSION }} -f ./dafni/Dockerfile .
docker save ctf:${{ env.VERSION }} | gzip > ctf-dafni-${{ env.VERSION }}.tar.gz

- name: Install DAFNI-CLI and log in

- name: Log into DAFNI
run: |
python -m pip install dafni-cli
dafni login

- name: Upload to DAFNI
run: |
dafni upload model ./dafni/model_definition.yaml ctf-dafni-${{ env.VERSION }}.tar.gz --version-message "Causal Testing Framework ${{ env.VERSION }}. Uploaded via Github Actions." --parent-id ${{ env.DAFNI_PARENT_ID }} -y
dafni logout
dafni upload model ./dafni/model_definition.yaml ctf-dafni-${{ env.VERSION }}.tar.gz --version-message "Causal Testing Framework v${{ env.VERSION }}. Uploaded via Github Actions." --parent-id ${{ env.DAFNI_PARENT_ID }} -y
dafni logout
18 changes: 7 additions & 11 deletions dafni/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Define the Python version neded for CTF
FROM python:3.10-slim
FROM python:3.12-slim

## Prevents Python from writing pyc files
ENV PYTHONDONTWRITEBYTECODE=1
Expand All @@ -8,26 +8,22 @@ ENV PYTHONDONTWRITEBYTECODE=1
## from crashing without emitting any logs due to buffering
ENV PYTHONUNBUFFERED=1

#Label maintainer
# Label maintainer
LABEL maintainer="Dr. Farhad Allian - The University of Sheffield"

# Create a folder for the source code/outputs
RUN mkdir -p ./causal_testing
RUN mkdir -p ./data/outputs

# Copy the source code and test files from build into the container
COPY --chown=nobody ../causal_testing ./causal_testing
COPY --chown=nobody ./dafni/main_dafni.py ./
# Copy the source code from local root and test files from build into the container
COPY --chown=nobody ./causal_testing ./causal_testing
COPY --chown=nobody ./dafni/data/inputs ./data/inputs

# Install core dependencies using PyPi
RUN pip install causal-testing-framework --no-cache-dir

#For local testing purposes
ENV VARIABLES_PATH=./data/inputs/variables.json \
CAUSAL_TESTS=./data/inputs/causal_tests.json \
DATA_PATH=./data/inputs/runtime_data.csv \
DAG_PATH=./data/inputs/dag.dot
# Set the PYTHONPATH environment variable to include the /src directory
ENV PYTHONPATH="/causal_testing:${PYTHONPATH}"

# Define the entrypoint/commands
CMD python main_dafni.py --variables_path $VARIABLES_PATH --dag_path $DAG_PATH --data_path $DATA_PATH --tests_path $CAUSAL_TESTS
CMD python -m causal_testing --dag_path $DAG_PATH --data_path $DATA_PATH --test_config $TESTS_PATH --output $OUTPUT
22 changes: 13 additions & 9 deletions dafni/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@ to upload the framework onto [DAFNI](https://www.dafni.ac.uk).
- It is **not** recommended to install the causal testing framework using Docker, and should only be installed
using [PyPI](https://pypi.org/project/causal-testing-framework/).

### Folders
### Directory Hierarchy

- `data` contains two sub-folders (the structure is important for DAFNI).
- `inputs` is a folder that contains the input files that are (separately) uploaded to DAFNI.
- `causal_tests.json` is a JSON file that contains the causal tests.
- `variables.json` is a JSON file that contains the variables and constraints to be used.
- `dag.dot` is a dot file that contains the directed acyclc graph (dag) file.
- `runtime_data.csv` is a csv file that contains the runtime data.
- `dag.dot` is a dot file that contains the directed acyclic graph (dag). In this file, Causal Variables are defined as
node metadata attributes as key-value pairs using the following syntax:
`node [datatype="int", typestring="input"]`. The `datatype` key specifies the datatype of the causal variable
as a string (e.g. `"int"`, `"str"`) and the `typestring` key specifies its typestring, which is also a string
representing the variable type (e.g. `"input"` or `"output"`).
- `runtime_data.csv` is the `.csv` file that contains the runtime data.

- `outputs` is a folder where the `causal_tests_results.json` output file is created.

### Docker files
- `main_dafni.py` is the entry-point to the causal testing framework that is used by Docker.
- `model_definition.yaml` is the model metadata that is required to be uploaded to DAFNI.
- `.env` is an example of a configuration file containing the environment variables. This is only required
if using `docker-compose` to build the image.
- `Dockerfile` is the main blueprint that builds the image.
- `.dockerignore` tells the Dockerfile which files to not include in the image.
- `Dockerfile` is the main blueprint that builds the image. The main command calls the `causal_testing` module,
with specified paths for the DAG, input runtime data, test configurations, and the output filename as defined above.
This command is identical to that referenced in the main [README.md](../README.md) file.
- `docker-compose.yaml` is another method of building the image and running the container in one line.
Note: the `.env` file that contains the environment variables for `main_dafni.py` is only used here.
- `.dockerignore` tells the Dockerfile which files to not include in the image.
- `.env` is an example of a configuration file containing the environment variables. This is only required
if using `docker-compose` to build the image.


69 changes: 6 additions & 63 deletions dafni/data/inputs/causal_tests.json
Original file line number Diff line number Diff line change
@@ -1,58 +1,11 @@
{
"tests": [
{
"name": "max_doses _||_ cum_vaccinations",
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"max_doses"
],
"expected_effect": {
"cum_vaccinations": "NoEffect"
},
"formula": "cum_vaccinations ~ max_doses",
"alpha": 0.05,
"skip": false
},
{
"name": "max_doses _||_ cum_vaccinated",
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"max_doses"
],
"expected_effect": {
"cum_vaccinated": "NoEffect"
},
"formula": "cum_vaccinated ~ max_doses",
"alpha": 0.05,
"skip": false
},
{
"name": "max_doses _||_ cum_infections",
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"max_doses"
],
"expected_effect": {
"cum_infections": "NoEffect"
},
"formula": "cum_infections ~ max_doses",
"alpha": 0.05,
"skip": false
},
{
"name": "vaccine --> cum_vaccinations",
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"vaccine"
],
"treatment_variable": "vaccine",
"expected_effect": {
"cum_vaccinations": "SomeEffect"
},
Expand All @@ -64,9 +17,7 @@
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"vaccine"
],
"treatment_variable": "vaccine",
"expected_effect": {
"cum_vaccinated": "SomeEffect"
},
Expand All @@ -78,9 +29,7 @@
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"vaccine"
],
"treatment_variable": "vaccine",
"expected_effect": {
"cum_infections": "SomeEffect"
},
Expand All @@ -92,9 +41,7 @@
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"cum_vaccinations"
],
"treatment_variable": "cum_vaccinations",
"expected_effect": {
"cum_vaccinated": "NoEffect"
},
Expand All @@ -107,9 +54,7 @@
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"cum_vaccinations"
],
"treatment_variable": "cum_vaccinations",
"expected_effect": {
"cum_infections": "NoEffect"
},
Expand All @@ -122,9 +67,7 @@
"estimator": "LinearRegressionEstimator",
"estimate_type": "coefficient",
"effect": "direct",
"mutations": [
"cum_vaccinated"
],
"treatment_variable": "cum_vaccinated",
"expected_effect": {
"cum_infections": "NoEffect"
},
Expand Down
13 changes: 9 additions & 4 deletions dafni/data/inputs/dag.dot
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
digraph CausalDAG {
rankdir=LR;
"vaccine" -> "cum_vaccinations";
"vaccine" -> "cum_vaccinated";
"vaccine" -> "cum_infections";
"max_doses";
vaccine [datatype="int", typestring="input"];
cum_vaccinations [datatype="int", typestring="output"];
cum_vaccinated [datatype="int", typestring="output"];
cum_infections [datatype="int", typestring="output"];
max_doses [datatype="int", typestring="output"];
vaccine -> cum_vaccinations;
vaccine -> cum_vaccinated;
vaccine -> cum_infections;
max_doses;
}
47 changes: 0 additions & 47 deletions dafni/data/inputs/variables.json

This file was deleted.

Loading