25

I'm quite a newbie when it comes to Python, thus I beg foregiveness beforehand :). That said, I'm trying to make a script that, among other things, installs some Linux packages. First I tried to use subopen as explained here. While this can eventually work, I stumbled upon the python-apt API and since I'm not a big fan or re-inventing the wheel, I decided to give a try.

Problem comes when trying to find examples/tutorials on installing a package using python-apt. Searching the documentation I found the PackageManager class that has some methods to install a package. I tried some simple code to get this working:

apt_pkg.PackageManager.install("python")

This does not seem to work that easily, the install method expects apt_pkg.PackageManager instead of a plain String. Thus, looking a bit more, I found this example that looks promising, but I'm a bit reluctant to use since I don't really understand some of what is happening there.

Then, has anyone tried to install a package using python-apt or should I go for using plain-old subopen style?

Thanks!

Community
  • 1
  • 1
AlejandroVK
  • 7,373
  • 13
  • 54
  • 77
  • python-apt seems discontinued, most of the links no longer work and according to pypi the package hasn't seen an update since it's release in 2012 – DBX12 Dec 17 '18 at 08:05
  • @DBX12 I think it's just the pypi package that isn't being maintained. A much newer version is in the Debian repos. For py2 (https://packages.debian.org/stretch/python-apt) or (separate package) for py3 (https://packages.debian.org/stretch/python3-apt). – Jeremy Davis Apr 03 '19 at 04:24
  • Just the check if already installed instead: https://stackoverflow.com/questions/3387961/check-if-a-debian-package-is-installed-from-python – Ciro Santilli OurBigBook.com Nov 18 '19 at 16:53

1 Answers1

51

It's recommended to use the apt module from the python-apt Debian package. This is a higher level wrapper around the underlying C/C++ libapt-xxx libraries and has a Pythonic interface.

Here's an example script which will install the libjs-yui-doc package:

#!/usr/bin/env python
# aptinstall.py

import apt
import sys

pkg_name = "libjs-yui-doc"

cache = apt.cache.Cache()
cache.update()
cache.open()

pkg = cache[pkg_name]
if pkg.is_installed:
    print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
    pkg.mark_install()

    try:
        cache.commit()
    except Exception, arg:
        print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))

As with the use of apt-get, this must be run with superuser privileges to access and modify the APT cache.

$ sudo ./aptinstall.py

If you're attempting a package install as part of a larger script, it's probably a good idea to only raise to root privileges for the minimal time required.

You can find a small example in the /usr/share/pyshared/apt/progress/gtk2.py:_test() function showing how to install a package using a GTK front-end.

Community
  • 1
  • 1
Austin Phillips
  • 15,228
  • 2
  • 51
  • 50
  • 1
    This is exactly what I was looking for! Thanks Austin, you're a star :D – AlejandroVK Jul 09 '13 at 07:49
  • 2
    You probably want to call `cache.open()` after `cache.update()`, in order to utilise the new cache. Otherwise, the old cache will be used which can lead to strange bugs. – lrsjng Apr 22 '14 at 14:18
  • 1
    Any way to catch the progress of an install, then do something else once it finishes? – answerSeeker Jan 22 '17 at 02:37
  • You can deal with the progress of the un/install operation by subclassing InstallProgress, as described here: https://github.com/excid3/python-apt/blob/master/doc/examples/inst.py – ACK_stoverflow Mar 30 '22 at 17:03