You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature request: pipenv should have a native way to generate requirements.txt directly from the lockfile #4959
When you just run pipenv install [package] on your project the version in the Pipfile is not pinned, but the lockfile contains the installed package version. Unfortunately not all tooling around Python supports Pipfiles, which means that you very often need to generate a requirements.txt file based on your Pipfile.lock. I think all approaches for this are well described here: #3493, but for simplicity I will outline them below:
Run pipenv lock -r. Why this does not work is that it runs pipenv lock, which generates a new lockfile and then generates the requirements. This leads to problematic cases if you want to keep the requirements exactly the same.
Run pipenv run pip freeze > requirements.txt (potentially with pipenv sync before that to make sure that all the packages from Pipfile.lock` are installed). Why this is problematic is because running pip freeze very often leads to too many strict package dependencies being included which leads to dependency mismatches, rendering the whole file unusable.
Some methods based on jq or some similar tool that literally parse the lockfile and then output a requirements.txt
I think the problem with option 1 and 2 is that they both do too much. Option 3 is closest to what most people need, but introduces a new dependency on jq which is also annoying to enforce across a larger group of developers with multiple environments. Which lead to that I am now including a simple python file containing this in almost every repo:
import json
with open('Pipfile.lock', 'r') as f:
reqs = f.read()
with open('requirements.txt', 'w') as f:
f.writelines(f"{req_name}{value['version']}\n" for req_name, value in json.loads(reqs)['default'].items())
I feel that this is so mindbogglingly simple that it should be included somewhere in the pipenv package. My proposition is to include a command pipenv requirements which reads the Pipfile.lock json file and outputs a requirements.txt based on the default key. Adding --dev as an option also adds the requirements from the develop key. No locking, no syncing, no pip freezing. Just this.
I am not only asking for this, but also happy to take some time to implement/maintain this if other people support this idea.
Overall, I think pipenv is a vital tool in the Python ecosystem and will continue to use it in any case. Thanks for the work that went into this so far! I think adding this seemingly trivial extra command would resolve some confusion around the requirements.txt (f.e. #4731) and therefore would be a relatively low effort high value feature for pipenv.
@ImreC I am wondering if what you need is actually the --keep-outdated flag. Since the pipenv lock -r --keep-outdated will only add any new updates from the Pipfile, it will not generate a totally new lock file. It does require that you have the Pipfile in addition to the Pipfile.lock but from the sound of it you do, and are just trying to generate a requirements.txt without changing your locked dependencies, which I think should already be possible.
Run pipenv run pip freeze > requirements.txt (potentially with pipenv sync before that to make sure that all the packages from Pipfile.lock` are installed). Why this is problematic is because running pip freeze very often leads to too many strict package dependencies being included which leads to dependency mismatches, rendering the whole file unusable.
I am not sure I follow the argument here that the strict package dependencies being included lead to dependency mismatches, if you are generating the requirements.txt from the pip freeze then you are pinning to what is currently an installable environment. When you run pipenv lock -r --keep-outdated you also will be getting the rigidly defined versions from the lock file which should be ultimately very similar to pip freeze version.
Hi @matteius, thanks for responding! I can give an example of where pipenv run pip freeze > requirements.txt does not work well. For example this Pipfile:
which pins idna at 3.3, but I think requests depends on idna <3 so this errors out when you try to install with normal pip from requirements.txt (or at least I confirmed this when building with AWS SAM).
Running pipenv lock -r --keep-outdated > requirements.txt works in this case and I haven't tried to use that in a long time, but from memory, I think it still includes the Pipfile in the chain, meaning that packages will on some occasions still get updated. If you really just want a clean requirements.txt file from your Pipfile.lock, and be guaranteed that there is no change, I remember that this was not working in several cases. I think pipenv having a way to just generate a clean requirements.txt from the Pipfile.lock without any interactions with other pipenv components would benefit pipenv in this case.
I just went through the pipenv repo real quick and from what I can tell (in 5 minutes) the intended behavior of --keep-outdated is indeed to still process changes to the Pipfile while keeping outdated packages. What I am looking for specifically (along with the people who use jq in my previous outline) is to generate a requirements.txt based on Pipfile.lock without any changes. Regardless of Pipfile or something else, for the sole purpose of using the current locked requirements in a different tool chain that does not support Pipfile. The most obvious way to me is to parse the json from the lockfile
Running pipenv lock -r --keep-outdated > requirements.txt works in this case and I haven't tried to use that in a long time, but from memory, I think it still includes the Pipfile in the chain, meaning that packages will on some occasions still get updated. If you really just want a clean requirements.txt file from your Pipfile.lock, and be guaranteed that there is no change, I remember that this was not working in several cases.
Yes it still includes the Pipfile in the chain, but if it doesn't differ from the lock file, it will not update anything. What version of pipenv are you running with?
the intended behavior of --keep-outdated is indeed to still process changes to the Pipfile while keeping outdated packages.
Yes but if you haven't modified the Pipfile, there will be nothing to update to the lockfile. Since you didn't include the lock file in your example, it would have to be generated from the Pipfile you provided.
Regardless of Pipfile or something else, for the sole purpose of using the current locked requirements in a different tool chain that does not support Pipfile.
Your project is using pipenv, therefore it has a Pipfile, you can generate a requirements.txt from the Pipfile and Pipfile.lock -- this doesn't require the Pipfile after that, just for generating the requirements.txt.
It may be possible to have a command that generates the package requirements from just the lockfile, but I am not sure I really understand the use case and it feels a little bit like duplicating existing functionality (that currently also looks at the Pipfile) in order to get the same result.
pipenv run pip freeze > requirements.txt
This just puts what you have installed in your virtualenv into requirements.txt not looking at the Pipfile or the lock file.
which pins idna at 3.3, but I think requests depends on idna <3 so this errors out when you try to install with normal pip from requirements.txt (or at least I confirmed this when building with AWS SAM).
That means you have idna 3.3 installed somehow when you really depend on idna <3. I'd start by trying to figure that one out.
@ImreC Another thing about your latest example Pipfile is you have requests = "*" in the dev packages so its not going to force idna to be a specific version when just generating the lock.
I moved requests = "*" to the packages section but still got idna==3.3; python_version >= '3' which matches the setup.py restrictions for requests. Maybe you were talking about an older version of requests or something that is still python2? https://github.com/psf/requests/blob/main/setup.py#L46-L47
@matteius I tried to install the generated requirements.txt from pipenv run pip freeze > requirements.txt in a fresh manually created venv and this worked. This leads me to the conclusion that the package mismatches are not a pip problem.
This was the output of pipenv graph which led me to the original idea that the package mismatch was caused by requests:
but I see that the idna requirement that is printed out is indeed the requirement for Python 2, so I don't really know why this was printed out. On top of that I am currently unable to reproduce my original error even though I was able to this morning. I am genuinely confused by this.
I am using pipenv version 2022.1.8. Also, I know what pipenv lock and pipenv run pip freeze are supposed to do. I appreciate the deep dive though.
I just want to stress that I am not pushing to put something into pipenv that has no value. If pipenv lock -r --keep-outdated is what is supposed to work in this case, I'll happily give that a spin. I remember from 1,5 - 2 years ago that something about it was not working and we looked at it quite extensively at the time. However, I realize that this is a long time ago and that whatever issue we had with it back then may very well be fixed.
May I suggest we update the documentation here https://pipenv.pypa.io/en/latest/basics/#pipfile-lock-security-features to also mention the --keep-outdated flag? Even though I am not sure anymore about my original case, I am sure that people want to be able to generate a requirements.txt file and that this issue #3493 is still very high in the search results, which could lead people to all sorts of solutions which are not --keep-outdated.
Thanks for taking the time to look into this. Really appreciate it!
I just want to stress that I am not pushing to put something into pipenv that has no value.
I know, I was just trying to see if there is an existing solution that would work for you now, rather than wait for something to get accepted and published in a new release. There might be value in having a command that does such a thing when a Pipfile is lacking or has been changed and the history is gone. I just want to be careful before supporting too many new commands, if they are truly required. I am hoping others will weigh in on their uses cases, and also I'll say what I said to the developer that wrote the new verify command. If you want to have this change, and have time to make a PR for it, it will definitely be considered further. I personally don't have time right now to pursue creating such a PR as I am working on other things related to the project.
I have a bit of a busy period, but plan to revisit this in a couple of weeks. Also will look into creating a PR at that time. If people are reading this and feel this is a useful addition, please add a thumbs up.
Reacted by Shane Bishop, zarlo, Michael Yeaple, Lucero Yanez, Tyler Wilcox, Oz Tiram, Mystvio, professor-ben, Prakhar Agarwal, sandeep-gh and 3 more
Activity
matteius commentedon Feb 19, 2022
@ImreC I am wondering if what you need is actually the
--keep-outdatedflag. Since thepipenv lock -r --keep-outdatedwill only add any new updates from the Pipfile, it will not generate a totally new lock file. It does require that you have thePipfilein addition to thePipfile.lockbut from the sound of it you do, and are just trying to generate arequirements.txtwithout changing your locked dependencies, which I think should already be possible.matteius commentedon Feb 19, 2022
I am not sure I follow the argument here that the strict package dependencies being included lead to dependency mismatches, if you are generating the requirements.txt from the
pip freezethen you are pinning to what is currently an installable environment. When you runpipenv lock -r --keep-outdatedyou also will be getting the rigidly defined versions from the lock file which should be ultimately very similar topip freezeversion.Here is an experiment. Pipfile:
pipenv lock -r --keep-outdatedgenerates the following requirements.txt:pipenv syncandpipenv run pip freeze > requirements.txtyields:Which is basically identical to the one generated by
pipenv lock -r --keep-outdatedexcept that one also has annotations about python versions.ImreC commentedon Feb 21, 2022
Hi @matteius, thanks for responding! I can give an example of where
pipenv run pip freeze > requirements.txtdoes not work well. For example this Pipfile:This leads to the following requirements.txt
which pins idna at 3.3, but I think requests depends on idna <3 so this errors out when you try to install with normal pip from requirements.txt (or at least I confirmed this when building with AWS SAM).
Running
pipenv lock -r --keep-outdated > requirements.txtworks in this case and I haven't tried to use that in a long time, but from memory, I think it still includes the Pipfile in the chain, meaning that packages will on some occasions still get updated. If you really just want a cleanrequirements.txtfile from your Pipfile.lock, and be guaranteed that there is no change, I remember that this was not working in several cases. I think pipenv having a way to just generate a clean requirements.txt from the Pipfile.lock without any interactions with other pipenv components would benefit pipenv in this case.ImreC commentedon Feb 21, 2022
I just went through the pipenv repo real quick and from what I can tell (in 5 minutes) the intended behavior of
--keep-outdatedis indeed to still process changes to the Pipfile while keeping outdated packages. What I am looking for specifically (along with the people who use jq in my previous outline) is to generate a requirements.txt based on Pipfile.lock without any changes. Regardless of Pipfile or something else, for the sole purpose of using the current locked requirements in a different tool chain that does not support Pipfile. The most obvious way to me is to parse the json from the lockfilematteius commentedon Feb 21, 2022
Yes it still includes the Pipfile in the chain, but if it doesn't differ from the lock file, it will not update anything. What version of
pipenvare you running with?Yes but if you haven't modified the Pipfile, there will be nothing to update to the lockfile. Since you didn't include the lock file in your example, it would have to be generated from the Pipfile you provided.
Your project is using pipenv, therefore it has a Pipfile, you can generate a requirements.txt from the
PipfileandPipfile.lock-- this doesn't require the Pipfile after that, just for generating the requirements.txt.It may be possible to have a command that generates the package requirements from just the lockfile, but I am not sure I really understand the use case and it feels a little bit like duplicating existing functionality (that currently also looks at the Pipfile) in order to get the same result.
This just puts what you have installed in your virtualenv into requirements.txt not looking at the Pipfile or the lock file.
That means you have idna 3.3 installed somehow when you really depend on
idna <3. I'd start by trying to figure that one out.matteius commentedon Feb 21, 2022
@ImreC Another thing about your latest example Pipfile is you have
requests = "*"in thedevpackages so its not going to forceidnato be a specific version when just generating the lock.matteius commentedon Feb 21, 2022
I moved
requests = "*"to the packages section but still gotidna==3.3; python_version >= '3'which matches thesetup.pyrestrictions forrequests. Maybe you were talking about an older version ofrequestsor something that is still python2?https://github.com/psf/requests/blob/main/setup.py#L46-L47
ImreC commentedon Feb 21, 2022
@matteius I tried to install the generated requirements.txt from
pipenv run pip freeze > requirements.txtin a fresh manually created venv and this worked. This leads me to the conclusion that the package mismatches are not a pip problem.This was the output of
pipenv graphwhich led me to the original idea that the package mismatch was caused by requests:but I see that the idna requirement that is printed out is indeed the requirement for Python 2, so I don't really know why this was printed out. On top of that I am currently unable to reproduce my original error even though I was able to this morning. I am genuinely confused by this.
I am using pipenv version 2022.1.8. Also, I know what
pipenv lockandpipenv run pip freezeare supposed to do. I appreciate the deep dive though.I just want to stress that I am not pushing to put something into pipenv that has no value. If
pipenv lock -r --keep-outdatedis what is supposed to work in this case, I'll happily give that a spin. I remember from 1,5 - 2 years ago that something about it was not working and we looked at it quite extensively at the time. However, I realize that this is a long time ago and that whatever issue we had with it back then may very well be fixed.May I suggest we update the documentation here https://pipenv.pypa.io/en/latest/basics/#pipfile-lock-security-features to also mention the
--keep-outdatedflag? Even though I am not sure anymore about my original case, I am sure that people want to be able to generate a requirements.txt file and that this issue #3493 is still very high in the search results, which could lead people to all sorts of solutions which are not--keep-outdated.Thanks for taking the time to look into this. Really appreciate it!
matteius commentedon Feb 21, 2022
I know, I was just trying to see if there is an existing solution that would work for you now, rather than wait for something to get accepted and published in a new release. There might be value in having a command that does such a thing when a Pipfile is lacking or has been changed and the history is gone. I just want to be careful before supporting too many new commands, if they are truly required. I am hoping others will weigh in on their uses cases, and also I'll say what I said to the developer that wrote the new
verifycommand. If you want to have this change, and have time to make a PR for it, it will definitely be considered further. I personally don't have time right now to pursue creating such a PR as I am working on other things related to the project.ImreC commentedon Mar 1, 2022
I have a bit of a busy period, but plan to revisit this in a couple of weeks. Also will look into creating a PR at that time. If people are reading this and feel this is a useful addition, please add a thumbs up.
ImreC commentedon Mar 26, 2022
I have created a PR for this. Would appreciate a look.
Implements requirements command as per #4959 (#5013)
matteius commentedon Apr 6, 2022
This feature has been merged.
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps
Project: Use requirements file to install AppImage deps