Skip to content
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

feat: add middleware class #27

Merged
merged 27 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7c3f599
feat: create middleware outline
athith-g Aug 13, 2024
1d983f5
refactor: remove whitespace
athith-g Aug 13, 2024
dec2228
feat: check output paths for files
athith-g Aug 19, 2024
ad10247
feat: raise error if /vol/crypt/ is used
athith-g Aug 19, 2024
71f0fb2
feat: check volume in apply middleware
athith-g Aug 19, 2024
387a2cc
docs: add docstrings
athith-g Aug 19, 2024
cc467ee
docs: add class docstrings
athith-g Aug 19, 2024
96fd4d5
docs: clarify docstring
athith-g Aug 19, 2024
dd8bd0e
refactor: sort methods alphabetically
athith-g Aug 19, 2024
09412b1
revert: remove set_output_dir function
athith-g Aug 19, 2024
0fa2a02
docs: modify docstring
athith-g Aug 19, 2024
99de441
ci: add flask to project
athith-g Aug 19, 2024
7176d66
refactor: use path operations instead of strings
athith-g Aug 19, 2024
ff71827
docs: add type hints
athith-g Aug 19, 2024
d0f4721
feat: use custom error class
athith-g Aug 19, 2024
daeaf1b
docs: add docstring to error class
athith-g Aug 19, 2024
5224faf
refactor: remove pass statement
athith-g Aug 19, 2024
7eb9f7d
refactor: take request in as parameter
athith-g Sep 1, 2024
3d716cc
docs: revise docstrings
athith-g Sep 1, 2024
7bba453
test: add empty payload error
athith-g Sep 1, 2024
e26b7e8
refactor: remove functools
athith-g Sep 1, 2024
bfea79e
Merge branch 'main' into middleware
athith-g Sep 1, 2024
2c9aed5
feat: add /vol/crypt/ to volumes
athith-g Sep 1, 2024
d0391e0
docs: add trailing slash
athith-g Sep 1, 2024
b96a12a
refactor: use constant volume path
athith-g Sep 3, 2024
0bc513d
Merge branch 'main' into middleware
uniqueg Sep 3, 2024
7b0cecb
feat: randomize volume path
athith-g Sep 3, 2024
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
80 changes: 80 additions & 0 deletions crypt4gh_middleware/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""Crypt4GH middleware."""

from pathlib import Path

import flask

class PathNotAllowedError(ValueError):
"""Error raised when a path is not allowed."""

class CryptMiddleware:
athith-g marked this conversation as resolved.
Show resolved Hide resolved
"""Middleware class to handle Crypt4GH file inputs."""

def __init__(self):
self.request = None
self.original_input_paths = []
self.output_dir = Path("/vol/crypt/")

def _add_decryption_executor(self) -> None:
"""Add the decryption executor to the executor list."""
executor = {
"image": "athitheyag/crypt4gh:1.0",
athith-g marked this conversation as resolved.
Show resolved Hide resolved
"command": [
"python3",
"decrypt.py"
] + self.original_input_paths + [
"--output-dir",
str(self.output_dir)
]
}
self.request.json["executors"].insert(0, executor)

def _change_executor_paths(self) -> None:
"""Change original input file paths in executors to the output directory."""
for executor_body in self.request.json["executors"]:
for i, path in enumerate(executor_body["command"]):
if path in self.original_input_paths:
executor_body["command"][i] = str(self.output_dir/Path(path).name)

def _change_output_paths(self) -> None:
"""Change original output file paths to the output directory if the output path is
the same as an input path.

Accounts for case where input file is modified in place in a TES request.
"""
for output_body in self.request.json["outputs"]:
path = output_body["path"]
if path in self.original_input_paths:
output_body["path"] = str(self.output_dir/Path(path).name)

def _check_volumes(self) -> None:
"""Check volumes to ensure none start with /vol/crypt.

Raises:
ValueError if volumes start with /vol/crypt.
"""
for volume in self.request.json["volumes"]:
if volume.startswith("/vol/crypt"):
athith-g marked this conversation as resolved.
Show resolved Hide resolved
raise PathNotAllowedError("/vol/crypt/ is not allowed in volumes.")

def _set_original_input_paths(self) -> None:
"""Retrieve and store the original input file paths.

Raises:
ValueError if any path starts with /vol/crypt.
"""
for input_body in self.request.json["inputs"]:
if input_body["path"].startswith("/vol/crypt"):
raise PathNotAllowedError("/vol/crypt/ is not allowed in input path.")
self.original_input_paths.append(input_body["path"])

def apply_middleware(self, request: flask.Request) -> flask.Request:
"""Apply middleware to request."""
self.request = request
athith-g marked this conversation as resolved.
Show resolved Hide resolved
self._set_original_input_paths()
self._check_volumes()
self._change_executor_paths()
self._change_output_paths()
self._add_decryption_executor()

return self.request
198 changes: 197 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ ruff = "*"
pylint = "*"
mypy = "*"

[tool.poetry.group.middleware.dependencies]
flask = "*"

[tool.pylint."MESSAGES CONTROL"]
disable = ["logging-fstring-interpolation", "missing-timeout"]
disable = ["logging-fstring-interpolation", "missing-timeout", "too-few-public-methods"]