-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cf8ba9f
commit 39f766b
Showing
15 changed files
with
449 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
PLANTECH_API_KEY=<API_KEY> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# QA visualiser | ||
|
||
Python project for creating visualisations of the different question pathways for each topic, to support QA testing. | ||
|
||
## Local setup | ||
|
||
To run the qa-visualiser locally: | ||
1. Install [uv](https://github.com/astral-sh/uv) | ||
2. Setup your .env file by copying .env.example and adding the relevant keys | ||
3. create and activate a virtual environment by running | ||
```bash | ||
cd qa-visualiser | ||
uv venv | ||
source .venv/bin/activate | ||
``` | ||
4. Run the tool to generate visualisations with | ||
```bash | ||
uv run main.py | ||
``` | ||
|
||
## Linting and formatting | ||
|
||
Linting and formatting can be done with the commands: | ||
```bash | ||
uv run ruff check | ||
uv run ruff check --fix # fix linting errors automatically where possible | ||
uv run ruff format | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from src.fetch_sections import fetch_sections | ||
from src.generate_visualisations import process_sections | ||
|
||
|
||
def main(): | ||
sections = fetch_sections() | ||
process_sections(sections) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[project] | ||
name = "qa-visualiser" | ||
version = "0.1.0" | ||
description = "Tool for creating questionnaire flow visualisations for Plan Tech" | ||
readme = "README.md" | ||
requires-python = ">=3.12" | ||
dependencies = [ | ||
"graphviz>=0.20.3", | ||
"python-dotenv>=1.0.1", | ||
"requests>=2.32.3", | ||
] | ||
|
||
[tool.ruff.lint] | ||
extend-select = ["I"] | ||
|
||
[tool.uv] | ||
dev-dependencies = [ | ||
"ruff>=0.8.0", | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import os | ||
|
||
import requests | ||
from dotenv import load_dotenv | ||
|
||
from src.models import Section | ||
|
||
load_dotenv() | ||
|
||
|
||
def fetch_sections() -> list[Section]: | ||
token = os.getenv("PLANTECH_API_KEY") | ||
data = requests.get( | ||
"https://localhost:8080/api/cms/sections", | ||
headers={ | ||
"Accept": "application/json", | ||
"Authorization": f"Bearer {token}", | ||
}, | ||
) | ||
sections: list[Section] = data.json() | ||
return sections |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import textwrap | ||
from pathlib import Path | ||
|
||
from graphviz import Digraph | ||
|
||
from src.models import Section | ||
|
||
|
||
def _wrap_text(text: str, max_length: int) -> str: | ||
"""Wrap lines such that no line exceeds max_length, splitting on whitespace where possible.""" | ||
return textwrap.fill( | ||
text, | ||
width=max_length, | ||
break_long_words=True, | ||
break_on_hyphens=True, | ||
) | ||
|
||
|
||
def _create_blank_digraph() -> Digraph: | ||
"""Blank graph with styling options""" | ||
return Digraph( | ||
format="png", | ||
graph_attr={ | ||
"rankdir": "LR", | ||
"beautify": "true", | ||
}, | ||
edge_attr={ | ||
"arrowhead": "vee", | ||
"arrowsize": "0.5", | ||
}, | ||
) | ||
|
||
|
||
def _create_questionnaire_flowchart(section: Section) -> Digraph: | ||
tree = _create_blank_digraph() | ||
|
||
tree.node( | ||
"end", | ||
"Check Answers", | ||
shape="box", | ||
style="filled", | ||
fillcolor="lightblue:white", | ||
width="2", | ||
gradient="300", | ||
) | ||
|
||
for question in section["questions"]: | ||
current_question = question["sys"]["id"] | ||
question_text = _wrap_text(question["text"], 20) | ||
|
||
tree.node( | ||
current_question, | ||
question_text, | ||
shape="box", | ||
style="filled", | ||
fillcolor="grey:white", | ||
width="2", | ||
gradient="200", | ||
) | ||
|
||
for answer in question["answers"]: | ||
answer_text = _wrap_text(answer["text"], 20) | ||
|
||
if next_question := answer["nextQuestion"]: | ||
next_question_id = next_question["sys"]["id"] | ||
tree.node( | ||
next_question_id, | ||
"Missing Content", | ||
shape="diamond", | ||
style="filled", | ||
fillcolor="red:white", | ||
width="2", | ||
) | ||
tree.edge(current_question, next_question_id, label=answer_text) | ||
else: | ||
tree.edge(current_question, "end", label=answer_text) | ||
|
||
return tree | ||
|
||
|
||
def process_sections(sections: list[Section]) -> None: | ||
png_folder = Path("visualisations") | ||
png_folder.mkdir(exist_ok=True) | ||
|
||
for section in sections: | ||
output_file = Path(png_folder, section["name"]) | ||
flowchart = _create_questionnaire_flowchart(section) | ||
flowchart.render(output_file, cleanup=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from __future__ import annotations | ||
|
||
from typing import TypedDict | ||
|
||
|
||
class SystemDetails(TypedDict): | ||
id: str | ||
|
||
|
||
class Answer(TypedDict): | ||
sys: SystemDetails | ||
text: str | ||
nextQuestion: Question | None | ||
|
||
|
||
class Question(TypedDict): | ||
answers: list[Answer] | ||
helpText: str | None | ||
slug: str | ||
sys: SystemDetails | ||
text: str | ||
|
||
|
||
class Section(TypedDict): | ||
name: str | ||
questions: list[Question] | ||
firstQuestionId: str | ||
interstitialPage: dict | None | ||
sys: SystemDetails |
Oops, something went wrong.