2710

Is it possible to upgrade all Python packages at one time with pip?

Note: that there is a feature request for this on the official issue tracker.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thedjpetersen
  • 27,857
  • 4
  • 26
  • 28
  • 68
    Beware [software rot](http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/)—upgrading dependencies might break your app. You can list the exact version of all installed packages with `pip freeze` (like `bundle install` or `npm shrinkwrap`). Best to save a copy of that before tinkering. – Colonel Panic May 22 '13 at 13:01
  • 5
    If you want to update a single package and all of *its* dependencies (arguably a more sensible approach), do this: pip install -U --upgrade-strategy eager your-package – Cyberwiz Feb 24 '21 at 15:33
  • 13
    I use PowerShell 7 and currently I use this one-liner: `pip list --format freeze | %{pip install --upgrade $_.split('==')[0]}` (I am unable to post an answer here yet) –  Mar 07 '21 at 05:11
  • 1
    For those wondering like me, the was until recently pip didn't have a dependency resolver. https://github.com/pypa/pip/issues/4551 – qwr Sep 11 '22 at 19:07

57 Answers57

2811

There isn't a built-in flag yet. Starting with pip version 22.3, the --outdated and --format=freeze have become mutually exclusive. Use Python, to parse the JSON output:

pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))" | xargs -n1 pip install -U

If you are using pip<22.3 you can use:

pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

For older versions of pip:

pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

  • The grep is to skip editable ("-e") package definitions, as suggested by @jawache. (Yes, you could replace grep+cut with sed or awk or perl or...).

  • The -n1 flag for xargs prevents stopping everything if updating one package fails (thanks @andsens).


Note: there are infinite potential variations for this. I'm trying to keep this answer short and simple, but please do suggest variations in the comments!

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
rbp
  • 43,594
  • 3
  • 38
  • 31
  • 81
    Right :( The issue now lives at https://github.com/pypa/pip/issues/59 . But every suggestion seems to be answered with "Yeah, but I'm too sure if X is the right way to do Y"... Now is better than never? Practicality beats purity? :( – rbp Aug 12 '11 at 08:40
  • 28
    It also prints those packages that were installed with a normal package manager (like apt-get or Synaptic). If I execute this `pip install -U`, it will update all packages. I'm afraid it can cause some conflict with apt-get. – Jabba Sep 13 '11 at 04:11
  • 3
    Spot on - added an exclude to the grep to ignore editable packages. pip freeze --local | grep -v "\-e" | cut -d = -f 1 | xargs pip install -U – jawache Apr 25 '12 at 12:57
  • 2
    @PiotrDobrogost I've been trying to keep it simple. But, well, make sense. I've included it (with a small fix: I've pinned the regex to the beginning of the package name, in order to avoid excluding packages like "-e". – rbp Oct 22 '12 at 13:25
  • 8
    How about changing grep to: egrep -v '^(\-e|#)' (i get this line when running it on ubuntu 12.10: "## FIXME: could not find svn URL in dependency_links for this package:". – LasseValentini Mar 05 '13 at 14:29
  • 3
    You could also just use *sed*, for a much simpler line, e.g. (and this doesn't hit everything you included, but in principle it easily could): `pip freeze --local | sed 's/==.*//' | xargs pip install -U`. – Chris Krycho May 06 '13 at 03:34
  • 1
    How about this **pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -i bash -c 'pip install -U {} || :'** to prevent exit on error? – schemacs Nov 14 '13 at 13:59
  • 43
    I'd throw in a `tee` before doing the actual upgrade so that you can get a list of the original verisons. E.g. `pip freeze --local | tee before_upgrade.txt | ...` That way it would be easier to revert if there's any problems. – Emil L Mar 04 '14 at 06:29
  • 1
    @EmilH there are endless possibilities of enhancing or customising this :) I won't add your suggestion to the answer, to keep it simple (as much as possible). But it's a good one, thanks :) – rbp Mar 07 '14 at 11:05
  • 7
    If for some reason pip fails in the middle of it all (i.e. a package no longer exists) you can add `-n1` to `xargs`, this makes it pass only one argument at a time to pip, otherwise pip quits on the first error. – andsens Oct 20 '14 at 13:22
  • 1
    @andsens Is there any reason to not use -n1? Seems like it might make sense to include it by default... – Crawford Comeaux Feb 12 '15 at 10:56
  • 1
    @CrawfordComeaux No, not that I can think of :-) – andsens Feb 12 '15 at 11:40
  • 4
    The following incantation is updated to use pip list --outdated. It ignores any error or warning messages and does not consider them. `pip list --outdated | grep -G '(Current.*)' | sed 's/ (Current.*//' | xargs -n 1 sudo pip install --upgrade` – Utkonos Mar 02 '15 at 20:04
  • 1
    @richard-bronosky I've reverted your edit, although it was perfectly valid and probably even a good idea. As I've mentioned before, there are infinite variations of this solution, and I'm trying to keep the solution simple and as short as it's reasonable. For the record, Richard's solution was: pip freeze --local | tee before.pip.txt | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U (i.e., including "tee" to create a "before.pip.txt" file with the contents of "pip freeze" before the upgrade) – rbp Mar 04 '15 at 14:13
  • 4
    @rbp, that's fair. I have some suggestions since code golfing is the goal. (You said "simple and as short as it's reasonable") Instead of piping grep & cut, you can save **a process** and chars by using a single tool. Save 3 chars with awk `pip freeze --local | awk -F = '!/^-e/{print $1}' | xargs -n1 pip install -U` or 10 chars with sed `pip freeze --local | sed '/^-e/d;s/=.*//' | xargs -n1 pip install -U`. – Bruno Bronosky Mar 04 '15 at 15:19
  • 2
    User installed packages (i.e. those in ~/.local) should be handled separately, or they would be replaced with non-user installs. This looks like a decent task for a Github gist until pip has upgrade-all. – proski Apr 08 '15 at 14:44
  • 2
    Adding a sudo to the last element was required for me: pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | sudo xargs -n1 pip install - – Luke Dupin Sep 09 '15 at 22:23
  • 1
    @LukeDupin if you're installing packages globally, then yes, you might need that. If you're using virtualenv, it shouldn't be necessary. – rbp Sep 10 '15 at 16:20
  • 2
    Good example of pipes, but I would still use pip-review. Simple is better than complex;) – FredrikHedman Feb 13 '16 at 12:10
  • 1
    @FredrikHedman Perhaps, I've never used pip-review. You'll notice that this answer is *way* older than pip-review :) – rbp Feb 15 '16 at 09:42
  • 13
    I added `-H` to `sudo` to avoid an annoying error message: `$ pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 sudo -H pip install -U` – Mario S Mar 17 '16 at 01:53
  • 1
    pip list --outdated | grep -v 'sqlite3 (0.0.0)' | cut -d ' ' -f 1 | xargs -n1 pip install -U (to avoid upgrading sqilte3) – Ishayahu Dec 05 '16 at 12:26
  • Getting errors when running the above command on OSX, this answer: http://stackoverflow.com/a/25816730/2737316 solved the issue. i.e. run: ``pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U --user`` – vrleboss Mar 04 '17 at 00:46
  • 1
    I highly recommend running `pip check` afterwards to check if any upgrades caused a dependency to no longer be satisfied for another package. – Flimm Mar 08 '17 at 08:45
  • Is there any reason not to use xargs `-P` to parallelize the updates? – John Jones Jul 17 '17 at 18:26
  • The output is hard to read for outdated answer. This one is excellent: http://stackoverflow.com/questions/2720014/upgrading-all-packages-with-pip/42334797#42334797 – Douglas Daseeco Aug 31 '17 at 12:01
  • `Permission denied`... Any way to prevent this operating on system packages? – Tom Hale Oct 04 '17 at 13:05
  • In order to get rid of the permission issue, you might want to change it a bit into $pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 sudo -H pip install -U – thebeancounter Oct 30 '17 at 12:38
  • 1
    @rbp [Issue #59](https://github.com/pypa/pip/issues/59) is closed and references to [upgrade-all command #4551](https://github.com/pypa/pip/issues/4551), which depends on a not yet implemented [dependency resolver #988](https://github.com/pypa/pip/issues/988) – Dominik Nov 14 '17 at 14:45
  • This is exhaustive, it runs `--upgrade` on all packages , waste of time, we would upgrade the ones which are outdated right. – Morse Apr 02 '18 at 15:24
  • 2
    @pradyunsg, add `xargs -r` to prevent running upgrade commands if nothing to upgrade! :) – glen Apr 03 '18 at 04:42
  • 1
    To upgrade for logged in user (so doesn't require sudo): pip3 freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install --user -U – Fiddy Bux Apr 10 '18 at 10:11
  • 1
    Another reason to use `pip list --outdated --format=freeze` instead of `pip freeze --local` is that the latter does not upgrade `pip` itself if needed. – Giancarlo Sportelli Apr 13 '18 at 08:33
  • 2
    This failed on Windows 7: `'grep' is not recognized as an internal or external command, operable program or batch file.` – Stevoisiak Apr 26 '18 at 14:52
  • Why the ˋxargsˋ? – Timo Apr 30 '18 at 06:13
  • 1
    `pip 10` has added `--exclude-editable` option. https://pip.pypa.io/en/stable/news/#id30 – AXO Nov 30 '18 at 02:42
  • The output can be ambiguous when using this command. For a much more easily readable output, use this instead: https://stackoverflow.com/questions/2720014/upgrading-all-packages-with-pip/42334797#42334797 – Douglas Daseeco Jan 09 '19 at 08:17
  • 2
    In Python 3 there will be an error `TypeError: '>' not supported between instances of 'Version' and 'Version'` – Qin Heyang Mar 29 '19 at 20:15
  • @QinHeyang I don't follow. The command-line on the answer runs on bash. If you're getting this error, it's something to do with pip. – rbp Apr 01 '19 at 09:28
  • Has anyone figured out how to do this on Windows? – artemis May 21 '20 at 10:29
  • There seems to be a bug in the current version of pip that I have reported here: https://github.com/pypa/pip/issues/8331. When I run this command, pkg_resources==0.0.0 is getting added. Omitted -U in pip install seems to work – Hemil May 27 '20 at 07:57
  • pip was listing itself as outdated, which was breaking my brew installation. removing pip from the list of packages to update helps: `pip list --outdated --format=freeze | grep -v "pip=="| grep -v '^\-e' | cut -d = -f 1 | grep -v pip | xargs -n1 pip install -U`. Of course if another package ends with "pip" then it won't get updated, either :) – philshem Jul 06 '20 at 09:53
  • As of August 2020, this gives me many messages like so `ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.` is there a way to upgrade to dependencies along with the actual module? – Omglolyes Aug 11 '20 at 09:34
  • 2
    `pip list` has a `--not-required` option, which excludes packages that are dependencies of other installed packages. – Isaac Saffold Aug 22 '20 at 23:46
  • 1
    @Omglolyes Got the same error. Added `--use-feature=2020-resolver` at the end of the command and that resolved it. – Karsus Aug 23 '20 at 11:11
  • Seems like on Ubuntu, this also "updates" to an old version of `distro-info`, which breaks `do-release-upgrade`. See this AskUbuntu question https://askubuntu.com/questions/1182208/problem-with-upgrading-19-04-to-19-10-unicodedecodeerror-utf-8-codec-cant-d – Boris Verkhovskiy Aug 31 '20 at 16:05
  • Why show the cmd for older pip versions, is this still in use? Should I use an old pip version? – Timo Nov 23 '20 at 08:45
  • Python3 version: `pip3 list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip3 install -U` – Tomer Dec 16 '20 at 03:29
  • 1
    What is grep -v '^\-e' doing? Ah, read the whole post first! – Timo Dec 31 '20 at 09:51
  • I recently discovered that `pip list` has a `--user` option, which restricts the output to the user's *site-packages*. This avoids messing with *distro-info* on Ubuntu, which can cause serious [problems](https://github.com/pypa/pypi-support/issues/589). – Isaac Saffold Jan 26 '21 at 11:48
  • This has stopped working and gives a TypeError now. – John Tate May 03 '21 at 18:25
  • careful using this because it will likely override your distribution python packages – Scrooge McDuck May 30 '21 at 03:41
  • `pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U --user` - This is also a useful command. – Swapnadeep Mukherjee Jul 17 '21 at 16:06
  • 2
    What about adding `-r` to xargs, so it won't run `pip -U` _at all_ if there are no outdated packages? I did find this useful, otherwise I'd get the annoying message `ERROR: You must give at least one requirement to install (see "pip help install")` if I'd type that command in some environment with no outdated packages. NOTE: it seems `-r` option to xargs is a GNU extension. Enjoy! – Marco Pagliaricci Aug 01 '21 at 09:05
  • The grep-to-cut seems silly (and only gets sillier in the comments that grep multiple times), the output of `--format freeze` screams `awk`. `pip list -o --format freeze | awk 'BEGIN { FS="==" } { print $1 }' | xargs -n1 pip install -U` – sweenish Apr 04 '22 at 12:51
  • Nit: a superfluous space in the current edition of the answer, this part of the command (before the pipe): `cut -d = -f 1 |` – Graham Perrin Jun 11 '22 at 02:38
  • 2
    With latest pip format 'freeze' can not be used with the --outdated option anymore. – enclis Oct 19 '22 at 16:14
  • 1
    For those (like me) who did not understand instantly: pip3 --disable-pip-version-check list --outdated --format=json | python3 -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))" | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip3 install -U – enclis Oct 29 '22 at 20:38
  • 1
    You can use `pip3 list --outdated --format=json | jq -r '.[] | "\(.name)==\(.latest_version)"' | xargs -n1 pip3 install --upgrade`. – Suuuehgi Nov 14 '22 at 12:12
  • 3
    The first command is a lil bit misleading. It just lists the packages, NOT install/upgrade those. – Minh Nghĩa Jan 21 '23 at 07:16
  • Plus one for the comment of @Suuuehgi, the cmd works, but one need to install `jq`. The first command lists outdated pip packages, the third cmd works for me: `pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U`. – Timo Feb 19 '23 at 20:52
  • So the above generates a nice list of packages which have an update available. What is the remaining syntax to actually upgrade the identified packages; for WINDOWS? – Ghulam Mar 05 '23 at 15:18
  • 1
    The answer to my own question is: `pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys, subprocess; [subprocess.call(['pip', 'install', '--upgrade', x['name']]) for x in json.load(sys.stdin)]"` – Ghulam Mar 06 '23 at 09:42
  • For pip3 on the mac: `pip3 list --outdated | awk '{print $1}' | xargs -n1 pip3 install --upgrade` worked for me. – BitCrusher Mar 30 '23 at 22:48
852

To upgrade all local packages, you can install pip-review:

$ pip install pip-review

After that, you can either upgrade the packages interactively:

$ pip-review --local --interactive

Or automatically:

$ pip-review --local --auto

pip-review is a fork of pip-tools. See pip-tools issue mentioned by @knedlsepp. pip-review package works but pip-tools package no longer works. pip-review is looking for a new maintainer.

pip-review works on Windows since version 0.5.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • `NameError: name 'raw_input' is not defined` -- Broken for me. – hauzer Apr 25 '14 at 00:23
  • 3
    @hauzer: It doesn't support Python 3. Though [it might be a bug](https://github.com/nvie/pip-tools/pull/43) – jfs Apr 25 '14 at 00:27
  • 8
    @mkoistinen It's a good tool but until it's merged in PIP it means installing something additional which not everyone may desire to do. – Wernight Jul 22 '14 at 08:50
  • Works fine with mingw. Why are you using CMD on Windows if you're also using Python? – smaudet Nov 13 '14 at 20:30
  • 1
    @Wernight: if you can't install additional Python packages then you don't need `pip-review` (that automates installing new versions for you). In other words if you are in an environment where it makes sense to use `pip-review` tool then you can afford to install it too. – jfs Dec 01 '14 at 16:49
  • @J.F.Sebastian Yes pip-review is to upgrade and freeze dependencies. I meant that one will have `pip-review` in its `dev-requirements.txt`. It could become part of PIP. – Wernight Dec 02 '14 at 14:16
  • 1
    @julianz: There is [pip-toos-win](https://pypi.python.org/pypi/pip-tools-win/0.0.4), although I haven't tried it. – PTBNL Apr 28 '15 at 15:22
  • How to upgrade stuff for Python 3? It does not do so by default. – Ziyuan May 01 '15 at 08:52
  • @ziyuang create a new virtualenv using Python 3 version and install the necessary packages (`pip-dump` may help you to maintain the requirements file). See [Upgrade python in a virtualenv](http://stackoverflow.com/questions/10218946/upgrade-python-in-a-virtualenv) – jfs May 01 '15 at 21:24
  • 1
    If it no longer works, then shouldn't that be edited into the answer, since so many people don't read comments? – Daniel Oct 12 '15 at 04:21
  • 2
    @Daniel: pip-tools no longer works, pip-review (fork of pip-tools) works. – jfs Oct 12 '15 at 06:00
  • 8
    pip-review works just fine (at least for Python version 3.5.0) – FredrikHedman Feb 13 '16 at 12:13
  • 1
    pip-review should work under Windows as of version 0.5 (https://pypi.python.org/pypi/pip-review/0.5). Otherwise, please submit a ticket to https://github.com/jgonggrijp/pip-review/issues. – Julian Oct 09 '16 at 23:38
  • 1
    To skip system packages: `pip-review --auto --user` – Tom Hale Oct 04 '17 at 13:12
  • 35
    To update all without interactive mode: `pip-review --local --auto` – Dlamini May 21 '18 at 01:07
  • The output can be ambiguous when using this command. For a much more easily readable output, use this instead: https://stackoverflow.com/questions/2720014/upgrading-all-packages-with-pip/42334797#42334797 – Douglas Daseeco Jan 09 '19 at 08:18
  • For Windows, use `python.exe -m pip_review` instead of `pip-review`. (note the underscore instead of the dash) – Qin Heyang Nov 13 '19 at 04:03
  • pip-review --local --interactive does not seem to work: Complete output (5 lines): Traceback (most recent call last): File "", line 1, in File "/tmp/pip-install-ikq9nwd2/onedrivesdk/setup.py", line 9, in with open(NOTICE, 'r', encoding='utf-8') as f: NotADirectoryError: [Errno 20] Not a directory: '/tmp/pip-install-ikq9nwd2/onedrivesdk/setup.py/../NOTICE.rst' ---------------------------------------- ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output. – Gerd Mar 16 '20 at 10:42
  • @Gerd: it looks like an issue with the `onedrivesdk` package that is unrelated to `pip-review`. – jfs Mar 16 '20 at 16:28
  • Doesn't work with proxy, at least I didn't see that option – Aniruddha Kalburgi Nov 04 '22 at 16:29
  • It can take a lot of time to complete the run depending on how many packages are installed. – mac13k Jun 17 '23 at 12:57
832

You can use the following Python code. Unlike pip freeze, this will not print warnings and FIXME errors. For pip < 10.0.1

import pip
from subprocess import call

packages = [dist.project_name for dist in pip.get_installed_distributions()]
call("pip install --upgrade " + ' '.join(packages), shell=True)

For pip >= 10.0.1

import pkg_resources
from subprocess import call

packages = [dist.project_name for dist in pkg_resources.working_set]
call("pip install --upgrade " + ' '.join(packages), shell=True)
MSS
  • 3,306
  • 1
  • 19
  • 50
  • 30
    This works amazingly well… It's always so satisfying when a task takes a REALLY _long time_… and gives you a *bunch* of new stuff! PS: Run it as root if you're on OS X! – Alex Gray Dec 31 '11 at 04:13
  • 60
    Is there no way to install using pip without calling a subprocess? Something like `import pip` `pip.install('packagename')`? – endolith Mar 06 '12 at 16:18
  • 1
    @aspinei See my answer for Windows version of the shell script. – Piotr Dobrogost Oct 20 '12 at 10:07
  • 7
    I wrapped this up in a [fabfile.py](https://gist.github.com/joshkehn/5485111). Thanks! – Josh K Apr 29 '13 at 21:54
  • 1
    Question, will that upgrade System Packages as well? (Running as root)? If so, is there a way to prevent this instead of using virtualenv? Thanks. –  Jul 18 '13 at 10:25
  • 7
    @BenMezger: You really shouldn't be using system packages in your virtualenv. You also really shouldn't run more than a handful of trusted, well-known programs as root. Run your virtualenvs with --no-site-packages (default in recent versions). – jeffcook2150 Aug 26 '13 at 02:01
  • 3
    Thumbs up for this one, the chosen answer (above) fails if a package can't be found any more. This script simply continues to the next packages, wonderful. – Josh Jun 03 '14 at 12:42
  • It's awesome that this can be run within python! If I wanted it to print out whether or not a package was successfully updated, how would I modify this script? – Michael Jul 01 '14 at 17:35
  • 3
    This doesn't work and possibly screws things up work for dealing with system-wide packages. – Ian Kelling Sep 20 '14 at 04:43
  • 2
    Should be the accepted answer. Only one issue came up, if you have two or more Python installations in your Windows, only one gets to upgrade the packages. `pip` in this case is the `pip.exe` of the "default" Python. I changed it to `call("%s\\Scripts\\pip.exe install --upgrade %s" % (dirname(sys.executable), dist.project_name), shell=True)` which of course makes it unusable on non-Windows platforms, though. – 0xC0000022L Aug 11 '15 at 21:44
  • I hope this is the feature that gets implemented in pip package proper. Just a function `pip.updateall()` would be perfect. – FundThmCalculus Oct 12 '16 at 12:41
  • It's weird how `pip` doesn't write `--upgrade` flag in their help – Aminah Nuraini Feb 22 '17 at 21:42
  • @AminahNuraini: It does. – nightuser May 11 '17 at 07:26
  • pip freeze has a lot of permission denied for me even with sudo. this answer perfectly solves my problem – ArtificiallyIntelligence Jun 11 '17 at 18:16
  • `Permission denied`... Any way to prevent this operating on system packages? – Tom Hale Oct 04 '17 at 13:04
  • @TomHale Check the `dist.location` and filter the list accordingly. – Tomalak Nov 19 '17 at 11:40
  • This works with ActiveState ActivePython. However, after you do this, if you try to run a .py file by relying on the file association. Windows will attempt to run the ActiveState ActivePython installer again. – Benilda Key Feb 02 '18 at 06:05
  • 1
    Also note that this script fails if one package fails to install (which does happen for certain C extensions on Windows), while [the previous version of the script](https://stackoverflow.com/revisions/5839291/2) will continue upgrading everything else. – anonymoose Aug 03 '18 at 16:03
  • 1
    Best answer here. I created a gist on Github here: https://gist.github.com/SeppPenner/efc73891480b67c561aac7ba47df9df7 – FranzHuber23 Oct 30 '18 at 20:11
  • The output can be ambiguous when using this command. For a much more easily readable output, use this instead: https://stackoverflow.com/questions/2720014/upgrading-all-packages-with-pip/42334797#42334797 – Douglas Daseeco Jan 09 '19 at 08:18
  • 1
    I had to change the last line to `[call("pip install " + name + " --upgrade") for name in packages]` – Vasco Cansado Carvalho Jul 25 '20 at 14:26
  • @Josh fabric is for ssh, if I do not need ssh is your fabfile also interesting? I ask because the cmd of the answer for pip>10 does not work, I get an error when importing pkg_resources – Timo Dec 31 '20 at 10:42
  • @Josh the fabfile does not work in pip >10 – Timo Dec 31 '20 at 13:09
  • It worked for me on Windows for pip>=10.0.1 without changing anything. – Camilo Martinez M. Feb 09 '21 at 20:41
  • @0xC0000022L if you change the line `from subprocess import call` to `from subprocess import call, executable` and the call line to `call([executable, "-mpip", "install", "--upgrade"].extend(packages)], shell=True)` then it will call the `pip` for the current executable regardless of platform, venv, etc. – Steve Barnes Jan 13 '23 at 09:10
  • 1
    @SteveBarnes: thanks, agreed, I am aware of that method meanwhile and prefer it even. In addition on Windows I am preaching to people to use the Python loader (`py`) instead of some hardcoded paths to some possibly installed Python. As a side note, between my comment (from 2015) and now, I have also simply tapped into the `pip` module directly instead of doing that via the shell. E.g. in one project I had the project offer the option to pull in missing packages. – 0xC0000022L Jan 13 '23 at 09:41
458

The following works on Windows and should be good for others too ($ is whatever directory you're in, in the command prompt. For example, C:/Users/Username).

Do

$ pip freeze > requirements.txt

Open the text file, replace the == with >=, or have sed do it for you:

$ sed -i 's/==/>=/g' requirements.txt

and execute:

$ pip install -r requirements.txt --upgrade

If you have a problem with a certain package stalling the upgrade (NumPy sometimes), just go to the directory ($), comment out the name (add a # before it) and run the upgrade again. You can later uncomment that section back. This is also great for copying Python global environments.


Another way:

I also like the pip-review method:

py2
$ pip install pip-review

$ pip-review --local --interactive

py3
$ pip3 install pip-review

$ py -3 -m pip-review --local --interactive

You can select 'a' to upgrade all packages; if one upgrade fails, run it again and it continues at the next one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
azazelspeaks
  • 5,727
  • 2
  • 22
  • 39
  • 33
    You should remove `requirements.txt`'s `=={version}`. For example: `python-dateutil==2.4.2` to `python-dateutil` for all lines. – youngminz May 15 '16 at 05:28
  • 7
    I found that this didn't actually upgrade the packages on macOS. – jkooker Mar 08 '17 at 14:42
  • 14
    @youngminz I would recommand a quick 'Replace all "==" > ">=" ' in your editor/ide before running 'pip install...' to fix this – Amaury Liet Mar 16 '17 at 11:12
  • This is exactly what I wanted. I have a python virtualenv and I needed keep it up to date. It upgraded all existing packages in the requirements.txt. – alex Apr 07 '17 at 04:41
  • Although I like very much the jfs solution with pip-review, this solution gives you the flexibility to choose what you want upgrade or not, easily. @Amaury-Liet good catch! – tombolinux Dec 10 '17 at 08:26
  • 9
    for linux: `$ pip freeze | cut -d '=' -f1> requirements.txt` in order to remove the version – Cavaz Jan 14 '18 at 18:22
  • 2
    If the shell you use is bash, you can shorten it into one command via `pip3 install -r <(pip3 freeze) --upgrade` Effectively, `<(pip3 freeze)` is an anonymous pipe, but it will act as a file object – Sergiy Kolodyazhnyy Sep 03 '18 at 22:17
  • And in case it [fails on a single package](https://stackoverflow.com/questions/22250483/stop-pip-from-failing-on-single-package-when-installing-with-requirements-txt), you can make it `xargs -L 1 -a <(pip3 freeze) pip3 install --upgrade` – Sergiy Kolodyazhnyy Sep 03 '18 at 22:26
  • Works for me in Ubuntu 16.04 (with@Cavaz's modification): `$ pip freeze | cut -d '=' -f1> reqs` and then I open file and comment `cytoolz` (using `#`) which was causing errors; finally `$ pip install -r reqs --upgrade`. – Daniel Feb 09 '20 at 16:34
  • 1
    Combine the above comments, this one-liner `pip3 install -r <(pip3 freeze | cut -d '=' -f1) --upgrade` works on Bash. – whatacold Jun 13 '20 at 14:00
  • As this answer relates to Windows, here is a PS try: `$pfr=$(pip freeze > requirements.txt) $pfr=$pfr.split('=')`. Error `WARNING: Could not generate requirement for distribution -p 20.2.3 (c:\python39\lib\site-packages): Parse error at "'-p==20.2'": Expected W:(abcd...)` – Timo Nov 23 '20 at 12:11
  • I am on python 3. `py -3 -m pip-review --local --interactive` gave an error: `No module named pip-review`. Simply `pip-review` worked for me. – N3RDIUM Jan 07 '22 at 11:32
287

Use pipupgrade! ... last release 2019

pip install pipupgrade
pipupgrade --verbose --latest --yes

pipupgrade helps you upgrade your system, local or packages from a requirements.txt file! It also selectively upgrades packages that don't break change.

pipupgrade also ensures to upgrade packages present within multiple Python environments. It is compatible with Python 2.7+, Python 3.4+ and pip 9+, pip 10+, pip 18+, pip 19+.

Enter image description here

Note: I'm the author of the tool.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
159

Windows version after consulting the excellent documentation for FOR by Rob van der Woude:

for /F "delims===" %i in ('pip freeze') do pip install --upgrade %i
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
  • 33
    `for /F "delims= " %i in ('pip list --outdated') do pip install -U %i ` Quicker since it'll only try and update "outdated" packages – Refael Ackermann Apr 19 '16 at 19:30
  • 3
    @RefaelAckermann I suspect this will be slower than the original :) To know which packages are outdated pip has to first check what's the latest version of each package. It does exactly the same as the first step when updating and does not proceed if there's no newer version available. However in your version pip will check versions two times, the first time to establish the list of outdated packages and the second time when updating packages on this list. – Piotr Dobrogost Jan 17 '17 at 09:22
  • @PiotrDobrogost, If we want to analyse this rigorously ;) let `n` be number of installed packages, and `m` <= `n` number of "outdated" packages. your's will spin-up `pip` for ALL packages for `1 + n` executions of `pip` with `n*log(n)` web lookups for versions and all dependencies, and `m` downloads and installs. Mine will do `n` web lookups for the `--outdated` call then will only spinup `m` `pip` calls with `m*log(n)` web lookups for dependencies + `m` download and installs. for if `m` << `n` I win :) – Refael Ackermann Jan 18 '17 at 14:25
  • 3
    @RefaelAckermann Spinning up pip is order of magnitude faster than checking version of a package over network so that's number of checks which should be optimized not number of spin ups. Mine makes n checks, yours makes n+m checks. – Piotr Dobrogost Jan 18 '17 at 14:38
  • 2
    +1 - It's 6.20.2019, I'm using Python 3.7.3 on WIndows 10, and this was the best way for me to update all my local packages. – MacItaly Jun 20 '19 at 17:44
  • 8
    Need to skip the first two lines of the output: `for /F "skip=2 delims= " %i in ('pip list --outdated') do pip install --upgrade %i`. If this is run from a batch file, make sure to use `%%i` instead of `%i`. Also note that it's cleaner to update `pip` prior to running this command using `python -m pip install --upgrade pip`. – Andy Jul 13 '19 at 08:15
  • @PiotrDobrogost I tried your solution for windows 10 but it's not works. here's a [print-screen](https://i.imgur.com/f61KBm1.png) – αԋɱҽԃ αмєяιcαη Apr 23 '20 at 23:46
  • 1
    @αԋɱҽԃαмєяιcαη this is for cmd.exe, where the `for` command is built-in. It is not for powershell, where it would be better to use a native looping construct. If you still wanted to use this solution in powershell you would need to invoke cmd.exe explicitly: `cmd /c "for /F ""delims==="" %i in ('pip freeze -l') do pip install -U %i"` – Amit Naidu Apr 29 '20 at 22:48
102

This option seems to me more straightforward and readable:

pip install -U `pip list --outdated | awk 'NR>2 {print $1}'`

The explanation is that pip list --outdated outputs a list of all the outdated packages in this format:

Package   Version Latest Type
--------- ------- ------ -----
fonttools 3.31.0  3.32.0 wheel
urllib3   1.24    1.24.1 wheel
requests  2.20.0  2.20.1 wheel

In the AWK command, NR>2 skips the first two records (lines) and {print $1} selects the first word of each line (as suggested by SergioAraujo, I removed tail -n +3 since awk can indeed handle skipping records).

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Marc
  • 1,630
  • 1
  • 15
  • 17
81

The following one-liner might prove of help:

(pip >= 22.3)

as per this readable answer:

pip install -U `pip list --outdated | awk 'NR>2 {print $1}'`

or as per the accepted answer:

pip --disable-pip-version-check list --outdated --format=json |
    python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))" |
    xargs -n1 pip install -U

(pip 20.0 < 22.3)

pip list --format freeze --outdated | sed 's/=.*//g' | xargs -n1 pip install -U

Older Versions:

pip list --format freeze --outdated | sed 's/(.*//g' | xargs -n1 pip install -U

xargs -n1 keeps going if an error occurs.

If you need more "fine grained" control over what is omitted and what raises an error you should not add the -n1 flag and explicitly define the errors to ignore, by "piping" the following line for each separate error:

| sed 's/^<First characters of the error>.*//'

Here is a working example:

pip list --format freeze --outdated | sed 's/=.*//g' | sed 's/^<First characters of the first error>.*//' | sed 's/^<First characters of the second error>.*//' | xargs pip install -U
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
raratiru
  • 8,748
  • 4
  • 73
  • 113
76

You can just print the packages that are outdated:

pip freeze | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
janrito
  • 885
  • 6
  • 4
71

More Robust Solution

For pip3, use this:

pip3 freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip3 install -U \1/p' |sh

For pip, just remove the 3s as such:

pip freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip install -U \1/p' |sh

OS X Oddity

OS X, as of July 2017, ships with a very old version of sed (a dozen years old). To get extended regular expressions, use -E instead of -r in the solution above.

Solving Issues with Popular Solutions

This solution is well designed and tested1, whereas there are problems with even the most popular solutions.

  • Portability issues due to changing pip command line features
  • Crashing of xargs because of common pip or pip3 child process failures
  • Crowded logging from the raw xargs output
  • Relying on a Python-to-OS bridge while potentially upgrading it3

The above command uses the simplest and most portable pip syntax in combination with sed and sh to overcome these issues completely. Details of the sed operation can be scrutinized with the commented version2.


Details

[1] Tested and regularly used in a Linux 4.8.16-200.fc24.x86_64 cluster and tested on five other Linux/Unix flavors. It also runs on Cygwin64 installed on Windows 10. Testing on iOS is needed.

[2] To see the anatomy of the command more clearly, this is the exact equivalent of the above pip3 command with comments:

# Match lines from pip's local package list output
# that meet the following three criteria and pass the
# package name to the replacement string in group 1.
# (a) Do not start with invalid characters
# (b) Follow the rule of no white space in the package names
# (c) Immediately follow the package name with an equal sign
sed="s/^([^=# \t\\][^ \t=]*)=.*"

# Separate the output of package upgrades with a blank line
sed="$sed/echo"

# Indicate what package is being processed
sed="$sed; echo Processing \1 ..."

# Perform the upgrade using just the valid package name
sed="$sed; pip3 install -U \1"

# Output the commands
sed="$sed/p"

# Stream edit the list as above
# and pass the commands to a shell
pip3 freeze --local | sed -rn "$sed" | sh

[3] Upgrading a Python or PIP component that is also used in the upgrading of a Python or PIP component can be a potential cause of a deadlock or package database corruption.

Michel
  • 769
  • 4
  • 19
Douglas Daseeco
  • 3,475
  • 21
  • 27
  • 3
    another way to overcome the jurassic BSD `sed` of OS X is to use `gsed` (GNU sed) instead. To get it, `brew install gnu-sed` – Walter Tross Jan 09 '19 at 07:33
  • @WalterTross ... Jurassic ... good adjective use. So we now have two ways to group update pip packages with a nice audit trail on the terminal. (1) Use the -E option as in the answer and (2) install gsed to leave the Jurassic period. – Douglas Daseeco Jan 09 '19 at 08:13
52

I had the same problem with upgrading. Thing is, I never upgrade all packages. I upgrade only what I need, because project may break.

Because there was no easy way for upgrading package by package, and updating the requirements.txt file, I wrote this pip-upgrader which also updates the versions in your requirements.txt file for the packages chosen (or all packages).

Installation

pip install pip-upgrader

Usage

Activate your virtualenv (important, because it will also install the new versions of upgraded packages in current virtualenv).

cd into your project directory, then run:

pip-upgrade

Advanced usage

If the requirements are placed in a non-standard location, send them as arguments:

pip-upgrade path/to/requirements.txt

If you already know what package you want to upgrade, simply send them as arguments:

pip-upgrade -p django -p celery -p dateutil

If you need to upgrade to pre-release / post-release version, add --prerelease argument to your command.

Full disclosure: I wrote this package.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Simion Agavriloaei
  • 3,281
  • 2
  • 17
  • 10
46

This seems more concise.

pip list --outdated | cut -d ' ' -f1 | xargs -n1 pip install -U

Explanation:

pip list --outdated gets lines like these

urllib3 (1.7.1) - Latest: 1.15.1 [wheel]
wheel (0.24.0) - Latest: 0.29.0 [wheel]

In cut -d ' ' -f1, -d ' ' sets "space" as the delimiter, -f1 means to get the first column.

So the above lines becomes:

urllib3
wheel

Then pass them to xargs to run the command, pip install -U, with each line as appending arguments.

-n1 limits the number of arguments passed to each command pip install -U to be 1.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Shihao Xu
  • 1,160
  • 2
  • 10
  • 23
  • I received this warning `DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.` – Reman Nov 26 '16 at 14:01
  • 2
    @Reman: that is because you are using Pip v9.0.1. This is just a deprecation message meaning that some functionalities will not survive in a future Pip release. Nothing to be concerned about ;) – AlessioX Dec 17 '16 at 20:11
  • However, this has to be marked as the final solution. Indeed the accepted answer will run all over your pip packages, which is a waste of time if you have to update only 1 or 2 packages. This solution, as instead, will run just all over the outdated packages – AlessioX Dec 17 '16 at 20:12
30

One-liner version of Ramana's answer.

python -c 'import pip, subprocess; [subprocess.call("pip install -U " + d.project_name, shell=1) for d in pip.get_installed_distributions()]'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Samuel Katz
  • 24,066
  • 8
  • 71
  • 57
29

From yolk:

pip install -U `yolk -U | awk '{print $1}' | uniq`

However, you need to get yolk first:

sudo pip install -U yolk
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
tkr
  • 358
  • 3
  • 3
28

The pip_upgrade_outdated (based on this older script) does the job. According to its documentation:

usage: pip_upgrade_outdated [-h] [-3 | -2 | --pip_cmd PIP_CMD]
                            [--serial | --parallel] [--dry_run] [--verbose]
                            [--version]

Upgrade outdated python packages with pip.

optional arguments:
  -h, --help         show this help message and exit
  -3                 use pip3
  -2                 use pip2
  --pip_cmd PIP_CMD  use PIP_CMD (default pip)
  --serial, -s       upgrade in serial (default)
  --parallel, -p     upgrade in parallel
  --dry_run, -n      get list, but don't upgrade
  --verbose, -v      may be specified multiple times
  --version          show program's version number and exit

Step 1:

pip install pip-upgrade-outdated

Step 2:

pip_upgrade_outdated
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
adrin
  • 4,511
  • 3
  • 34
  • 50
27

When using a virtualenv and if you just want to upgrade packages added to your virtualenv, you may want to do:

pip install `pip freeze -l | cut --fields=1 -d = -` --upgrade
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
brunobord
  • 294
  • 3
  • 4
26

The simplest and fastest solution that I found in the pip issue discussion is:

pip install pipdate
pipdate

Source: https://github.com/pypa/pip/issues/3819

RedEyed
  • 2,062
  • 1
  • 23
  • 26
25

Windows PowerShell solution

pip freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Apeirogon Prime
  • 1,218
  • 13
  • 25
  • `pip list --outdated | %{$_.split('==')[0]} | %{pip install --upgrade $_}`? – Foad S. Farimani May 22 '19 at 08:38
  • 5
    Perhaps `pip list --outdated --format freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}` would be more appropriate. – brainplot Jan 03 '20 at 05:06
  • Why is `pip list --outdated --format freeze..` preferred over the suggested answer in Powershell, @brainplot – Timo Sep 18 '21 at 09:06
  • @Timo When I wrote that comment the suggested answer only used `pip list` instead of `pip freeze`. I figured `--format freeze` would be more robust against possible changes in future updates than letting `pip list` decide the format. `pip freeze` also works! – brainplot Sep 19 '21 at 02:03
  • its even better to have it as function in your profile! This is perfect for anyone using powershell – Deekshith Anand Feb 06 '22 at 18:05
25

Updating Python packages on Windows or Linux

  1. Output a list of installed packages into a requirements file (requirements.txt):

    pip freeze > requirements.txt
    
  2. Edit requirements.txt, and replace all ‘==’ with ‘>=’. Use the ‘Replace All’ command in the editor.

  3. Upgrade all outdated packages

    pip install -r requirements.txt --upgrade
    

Source: How to Update All Python Packages

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Isaque Elcio
  • 1,029
  • 9
  • 4
21

Use AWK update packages:

pip install -U $(pip freeze | awk -F'[=]' '{print $1}')

Windows PowerShell update

foreach($p in $(pip freeze)){ pip install -U $p.Split("=")[0]}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
JohnDHH
  • 409
  • 3
  • 7
16

One line in PowerShell 5.1 with administrator rights, Python 3.6.5, and pip version 10.0.1:

pip list -o --format json | ConvertFrom-Json | foreach {pip install $_.name -U --no-warn-script-location}

It works smoothly if there are no broken packages or special wheels in the list...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • For purely aesthetic reasons, I like this approach the most. The output-producing executable provides our shell the object schema and there is no need for un-labelled index values `[0]` in the script. – Mavaddat Javid Nov 05 '21 at 20:07
  • # Set alias for pip upgrade all outdated package function PipUpgrade-Outdated { pip list -o --format json | ConvertFrom-Json | ForEach-Object {pip install $_.name -U} } – Sébastien Wieckowski Oct 14 '22 at 06:23
14

If you have pip<22.3 installed, a pure Bash/Z shell one-liner for achieving that:

for p in $(pip list -o --format freeze); do pip install -U ${p%%=*}; done

Or, in a nicely-formatted way:

for p in $(pip list -o --format freeze)
do
    pip install -U ${p%%=*}
done

After this you will have pip>=22.3 in which -o and --format freeze are mutually exclusive, and you can no longer use this one-liner.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
German Lashevich
  • 2,193
  • 27
  • 38
  • 1
    What does

    stand for?

    – ᐅdevrimbaris Jun 09 '20 at 17:31
  • 2
    @ᐅdevrimbaris this removes version spec and leaves only package name. You can see it by running `for p in $(pip list -o --format freeze); do echo "${p} -> ${p%%=*}"; done`. In more general way, `${haystack%%needle}` means `delete longest match of needle from back of haystack`. – German Lashevich Jun 10 '20 at 12:15
13

You can try this:

for i in `pip list | awk -F ' ' '{print $1}'`; do pip install --upgrade $i; done
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
3WA羽山秋人
  • 132
  • 1
  • 5
13

The rather amazing yolk makes this easy.

pip install yolk3k # Don't install `yolk`, see https://github.com/cakebread/yolk/issues/35
yolk --upgrade

For more information on yolk: https://pypi.python.org/pypi/yolk/0.4.3

It can do lots of things you'll probably find useful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1175849
  • 1,305
  • 9
  • 14
11

Use:

pip install -r <(pip freeze) --upgrade
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user8598996
  • 119
  • 1
  • 2
11

The shortest and easiest on Windows.

pip freeze > requirements.txt && pip install --upgrade -r requirements.txt && rm requirements.txt
Pang
  • 9,564
  • 146
  • 81
  • 122
Ankireddy
  • 179
  • 1
  • 6
  • @Enkouyami on windows 7 this command does not work without the -r. -r must preclude the path to the requirements file. – Chockomonkey Jul 16 '18 at 21:45
  • 1
    In what context? CMD? [PowerShell](https://en.wikipedia.org/wiki/Windows_PowerShell)? [Cygwin](https://en.wikipedia.org/wiki/Cygwin)? [Anaconda](https://en.wikipedia.org/wiki/Anaconda_(Python_distribution))? Something else? – Peter Mortensen Oct 06 '20 at 22:28
11

There is not necessary to be so troublesome or install some package.

Update pip packages on Linux shell:

pip list --outdated --format=freeze | awk -F"==" '{print $1}' | xargs -i pip install -U {}

Update pip packages on Windows powershell:

pip list --outdated --format=freeze | ForEach { pip install -U $_.split("==")[0] }

Some points:

  • Replace pip as your python version to pip3 or pip2.
  • pip list --outdated to check outdated pip packages.
  • --format on my pip version 22.0.3 only has 3 types: columns (default), freeze, or json. freeze is better option in command pipes.
  • Keep command simple and usable as many systems as possible.
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Linus SEO
  • 121
  • 2
  • 6
10

Ramana's answer worked the best for me, of those here, but I had to add a few catches:

import pip
for dist in pip.get_installed_distributions():
    if 'site-packages' in dist.location:
        try:
            pip.call_subprocess(['pip', 'install', '-U', dist.key])
        except Exception, exc:
            print exc

The site-packages check excludes my development packages, because they are not located in the system site-packages directory. The try-except simply skips packages that have been removed from PyPI.

To endolith: I was hoping for an easy pip.install(dist.key, upgrade=True), too, but it doesn't look like pip was meant to be used by anything but the command line (the docs don't mention the internal API, and the pip developers didn't use docstrings).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chbrown
  • 11,865
  • 2
  • 52
  • 60
  • On Ubuntu (and other Debian derivatives), `pip` apparently puts packages in `/usr/local/lib/python2.7/dist-packages` or similar. You could use '/usr/local/lib/' instead of 'site-packages' in the `if` statement in this case. – drevicko Jan 13 '13 at 04:31
10

This ought to be more effective:

pip3 list -o | grep -v -i warning | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U
  1. pip list -o lists outdated packages;
  2. grep -v -i warning inverted match on warning to avoid errors when updating
  3. cut -f1 -d1' ' returns the first word - the name of the outdated package;
  4. tr "\n|\r" " " converts the multiline result from cut into a single-line, space-separated list;
  5. awk '{if(NR>=3)print}' skips header lines
  6. cut -d' ' -f1 fetches the first column
  7. xargs -n1 pip install -U takes 1 argument from the pipe left of it, and passes it to the command to upgrade the list of packages.
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Alex V
  • 353
  • 4
  • 10
  • Here's my output: `kerberos iwlib PyYAML Could pygpgme Could Could Could ...` Note all the "Could"s. Those stem from output of `pip list -o` of "Could not find any downloads that satisfy the requirement " – DrStrangepork Nov 14 '14 at 21:03
  • Comments don't format this well, but here's a snippet (line endings are marked with ';'): `# pip list -o; urwid (Current: 1.1.1 Latest: 1.3.0); Could not find any downloads that satisfy the requirement python-default-encoding; pycups (Current: 1.9.63 Latest: 1.9.68); Could not find any downloads that satisfy the requirement policycoreutils-default-encoding; Could not find any downloads that satisfy the requirement sepolicy; ` – DrStrangepork Nov 17 '14 at 22:30
  • instead of filtering out all lines which shouldn't be used, I would suggest to filter the lines where an update exists: `pip install -U $(pip list -o | grep -i current | cut -f1 -d' ' | tr "\n|\r" " ") ` . Otherwise you could easily miss one line you don't want and get the result which DrStrangeprk mentioned. – antibus Feb 20 '15 at 08:33
  • 1
    I would strongly recommend using `xargs` instead. `pip list -o | awk '/Current:/ {print $1}' | xargs -rp -- pip install -U` The `-r` flag ensures that `pip install -U` won't be run if there are no outdated packages. The `-p` flag prompts the user to confirm before executing any command. You can add the `-n1` flag to have it prompt you prior to installing each package separately. – Six Apr 20 '16 at 22:45
9

Sent through a pull-request to the pip folks; in the meantime use this pip library solution I wrote:

from pip import get_installed_distributions
from pip.commands import install

install_cmd = install.InstallCommand()

options, args = install_cmd.parse_args([package.project_name
                                        for package in
                                        get_installed_distributions()])

options.upgrade = True
install_cmd.run(options, args)  # Chuck this in a try/except and print as wanted
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Samuel Marks
  • 1,611
  • 1
  • 20
  • 25
9

This seemed to work for me...

pip install -U $(pip list --outdated | awk '{printf $1" "}')

I used printf with a space afterwards to properly separate the package names.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
SaxDaddy
  • 246
  • 2
  • 9
9

This is a PowerShell solution for Python 3:

pip3 list --outdated --format=legacy | ForEach { pip3 install -U $_.split(" ")[0] }

And for Python 2:

pip2 list --outdated --format=legacy | ForEach { pip2 install -U $_.split(" ")[0] }

This upgrades the packages one by one. So a

pip3 check
pip2 check

afterwards should make sure no dependencies are broken.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nils Ballmann
  • 645
  • 10
  • 11
7

A JSON + jq answer:

pip list -o --format json | jq '.[] | .name' | xargs pip install -U
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Alex
  • 948
  • 1
  • 13
  • 17
6

See all outdated packages

pip list --outdated --format=columns

Install

sudo pip install pipdate

then type

sudo -H pipdate
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MUK
  • 371
  • 4
  • 13
6

Here's the code for updating all Python 3 packages (in the activated virtualenv) via pip:

import pkg_resources
from subprocess import call

for dist in pkg_resources.working_set:
    call("python3 -m pip install --upgrade " + dist.project_name, shell=True)
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Justin Lee
  • 800
  • 1
  • 11
  • 22
5

Here is a script that only updates the outdated packages.

import os, sys
from subprocess import check_output, call

file = check_output(["pip.exe",  "list", "--outdated", "--format=legacy"])
line = str(file).split()

for distro in line[::6]:
    call("pip install --upgrade " + distro, shell=True)

For a new version of pip that does not output as a legacy format (version 18+):

import os, sys
from subprocess import check_output, call

file = check_output(["pip.exe", "list", "-o", "--format=json"])
line = str(file).split()

for distro in line[1::8]:
    distro = str(distro).strip('"\",')
    call("pip install --upgrade " + distro, shell=True)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Storm Shadow
  • 442
  • 5
  • 12
  • That sadly no longer works. pip --format does not accept "legacy" as a choice. At least not on my python release. – Jan Schnupp Nov 24 '18 at 09:22
  • @StormShadow as you hope know, pip really poorly control depencies. it does exactly as other solution - yep(( Better to add disclaimer – Rocketq Feb 28 '19 at 07:58
5

Use:

import pip
pkgs = [p.key for p in pip.get_installed_distributions()]
for pkg in pkgs:
    pip.main(['install', '--upgrade', pkg])

Or even:

import pip
commands = ['install', '--upgrade']
pkgs = commands.extend([p.key for p in pip.get_installed_distributions()])
pip.main(commands)

It works fast as it is not constantly launching a shell.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
  • Does constantly launching a shell really make a measurable difference when we'll end up downloading packages from pypi followed by (compilation and) installation? – gerrit Jun 16 '17 at 15:36
  • @gerrit I my experience yes it does, especially in an environment where you have aggressive anti-virus software that you can't turn off running. Where I work we cannot disable or suppress the AV and each shell launch takes 20-30 seconds but, on good days, we do have a fast internet connection. When you are installing large packages the installation time can be significant but when it is a lot of smaller package the shell start time is very significant. – Steve Barnes Jun 17 '17 at 04:35
5

I've been using pur lately. It's simple and to the point. It updates your requirements.txt file to reflect the upgrades and you can then upgrade with your requirements.txt file as usual.

$ pip install pur
...
Successfully installed pur-4.0.1

$ pur
Updated boto3: 1.4.2 -> 1.4.4
Updated Django: 1.10.4 -> 1.10.5
Updated django-bootstrap3: 7.1.0 -> 8.1.0
All requirements up-to-date.

$ pip install --upgrade -r requirements.txt
Successfully installed Django-1.10.5 ...
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kichik
  • 33,220
  • 7
  • 94
  • 114
5

The below Windows cmd snippet does the following:

  • Upgrades pip to latest version.
  • Upgrades all outdated packages.
  • For each packages being upgraded checks requirements.txt for any version specifiers.
@echo off
Setlocal EnableDelayedExpansion
rem https://stackoverflow.com/questions/2720014/

echo Upgrading pip...
python -m pip install --upgrade pip
echo.

echo Upgrading packages...
set upgrade_count=0
pip list --outdated > pip-upgrade-outdated.txt
for /F "skip=2 tokens=1,3 delims= " %%i in (pip-upgrade-outdated.txt) do (
    echo ^>%%i
    set package=%%i
    set latest=%%j
    set requirements=!package!

    rem for each outdated package check for any version requirements:
    set dotest=1
    for /F %%r in (.\python\requirements.txt) do (
        if !dotest!==1 (
            call :substr "%%r" !package! _substr
            rem check if a given line refers to a package we are about to upgrade:
            if "%%r" NEQ !_substr! (
                rem check if the line contains more than just a package name:
                if "%%r" NEQ "!package!" (
                    rem set requirements to the contents of the line:
                    echo requirements: %%r, latest: !latest!
                    set requirements=%%r
                )
                rem stop testing after the first instance found,
                rem prevents from mistakenly matching "py" with "pylint", "numpy" etc.
                rem requirements.txt must be structured with shorter names going first
                set dotest=0
            )
        )
    )
    rem pip install !requirements!
    pip install --upgrade !requirements!
    set /a "upgrade_count+=1"
    echo.
)

if !upgrade_count!==0 (
    echo All packages are up to date.
) else (
    type pip-upgrade-outdated.txt
)

if "%1" neq "-silent" (
    echo.
    set /p temp="> Press Enter to exit..."
)
exit /b


:substr
rem string substition done in a separate subroutine -
rem allows expand both variables in the substring syntax.
rem replaces str_search with an empty string.
rem returns the result in the 3rd parameter, passed by reference from the caller.
set str_source=%1
set str_search=%2
set str_result=!str_source:%str_search%=!
set "%~3=!str_result!"
rem echo !str_source!, !str_search!, !str_result!
exit /b
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Andy
  • 2,670
  • 3
  • 30
  • 49
  • 1
    @ScamCast Glad you liked it! I've just updated the snipped to the latest version I'm using. – Andy Mar 10 '20 at 08:22
  • `for /F "skip=2" %G in ('pip list --outdated') do pip install %G --upgrade` should do the job as well however preceding `python -m pip install --upgrade pip` isn't a bad idea:) – JosefZ Mar 20 '20 at 20:17
5

Here is my variation on rbp's answer, which bypasses "editable" and development distributions. It shares two flaws of the original: it re-downloads and reinstalls unnecessarily; and an error on one package will prevent the upgrade of every package after that.

pip freeze |sed -ne 's/==.*//p' |xargs pip install -U --

Related bug reports, a bit disjointed after the migration from Bitbucket:

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tobu
  • 24,771
  • 4
  • 91
  • 98
4

I have tried the code of Ramana and I found out on Ubuntu you have to write sudo for each command. Here is my script which works fine on Ubuntu 13.10 (Saucy Salamander):

#!/usr/bin/env python
import pip
from subprocess import call

for dist in pip.get_installed_distributions():
    call("sudo pip install --upgrade " + dist.project_name, shell=True)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
antibus
  • 983
  • 1
  • 11
  • 16
4

Here is another way of doing with a script in Python:

import pip, tempfile, contextlib

with tempfile.TemporaryFile('w+') as temp:
    with contextlib.redirect_stdout(temp):
        pip.main(['list', '-o'])
    temp.seek(0)
    for line in temp:
        pk = line.split()[0]
        print('--> updating', pk, '<--')
        pip.main(['install', '-U', pk])
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Copperfield
  • 8,131
  • 3
  • 23
  • 29
4

One liner (bash). Shortest, easiest, for me.

pip install -U $(pip freeze | cut -d = -f 1)

Explanations:

  • pip freeze returns package_name==version for each package
  • cut -d = -f 1 means "for each line, return the 1st line's field where fields are delimited by ="
  • $(cmd) returns the result of command cmd. So here, cmd will return the list of package names and pip install -U will upgrade them.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alexandre Huat
  • 806
  • 10
  • 16
3
import os
import pip
from subprocess import call, check_call

pip_check_list = ['pip', 'pip3']
pip_list = []
FNULL = open(os.devnull, 'w')


for s_pip in pip_check_list:
    try:
        check_call([s_pip, '-h'], stdout=FNULL)
        pip_list.append(s_pip)
    except FileNotFoundError:
        pass


for dist in pip.get_installed_distributions():
    for pip in pip_list:
        call("{0} install --upgrade ".format(pip) + dist.project_name, shell=True)

I took Ramana's answer and made it pip3 friendly.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mo Ali
  • 639
  • 1
  • 6
  • 17
2

If you are on macOS,

  1. make sure you have Homebrew installed
  2. install jq in order to read the JSON you’re about to generate
brew install jq
  1. update each item on the list of outdated packages generated by pip3 list --outdated
pip3 install --upgrade  `pip3 list --outdated --format json | jq '.[] | .name' | awk -F'"' '{print $2}'`
Lucas
  • 523
  • 2
  • 10
  • 20
Dio Chou
  • 653
  • 5
  • 4
2

As another answer here stated:

pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U

Is a possible solution: Some comments here, myself included, had issues with permissions while using this command. A little change to the following solved those for me.

pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 sudo -H pip install -U

Note the added sudo -H which allowed the command to run with root permissions.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thebeancounter
  • 4,261
  • 8
  • 61
  • 109
  • Use the first version with a virtual environment and the second (```sudo -H```) version when updating the packages for your whole system. – Manu CJ Nov 20 '17 at 16:47
2

One line in cmd:

for /F "delims= " %i in ('pip list --outdated --format=legacy') do pip install -U %i

So a

pip check

afterwards should make sure no dependencies are broken.

JonathanDavidArndt
  • 2,518
  • 13
  • 37
  • 49
Ilya
  • 31
  • 7
1

for in a bat script:

call pip freeze > requirements.txt
call powershell "(Get-Content requirements.txt) | ForEach-Object { $_ -replace '==', '>=' } | Set-Content requirements.txt"
call pip install -r requirements.txt --upgrade
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
extreme4all
  • 326
  • 1
  • 3
  • 16
1

To upgrade all of your pip default packages in your default Python version, just run the below Python code in your terminal or command prompt:

import subprocess
import re

pkg_list = subprocess.getoutput('pip freeze')

pkg_list = pkg_list.split('\n')

new_pkg = []
for i in pkg_list:
    re.findall(r"^(.*)==.*", str(i))
    new = re.findall(r"^(.*)==.*", str(i))[0]
    new_pkg.append(new)

for i in new_pkg:
    print(subprocess.getoutput('pip install '+str(i)+' --upgrade'))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sina M
  • 84
  • 11
1
  1. By using pip-upgrader

    • using this library you can easily upgrade all the dependencies packages. These are set up you follows.

      pip install pip-upgrader
      
      pip-upgrade path/of/requirements_txt_file
      

An interactive pip requirements upgrader. Because upgrading requirements, package by package, is a pain in the ass. It also updates the version in your requirements.txt file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

Use pipx instead:

pipx upgrade-all
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • What is this "pipx" you speak of? E.g., can you add some references? Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/74425440/edit), not here in comments (******** ***without*** ******** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Feb 12 '23 at 07:09
1
pip install --upgrade `pip list --format=freeze | cut -d '=' -f 1`

pip list --format=freeze includes pip and setuptools. pip freeze does not.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
young_souvlaki
  • 1,886
  • 4
  • 24
  • 28
0
python -c 'import pip; [pip.main(["install", "--upgrade", d.project_name]) for d in pip.get_installed_distributions()]'

One liner!

Rob
  • 26,989
  • 16
  • 82
  • 98
0

If you want upgrade only packaged installed by pip, and to avoid upgrading packages that are installed by other tools (like apt, yum etc.), then you can use this script that I use on my Ubuntu (maybe works also on other distros) - based on this post:

printf "To update with pip: pip install -U"
pip list --outdated 2>/dev/null | gawk '{print $1;}' | while read; do pip show "${REPLY}" 2>/dev/null | grep 'Location: /usr/local/lib/python2.7/dist-packages' >/dev/null; if (( $? == 0 )); then printf " ${REPLY}"; fi; done; echo
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
keypress
  • 759
  • 9
  • 12
0

I like to use pip-tools to handle this process.

Package pip-tools presents two scripts:

pip-compile: used to create a viable requirements.txt from a requirement.in file. pip-sync: used to sync the local environment pip repository to match that of your requirements.txt file.

If I want to upgrade a particular package say:

django==3.2.12

to

django==3.2.16

I can then change the base version of Django in requirements.in, run pip-compile and then run pip-sync. This will effectively upgrade django (and all dependent packages too) by removing older versions and then installing new versions.

It is very simple to use for upgrades in addition to pip package maintenance.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Harlin
  • 1,059
  • 14
  • 18
0
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Elvin Jafarov
  • 1,341
  • 11
  • 25
  • 2
    Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? **If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient.** Can you kindly [edit] your answer to offer an explanation? – Jeremy Caney Aug 03 '23 at 00:32
-1

All posted solutions here break dependencies.

From this conversation to include the functionality directly into pip, including properly managing dependencies:

The author of Meta Package Manager (MPM) writes that MPM can emulate the missing upgrade-all command:

mpm --pip upgrade --all
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dreamflasher
  • 1,387
  • 15
  • 22