Skip to content

Commit

Permalink
Add new user-focused API
Browse files Browse the repository at this point in the history
See docker#1086

Signed-off-by: Ben Firshman <[email protected]>
  • Loading branch information
bfirsh committed Nov 17, 2016
1 parent 3ed65bc commit 2aa2ecc
Show file tree
Hide file tree
Showing 36 changed files with 3,971 additions and 77 deletions.
77 changes: 62 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,73 @@
docker-py
=========
# Docker SDK for Python

[![Build Status](https://travis-ci.org/docker/docker-py.png)](https://travis-ci.org/docker/docker-py)

A Python library for the Docker Remote API. It does everything the `docker` command does, but from within Python – run containers, manage them, pull/push images, etc.
A Python library for the Docker API. It lets you do anything the `docker` command does, but from within Python apps – run containers, manage containers, manage Swarms, etc.

Installation
------------
## Installation

The latest stable version is always available on PyPi.
The latest stable version [is available on PyPi](https://pypi.python.org/pypi/docker/). Either add `docker` to your `requirements.txt` file or install with pip:

pip install docker-py
pip install docker

Documentation
-------------
## Usage

[![Documentation Status](https://readthedocs.org/projects/docker-py/badge/?version=latest)](https://readthedocs.org/projects/docker-py/?badge=latest)
Connect to Docker using the default socket or the configuration in your environment:

[Read the full documentation here](https://docker-py.readthedocs.io/en/latest/).
The source is available in the `docs/` directory.
```python
import docker
client = docker.from_env()
```

You can run containers:

License
-------
Docker is licensed under the Apache License, Version 2.0. See LICENSE for full license text
```python
>>> client.containers.run("ubuntu", "echo hello world")
'hello world\n'
```

You can run containers in the background:

```python
>>> client.containers.run("bfirsh/reticulate-splines", detach=True)
<Container '45e6d2de7c54'>
```

You can manage containers:

```python
>>> client.containers.list()
[<Container '45e6d2de7c54'>, <Container 'db18e4f20eaa'>, ...]

>>> container = client.containers.get('45e6d2de7c54')

>>> container.attrs['Config']['Image']
"bfirsh/reticulate-splines"

>>> container.logs()
"Reticulating spline 1...\n"

>>> container.stop()
```

You can stream logs:

```python
>>> for line in container.logs(stream=True):
... print line.strip()
Reticulating spline 2...
Reticulating spline 3...
...
```

You can manage images:

```python
>>> client.images.pull('nginx')
<Image 'nginx'>

>>> client.images.list()
[<Image 'ubuntu'>, <Image 'nginx'>, ...]
```

[Read the full documentation](https://docs.docker.com/sdk/python/) to see everything you can do.
1 change: 1 addition & 0 deletions docker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# flake8: noqa
from .api import APIClient
from .client import Client, from_env
from .version import version, version_info

__version__ = version
Expand Down
22 changes: 5 additions & 17 deletions docker/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,18 @@
from ..constants import (DEFAULT_TIMEOUT_SECONDS, DEFAULT_USER_AGENT,
IS_WINDOWS_PLATFORM, DEFAULT_DOCKER_API_VERSION,
STREAM_HEADER_SIZE_BYTES, DEFAULT_NUM_POOLS)
from ..errors import DockerException, APIError, TLSParameterError, NotFound
from ..errors import (DockerException, TLSParameterError,
create_api_error_from_http_exception)
from ..tls import TLSConfig
from ..transport import UnixAdapter
from ..utils import utils, check_resource, update_headers, kwargs_from_env
from ..utils import utils, check_resource, update_headers
from ..utils.socket import frames_iter
try:
from ..transport import NpipeAdapter
except ImportError:
pass


def from_env(**kwargs):
return APIClient.from_env(**kwargs)


class APIClient(
requests.Session,
BuildApiMixin,
Expand Down Expand Up @@ -143,13 +140,6 @@ def __init__(self, base_url=None, version=None,
)
)

@classmethod
def from_env(cls, **kwargs):
timeout = kwargs.pop('timeout', None)
version = kwargs.pop('version', None)
return cls(timeout=timeout, version=version,
**kwargs_from_env(**kwargs))

def _retrieve_server_version(self):
try:
return self.version(api_version=False)["ApiVersion"]
Expand Down Expand Up @@ -203,14 +193,12 @@ def _url(self, pathfmt, *args, **kwargs):
else:
return '{0}{1}'.format(self.base_url, pathfmt.format(*args))

def _raise_for_status(self, response, explanation=None):
def _raise_for_status(self, response):
"""Raises stored :class:`APIError`, if one occurred."""
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
raise NotFound(e, response, explanation=explanation)
raise APIError(e, response, explanation=explanation)
raise create_api_error_from_http_exception(e)

def _result(self, response, json=False, binary=False):
assert not (json and binary)
Expand Down
157 changes: 157 additions & 0 deletions docker/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
from .api.client import APIClient
from .models.containers import ContainerCollection
from .models.images import ImageCollection
from .models.networks import NetworkCollection
from .models.nodes import NodeCollection
from .models.services import ServiceCollection
from .models.swarm import Swarm
from .models.volumes import VolumeCollection
from .utils import kwargs_from_env


class Client(object):
"""
A client for communicating with a Docker server.
Example:
>>> import docker
>>> client = Client(base_url='unix://var/run/docker.sock')
Args:
base_url (str): URL to the Docker server. For example,
``unix:///var/run/docker.sock`` or ``tcp://127.0.0.1:1234``.
version (str): The version of the API to use. Set to ``auto`` to
automatically detect the server's version. Default: ``1.24``
timeout (int): Default timeout for API calls, in seconds.
tls (bool or :py:class:`~docker.tls.TLSConfig`): Enable TLS. Pass
``True`` to enable it with default options, or pass a
:py:class:`~docker.tls.TLSConfig` object to use custom
configuration.
user_agent (str): Set a custom user agent for requests to the server.
"""
def __init__(self, *args, **kwargs):
self.api = APIClient(*args, **kwargs)

@classmethod
def from_env(cls, **kwargs):
"""
Return a client configured from environment variables.
The environment variables used are the same as those used by the
Docker command-line client. They are:
.. envvar:: DOCKER_HOST
The URL to the Docker host.
.. envvar:: DOCKER_TLS_VERIFY
Verify the host against a CA certificate.
.. envvar:: DOCKER_CERT_PATH
A path to a directory containing TLS certificates to use when
connecting to the Docker host.
Args:
version (str): The version of the API to use. Set to ``auto`` to
automatically detect the server's version. Default: ``1.24``
timeout (int): Default timeout for API calls, in seconds.
ssl_version (int): A valid `SSL version`_.
assert_hostname (bool): Verify the hostname of the server.
environment (dict): The environment to read environment variables
from. Default: the value of ``os.environ``
Example:
>>> import docker
>>> client = docker.from_env()
.. _`SSL version`:
https://docs.python.org/3.5/library/ssl.html#ssl.PROTOCOL_TLSv1
"""
timeout = kwargs.pop('timeout', None)
version = kwargs.pop('version', None)
return cls(timeout=timeout, version=version,
**kwargs_from_env(**kwargs))

# Resources
@property
def containers(self):
"""
An object for managing containers on the server. See the
:doc:`containers documentation <containers>` for full details.
"""
return ContainerCollection(client=self)

@property
def images(self):
"""
An object for managing images on the server. See the
:doc:`images documentation <images>` for full details.
"""
return ImageCollection(client=self)

@property
def networks(self):
"""
An object for managing networks on the server. See the
:doc:`networks documentation <networks>` for full details.
"""
return NetworkCollection(client=self)

@property
def nodes(self):
"""
An object for managing nodes on the server. See the
:doc:`nodes documentation <nodes>` for full details.
"""
return NodeCollection(client=self)

@property
def services(self):
"""
An object for managing services on the server. See the
:doc:`services documentation <services>` for full details.
"""
return ServiceCollection(client=self)

@property
def swarm(self):
"""
An object for managing a swarm on the server. See the
:doc:`swarm documentation <swarm>` for full details.
"""
return Swarm(client=self)

@property
def volumes(self):
"""
An object for managing volumes on the server. See the
:doc:`volumes documentation <volumes>` for full details.
"""
return VolumeCollection(client=self)

# Top-level methods
def events(self, *args, **kwargs):
return self.api.events(*args, **kwargs)
events.__doc__ = APIClient.events.__doc__

def info(self, *args, **kwargs):
return self.api.info(*args, **kwargs)
info.__doc__ = APIClient.info.__doc__

def login(self, *args, **kwargs):
return self.api.login(*args, **kwargs)
login.__doc__ = APIClient.login.__doc__

def ping(self, *args, **kwargs):
return self.api.ping(*args, **kwargs)
ping.__doc__ = APIClient.ping.__doc__

def version(self, *args, **kwargs):
return self.api.version(*args, **kwargs)
version.__doc__ = APIClient.version.__doc__

from_env = Client.from_env
Loading

0 comments on commit 2aa2ecc

Please sign in to comment.