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 ContainerInfo class to inspect_container return type #3287

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 39 additions & 3 deletions docker/api/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,40 @@
)


class ContainerInfo:
def __init__(self, info: dict):
self._info = info

def __repr__(self):
return (
f"<ContainerInfo id={self._info.get('Id')}, name={self._info.get('Name')}>"
)

def __getattr__(self, item):
"""
Dynamically fetch any attribute from the underlying dictionary.
This allows direct access to all fields without manually defining them.
"""
try:
value = self._info[item]
if isinstance(value, dict):
return ContainerInfo(value)
return value
except KeyError as err:
raise AttributeError(
f"'ContainerInfo' object has no attribute '{item}'"
) from err

def __getitem__(self, item):
"""
Optional: If you'd like to access attributes using bracket notation.
"""
return self._info.get(item)

def get_info(self):
"""Returns the entire dictionary for reference if needed"""
return self._info

class ContainerApiMixin:
@utils.check_resource('container')
def attach(self, container, stdout=True, stderr=True,
Expand Down Expand Up @@ -783,16 +817,18 @@ def inspect_container(self, container):
container (str): The container to inspect

Returns:
(dict): Similar to the output of `docker inspect`, but as a
single dict
(ContainerInfo): Similar to the output of `docker inspect`, but as a
docker.api.container.ContainerInfo object

Raises:
:py:class:`docker.errors.APIError`
If the server returns an error.
"""
return self._result(
container_info = self._result(
self._get(self._url("/containers/{0}/json", container)), True
)
return ContainerInfo(container_info)


@utils.check_resource('container')
def kill(self, container, signal=None):
Expand Down
17 changes: 17 additions & 0 deletions tests/integration/api_container_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1572,3 +1572,20 @@ def test_remove_link(self):
x['Id'].startswith(container2_id)
]
assert len(retrieved) == 2

class ContainerInfoObjectTest(BaseAPIIntegrationTest):
def test_container_info_object(self):
container = self.client.create_container(
TEST_IMG, 'true', host_config=self.client.create_host_config())
self.tmp_containers.append(container)
self.client.start(container)

inspect_data = self.client.inspect_container(container)
assert isinstance(inspect_data, docker.api.container.ContainerInfo)
assert inspect_data['Config']['Image'] == TEST_IMG
assert inspect_data['HostConfig']['NetworkMode'] == 'bridge'

# attribute style access
assert inspect_data.Id == container['Id']
assert inspect_data.Config.Image == TEST_IMG
assert inspect_data.HostConfig.NetworkMode == 'bridge'
Loading