From: Kent Gibson <warthog618@gmail.com>
To: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Darrien <darrien@freenet.de>,
Viresh Kumar <viresh.kumar@linaro.org>, Jiri Benc <jbenc@upir.cz>,
Joel Savitz <joelsavitz@gmail.com>,
linux-gpio@vger.kernel.org
Subject: Re: [libgpiod v2][PATCH 3/5] bindings: python: add examples for v2 API
Date: Fri, 3 Jun 2022 20:46:00 +0800 [thread overview]
Message-ID: <20220603124600.GA35695@sol> (raw)
In-Reply-To: <20220525140704.94983-4-brgl@bgdev.pl>
On Wed, May 25, 2022 at 04:07:02PM +0200, Bartosz Golaszewski wrote:
> This adds the usual set of reimplementations of gpio-tools using the new
> python module.
>
> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
> ---
> bindings/python/examples/Makefile.am | 10 ++++++++
> bindings/python/examples/gpiodetect.py | 17 +++++++++++++
> bindings/python/examples/gpiofind.py | 20 +++++++++++++++
> bindings/python/examples/gpioget.py | 31 +++++++++++++++++++++++
> bindings/python/examples/gpioinfo.py | 35 ++++++++++++++++++++++++++
> bindings/python/examples/gpiomon.py | 31 +++++++++++++++++++++++
> bindings/python/examples/gpioset.py | 35 ++++++++++++++++++++++++++
> 7 files changed, 179 insertions(+)
> create mode 100644 bindings/python/examples/Makefile.am
> create mode 100755 bindings/python/examples/gpiodetect.py
> create mode 100755 bindings/python/examples/gpiofind.py
> create mode 100755 bindings/python/examples/gpioget.py
> create mode 100755 bindings/python/examples/gpioinfo.py
> create mode 100755 bindings/python/examples/gpiomon.py
> create mode 100755 bindings/python/examples/gpioset.py
>
> diff --git a/bindings/python/examples/Makefile.am b/bindings/python/examples/Makefile.am
> new file mode 100644
> index 0000000..4169469
> --- /dev/null
> +++ b/bindings/python/examples/Makefile.am
> @@ -0,0 +1,10 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +EXTRA_DIST = \
> + gpiodetect.py \
> + gpiofind.py \
> + gpioget.py \
> + gpioinfo.py \
> + gpiomon.py \
> + gpioset.py
> diff --git a/bindings/python/examples/gpiodetect.py b/bindings/python/examples/gpiodetect.py
> new file mode 100755
> index 0000000..08e586b
> --- /dev/null
> +++ b/bindings/python/examples/gpiodetect.py
> @@ -0,0 +1,17 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Reimplementation of the gpiodetect tool in Python."""
> +
> +import gpiod
> +import os
> +
> +if __name__ == "__main__":
> + for entry in os.scandir("/dev/"):
> + if gpiod.is_gpiochip_device(entry.path):
> + with gpiod.Chip(entry.path) as chip:
> + info = chip.get_info()
> + print(
> + "{} [{}] ({} lines)".format(info.name, info.label, info.num_lines)
> + )
> diff --git a/bindings/python/examples/gpiofind.py b/bindings/python/examples/gpiofind.py
> new file mode 100755
> index 0000000..e488a49
> --- /dev/null
> +++ b/bindings/python/examples/gpiofind.py
> @@ -0,0 +1,20 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Reimplementation of the gpiofind tool in Python."""
> +
> +import gpiod
> +import os
> +import sys
> +
> +if __name__ == "__main__":
> + for entry in os.scandir("/dev/"):
> + if gpiod.is_gpiochip_device(entry.path):
> + with gpiod.Chip(entry.path) as chip:
> + offset = chip.get_line_offset_from_name(sys.argv[1])
> + if offset is not None:
> + print("{} {}".format(chip.get_info().name, offset))
> + sys.exit(0)
> +
> + sys.exit(1)
> diff --git a/bindings/python/examples/gpioget.py b/bindings/python/examples/gpioget.py
> new file mode 100755
> index 0000000..c509f38
> --- /dev/null
> +++ b/bindings/python/examples/gpioget.py
> @@ -0,0 +1,31 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Simplified reimplementation of the gpioget tool in Python."""
> +
> +import gpiod
> +import sys
> +
> +Direction = gpiod.Line.Direction
> +Value = gpiod.Line.Value
> +
> +if __name__ == "__main__":
> + if len(sys.argv) < 3:
> + raise TypeError("usage: gpioget.py <gpiochip> <offset1> <offset2> ...")
> +
> + path = sys.argv[1]
> + offsets = []
> + for off in sys.argv[2:]:
> + offsets.append(int(off))
> +
> + with gpiod.request_lines(
> + path,
> + gpiod.RequestConfig(offsets=offsets, consumer="gpioget.py"),
> + gpiod.LineConfig(direction=Direction.INPUT),
> + ) as request:
With request_lines() being the primary entry point to the gpiod module,
consider extending it to allow the RequestConfig and LineConfig kwargs to
be passed directly to request_lines(), and for those transient objects to
be constructed within request_lines().
That way the average user does not need to concern themselves with those
objects and the code is easier to read.
i.e.
with gpiod.request_lines(
path,
offsets=offsets,
consumer="gpioget.py",
direction=Direction.INPUT,
) as request:
You can still support passing in complete RequestConfig and LineConfig
as kwargs for cases where the user requires complex configuration.
i.e.
with gpiod.request_lines(
path,
req_cfg=gpiod.RequestConfig(offsets=offsets, consumer="gpioget.py"),
line_cfg=gpiod.LineConfig(direction=Direction.INPUT),
) as request:
Or for those use cases the user could use the Chip.request_lines() (which
wouldn't have the kwarg sugar) instead.
Would be good to have some examples with complex configuration as well,
not just the tool reimplementations.
> + vals = request.get_values()
> +
> + for val in vals:
> + print("0" if val == Value.INACTIVE else "1", end=" ")
> + print()
> diff --git a/bindings/python/examples/gpioinfo.py b/bindings/python/examples/gpioinfo.py
> new file mode 100755
> index 0000000..3097d10
> --- /dev/null
> +++ b/bindings/python/examples/gpioinfo.py
> @@ -0,0 +1,35 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Simplified reimplementation of the gpioinfo tool in Python."""
> +
> +import gpiod
> +import os
> +
> +if __name__ == "__main__":
> + for entry in os.scandir("/dev/"):
> + if gpiod.is_gpiochip_device(entry.path):
> + with gpiod.Chip(entry.path) as chip:
> + cinfo = chip.get_info()
> + print("{} - {} lines:".format(cinfo.name, cinfo.num_lines))
> +
> + for offset in range(0, cinfo.num_lines):
> + linfo = chip.get_line_info(offset)
> + offset = linfo.offset
> + name = linfo.name
> + consumer = linfo.consumer
> + direction = linfo.direction
> + active_low = linfo.active_low
> +
> + print(
> + "\tline {:>3}: {:>18} {:>12} {:>8} {:>10}".format(
> + offset,
> + "unnamed" if name is None else name,
> + "unused" if consumer is None else consumer,
> + "input"
> + if direction == gpiod.Line.Direction.INPUT
> + else "output",
> + "active-low" if active_low else "active-high",
> + )
> + )
> diff --git a/bindings/python/examples/gpiomon.py b/bindings/python/examples/gpiomon.py
> new file mode 100755
> index 0000000..b0f4b88
> --- /dev/null
> +++ b/bindings/python/examples/gpiomon.py
> @@ -0,0 +1,31 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Simplified reimplementation of the gpiomon tool in Python."""
> +
> +import gpiod
> +import sys
> +
> +Edge = gpiod.Line.Edge
> +
> +if __name__ == "__main__":
> + if len(sys.argv) < 3:
> + raise TypeError("usage: gpiomon.py <gpiochip> <offset1> <offset2> ...")
> +
> + path = sys.argv[1]
> + offsets = []
> + for off in sys.argv[2:]:
> + offsets.append(int(off))
> +
> + buf = gpiod.EdgeEventBuffer()
> +
> + with gpiod.request_lines(
> + path,
> + gpiod.RequestConfig(offsets=offsets, consumer="gpiomon.py"),
> + gpiod.LineConfig(edge_detection=Edge.BOTH),
> + ) as request:
> + while True:
> + request.read_edge_event(buf)
> + for event in buf:
> + print(event)
Can you hide the buffer here to simplify the common case?
How about having the request manage the buffer, and add a generator
method that returns the next event, say edge_events()?
For the uncommon case, add kwargs to allow the user to provide the buffer,
or to specify the buffer size. If neither provided then the request
constructs a default sized buffer.
Then the code becomes:
with gpiod.request_lines(
path,
offsets=offsets,
consumer="gpiomon.py",
edge_detection=Edge.BOTH,
) as request:
for event in request.edge_events():
print(event)
> diff --git a/bindings/python/examples/gpioset.py b/bindings/python/examples/gpioset.py
> new file mode 100755
> index 0000000..3a8f8cc
> --- /dev/null
> +++ b/bindings/python/examples/gpioset.py
> @@ -0,0 +1,35 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
> +
> +"""Simplified reimplementation of the gpioset tool in Python."""
> +
> +import gpiod
> +import sys
> +
> +Value = gpiod.Line.Value
> +
> +if __name__ == "__main__":
> + if len(sys.argv) < 3:
> + raise TypeError("usage: gpioset.py <gpiochip> <offset1>=<value1> ...")
> +
> + path = sys.argv[1]
> + values = dict()
> + for arg in sys.argv[2:]:
> + arg = arg.split("=")
> + key = int(arg[0])
> + val = int(arg[1])
> +
> + if val == 1:
> + values[key] = Value.ACTIVE
> + elif val == 0:
> + values[key] = Value.INACTIVE
> + else:
> + raise ValueError("{} is an invalid value for GPIO lines".format(val))
> +
> + with gpiod.request_lines(
> + path,
> + gpiod.RequestConfig(offsets=values.keys(), consumer="gpioset.py"),
> + gpiod.LineConfig(direction=gpiod.Line.Direction.OUTPUT, output_values=values),
> + ) as request:
> + input()
> --
> 2.34.1
>
The focus of my comments above is to simplify the API for the most common
case, and to make it a little more Pythonic rather than mirroring the C
API, in both cases by hiding implementation details that the casual user
doesn't need to know about.
I'm pretty sure other minor things that I'm not 100% comfortable with are
the same as with the C++ bindings, and the Python is in keeping with that,
so I wont recover the same ground.
I'm ok with the series overall. As per my C++ comments, it would be
great to get some feedback from Python developers.
Cheers,
Kent.
next prev parent reply other threads:[~2022-06-03 12:46 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-25 14:06 [libgpiod v2][PATCH 0/5] bindings: implement python bindings for libgpiod v2 Bartosz Golaszewski
2022-05-25 14:07 ` [libgpiod v2][PATCH 1/5] bindings: python: remove old version Bartosz Golaszewski
2022-05-25 14:07 ` [libgpiod v2][PATCH 2/5] bindings: python: enum: add a piece of common code for using python's enums from C Bartosz Golaszewski
2022-05-25 14:07 ` [libgpiod v2][PATCH 3/5] bindings: python: add examples for v2 API Bartosz Golaszewski
2022-06-03 12:46 ` Kent Gibson [this message]
2022-06-04 2:41 ` Kent Gibson
2022-06-06 10:14 ` Andy Shevchenko
2022-06-07 1:52 ` Kent Gibson
2022-06-07 10:43 ` Andy Shevchenko
2022-06-08 15:39 ` Bartosz Golaszewski
2022-06-09 4:49 ` Kent Gibson
2022-06-09 8:42 ` Bartosz Golaszewski
2022-06-09 13:21 ` Jiri Benc
2022-06-09 16:06 ` Bartosz Golaszewski
2022-06-10 4:23 ` Kent Gibson
2022-06-10 6:57 ` Bartosz Golaszewski
2022-05-25 14:07 ` [libgpiod v2][PATCH 4/5] bindings: python: add tests " Bartosz Golaszewski
2022-05-25 14:07 ` [libgpiod v2][PATCH 5/5] bindings: python: add the implementation " Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220603124600.GA35695@sol \
--to=warthog618@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=brgl@bgdev.pl \
--cc=darrien@freenet.de \
--cc=jbenc@upir.cz \
--cc=joelsavitz@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.