Skip to content

Commit

Permalink
Replace cgi and logging.warn with new APIs (#292)
Browse files Browse the repository at this point in the history
The `cgi` Python module has been deprecated in PEP 594. In particular,
the `parse_header` function has been deprecated in favor of the new
`email.message.Message` API. This commit replaces all occurrences of
`parse_header` with the new API. This commit also adds a test for the
`remotepath.download` API to avoid regressions.

As of Python 3.3, the `logging.warn` API has been deprected in favor of
the `logging.warning` method. This commit substitutes all occurrences of
the `warn()` method with the equivalent `warning()` API.
  • Loading branch information
GlassOfWhiskey authored Nov 26, 2023
1 parent 05dcd32 commit 4114a06
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 164 deletions.
2 changes: 1 addition & 1 deletion streamflow/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(self, name: str, config: MutableMapping[str, Any]) -> None:
self.deplyoments = config.get("models", {})
if self.deplyoments:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `models` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `deployments` instead."
)
Expand Down
2 changes: 1 addition & 1 deletion streamflow/cwl/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1533,7 +1533,7 @@ def _translate_command_line_tool(
# Otherwise, throw a warning and skip the DockerRequirement conversion
else:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
f"Skipping DockerRequirement conversion for step `{name_prefix}` "
f"when executing on `{target.deployment.name}` deployment."
)
Expand Down
32 changes: 19 additions & 13 deletions streamflow/data/remotepath.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from __future__ import annotations

import asyncio
import cgi
import errno
import glob
import hashlib
import os
import posixpath
import shutil
from email.message import Message
from typing import MutableSequence, TYPE_CHECKING

import aiohttp
from aiohttp import ClientResponse

from streamflow.core import utils
from streamflow.core.context import StreamFlowContext
Expand Down Expand Up @@ -41,6 +42,15 @@ def _file_checksum_local(path: str) -> str:
return sha1_checksum.hexdigest()


def _get_filename_from_response(response: ClientResponse, url: str):
if cd_header := response.headers.get("Content-Disposition"):
message = Message()
message["Content-Disposition"] = cd_header
if filename := message.get_param("filename"):
return filename
return url.rsplit("/", 1)[-1]


def _listdir_local(path: str, file_type: FileType | None) -> MutableSequence[str]:
content = []
dir_content = os.listdir(path)
Expand Down Expand Up @@ -95,25 +105,22 @@ async def download(
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
_, params = cgi.parse_header(
response.headers.get("Content-Disposition", "")
filepath = os.path.join(
parent_dir, _get_filename_from_response(response, url)
)
filepath = os.path.join(parent_dir, params["filename"])
content = await response.read()
with open(filepath, mode="wb") as f:
f.write(await response.read())
else:
raise Exception(
f"Downloading {url} failed with status {response.status}:\n{response.content}"
)
with open(filepath, mode="wb") as f:
f.write(content)
else:
async with aiohttp.ClientSession() as session:
async with session.head(url, allow_redirects=True) as response:
if response.status == 200:
_, params = cgi.parse_header(
response.headers.get("Content-Disposition", "")
filepath = posixpath.join(
parent_dir, _get_filename_from_response(response, url)
)
filepath = posixpath.join(parent_dir, params["filename"])
else:
raise Exception(
f"Downloading {url} failed with status {response.status}:\n{response.content}"
Expand All @@ -125,9 +132,8 @@ async def download(
connector.run(
location=location,
command=[
'if [ command -v curl ]; curl -L -o "{path}"; else wget -P "{dir}" {url}; fi'.format(
dir=parent_dir, path=filepath, url=url
)
f'if [ command -v curl ]; then curl -L -o "{filepath}" "{url}"; '
f'else wget -P "{parent_dir}" "{url}"; fi'
],
)
)
Expand Down
4 changes: 2 additions & 2 deletions streamflow/deployment/connector/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def __init__(
cacheSize = resourcesCacheSize
if cacheSize is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `resourcesCacheSize` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `locationsCacheSize` instead."
)
Expand All @@ -134,7 +134,7 @@ def __init__(
cacheTTL = resourcesCacheTTL
if cacheTTL is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `resourcesCacheTTL` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `locationsCacheTTL` instead."
)
Expand Down
4 changes: 2 additions & 2 deletions streamflow/deployment/connector/kubernetes.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def __init__(
cacheSize = resourcesCacheSize
if cacheSize is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `resourcesCacheSize` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `locationsCacheSize` instead."
)
Expand All @@ -200,7 +200,7 @@ def __init__(
cacheTTL = resourcesCacheTTL
if cacheTTL is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `resourcesCacheTTL` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `locationsCacheTTL` instead."
)
Expand Down
8 changes: 4 additions & 4 deletions streamflow/deployment/connector/queue_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def __init__(
self._inner_ssh_connector: bool = False
if hostname is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"Inline SSH options are deprecated and will be removed in StreamFlow 0.3.0. "
f"Define a standalone `SSHConnector` and link the `{self.__class__.__name__}` "
"to it using the `wraps` property."
Expand Down Expand Up @@ -375,7 +375,7 @@ def __init__(
files_map[name] = f.read()
if file is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `file` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `services` instead."
)
Expand Down Expand Up @@ -553,12 +553,12 @@ async def undeploy(self, external: bool) -> None:
self.scheduledJobs = {}
if self._inner_ssh_connector:
if logger.isEnabledFor(logging.INFO):
logger.warn(
logger.warning(
f"UNDEPLOYING inner SSH connector for {self.deployment_name} deployment."
)
await self.connector.undeploy(external)
if logger.isEnabledFor(logging.INFO):
logger.warn(
logger.warning(
f"COMPLETED Undeployment of inner SSH connector for {self.deployment_name} deployment."
)

Expand Down
2 changes: 1 addition & 1 deletion streamflow/deployment/connector/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def __init__(
services_map[name] = f.read()
if file is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `file` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `services` instead."
)
Expand Down
2 changes: 1 addition & 1 deletion streamflow/deployment/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ async def _inner_deploy(
else:
if deployment_config.wraps is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
f"The `wraps` directive has no effect on deployment {deployment_config.name}, "
f"as the `{deployment_config.type}` connector does not inherit from the ConnectorWrapper class."
)
Expand Down
4 changes: 2 additions & 2 deletions streamflow/deployment/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_binding_config(
else:
target_deployment = workflow_config.deplyoments[target["model"]]
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `model` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `deployment` instead."
)
Expand All @@ -40,7 +40,7 @@ def get_binding_config(
locations = target.get("resources")
if locations is not None:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"The `resources` keyword is deprecated and will be removed in StreamFlow 0.3.0. "
"Use `locations` instead."
)
Expand Down
2 changes: 1 addition & 1 deletion streamflow/ext/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def _register(self, name: str, cls: type, extension_point: str):
)
if name in extension_points[extension_point]:
if logger.isEnabledFor(logging.WARN):
logger.warn(
logger.warning(
"{} is already installed and will be overridden by {}".format(
name, self.__class__.__module__ + "." + self.__class__.__name__
)
Expand Down
6 changes: 3 additions & 3 deletions streamflow/provenance/run_crate.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ async def add_file(self, file: MutableMapping[str, str]) -> None:
dst_parent = posixpath.dirname(posixpath.normpath(dst))
if src in self.files_map:
if logger.isEnabledFor(logging.WARN):
logger.warn(f"File {src} is already present in the archive.")
logger.warning(f"File {src} is already present in the archive.")
else:
if os.path.isfile(os.path.realpath(src)):
checksum = _file_checksum(
Expand Down Expand Up @@ -681,7 +681,7 @@ async def add_property(self, key: str, value: str):
current_obj = current_obj[k]
if logger.isEnabledFor(logging.WARN):
if keys[-1] in current_obj:
logger.warn(
logger.warning(
f"Key {key} already exists in archive manifest and will be overridden."
)
value = ESCAPED_EQUAL.sub("=", value)
Expand Down Expand Up @@ -889,7 +889,7 @@ async def create_archive(
if dst not in archive.namelist():
archive.write(src, dst)
else:
logger.warn(f"File {src} does not exist.")
logger.warning(f"File {src} does not exist.")
print(f"Successfully created run_crate archive at {path}")

@abstractmethod
Expand Down
Loading

0 comments on commit 4114a06

Please sign in to comment.