Skip to content

Commit

Permalink
Allow the streaming of the docker.compose.pull logs (#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
HemaZ committed Nov 11, 2023
1 parent 0a14f90 commit 3599854
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
41 changes: 39 additions & 2 deletions python_on_whales/components/compose/cli_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,36 @@ def ls(
for proj in json.loads(run(full_cmd))
]

@overload
def pull(
self,
services: Union[List[str], str, None] = ...,
ignore_pull_failures: bool = ...,
include_deps: bool = ...,
quiet: bool = ...,
stream_logs: Literal[True] = ...,
) -> Iterable[Tuple[str, bytes]]:
...

@overload
def pull(
self,
services: Union[List[str], str, None] = ...,
ignore_pull_failures: bool = ...,
include_deps: bool = ...,
quiet: bool = ...,
stream_logs: Literal[False] = ...,
) -> None:
...

def pull(
self,
services: Union[List[str], str, None] = None,
ignore_pull_failures: bool = False,
include_deps: bool = False,
quiet: bool = False,
):
stream_logs: bool = False,
) -> Union[Iterable[Tuple[str, bytes]], None]:
"""Pull service images
Parameters:
Expand All @@ -452,8 +475,19 @@ def pull(
include_deps: Also pull services declared as dependencies
quiet: By default, the progress bars are printed in stdout and stderr (both).
To disable all output, use `quiet=True`
stream_logs: If `False` this function returns None. If `True`, this
function returns an Iterable of `Tuple[str, bytes]` where the first element
is the type of log (`"stdin"` or `"stdout"`). The second element is the log itself,
as bytes, you'll need to call `.decode()` if you want the logs as `str`.
See [the streaming guide](https://gabrieldemarmiesse.github.io/python-on-whales/user_guide/docker_run/#stream-the-output) if you are
not familiar with the streaming of logs in Python-on-whales.
"""
if quiet and stream_logs:
raise ValueError(
"It's not possible to have stream_logs=True and quiet=True at the same time. "
"Only one can be activated at a time."
)
full_cmd = self.docker_compose_cmd + ["pull"]
full_cmd.add_flag("--ignore-pull-failures", ignore_pull_failures)
full_cmd.add_flag("--include-deps", include_deps)
Expand All @@ -463,7 +497,10 @@ def pull(
elif services is not None:
services = to_list(services)
full_cmd += services
run(full_cmd, capture_stdout=False, capture_stderr=False)
if stream_logs:
return stream_stdout_and_stderr(full_cmd)
else:
run(full_cmd, capture_stdout=False, capture_stderr=False)

def push(self, services: Optional[List[str]] = None):
"""Push service images
Expand Down
15 changes: 15 additions & 0 deletions tests/python_on_whales/components/test_compose.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,21 @@ def test_docker_compose_pull():
docker.compose.pull(["busybox", "alpine"], quiet=True)


def test_docker_compose_pull_stream():
try:
docker.image.remove("busybox")
except NoSuchImage:
pass
logs = list(docker.compose.pull("busybox", stream_logs=True))
assert len(logs) >= 3
logs_as_big_binary = b""
for log_type, log_value in logs:
assert log_type in ("stdout", "stderr")
logs_as_big_binary += log_value
assert b"busybox Pulled" in logs_as_big_binary
assert b"Pull complete" in logs_as_big_binary


def test_docker_compose_pull_ignore_pull_failures():
docker = DockerClient(
compose_files=[
Expand Down

0 comments on commit 3599854

Please sign in to comment.