Skip to content

Documentation Style

Example of a Properly Formatted Docstring in Functions

Section titled “Example of a Properly Formatted Docstring in Functions”
"""
Reads entries from the given streams.
See https://valkey.io/commands/xread for more details.
Note:
When in cluster mode, all keys in `keys_and_ids` must map to the same hash slot.
Warning:
If we wanted to provide a warning message, we would format it like this.
Args:
keys_and_ids (Mapping[TEncodable, TEncodable]): A mapping of keys and entry
IDs to read from.
options (Optional[StreamReadOptions]): Options detailing how to read the stream.
Returns:
Optional[Mapping[bytes, Mapping[bytes, List[List[bytes]]]]]: A mapping of stream keys, to a mapping of stream IDs,
to a list of pairings with format `[[field, entry], [field, entry], ...]`.
None will be returned under the following conditions:
- All key-ID pairs in `keys_and_ids` have either a non-existing key or a non-existing ID, or there are no
entries after the given ID.
- The `BLOCK` option is specified and the timeout is hit.
Examples:
>>> await client.xadd("mystream", [("field1", "value1")], StreamAddOptions(id="0-1"))
>>> await client.xadd("mystream", [("field2", "value2"), ("field2", "value3")], StreamAddOptions(id="0-2"))
>>> await client.xread({"mystream": "0-0"}, StreamReadOptions(block_ms=1000))
{
b"mystream": {
b"0-1": [[b"field1", b"value1"]],
b"0-2": [[b"field2", b"value2"], [b"field2", b"value3"]],
}
}
# Indicates the stream entries for "my_stream" with IDs greater than "0-0". The operation blocks up to
# 1000ms if there is no stream data.
"""

Example of Properly Formatted Documentation for a Class

Section titled “Example of Properly Formatted Documentation for a Class”
class BitOffsetMultiplier(BitFieldOffset):
"""
Represents an offset in an array of bits for the `BITFIELD` or `BITFIELD_RO` commands. The bit offset index is
calculated as the numerical value of the offset multiplied by the encoding value. Must be greater than or equal
to 0.
For example, if we have the binary 01101001 with offset multiplier of 1 for an unsigned encoding of size 4, then
the value is 9 from `0110(1001)`.
Attributes:
offset (int): The offset in the array of bits, which will be multiplied by the encoding value to get the
final bit index offset.
"""
#: Prefix specifying that the offset uses an encoding multiplier.
OFFSET_MULTIPLIER_PREFIX = "#"
def __init__(self, offset: int):
self._offset = f"{self.OFFSET_MULTIPLIER_PREFIX}{str(offset)}"
def to_arg(self) -> str:
return self._offset

Example of Properly Formatted Documentation for Enums

Section titled “Example of Properly Formatted Documentation for Enums”
class ConditionalChange(Enum):
"""
A condition to the `SET`, `ZADD` and `GEOADD` commands.
"""
ONLY_IF_EXISTS = "XX"
""" Only update key / elements that already exist. Equivalent to `XX` in the Valkey API. """
ONLY_IF_DOES_NOT_EXIST = "NX"
""" Only set key / add elements that does not already exist. Equivalent to `NX` in the Valkey API. """

To provide documentation for arguments or attributes, we can have each argument or attribute next to each other with descriptions that exceed the max line length indented on the next line:

Args:
some_num (int): If this line ever gets too long, what we could do is break this line
to the next line here, and indent it so that sphinx can see the line as part of
the same argument.
options (Optional[StreamReadOptions]): For other arguments, we start by having the indent
match up with the indent of the first line of the previous argument, and then follow
the same rule.
some_bool (bool): And then one-line descriptions are as usual.
Attributes:
some_num (int): If this line ever gets too long, what we could do is break this line
to the next line here, and indent it so that sphinx can see the line as part of
the same argument.
options (Optional[StreamReadOptions]): For other arguments, we start by having the indent
match up with the indent of the first line of the previous argument, and then follow
the same rule.
some_bool (bool): And then one-line descriptions are as usual.

Return values are a little special for sphinx. If we wanted to provide more context or multiple possible return values, the convention we will go for is that we should add a space between every different return value.

We start by adding the return type on the first line, followed by a description of the return value.

Note: for each return value, we should not indent the docs like args to show that it is part of the same return value. For example:

Returns:
List[int]: Some description here regarding the purpose of the list of ints being
returned. Notice how this new line is not indented but it is still apart of the same
description.
If we ever want to provide more context or another description of another return value
(ex. None, -1, True/False, etc.) we add a space between this description and the
previous description.

We have to add a space between the previous line and a line after the list ends and also indent the list by one indent level:

Args:
key (TEncodable): The key of the stream.
start (StreamRangeBound): The starting stream ID bound for the range.
- Use `IdBound` to specify a stream ID.
- Use `ExclusiveIdBound` to specify an exclusive bounded stream ID.
- Use `MinId` to start with the minimum available ID.
end (StreamRangeBound): The ending stream ID bound for the range.
- Use `IdBound` to specify a stream ID.
- Use `ExclusiveIdBound` to specify an exclusive bounded stream ID.
- Use `MaxId` to end with the maximum available ID.
count (Optional[int]): An optional argument specifying the maximum count of stream entries to return.

For examples, we can use the Example: or Examples: keyword and indent the following code block:

Examples:
>>> await client.xadd("mystream", [("field1", "value1")], StreamAddOptions(id="0-1"))
>>> await client.xadd("mystream", [("field2", "value2"), ("field2", "value3")], StreamAddOptions(id="0-2"))
>>> await client.xread({"mystream": "0-0"}, StreamReadOptions(block_ms=1000))
{
b"mystream": {
b"0-1": [[b"field1", b"value1"]],
b"0-2": [[b"field2", b"value2"], [b"field2", b"value3"]],
}
}
# Indicates the stream entries for "my_stream" with IDs greater than "0-0". The operation blocks up to
# 1000ms if there is no stream data.
... # More examples here

If we wanted to add a code block in a place other than the Examples block, we have to use a double colon syntax and indent the code block.

Attributes:
addresses (List[NodeAddress]): DNS Addresses and ports of known nodes in the cluster.
If the server is in cluster mode the list can be partial, as the client will attempt to map out
the cluster and find all nodes.
If the server is in standalone mode, only nodes whose addresses were provided will be used by the
client.
For example::
[
{address:sample-address-0001.use1.cache.amazonaws.com, port:6379},
{address: sample-address-0002.use2.cache.amazonaws.com, port:6379}
]
use_tls (bool): True if communication with the cluster should use Transport Level Security.
Should match the TLS configuration of the server/cluster, otherwise the connection attempt will fail

We want to use #: to add documentation for constants:

#: "GET" subcommand string for use in the `BITFIELD` or `BITFIELD_RO` commands.
GET_COMMAND_STRING = "GET"

We provide a general description at the top, and follow each enum value with a description beneath. Refer to the example.

If we wanted to show a regular link, we can add it as is. If we wanted to show hyperlinks, follow the reStructuredText (rst) link format:

Format: `text <link>`_

Example: `SORT <https://valkey.io/commands/sort/>`_