diff --git a/Makefile b/Makefile index aedfed33..110f0b95 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,6 @@ export PODMAN_VERSION ?= "3.2.0" podman-py: rm dist/* || : python -m pip install --user -r requirements.txt - python -m pip install --user -r test-requirements.txt PODMAN_VERSION=$(PODMAN_VERSION) \ $(PYTHON) setup.py sdist bdist bdist_wheel @@ -24,6 +23,7 @@ lint: .PHONY: tests tests: + python -m pip install --user -r test-requirements.txt DEBUG=1 coverage run -m unittest discover -s podman/tests coverage report -m --skip-covered --fail-under=80 --omit=./podman/tests/* --omit=.tox/* \ --omit=/usr/lib/* --omit=*/lib/python* @@ -52,7 +52,9 @@ release: docs: mkdir -p build/docs/source cp -R docs/source/* build/docs/source - sphinx-apidoc -f -o build/docs/source podman podman/tests podman/api_connection.py podman/containers podman/images \ + sphinx-apidoc --separate --no-toc --force --templatedir build/docs/source/_templates/apidoc \ + -o build/docs/source \ + podman podman/tests podman/api_connection.py podman/containers podman/images \ podman/manifests podman/networks podman/pods podman/system sphinx-build build/docs/source build/html @@ -77,7 +79,7 @@ uninstall: .PHONY: clean clean: - rm -rf podman_py.egg-info dist build/docs + rm -rf podman_py.egg-info dist build/* find . -depth -name __pycache__ -exec rm -rf {} \; find . -depth -name \*.pyc -exec rm -f {} \; $(PYTHON) ./setup.py clean --all diff --git a/docs/source/_static/about.html b/docs/source/_static/about.html new file mode 100644 index 00000000..916dd519 --- /dev/null +++ b/docs/source/_static/about.html @@ -0,0 +1,10 @@ + + + + + About PodmanPy + + +About PodmanPy + + diff --git a/docs/source/_static/podman-logo.ico b/docs/source/_static/podman-logo.ico new file mode 100644 index 00000000..cb1dab6a Binary files /dev/null and b/docs/source/_static/podman-logo.ico differ diff --git a/docs/source/_static/podman-logo.png b/docs/source/_static/podman-logo.png new file mode 100644 index 00000000..90acf9cb Binary files /dev/null and b/docs/source/_static/podman-logo.png differ diff --git a/docs/source/_templates/apidoc/module.rst_t b/docs/source/_templates/apidoc/module.rst_t new file mode 100644 index 00000000..c98c5fc7 --- /dev/null +++ b/docs/source/_templates/apidoc/module.rst_t @@ -0,0 +1,9 @@ +{%- if show_headings %} +{{- basename | replace("podman.", "") | e | heading }} + +{% endif -%} +.. automodule:: {{ qualname }} +{%- for option in automodule_options %} + :{{ option }}: +{%- endfor %} + diff --git a/docs/source/_templates/apidoc/package.rst_t b/docs/source/_templates/apidoc/package.rst_t new file mode 100644 index 00000000..b7380e8a --- /dev/null +++ b/docs/source/_templates/apidoc/package.rst_t @@ -0,0 +1,53 @@ +{%- macro automodule(modname, options) -%} +.. automodule:: {{ modname }} +{%- for option in options %} + :{{ option }}: +{%- endfor %} +{%- endmacro %} + +{%- macro toctree(docnames) -%} +.. toctree:: + :maxdepth: {{ maxdepth }} +{% for docname in docnames %} + {{ docname }} +{%- endfor %} +{%- endmacro %} + +{%- if is_namespace %} +{{- [pkgname, "namespace"] | join(" ") | e | heading }} +{% else %} +{{- [pkgname, "package"] | join(" ") | e | heading }} +{% endif %} + +{%- if modulefirst and not is_namespace %} +{{ automodule(pkgname, automodule_options) }} +{% endif %} + +{%- if subpackages %} +Subpackages +----------- + +{{ toctree(subpackages) }} +{% endif %} + +{%- if submodules %} +Submodules +---------- +{% if separatemodules %} +{{ toctree(submodules) }} +{% else %} +{%- for submodule in submodules %} +{% if show_headings %} +{{- [submodule, "module"] | join(" ") | e | heading(2) }} +{% endif %} +{{ automodule(submodule, automodule_options) }} +{% endfor %} +{%- endif %} +{%- endif %} + +{%- if not modulefirst and not is_namespace %} +Module contents +--------------- + +{{ automodule(pkgname, automodule_options) }} +{% endif %} diff --git a/docs/source/_templates/apidoc/toc.rst_t b/docs/source/_templates/apidoc/toc.rst_t new file mode 100644 index 00000000..f0877eeb --- /dev/null +++ b/docs/source/_templates/apidoc/toc.rst_t @@ -0,0 +1,8 @@ +{{ header | heading }} + +.. toctree:: + :maxdepth: {{ maxdepth }} +{% for docname in docnames %} + {{ docname }} +{%- endfor %} + diff --git a/docs/source/conf.py b/docs/source/conf.py index 7365a401..b2afab15 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,12 +20,13 @@ # -- Project information ----------------------------------------------------- -project = 'Podman SDK for Python' -copyright = '2021 Red Hat, Inc' -author = 'Red Hat' +project = u'Podman Python SDK' +copyright = u'2021, Red Hat Inc' +author = u'Red Hat Inc' # The full version, including alpha/beta/rc tags -release = '3.1.2.1' +version = '3.1.2.1' +release = version add_module_names = False @@ -34,7 +35,12 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon'] +# isort: unique-list +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon', + 'sphinx.ext.viewcode', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -50,11 +56,31 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -# html_theme = 'alabaster' -html_theme = 'default' +html_theme = 'alabaster' +html_favicon = '_static/podman-logo.ico' html_theme_options = { - 'description': 'A Python library for the Podman service API', - 'fixed_sidebar': True, + 'description': 'Develop scripted Podman operations', + 'fixed_sidebar': False, + 'github_banner': True, + 'github_repo': 'podman-py', + 'github_user': 'containers', + 'logo': "podman-logo.png", + 'logo_name': True, + 'show_powered_by': False, + 'extra_nav_links': { + 'Report PodmanPy Issue': 'http://github.com/containers/podman-py/issues', + 'Podman Reference': 'http://docs.podman.io', + 'Podman on github': 'http://github.com/containers/podman', + }, +} + +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', + 'searchbox.html', + ] } # Add any paths that contain custom static files (such as style sheets) here, @@ -63,6 +89,12 @@ html_static_path = ['_static'] # -- autoclass settings ------------------------------------------------------ s +autodoc_member_order = "groupwise" +autodoc_default_options = { + 'members': True, + 'inherited-members': True, + 'show-inheritance': True, +} autoclass_content = "both" # -- Napoleon settings ------------------------------------------------------ s diff --git a/docs/source/index.rst b/docs/source/index.rst index 33b8c663..6462a41a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,24 +1,70 @@ +PodmanPy: Python scripting for Podman services +============================================== +.. image:: https://img.shields.io/pypi/l/podman-py.svg + :target: https://pypi.org/project/podman-py/ -.. image:: https://github.com/containers/podman/blob/master/logo/podman-logo.png?raw=true +.. image:: https://img.shields.io/pypi/wheel/podman-py.svg + :target: https://pypi.org/project/podman-py/ -What is PodmanPy? -==================================== +.. image:: https://img.shields.io/pypi/pyversions/podman-py.svg + :target: https://pypi.org/project/podman-py/ PodmanPy is a Python3 module that allows you to write Python scripts that access resources -maintained by a Podman service. +maintained by a Podman service. It leverages the Podman service RESTful API. -PodmanPy leverages the Podman service RESTful API. Connections via http+ssh://, http+unix:// or -tcp:// are supported. +Podman services are addressed using a URL where the scheme signals to the client how to connect to +service. Supported schemes are: ``http+ssh``, ``http+unix`` or ``tcp``. Formats are the following styles: -.. automodule:: podman - :members: - :inherited-members: + - ``http+ssh://[@][:]/`` + + - ``http+ssh://alice@api.example:22/run/user/1000/podman/podman.sock`` + - The scheme ``ssh`` is excepted as an alias + + - ``http+unix://`` + + - ``http+unix:///run/podman/podman.sock`` + - The scheme ``unix`` is excepted as an alias + + - ``tcp://:`` + + - ``tcp://api.example:8888`` + +Example +------- +.. code-block:: python + :linenos: + + import podman + + with podman.Client() as client: + if client.ping(): + images = client.images.list() + for image in images: + print(image.id) + +.. toctree:: + :caption: Podman Client + :maxdepth: 2 + + podman.client .. toctree:: - :maxdepth: 2 - :caption: Contents: + :caption: Podman Entities + :glob: + :hidden: - modules + podman.domain.containers + podman.domain.containers_manager + podman.domain.images + podman.domain.images_manager + podman.domain.events* + podman.domain.manifests* + podman.domain.networks* + podman.domain.pods* + podman.domain.secrets* + podman.domain.system* + podman.domain.volume* + podman.errors.exceptions Indices and tables ================== diff --git a/podman/domain/containers.py b/podman/domain/containers.py index 929d4972..3bdccd1b 100644 --- a/podman/domain/containers.py +++ b/podman/domain/containers.py @@ -93,9 +93,6 @@ def commit(self, repository: str = None, tag: str = None, **kwargs) -> Image: format (str): Format of the image manifest and metadata message (str): Commit message to include with Image pause (bool): Pause the container before committing it - - Notes: - See https://docs.podman.io/en/latest/_static/api.html#operation/libpodCommitContainer """ params = { "author": kwargs.get("author"), diff --git a/podman/domain/images.py b/podman/domain/images.py index 4149619b..ffdeb78b 100644 --- a/podman/domain/images.py +++ b/podman/domain/images.py @@ -44,23 +44,23 @@ def history(self) -> List[Dict[str, Any]]: response.raise_for_status(not_found=ImageNotFound) return response.json() - def remove(self, **kwargs) -> List[Dict[str, Union[str, int]]]: + def remove( + self, **kwargs + ) -> List[Dict[api.Literal["Deleted", "Untagged", "Errors", "ExitCode"], Union[str, int]]]: """Delete image from Podman service. + Podman only + Keyword Args: force: Delete Image even if in use noprune: Ignored. Returns: - List[Dict[Literal["Deleted", "Untagged", "Errors", "ExitCode"], Union[str, int]]] + Report on which images were deleted and untagged, including any reported errors. Raises: ImageNotFound: when image does not exist APIError: when service returns an error - - Notes: - - Podman only - - The dictionaries with keys Errors and ExitCode are added. """ return self.manager.remove(self.id, **kwargs) @@ -71,6 +71,8 @@ def save( ) -> Iterator[bytes]: """Returns Image as tarball. + Format is set to docker-archive, this allows load() to import this tarball. + Args: chunk_size: If None, data will be streamed in received buffer size. If not None, data will be returned in sized buffers. Default: 2MB @@ -78,9 +80,6 @@ def save( Raises: APIError: when service returns an error - - Notes: - Format is set to docker-archive, this allows load() to import this tarball. """ response = self.client.get( f"/images/{self.id}/get", params={"format": ["docker-archive"]}, stream=True diff --git a/setup.cfg b/setup.cfg index 6a758858..2d0b9148 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,7 +33,8 @@ test_suite = install_requires = requests>=2.24 toml>=0.10.2 - urllib3~=1.26.4 + urllib3~=1.24.2 + pyxdg~=0.26 [bdist_wheel] # python < 3.6 not supported diff --git a/test-requirements.txt b/test-requirements.txt index 93be1a72..9242df59 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,3 +1,4 @@ +-r requirements.txt black coverage fixtures~=3.0.0