mirror of https://github.com/docker/docker-py.git
Merge 00a5086d23
into db7f8b8bb6
This commit is contained in:
commit
78360a5ec5
|
@ -11,6 +11,40 @@ from ..types import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
class ContainerApiMixin:
|
||||||
@utils.check_resource('container')
|
@utils.check_resource('container')
|
||||||
def attach(self, container, stdout=True, stderr=True,
|
def attach(self, container, stdout=True, stderr=True,
|
||||||
|
@ -783,16 +817,18 @@ class ContainerApiMixin:
|
||||||
container (str): The container to inspect
|
container (str): The container to inspect
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(dict): Similar to the output of `docker inspect`, but as a
|
(ContainerInfo): Similar to the output of `docker inspect`, but as a
|
||||||
single dict
|
docker.api.container.ContainerInfo object
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
:py:class:`docker.errors.APIError`
|
:py:class:`docker.errors.APIError`
|
||||||
If the server returns an error.
|
If the server returns an error.
|
||||||
"""
|
"""
|
||||||
return self._result(
|
container_info = self._result(
|
||||||
self._get(self._url("/containers/{0}/json", container)), True
|
self._get(self._url("/containers/{0}/json", container)), True
|
||||||
)
|
)
|
||||||
|
return ContainerInfo(container_info)
|
||||||
|
|
||||||
|
|
||||||
@utils.check_resource('container')
|
@utils.check_resource('container')
|
||||||
def kill(self, container, signal=None):
|
def kill(self, container, signal=None):
|
||||||
|
|
|
@ -1572,3 +1572,20 @@ class LinkTest(BaseAPIIntegrationTest):
|
||||||
x['Id'].startswith(container2_id)
|
x['Id'].startswith(container2_id)
|
||||||
]
|
]
|
||||||
assert len(retrieved) == 2
|
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…
Reference in New Issue