পাইথন প্যাকেজটি প্রোগ্রামগতভাবে সর্বশেষ সংস্করণ কিনা তা কীভাবে পরীক্ষা করবেন?


29

কোনও প্যাকেজ প্রোগ্রামে কোনও স্ক্রিপ্টে তার সর্বশেষ সংস্করণে রয়েছে কিনা তা আপনি কীভাবে পরীক্ষা করতে পারেন এবং সত্য বা মিথ্যা ফিরিয়ে দেন?

আমি এর মতো স্ক্রিপ্ট দিয়ে পরীক্ষা করতে পারি:

package='gekko'
import pip
if hasattr(pip, 'main'):
    from pip import main as pipmain
else:
    from pip._internal import main as pipmain
pipmain(['search','gekko'])

অথবা কমান্ড লাইনের সাথে:

(base) C:\User>pip search gekko
gekko (0.2.3)  - Machine learning and optimization for dynamic systems
  INSTALLED: 0.2.3 (latest)

তবে আমি কীভাবে প্রোগ্রামক্রমে চেক করব এবং সত্য বা মিথ্যা ফিরে দেব?


4
একটি সম্পূর্ণ সমাধান নয় তবে এটি আপনাকে কিছু ধারণা দিতে পারে। stackoverflow.com/questions/4888027/...
reyPanda

আপনি যে কল করতে পারেন তাতে কি পাইপ নেই?
আলুয়ান হাদাদাদ

3
আপনি যদি এটির ব্যবহার করতে পারেন তবে পাইথন ৩.৮ এই ধরণের স্টাফগুলির জন্য সমর্থনটি উন্নত করেছে, কমপক্ষে এটি স্থানীয়ভাবে ইনস্টল হওয়া কোনও বিষয় রয়েছে। docs.python.org/3/library/importlib.metadata.html
জেএল

1
pipএকটি এপিআই নেই। আপনি হয়ত pip-apiপ্রকল্পটি দেখতে চান , কিন্তু এখনও খুব বেশি কিছু নেই।
wim

উত্তর:


16

দ্রুত সংস্করণ (কেবল প্যাকেজ পরীক্ষা করা হচ্ছে)

নীচের কোডটি অনুপলব্ধ সংস্করণের মতো প্যাকেজটিকে কল করে pip install package_name==random। কল সমস্ত উপলব্ধ সংস্করণ প্রদান করে। প্রোগ্রামটি সর্বশেষ সংস্করণ পড়ে reads

প্রোগ্রামটি তখন pip show package_nameপ্যাকেজের বর্তমান সংস্করণে চলে এবং পায়।

যদি এটি কোনও মিল খুঁজে পায়, তবে এটি সত্য, অন্যথায় মিথ্যা প্রত্যাবর্তন করে।

এটি নির্ভরযোগ্য একটি বিকল্প যা এটি স্থির থাকে pip

import subprocess
import sys
def check(name):
    latest_version = str(subprocess.run([sys.executable, '-m', 'pip', 'install', '{}==random'.format(name)], capture_output=True, text=True))
    latest_version = latest_version[latest_version.find('(from versions:')+15:]
    latest_version = latest_version[:latest_version.find(')')]
    latest_version = latest_version.replace(' ','').split(',')[-1]

    current_version = str(subprocess.run([sys.executable, '-m', 'pip', 'show', '{}'.format(name)], capture_output=True, text=True))
    current_version = current_version[current_version.find('Version:')+8:]
    current_version = current_version[:current_version.find('\\n')].replace(' ','') 

    if latest_version == current_version:
        return True
    else:
        return False

নিম্নলিখিত কোডগুলির জন্য কল করা হয়েছে pip list --outdated:

import subprocess
import sys

def check(name):
    reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'list','--outdated'])
    outdated_packages = [r.decode().split('==')[0] for r in reqs.split()]
    return name in outdated_packages

আমি এটি আপডেট করেছি। এখন এটি কেবল প্যাকেজটি যাচাই করে যা ব্যবহারকারী আগ্রহী। আমি উভয় বিকল্প রেখেছি।
ইউসুফ বক্তির

1
সাধারণত if (boolean): return True else: return Falseভাল শুধু হয়return boolean
Wim

"0" কে বোগাস সংস্করণ নম্বর হিসাবে ব্যবহার করা ভাল নয়, কারণ কখনও কখনও এটি কেবল এগিয়ে যায় এবং একটি প্যাকেজ ইনস্টল করা হয়! ( pip install p==0উদাহরণস্বরূপ চেষ্টা করুন )।
wim

আমি ব্যবহার randomকরেছি আমি নিশ্চিত যে এলোমেলো সংস্করণ নেই
ইউসুফ বখ্তির

10

আমার প্রকল্পে johnnydepএই বৈশিষ্ট্য রয়েছে।

আবরণের ভেতরে:

pip install --upgrade pip johnnydep
pip install gekko==0.2.0

পাইথনে:

>>> from johnnydep.lib import JohnnyDist
>>> dist = JohnnyDist("gekko")
>>> dist.version_installed  
'0.2.0'
>>> dist.version_latest 
'0.2.3'

আমি যখন এটি উইন্ডোজ কমান্ড প্রম্পটে চালনা করি, তখন আমি এএনএসআই এস্কেপ কোডগুলি পাই যা ফলাফলটি অপঠনযোগ্য করে তোলে। আমি মনে করি আপনি এটি ঠিক করতে চান?
ব্যবহারকারী541686

আমার কাছে কলোরামা == 0.4.1 এবং স্ট্রাকলগ == 19.2.0 রয়েছে এবং হ্যাঁ, আমি এই কমান্ডের সাথে সাথে এস্কেপ কোডগুলিও দেখতে পাচ্ছি। যদি এটি সহায়তা করে তবে আমি এটি উইন্ডোজ 10.0.17763.195, পাইথন 3.7.4 এ চালাচ্ছি। দুর্ভাগ্যক্রমে কোনও সমস্যা পোস্ট করার আমার এখনই সুযোগ নেই।
ব্যবহারকারী541686

@ user541686 এই ছিল issue232 আজই মুক্তি structlog v20.1.0 মধ্যে সমাধান। প্রতিবেদনের জন্য ধন্যবাদ।
Wim

অান্তরিক ধন্যবাদ!
user541686

4

সম্পাদনা: পাইপ অনুসন্ধান সরান

বেশ কয়েকটি পরামর্শের জন্য ধন্যবাদ। এখানে একটি নতুন সংস্করণ রয়েছে যা ব্যবহার করে না pip searchবরং ড্যানিয়েল হিলpypi দ্বারা প্রস্তাবিত হিসাবে সরাসরি নতুন সংস্করণটি টান দেয় । এটি স্ট্রিংয়ের মিথ্যা ম্যাচগুলির সাথেও সমস্যার সমাধান করে।

def check(name):
    import subprocess
    import sys
    import json
    import urllib.request

    # create dictionary of package versions
    pkgs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
    keys = [p.decode().split('==')[0] for p in pkgs.split()]
    values = [p.decode().split('==')[1] for p in pkgs.split()]
    d = dict(zip(keys, values)) # dictionary of all package versions

    # retrieve info on latest version
    contents = urllib.request.urlopen('https://pypi.org/pypi/'+name+'/json').read()
    data = json.loads(contents)
    latest_version = data['info']['version']

    if d[name]==latest_version:
        print('Latest version (' + d[name] + ') of '+str(name)+' is installed')
        return True
    else:
        print('Version ' + d[name] + ' of '+str(name)+' not the latest '+latest_version)
        return False

print(check('gekko'))

আসল প্রতিক্রিয়া

এখানে একটি দ্রুত সমাধান রয়েছে যা কেবলমাত্র gekkoআগ্রহের প্যাকেজটিতে সর্বশেষ সংস্করণ তথ্য পুনরুদ্ধার করে ।

def check(name):
    import subprocess
    import sys
    # create dictionary of package versions
    pkgs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
    keys = [p.decode().split('==')[0] for p in pkgs.split()]
    values = [p.decode().split('==')[1] for p in pkgs.split()]
    d = dict(zip(keys, values)) # dictionary of all package versions

    # retrieve info on latest version
    s = subprocess.check_output([sys.executable, '-m', 'pip', 'search', name])

    if d[name] in s.decode():  # weakness
        print('Latest version (' + d[name] + ') of '+str(name)+' is installed')
        return True
    else:
        print(s.decode())
        return False

print(check('gekko'))

এটি বার্তাটি উত্পন্ন করে Latest version (0.2.3) of gekko is installedএবং Trueসর্বশেষ সংস্করণ (অথবা Falseসর্বশেষ সংস্করণ না হলে) নির্দেশিত করতে ফিরে আসে । এটি সেরা সমাধান নাও হতে পারে কারণ এটি কেবলমাত্র একটি সংস্করণ সহ স্ট্রিংয়ের জন্য পরীক্ষা করে if d[name] in s.decode():তবে এটি pip list --outdatedসমস্ত প্যাকেজগুলি যাচাই করে তার চেয়ে দ্রুত । এটি সর্বাধিক নির্ভরযোগ্য পদ্ধতি নয় কারণ এটি Trueযদি বর্তমান ইনস্টলড সংস্করণ হয় 0.2.3তবে সর্বশেষ সংস্করণটি হয় 0.2.30বা এটি একটি ভুল ফিরিয়ে দেয় 0.2.3a। একটি উন্নতি হ'ল প্রোগ্রামগতভাবে সর্বশেষতম সংস্করণ পাওয়া এবং সরাসরি তুলনা করা।


যত্নশীল pip search। এটি একটি অবহেলিত XML-RPC এপিআই ব্যবহার করে এবং কখনও কখনও অনুসন্ধান ফলাফলগুলি ভুল / ভুল হয় আসলে আমি মনে করি এটি শীঘ্রই অপসারণ করা যেতে পারে, দেখুন পাইপ অনুসন্ধান কমান্ড # 5216 সরান
wim

ড্যানিয়েলের বর্তমান প্যাকেজ সংস্করণটি টানানোর পদ্ধতিটি ব্যবহার করার জন্য আমি কোডটি সংশোধন করেছি। বর্তমান জেক্কো সংস্করণটি পাওয়ার আরেকটি উপায় হ'ল import gekkoতারপরে current_version=gekko.__version__সমস্ত প্যাকেজ সংস্করণের একটি অভিধান তৈরি করে। তবে, সমস্ত প্যাকেজের প্যাকেজে কোনও সংস্করণ নম্বর অ্যাক্সেসযোগ্য নয়।
জন হেডেনগ্রেন

4

সর্বশেষ সংস্করণ:

আমার প্রকল্পের ludditeএই বৈশিষ্ট্যটি রয়েছে:

>>> import luddite
>>> luddite.get_version_pypi("gekko")
'0.2.3'

ইনস্টল করা সংস্করণ:

ইনস্টল করা সংস্করণটি যাচাইয়ের প্রথাগত উপায়টি কেবলমাত্র __version__শীর্ষ-স্তরের নেমস্পেসের বৈশিষ্ট্যটি অ্যাক্সেস করার জন্য:

>>> import gekko
>>> gekko.__version__
'0.2.0'

দুর্ভাগ্যক্রমে সমস্ত প্রকল্প এই বৈশিষ্ট্যটি সেট করে না। যখন এটি না হয় আপনি pkg_resourcesমেটাডেটা থেকে এটি খনন করতে ব্যবহার করতে পারেন :

>>> import pkg_resources
>>> pkg_resources.get_distribution("gekko").version
'0.2.0'

2

কমপক্ষে ডেমো উদ্দেশ্যে এটি কৌশলটি করা উচিত। isLatestVersionআপনি যে প্যাকেজটি পরীক্ষা করতে চান তার নাম সহ কেবল কল করুন । আপনি যদি এটি অন্য কোথাও গুরুত্বপূর্ণভাবে ব্যবহার করে থাকেন তবে আপনি url অনুরোধটি চেষ্টা করতে / ধরতে চাইবেন কারণ ইন্টারনেট অ্যাক্সেস নাও পেতে পারে। এছাড়াও নোট করুন যে প্যাকেজটি ইনস্টল না করা থাকলে isLatestVersionমিথ্যা ফিরিয়ে দেবে।

এটি পাইথন 3.7.4 এবং পাইপ 19.0.3 এর জন্য পরীক্ষা করা হয়।

import pip
import subprocess
import json
import urllib.request
from pip._internal.operations.freeze import freeze

def isLatestVersion(pkgName):
    # Get the currently installed version
    current_version = ''
    for requirement in freeze(local_only=False):
        pkg = requirement.split('==')
        if pkg[0] == pkgName:
            current_version = pkg[1]

    # Check pypi for the latest version number
    contents = urllib.request.urlopen('https://pypi.org/pypi/'+pkgName+'/json').read()
    data = json.loads(contents)
    latest_version = data['info']['version']

    return latest_version == current_version

1
pip._internalসর্বজনীন এপিআই নয়। এমনকি এটি পিপের ডক্সে স্পষ্টতই নিরুৎসাহিত করা হয়েছে : " আপনাকে অবশ্যই পাইপের অভ্যন্তরীণ এপিআইগুলি ব্যবহার করবেন না "।
wim

@ উইম জেনে রাখা ভাল। আমি এই সম্পর্কে সচেতন ছিল না। আমাকে জানতে দেওয়ার জন্য ধন্যবাদ। আমি অবশ্যই লোকেরা ইউসুফ বকতারের পদ্ধতিটি এর পরিবর্তে যাইহোক সহজতর ব্যবহার করার পরামর্শ দিচ্ছি।
ড্যানিয়েল হিল

2

পিআইপিআই এপিআই জিজ্ঞাসা করে একটি সাধারণ স্ক্রিপ্ট নিজে লেখা শক্ত নয় । সর্বশেষতম পাইথন ৩.৮ এর সাহায্যে কেবলমাত্র স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করা সম্ভব (পাইথন ৩.7 বা তার বেশি বয়সী ব্যবহার করার সময়, আপনাকে importlib_metadataব্যাকপোর্টটি ইনস্টল করতে হবে ):

# check_version.py

import json
import urllib.request
import sys

try:
    from importlib.metadata import version
except ImportError:
    from importlib_metadata import version

from distutils.version import LooseVersion


if __name__ == '__main__':
    name = sys.argv[1]
    installed_version = LooseVersion(version(name))

    # fetch package metadata from PyPI
    pypi_url = f'https://pypi.org/pypi/{name}/json'
    response = urllib.request.urlopen(pypi_url).read().decode()
    latest_version = max(LooseVersion(s) for s in json.loads(response)['releases'].keys())

    print('package:', name, 'installed:', installed_version, 'latest:', latest_version)

ব্যবহারের উদাহরণ:

$ python check_version.py setuptools
package: setuptools installed: 41.2.0 latest: 41.6.0

আপনি যদি packagingইনস্টল করে distutils.versionফেলেছেন তবে সংস্করণ পার্সিংয়ের এটি আরও ভাল বিকল্প :

from distutils.version import LooseVersion

...

LooseVersion(s)

হয়ে

from packaging.version import parse

...

parse(s)

এই পিপ থেকে ভিন্ন ফলাফল অতিরিক্ত বা বিকল্প ইনডেক্স ব্যবহারকারীর জন্য কনফিগার করা হয় (pip.conf ফাইল বা PIP_INDEX_URL বা PIP_EXTRA_INDEX_URL env মাধ্যমে Vars) দিতে পারেন
Wim
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.