1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
:mod:`aptdaemon.client` --- The client module
=============================================
Introduction
------------
Aptdaemon comes with a client module which provides a smoother interface on top
of the D-Bus interface. It provides GObjects of the daemon and each transaction.
.. _life_cycle:
Life cycle of a transaction based action
----------------------------------------
At first you initialize an AptClient instance.
>>> from aptdaemon import client
>>>
>>> apt_client = client.AptClient()
Secondly you call the whished action, e.g. updating the package cache. It will
give you a new transaction instance.
>>> transaction = apt_client.update()
The transaction has not been started yet. So you can make some further
adjustements to it, e.g. setting a different language:
>>> transaction.set_locale("de_DE")
... or setup the monitoring of the transaction:
>>> transaction.connect("finished", on_transaction_finished)
You can then put the transaction on the queue by calling its :meth:`run()`
method:
>>> transaction.run()
If you don't need the underlying transcation instance of an action, you can
alternatively set the wait argument to True. The AptClient method will return
after the transaction is done:
>>> apt_client.update_cache(wait=True)
This can also be used with asynchronous programming, see below.
Asynchronous programming
------------------------
In the above examples simple synchronous calls have been made to the D-Bus.
Until these calls return your whole application is blocked/frozen.
In the case of password prompts this can be quite long. So aptdaemon supports
the following asynchronous styles:
D-Bus style callbacks
^^^^^^^^^^^^^^^^^^^^^
Since the client module is basically a wrapper around D-Bus calls, it provides
a pair of reply_handler and error_handler for each method. You are perhaps
already familiar with those if you have written a Python D-Bus client before:
>>> def run(trans):
... trans.run(reply_handler=trans_has_started, error_handler=on_error)
...
>>> def trans_has_started():
... pass
...
>>> def on_error(error):
... raise error
...
>>> client = AptClient()
>>> client.update(reply_handler=run, error_handler=on_error)
Deferred callbacks
^^^^^^^^^^^^^^^^^^
Aptdaemon uses a simplified version of Twisted deferreds internally, called
python-defer. But you can also make use of them in your application.
The inline_callbacks decorator of python-defer allows to write asynchronous
code in a synchronous way:
>>> @defer.inline_callbacks
... def update_cache():
... apt_client = client.AptClient()
... try:
... transaction = yield apt_client.update()
... except errors.NotAuthorizedError:
... print "You are not allowed to update the cache!"
... return
... yield transaction.set_locale("de_DE")
... yield transaction.run()
... print "Transaction has started"
.. _chaining:
Chaining Transactions
---------------------
It is possible to chain transactions. This allows to add a simple
dependency relation, e.g. you want to add a new repository, update
the cache and finally install a new package.
>>> client = aptdaemon.client.AptClient()
>>> trans1 = client.add_repository("deb", [...])
>>> trans2 = client.update_cache()
>>> trans3 = client.install_packages(["new-package"])
>>> trans2.run_after(trans1)
>>> trans3.run_after(trans2)
>>> trans1.run()
If a transaction in a chain fails all other ones which follow will
fail too with the :data:`enums.EXIT_PREVIOUS_FAILED` exit state.
Class Reference
---------------
.. autoclass:: aptdaemon.client.AptClient
:members:
.. autoclass:: aptdaemon.client.AptTransaction
:members:
Function Reference
------------------
.. autofunction:: aptdaemon.client.get_transaction
.. autofunction:: aptdaemon.client.get_aptdaemon
|