jenkins: include local bin directory in PATH
[gnupg-doc.git] / misc / blog.gnupg.org / 20160921-python-bindings-for-gpgme.org
1 # Python bindings for GPGME
2 #+STARTUP: showall
3 #+AUTHOR: Justus
4 #+DATE: September 21th, 2016
5
6 ** Python bindings for GPGME
7
8 GPGME 1.7 includes bindings for Python >= 2.7.  The bindings are a
9 port of the [[https://bitbucket.org/malb/pyme][~pyme~]] bindings to Python 3 retaining compatibility with
10 Python 2.7, with a small shim on top to provide a more idiomatic
11 interface.  For the purposes of this post I will refer to the
12 preexisting bindings that are for Python 2 only ~pyme2~, and to our
13 new bindings as ~pyme3~.  Existing applications using ~pyme2~ should
14 continue to work no changes.
15
16 ~pyme2~ offers an interface that is very close to that of GPGME.  This
17 interface exposes all features of the underlying library, but it is
18 not very "pythonic".  Therefore, we made an effort to provide a nicer
19 interface on top of that.  Let me demonstrate how that looks.
20
21 One important aspect is how to pass data around.  GPGME uses
22 ~gpgme_data_t~ for that, and in ~pyme2~ one had to explicitly create
23 ~pyme.core.Data~ objects to pass data to GPGME or to receive data.
24 With ~pyme3~ one can use every object that implements the buffer
25 protocol (e.g. ~bytes~), file-like objects with a ~fileno~ method, or
26 explicit ~pyme.Data~ objects in places where GPGME expects a
27 ~gpgme_data_t~ object:
28
29 #+BEGIN_SRC python
30 import pyme
31 with pyme.Context(armor=True) as c:
32     ciphertext, _, _ = c.encrypt(b"Hello Python world :)", passphrase="foo")
33 #+END_SRC
34
35 This will encrypt the given plaintext using symmetric encryption and
36 the given passphrase, wrap it up using the OpenPGP protocol, and
37 encode it using ASCII-armor.  The plaintext is easily recovered using:
38
39 #+BEGIN_SRC python
40 with pyme.Context() as c:
41     plaintext, _, _ = c.decrypt(ciphertext, passphrase="foo")
42 assert plaintext == b"Hello Python world :)"
43 #+END_SRC
44
45 If ~passphrase~ is omitted, it is asked for out-of-band using GnuPG's
46 pinentry mechanism.  Alternatively, if one or more recipients are
47 specified, asymmetric encryption is used.  For details, please have a
48 look at the docstring of ~pyme.Context.encrypt~.
49
50 Most file-like objects can be used without explicit wrapping.  This is
51 a filter that decrypts OpenPGP messages in three lines of code:
52
53 #+BEGIN_SRC python
54 import sys
55 import pyme
56 pyme.Context().decrypt(sys.stdin, sink=sys.stdout)
57 #+END_SRC
58
59 For more examples, have a look at the tests and examples shipped with
60 the bindings under ~lang/python~.
61
62 If you cannot wait until ~pyme3~ is packaged by your distribution, and
63 you do not want to build GPGME 1.7 from source merely to get ~pyme3~,
64 you can build it out-of-tree provided you have at least GPGME 1.6, the
65 Python development packages, and SWIG.  You can get it from [[https://pypi.python.org/pypi/pyme3][pypi]] or
66 directly install it using ~pip~:
67
68 #+BEGIN_SRC sh
69 # As of this writing, there is no released version uploaded to pypi,
70 # hence we need --pre.
71 $ pip install --pre pyme3
72 #+END_SRC