From b1581f5d521911f847e20501c270c840b1eb6494 Mon Sep 17 00:00:00 2001 From: kaliko Date: Sun, 10 Mar 2024 07:59:34 +0100 Subject: [PATCH] Add more docstrings --- doc/source/conf.py | 9 ++++++--- doc/source/explanations.rst | 10 +++++----- doc/source/reference.rst | 20 +++++++++++++++++-- doc/source/tutorial.rst | 12 +++++++++-- mpdaio/client.py | 40 +++++++++++++++++++++++++++++-------- mpdaio/const.py | 1 - 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index c0f2a05..94bd369 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -5,10 +5,10 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -import os +import pathlib import sys -sys.path.insert(0, os.path.abspath('../../')) +sys.path.insert(0, pathlib.Path(__file__).parents[2].resolve().as_posix()) from mpdaio.const import VERSION project = 'musicpdaio' @@ -51,9 +51,12 @@ rst_epilog = """ .. _python-musicpd: https://kaliko.gitlab.io/python-musicpd .. _Semantic Versioning: https://semver.org/spec/v2.0.0.html .. _snake case: https://en.wikipedia.org/wiki/Snake_case - +.. |mpdaio.MPDClient| replace:: :py:class:`mpdaio.MPDClient` """ +autodoc_typehints = 'description' +autodoc_member_order = 'bysource' + # -- Options for intersphinx extension --------------------------------------- # https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration diff --git a/doc/source/explanations.rst b/doc/source/explanations.rst index b3d4fbb..86c45ce 100644 --- a/doc/source/explanations.rst +++ b/doc/source/explanations.rst @@ -40,7 +40,7 @@ The MPD command protocol exchanges line-based text records. The client emits a command with optional arguments. In the example above the client sends a `setvol` command with the string argument `42`. -MPD commands are exposed as :py:class:`mpdaio.MPDClient` methods. Methods +MPD commands are exposed as |mpdaio.MPDClient| methods. Methods **arguments are python strings**. Some commands are composed of more than one word (ie "**tagtypes [disable|enable|all]**"), for these use a `snake case`_ style to access the method. Then **"tagtypes enable"** command is called with @@ -52,11 +52,11 @@ strings. In the example above, an integer can be used as argument for the written to the socket. To avoid confusion use regular string instead of relying on object string representation. -:py:class:`mpdaio.MPDClient` methods returns different kinds of objects +|mpdaio.MPDClient| methods returns different kinds of objects depending on the command. Could be :py:obj:`None`, a single object as a :py:obj:`str` or a :py:obj:`dict`, a list of :py:obj:`dict`. -Then :py:class:`mpdaio.MPDClient` **methods signatures** are not hard coded +Then |mpdaio.MPDClient| **methods signatures** are not hard coded within this module since the protocol is handled on the server side. Please refer to the protocol and MPD commands in `MPD protocol documentation`_ to learn how to call commands and what kind of arguments they expect. @@ -64,7 +64,7 @@ learn how to call commands and what kind of arguments they expect. Some examples are provided for the most common cases, see :ref:`tutorial`. **musicpdaio** tries to come with sane defaults, then running -:py:class:`mpdaio.MPDClient` with no explicit argument will try default values +|mpdaio.MPDClient| with no explicit argument will try default values to connect to MPD. Cf. :ref:`reference` for more about :ref:`defaults`. @@ -77,7 +77,7 @@ Socket connection **musicpdaio** uses a connection pool internally to keep already opened socket and reuse it. -When first instantiated :py:class:`mpdaio.MPDClient` comes with an empty pool, +When first instantiated |mpdaio.MPDClient| comes with an empty pool, when the first MPD command is called a connection is opened, saved and potentially reused later. In case a concurrent MPD command is called while the connection is still in use a new connection is made and kept in the pool. diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 1459b92..8bca579 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -8,7 +8,7 @@ Reference Environment variables --------------------- -:py:class:`mpdaio.MPDClient` honors the following environment variables: +:py:class:`mpdaio.MPDClient` honors the following environment variables: .. envvar:: MPD_HOST @@ -48,8 +48,24 @@ Default timeout: * use :envvar:`MPD_TIMEOUT` if set * else use :py:obj:`mpdaio.const.CONNECTION_TIMEOUT` - Supported commands ------------------ .. include:: commands.rst + +Module documentation +-------------------- + +MPDClient class +^^^^^^^^^^^^^^^ + +.. automodule:: mpdaio.client + :members: + +Constants +^^^^^^^^^ + +.. automodule:: mpdaio.const + :members: + +.. vim: spell spelllang=en diff --git a/doc/source/tutorial.rst b/doc/source/tutorial.rst index b0280d7..0540df9 100644 --- a/doc/source/tutorial.rst +++ b/doc/source/tutorial.rst @@ -44,10 +44,18 @@ Getting started .. index:: single: command; password +**musicpdaio** tries to come with sane defaults, then running +:py:class:`mpdaio.MPDClient` with no explicit argument will try default values +to connect to MPD. Cf. :ref:`reference` for more about +:ref:`defaults`. + **Using a specific host, port and a password.** -The password is sent when a connection is made, no need to explicitly send the -password command. +The password is sent when a connection is made, no need to explicitly use the +password command. In the following code a client is constructed with a password argument, then when the ping method is called: + * the client fetch a connection from the pool + * then a password command is sent with the password + * finally the ping command is sent. .. sourcecode:: python diff --git a/mpdaio/client.py b/mpdaio/client.py index 48b37bd..c37e0d6 100644 --- a/mpdaio/client.py +++ b/mpdaio/client.py @@ -17,16 +17,38 @@ log = logging.getLogger(__name__) class MPDClient: + """:synopsis: Main class to instanciate building an MPD client. - def __init__(self, host: str | None = None, port: str | int | None = None, password: str | None = None): + :param host: MPD server IP|FQDN to connect to + :param port: MPD port to connect to + :param password: MPD password + + **musicpdaio** tries to come with sane defaults, then running + |mpdaio.MPDClient| with no explicit argument will try default values + to connect to MPD. Cf. :ref:`reference` for more about + :ref:`defaults`. + + The class is also exposed in mpdaio namespace. + + >>> import mpdaio + >>> cli = mpdaio.MPDClient(host='example.org') + >>> print(await cli.currentsong()) + >>> await cli.close() + """ + + def __init__(self, host: str | None = None, + port: str | int | None = None, + password: str | None = None): + #: Connection pool self._pool = ConnectionPool(max_connections=CONNECTION_MAX) self._get_envvars() - #: host used with the current connection (:py:obj:`str`) + #: Host used to make connections (:py:obj:`str`) self.host = host or self.server_discovery[0] - #: password detected in :envvar:`MPD_HOST` environment variable (:py:obj:`str`) + #: password used to connect (:py:obj:`str`) self.pwd = password or self.server_discovery[2] #: port used with the current connection (:py:obj:`int`, :py:obj:`str`) self.port = port or self.server_discovery[1] + #: connection timeout self.mpd_timeout = CONNECTION_TIMEOUT log.info('Using %s:%s to connect', self.host, self.port) @@ -87,8 +109,9 @@ class MPDClient: return lambda *args: wrapper(command, args) @property - def version(self): - """MPD protocol version""" + def version(self) -> str: + """MPD protocol version + """ host = (self.host, self.port) version = {_.version for _ in self.connections} if not version: @@ -99,12 +122,13 @@ class MPDClient: return version.pop() @property - def connections(self): - """Open connections""" + def connections(self) -> list[Connection]: + """connections in the pool""" host = (self.host, self.port) return self._pool._connections.get(host, []) - async def close(self): + async def close(self) -> None: + """:synopsis: Close connections in the pool""" await self._pool.close() diff --git a/mpdaio/const.py b/mpdaio/const.py index 35d86c6..e3cadf3 100644 --- a/mpdaio/const.py +++ b/mpdaio/const.py @@ -6,7 +6,6 @@ HELLO_PREFIX = 'OK MPD ' ERROR_PREFIX = 'ACK ' SUCCESS = 'OK' NEXT = 'list_OK' -#: Module version VERSION = '0.1.0b0' #: Seconds before a connection attempt times out #: (overriden by :envvar:`MPD_TIMEOUT` env. var.) -- 2.39.2