gpt4 book ai didi

python - 如何获取特定日期之前发布的 python 包的版本号列表?

转载 作者:太空宇宙 更新时间:2023-11-03 14:43:08 27 4
gpt4 key购买 nike

考虑有一个 python requirements.txt 文件,其中包含(未版本化的)依赖项(python 包)列表。安装它们后(例如 pip install -r requirements.txt),您可以调用 pip freeze 并获得所有已安装的(版本控制)列表python 包。

这将是当时可用的 python 包版本(及其依赖项)的快照。我需要生成的是同一个列表,但针对的是过去的日期(比如 2018-06-12)。

我想从技术上讲,我只需要找到 requirements.txt 文件中包含的所有包的发布版本。

理想情况下,会有一个命令 pip install -r requirements.txt --before 2018-06-21 然后调用 pip freeze,但我没有在 pip install --help 中看不到类似的内容。我确实看到了一种指定另一个 --index-url 的方法,我可以想象如果从那个日期开始有一个 archived 索引,我可以指向 pip 到那个,它应该工作?

还有一个--constraint选项,它:

Constrain versions using the given constraints file

但我猜在那种情况下我已经必须有日期限制版本了?

最佳答案

根据你的问题,如果我没猜错的话,你想使用以下命令安装依赖项:

pip install -r requirements.txt --before 2018-06-21

这需要修补 pip 本身,以便添加 --before 选项来提供目标日期。

它下面的代码是第二好的东西。目前它是一个粗略的草图,但它几乎可以满足您的需求,而不是生成 requirements.txt,它会将最新版本的包输出到控制台,直到提供的日期为止,格式:

$ pipenv run python <script_name>.py django click --before 2018-06-21
pip install django==2.0.6 click==6.7

这与您的想法并不完全相同,但非常接近。随意根据您的需要更改它,通过添加(或不添加)-r 选项并在新行上输出每个依赖项,然后通过重定向输出,它看起来像这样:

$ pipenv run python <script_name>.py django click --before 2018-06-21 >> requirements.txt

代码(或仅使用指向 gist 的链接):

import sys
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import click

PYPI_URL = "https://pypi.org/project/{project_name}/#history"

def get_releases(request):

soup = BeautifulSoup(request, 'html.parser')
releases = list()

for release in soup.find_all('div', class_='release'):
release_version = release.find('p', class_='release__version').text.strip()
if not is_numeric(release_version):
continue
release_date = try_parsing_date(release.find('time').text.strip())
releases.append({'version': release_version, 'date': release_date})

sorted_packages = sorted(releases, key=lambda s: list(map(int, s['version'].split('.'))))

return sorted_packages


def is_numeric(s):
for char in s:
if not char.isdigit() and char not in [" ", ".", ","]:
return False

return True


def try_parsing_date(text):
for fmt in ('%d.%m.%Y', '%d/%m/%Y', '%b %d, %Y', '%Y-%m-%d'):
try:
return datetime.strptime(text, fmt)
except ValueError:
pass
click.echo('Not valid date format. Try to use one of this: <31.12.2018>, <31/12/2019> or <2018-12-31>')
sys.exit(0)


@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('-b', '--before', help='Get latest package before specified date')
@click.argument('packages', nargs=-1, type=click.UNPROCESSED)
def cli(before, packages):
target_date = try_parsing_date(before) if before else datetime.today()

required_packages = list()
not_found = list()

for package in packages:
project_url = PYPI_URL.format(project_name=package)
r = requests.get(project_url)
if r.status_code is not 200:
not_found.append(package)
continue

releases = get_releases(r.text)
last_release = None
for idx, release in enumerate(releases):
release_date = release['date']
if release_date > target_date:
if last_release and last_release['date'] <= release_date:
continue
last_release = release

required_packages.append({'package': package,
'release_date': last_release['date'],
'release_version': last_release['version']})


print('pip install ' + ' '.join('{}=={}'.format(p['package'], str(p['release_version'])) for p in required_packages))
if len(not_found) > 0:
print('\nCould not find the following packages: {}'.format(' '.join(p for p in not_found)))

if __name__ == '__main__':
cli()

所需的依赖项(Python3):

beautifulsoup4==4.7.1
Click==7.0
requests==2.21.0

关于python - 如何获取特定日期之前发布的 python 包的版本号列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51773066/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com