পাইথন সেটআপলগুলি সহ পোস্ট-ইনস্টল স্ক্রিপ্ট


100

সেটআপটুলস সেটআপ.পি ফাইলের অংশ হিসাবে পাইথন পরবর্তী পোস্ট স্ক্রিপ্ট ফাইলটি নির্দিষ্ট করা সম্ভব যাতে কোনও ব্যবহারকারী কমান্ডটি চালাতে পারেন:

python setup.py install

একটি স্থানীয় প্রকল্প ফাইল সংরক্ষণাগার, বা

pip install <name>

একটি পিপিআই প্রকল্পের জন্য এবং স্ক্রিপ্টটি স্ট্যান্ডার্ড সেটআপলগুলি ইনস্টল করার সমাপ্তিতে চালিত হবে? আমি ইনস্টল-পরবর্তী কাজগুলি সম্পাদন করতে যাচ্ছি যা একক পাইথন স্ক্রিপ্ট ফাইলে কোড করা যায় (যেমন, ব্যবহারকারীকে একটি কাস্টম পোস্ট-ইনস্টল বার্তা সরবরাহ করুন, কোনও ভিন্ন দূরবর্তী উত্স সংগ্রহস্থল থেকে অতিরিক্ত ডেটা ফাইলগুলি টানুন)।

আমি বেশ কয়েক বছর আগে এই এসও উত্তরটি পেরিয়ে এসেছি যা বিষয়টিকে সম্বোধন করে এবং মনে হয় যে সেই সময়ের sensকমত্যটি আপনাকে একটি ইনস্টল সাবকম্যান্ড তৈরি করা দরকার। যদি এখনও এটি হয় তবে কারও পক্ষে কীভাবে এটি করা যায় তার উদাহরণ প্রদান করা সম্ভব হবে যাতে ব্যবহারকারীর পক্ষে স্ক্রিপ্টটি চালানোর জন্য দ্বিতীয় কমান্ড প্রবেশ করা প্রয়োজন হয় না?


4
আমি ব্যবহারকারীকে দ্বিতীয় কমান্ড প্রবেশ করানোর পরিবর্তে স্ক্রিপ্ট রানটি স্বয়ংক্রিয় করার আশা করছি। কোন চিন্তা?
ক্রিস সিম্পিকিনস

4
এই হতে পারে কি আপনি যা খুঁজছেন: stackoverflow.com/questions/17806485/...
limp_chimp

4
ধন্যবাদ! আমি এটি যাচাই করবো
ক্রিস সিম্পিকিনস

4
আপনার যদি এটির প্রয়োজন হয় তবে একটি দ্রুত গুগলের মাধ্যমে পাওয়া এই ব্লগ পোস্টটি দেখে মনে হচ্ছে এটি কার্যকর হবে। (আরো দেখুন সম্প্রসারণ এবং পুনঃব্যবহার Setuptools ডক্সে।)
abarnert

4
@ সিমন ওয়েল, আপনি 4 বছর আগে এমন কিছু সম্পর্কে একটি মন্তব্য খুঁজছেন যা সম্ভবত এই সমস্যাটির সাথে কেউ চায় না, তাই আপনি এটি পর্যবেক্ষণ এবং আপ টু ডেট রাখার আশা করতে পারবেন না। যদি এটির কোনও উত্তর হয়ে থাকে তবে সেগুলি প্রতিস্থাপনের জন্য নতুন উত্সগুলি সন্ধানের জন্য মূল্যবান হওয়া উচিত তবে তা তা নয়। আপনার যদি পুরানো তথ্যের প্রয়োজন হয় তবে আপনি সর্বদা ওয়েব্যাক মেশিন ব্যবহার করতে পারেন বা আপনি বর্তমান ডক্সে সমমানের বিভাগটি সন্ধান করতে পারেন।
অবার্নেট

উত্তর:


93

দ্রষ্টব্য: কেবলমাত্র উত্স বিতরণ জিপ বা টার্বল ইনস্টল করার সময় বা উত্স ট্রি থেকে সম্পাদনযোগ্য মোডে ইনস্টল করার সময় নীচের সমাধানটি কার্যকর হয়। বাইনারি চাকা ( ) থেকে ইনস্টল করার সময় এটি কাজ করবে না.whl


এই সমাধানটি আরও স্বচ্ছ:

আপনি এতে কিছু সংযোজন করবেন setup.pyএবং অতিরিক্ত ফাইলের প্রয়োজন নেই।

এছাড়াও আপনাকে দুটি পৃথক পোস্ট-ইনস্টলেশন বিবেচনা করতে হবে; একটি বিকাশ / সম্পাদনাযোগ্য মোডের জন্য এবং অন্যটি ইনস্টল মোডের জন্য।

এই দুটি ক্লাস যুক্ত করুন যাতে এতে আপনার পোস্ট-ইনস্টল স্ক্রিপ্টটি অন্তর্ভুক্ত থাকে setup.py:

from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install


class PostDevelopCommand(develop):
    """Post-installation for development mode."""
    def run(self):
        develop.run(self)
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        install.run(self)
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION

এবং এতে কাজ cmdclassকরার জন্য যুক্তি সন্নিবেশ করান :setup()setup.py

setup(
    ...

    cmdclass={
        'develop': PostDevelopCommand,
        'install': PostInstallCommand,
    },

    ...
)

এমনকি আপনি ইনস্টলেশন চলাকালীন শেল কমান্ড কল করতে পারেন, উদাহরণস্বরূপ যা প্রাক-ইনস্টলেশন প্রস্তুতি করে:

from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
from subprocess import check_call


class PreDevelopCommand(develop):
    """Pre-installation for development mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        develop.run(self)

class PreInstallCommand(install):
    """Pre-installation for installation mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        install.run(self)


setup(
    ...

PS সেটআপলগুলিতে কোনও প্রাক-ইনস্টল এন্ট্রি পয়েন্ট নেই। আপনি কেন ভাবছেন না কেন এই আলোচনাটি পড়ুন ।


অন্যদের চেয়ে আরও ভাল দেখায়, তবে এটি কি প্রকৃত আদেশের আগে কাস্টম কোডটি কার্যকর করে না install?
রাফাইনস

7
এটি আপনার runউপর নির্ভর করে : আপনি যদি প্রথমে পিতামাতাকে কল করেন তবে আপনার কমান্ডটি একটি পোস্ট-ইনস্টল, অন্যথায় এটি প্রাক-ইনস্টল। আমি এই প্রতিফলিত উত্তর আপডেট করেছি।
কিনান

4
এই সমাধানটি ব্যবহার করে দেখে মনে হয় যে install_requiresনির্ভরতাগুলি উপেক্ষা করা হয়
ealfonso

7
এটি আমার সাথে কাজ করে না pip3। প্যাকেজটি প্রকাশ করার সময় ইনস্টল স্ক্রিপ্টটি চলেছিল, তবে এটি ইনস্টল করার সময় নয়।
এরিক ভিয়েনার

4
পছন্দ করুন কেন জানি ঠিক এই মুহুর্তে এটি ভেঙে গেল। এখনই bugs.python.org এর সাথে কিছু ভুল হয়েছে ।
Mertyildiran

14

দ্রষ্টব্য: কেবলমাত্র উত্স বিতরণ জিপ বা টার্বল ইনস্টল করার সময় বা উত্স ট্রি থেকে সম্পাদনযোগ্য মোডে ইনস্টল করার সময় নীচের সমাধানটি কার্যকর হয়। বাইনারি চাকা ( ) থেকে ইনস্টল করার সময় এটি কাজ করবে না.whl


এটিই কেবলমাত্র কৌশল যা আমার পক্ষে কাজ করেছে যখন ইনস্টল-পরবর্তী স্ক্রিপ্টটির প্রয়োজন প্যাকেজ নির্ভরতা ইতিমধ্যে ইনস্টল করা আছে:

import atexit
from setuptools.command.install import install


def _post_install():
    print('POST INSTALL')


class new_install(install):
    def __init__(self, *args, **kwargs):
        super(new_install, self).__init__(*args, **kwargs)
        atexit.register(_post_install)


setuptools.setup(
    cmdclass={'install': new_install},

atexitইনস্টলেশন পদক্ষেপের পরে আপনি কেন কেবল পোস্ট ইনস্টল ফাংশন কল করার চেয়ে কোনও হ্যান্ডলার নিবন্ধন করেন ?
কিনান

4
@ কেনান কারণ বেশিরভাগ setuptoolsনথিভুক্ত। অন্যরা ইতিমধ্যে সঠিক সমাধানগুলি সহ এই প্রশ্নোত্তর সম্পর্কে তাদের উত্তরগুলি সংশোধন করেছেন।
অপালালা

4
ঠিক আছে অন্য উত্তরগুলি আমার পক্ষে কাজ করে না: হয় ইনস্টল পোস্টের স্ক্রিপ্টটি কার্যকর হয় না, বা নির্ভরতা আর পরিচালিত হয় না। এখনও অবধি, আমি দৃ stick ়প্রত্যয় করব atexitএবং পুনরায় সংজ্ঞা দিচ্ছি নাinstall.run() (এই কারণেই নির্ভরতাগুলি আর পরিচালনা করা হয় না)। এছাড়াও, ইনস্টল ডিরেক্টরিটি জানতে, আমি _post_install()একটি পদ্ধতি হিসাবে রেখেছি new_install, আমাকে কী অ্যাক্সেস করতে দেয় self.install_purelibএবং self.install_platlib(কোনটি ব্যবহার করতে হবে তা জানেন না, তবে self.install_libভুল, অদ্ভুতভাবে)।
জিজোলো

4
আমার জন্য নির্ভরতা এবং অ্যাক্সিট কাজগুলির সাথেও আমার সমস্যা ছিল
ইলফোনসো

7
এখানকার কোনও পদ্ধতিই চাকা দিয়ে কাজ করছে বলে মনে হয় না। চাকা সেটআপ.পি চালায় না তাই বার্তাগুলি কেবল নির্মাণের সময় প্রদর্শিত হয়, প্যাকেজ ইনস্টল করার সময় নয়।
জিসিবিজি

7

দ্রষ্টব্য: কেবলমাত্র উত্স বিতরণ জিপ বা টার্বল ইনস্টল করার সময় বা উত্স ট্রি থেকে সম্পাদনযোগ্য মোডে ইনস্টল করার সময় নীচের সমাধানটি কার্যকর হয়। বাইনারি চাকা ( ) থেকে ইনস্টল করার সময় এটি কাজ করবে না.whl


একটি সমাধান একটি অন্তর্ভুক্ত করা হতে পারে post_setup.pyমধ্যে setup.pyএর নির্দেশিকা। post_setup.pyএতে একটি ফাংশন থাকবে যা পোস্ট-ইনস্টল করে এবং setup.pyএটি কেবল উপযুক্ত সময়ে আমদানি করে চালু করবে।

ইন setup.py:

from distutils.core import setup
from distutils.command.install_data import install_data

try:
    from post_setup import main as post_install
except ImportError:
    post_install = lambda: None

class my_install(install_data):
    def run(self):
        install_data.run(self)
        post_install()

if __name__ == '__main__':
    setup(
        ...
        cmdclass={'install_data': my_install},
        ...
    )

ইন post_setup.py:

def main():
    """Do here your post-install"""
    pass

if __name__ == '__main__':
    main()

setup.pyএর ডিরেক্টরি থেকে প্রবর্তন করার সাধারণ ধারণাটি দিয়ে আপনি আমদানি করতে সক্ষম হবেন post_setup.pyঅন্যথায় এটি একটি খালি ফাংশন চালু করবে।

ইন post_setup.py, if __name__ == '__main__':বিবৃতি আপনাকে ম্যানুয়ালি কমান্ড লাইন থেকে পোস্ট-ইনস্টল করতে অনুমতি দেয়।


4
আমার ক্ষেত্রে, ওভাররাইডিংয়ের run()ফলে প্যাকেজ নির্ভরতা ইনস্টল করা হবে না।
আপালালা

4
@ অপালালা যেহেতু ভুল cmdclassপ্রতিস্থাপন করা হয়েছিল, আমি এটি স্থির করেছি।
কিনান

4
আহ, শেষ পর্যন্ত, আমরা সঠিক উত্তর খুঁজে পাই। ভুল উত্তর কীভাবে স্ট্যাকওভারফ্লোতে এতগুলি ভোট পায়? প্রকৃতপক্ষে, আপনি আপনার চালানোর আছে post_install() পরেinstall_data.run(self) অন্যথায় তোমাকে মিস করব কিছু উপাদান। data_filesকমপক্ষে ভালো লাগে। ধন্যবাদ ক্যানন
ব্যক্তিগত_ক্লৌড

4
আমার জন্য কাজ করে না। আমার ধারণা, যে কোনও কারণে, কমান্ডটি install_dataআমার ক্ষেত্রে কার্যকর করা হয় না। সুতরাং, atexitপোস্ট ইনস্টল স্ক্রিপ্টটি শেষ পর্যন্ত কোন পরিস্থিতিতে কার্যকর করা হবে তা নিশ্চিত করার সুবিধা নেই?
zizollo

3

@ অ্যাপালালা, @ জুলু এবং @ জার্তিল্ডিরান এর উত্তরগুলির সংমিশ্রণ; এটি পাইথনের ৩.৫ পরিবেশে আমার জন্য কাজ করেছে:

import atexit
import os
import sys
from setuptools import setup
from setuptools.command.install import install

class CustomInstall(install):
    def run(self):
        def _post_install():
            def find_module_path():
                for p in sys.path:
                    if os.path.isdir(p) and my_name in os.listdir(p):
                        return os.path.join(p, my_name)
            install_path = find_module_path()

            # Add your post install code here

        atexit.register(_post_install)
        install.run(self)

setup(
    cmdclass={'install': CustomInstall},
...

এটি আপনাকে প্যাকেজের ইনস্টলেশন পথে অ্যাক্সেস দেয় install_path, কিছু শেল কাজ করার জন্য।


2

আমি মনে করি পোস্ট-ইনস্টলটি সম্পাদন করার এবং প্রয়োজনীয়তাগুলি রাখার সবচেয়ে সহজ উপায় হ'ল কলটি সাজাতে setup(...):

from setup tools import setup


def _post_install(setup):
    def _post_actions():
        do_things()
    _post_actions()
    return setup

setup = _post_install(
    setup(
        name='NAME',
        install_requires=['...
    )
)

setup()ঘোষণা করার সময় এটি চলবে setup। প্রয়োজনীয়তা ইনস্টলেশন শেষ হয়ে গেলে এটি _post_install()ফাংশনটি চালাবে যা অভ্যন্তরীণ ফাংশনটি চালাবে _post_actions()


4
আপনি কি এই চেষ্টা করেছেন? আমি পাইথন ৩.৪ দিয়ে চেষ্টা করছি এবং ইনস্টলটি স্বাভাবিক হিসাবে কাজ করে তবে পোস্ট_জেক্টগুলি কার্যকর হয় না ...
dojuba

1

অ্যাক্সিট ব্যবহার করা হলে নতুন সেন্টিমিডি ক্লাস তৈরি করার দরকার নেই। সেটআপ () কল করার ঠিক আগে আপনি কেবলমাত্র নিজের অ্যাক্সিট রেজিস্টার তৈরি করতে পারেন। এটি একই জিনিস করে।

এছাড়াও, যদি আপনাকে প্রথমে ইনস্টল করার জন্য নির্ভরতা প্রয়োজন হয় তবে এটি পিপ ইনস্টলের সাথে কাজ করে না কারণ প্যাকগুলি প্যাকেজগুলি স্থানান্তরিত করার আগে আপনার অ্যাক্সিট হ্যান্ডলারটি ডাকা হবে।


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

1

আমি উপস্থাপিত কোনও প্রস্তাবনা দিয়ে কোনও সমস্যার সমাধান করতে পারিনি, সুতরাং যা আমাকে সাহায্য করেছে তা এখানে।

আপনি ফাংশন কল করবো যে আপনি শুধু পরে ইনস্টলেশনের পরে চালাতে চান setup()মধ্যে setup.pyযে মত:

from setuptools import setup

def _post_install():
    <your code>

setup(...)

_post_install()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.