0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実行環境も一つのフォルダー以下に収められる可搬的なPythonスクリプトのスケルトン作成ユーティリティ+ついでにkivyのTips

Last updated at Posted at 2024-07-27

動機

以前、「可搬的なpythonツールのためのスケルトン作成ユーティリティ」というのを作成した。これは、もともとpythonスクリプトを色々な環境に持って行ってに使うのを楽にするため作成した「比較的小規模で可搬的なPython toolのスケルトン」というのが元になっている。

本体はbashのシェルスクリプトで、主な機能としては、

  • Pythonの必要なモジュールをpipでローカルなディレクトリにインストールする
  • 環境変数PYTHONPATHにそのローカルディレクトリを加えてpythonスクリプトを実行するラッパースクリプト
  • ローカルディレクトリにpythonスクリプトなどのテンプレートを作成する
  • 自分で作成したpythonスクリプトなど他の環境にコピーするファイルは残して、pipでローカルにインストールしたモジュールファイルをまとめて消去する。 (配布物の作成を楽にする。)

の4つがある。個人的には大変使い勝手がよく、いろいろな環境にもっていって使うpythonスクリプトを書くさいに多用するようになった。しかしながら、さらに毎回ルーチンワーク的にやっている作業があることに気づいたので、より省力化がはかれるのではないか、と思うようになった。

また、少し前に「よく使うシェルスクリプト(bash)のツールの保守性/汎用性を高める試み。」というのを作成した。これは、bashスクリプトをsource(.)しても副作用がないようなものにする工夫である。この工夫をすればbashスクリプトをalias的にすることもできるのでないか、と思えてきた。
(個人的には、作業用にログインシェル的にはtcshを使っているので、その恩恵はないと思うが......)

これらのため、シェルスクリプトとしては大幅に書き換えることになったので、名前を変えて新しいツールとすることにした。pythonツールやそれに必要なものがまとめて入った小型容器ということで、py_canisterと命名した。

ファイル置き場

基本的な動作 (従前とおなじ)

まず初めに--manageオプションをつけて、py_canister.shinitサブコマンドで実行すると、pythonスクリプトのスケルトンを作成できます。 下記の例だと、 新規ディレクトリ~/tmp/py_working_tool以下に、show_status3.pyという名のpython3スクリプトのスニペットが準備されるとともに、これを実行するためのラッパースクリプト(へのシンボリックリンク)が作成されます。

実行例
%  ~/somewhere/py_canister.sh --manage \
       -p ~/tmp/py_working_tool -g -r -3 \
       -t 'Working tool by Python' init show_status

できたファイルを確認すると、下記のようになっています。

実行結果(作成されたファイル)
% find ~/tmp/py_working_tool/ -ls
....  ~/tmp/py_working_tool/
....  ~/tmp/py_working_tool/bin
....  ~/tmp/py_working_tool/bin/py_canister.sh
....  ~/tmp/py_working_tool/bin/mng_pyenv -> py_canister.sh
....  ~/tmp/py_working_tool/bin/show_status -> py_canister.sh
....  ~/tmp/py_working_tool/bin/mng_pyenv2 -> py_canister.sh
....  ~/tmp/py_working_tool/bin/mng_pyenv3 -> py_canister.sh
....  ~/tmp/py_working_tool/bin/show_status3 -> py_canister.sh
....  ~/tmp/py_working_tool/README.md
....  ~/tmp/py_working_tool/.gitignore
....  ~/tmp/py_working_tool/lib
....  ~/tmp/py_working_tool/lib/python
....  ~/tmp/py_working_tool/lib/python/show_status3.py
....  ~/tmp/py_working_tool/lib/python/show_status.py -> show_status3.py
....  ~/tmp/py_working_tool/lib/python/site-packages
....  ~/tmp/py_working_tool/lib/python/site-packages/.gitkeep

ここで作成されたshow_status3.pyですが、

show_status3.pyの先頭
% head  ~/tmp/py_working_tool/lib/python/show_status3.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
...
import pytz
import tzlocal
...

非標準のモジュールpytz,tzlocalを読み込んでいますので、このままでは実行できませんが、mng_pyenv3pipを使ってローカルにモジュールをインストールできます。

Pythonモジュールのインストール(pip3を利用)
% ~/tmp/py_working_tool/bin/mng_pyenv3 install pytz tzlocal
Collecting pytz
  Using cached pytz-2024.1-py2.py3-none-any.whl.metadata (22 kB)
Collecting tzlocal
  Using cached tzlocal-5.2-py3-none-any.whl.metadata (7.8 kB)
Using cached pytz-2024.1-py2.py3-none-any.whl (505 kB)
Using cached tzlocal-5.2-py3-none-any.whl (17 kB)
Installing collected packages: pytz, tzlocal
Successfully installed pytz-2024.1 tzlocal-5.2

ファイルを確認すると、ローカルフォルダにインストールされてます。

ファイルリスト(抜粋)
% find ~/tmp/py_working_tool/ -ls
......
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/pytz-2024.1.dist-info
...... 
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/pytz
...... 
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/tzlocal-5.2.dist-info
...... 
...... ~/tmp/py_working_tool/lib/python/site-packages/3.12/tzlocal
......

bin/show_status3bin/py_canister.shへのシンボリックリンクですが、ここではpy_canister.shは、--manageオプションがない場合には、シンボリック名もしくはコマンドライン第一引数のファイルをPYTHONPATHを設定して実行するラッパースクリプトとして動作します。

実行例(ローカルに追加したpytz,tzlocalを利用して動作)
%  ~/tmp/py_working_tool/bin/show_status3 -d
Hello, World! ......
Python : 3.12.1 (..../bin/python3)
.... (PYTHONPATH一覧を表示)

これで準備が完了したので、py_working_tool/lib/python/show_status3.pyを所望の動作をするようにバリバリ書き換え、また必要に応じてpy_working_tool/bin/mng_pyenv3 install ...として、さらに追加で必要となるpythonモジュールを追加していく、というのが作業になります。ここまでは、以前の「可搬的なpythonツールのためのスケルトン作成ユーティリティ」と同じです。

追加した機能

「可搬的なPythonスクリプトツール」を作っている時にほとんど場合に必要となることは、スクリプトやその実行に必要なモジュールファイルだけでなく、データファイルや設定ファイルの可搬性を確保することが必要になる。その際には、要は必要なファイルを一つのディレクトリ以下に収めるというドクトリンになるわけであるが、そのために毎回同じような機能を書いていることに気づいた。そのため、py_canister.shにはよく使うpythonコードをテンプレートとして埋め込んでおけるようなに実装した。例として、自分が常用するコードから、ローカルディレクトリの構造をハンドルするpkg_structure.pyというファイルと、データキャッシュを使うpkg_cache.pyというのを入れてみた。

使い方としては、

新機能を使う実行例
%  ~/somewhere/py_canister.sh --manage -3 -p ~/tmp/py_working_tool -g -r -t 'Working tool by Python' \
       -s pkg_structure init show_status

のように-sオプションで、埋め込んだテンプレートから実ファイル作成することを指示すると、

-sオプションで追加で作成されるファイル
% find ~/tmp/py_working_tool/ -ls
.......
....  ~/tmp/py_working_tool/lib/python/pkg_structure.py
.......

と、追加でpythonのモジュール的に使用できるファイルが作成される。

ローカルディレクトリの構造の定型化(pkg_structure.py)

前述のとおり、pythonスクリプトやモジュールだけでなく、なんらかのデータファイルや設定ファイルなどもまとめて他の環境にもっていく必要があることも少なくない。「可搬的なスクリプトツール」を目指す、という観点からは、

  1. 1つのディレクトリ以下に必要なファイルが収まっている。
  2. そのフォルダがどこの場所に置いても必要なファイルを読み込んで動作する
  3. そのファイル以外の場所に意図せずファイルを作らない

の3点を満たしたい。とくに2点目や3点目に関して、実行スクリプトの親ディレクトリを調べて相対的にデータファイルや中間ファイルや出力ファイルのpathを決める、というコードを毎回書くことになっていた。このためのpkg_structure.pyというコードを用意した。

py_canister.shでは、トップディレクトリ(上記実行例では~/tmp/py_working_tool)以下のbinディレクトリ以下に実行ファイルを、lib/python以下にPythonスクリプトを配置している。

pkg_structure.pyはこれを発展させて、トップディレクトリ以下にvar, share,etc,...といったGNU Coding StandardFilesystem Hierarchy Standardに準じたディレクトリ構造を持たせるのをサポートする。

pkg_structure.pyの利用例

具体的な例として、GUIライブラリの一つであるkivyを使ったpythonスクリプトの例を挙げる。見た目のよいマルチタッチアプリケーションが作成可能ということでkivyを使っている方もいると思いますが、可搬的にスクリプトにする、という点では下記の点が問題になります。

  • Wigetの配置などをpythonスクリプトとは別の独自言語(kv)のファイルに記述する。
  • 最初に起動したとき、(~/.kivy)という隠しディレクトリを作って、その下に設定ファイルを作成する。
  • さらに~/.kivy/log以下に実行ログを残していく。(ユーザーが気づかない場所で静かにディスク容量が食われていく)
  • これに加えて、デフォルトでは、kivyで作成したアプリ(kivy.app.Appを継承したクラス)毎の設定ファイルを、~/.config(macOSの場合は~/Library/Application Support/)以下に作成する。

作成したpkg_structure.pyを使って、これらを回避する例を作ってみました。全体像は最後につけますが,上記ポイントに関係する部分を抽出して説明します。

pkg_structure.pyの使用

まず、モジュールをimportして、それを使うPkgStructureクラスのエンティティを定義します。コンストラクタの引数であたえたスクリプトから親ディレクトリを推測します。

pkg_structure.pyの利用
import pkg_structure
...
    pkg_info = pkg_structure.PkgStructure(script_path=sys.argv[0])
    # pkg_info.dump(relpath=False, with_seperator=True)
...
    pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
    os.environ['KIVY_HOME']     = pkg_info.concat_path('pkg_sysconfdir', 'kivy')
....

それによりどんなサブディレクトリが定義されるかは、メンバ関数dump()で表示できます。引数に与えたスクリプトのパス('base_script')が、~/tmp/py_working_tool/lib/python/show_status3.pyの場合には、
上位のlib/python/のさらに親ディレクトリが、このパッケージのディレクトリと類推して、

  • そのディレクトリ名py_working_toolをこのパッケージの名前:'pkg_name'

  • そのディレクトリの場所~/tmp/py_working_toolがディレクトリ構造のトップ('prefix')
    と決めます。それいかに、GNU Coding StandardやFHSで定義されている。

  • 'bindir': ~/tmp/py_working_tool/bin

  • 'datadir': ~/tmp/py_working_tool/share

  • 'sysconfdir': ~/tmp/py_working_tool/etc

  • 'localstatedir': ~/tmp/py_working_tool/var

  • 'runstatedir': ~/tmp/py_working_tool/var/run

  • 'tmpdir': ~/tmp/py_working_tool/tmp

などのサブディレクトリや、これらのディレクトリ名の直下のパッケージの名前('pkg_name')のサブディレクトリ

  • 'pkg_datadir': ~/tmp/py_working_tool/share/py_working_tool
  • 'pkg_sysconfdir': ~/tmp/py_working_tool/etc/py_working_tool
  • 'pkg_cachedir': ~/tmp/py_working_tool/var/cache/py_working_tool
  • 'pkg_statedatadir': ~/tmp/py_working_tool/var/lib/py_working_tool
  • 'pkg_logdir': ~/tmp/py_working_tool/var/log/py_working_tool
  • 'pkg_spooldir': ~/tmp/py_working_tool/var/spool/py_working_tool

に相当する文字列が定義され、PkgStructureクラスのプロパティとしてアクセスできるようになります。
どのようなプロパティ(サブディレクトリ名)が定義されるかは、lib/python/pkg_structure.pyを単体で直接実行することでも確認できます。(********は実行ユーザー名になります)

pkg_structure.py実行例
'pkg_name':         py_working_tool
'pkg_path':         ~/tmp/py_working_tool
----------------------------------------------------------------------
'base_script':      ~/tmp/py_working_tool/lib/python/pkg_structure.py
----------------------------------------------------------------------
'script_mnemonic':  pkg_structure
'script_path':      ~/tmp/py_working_tool/lib/python/pkg_structure.py
'script_location':  ~/tmp/py_working_tool/lib/python
'script_basename':  pkg_structure.py
----------------------------------------------------------------------
'prefix':           ~/tmp/py_working_tool
----------------------------------------------------------------------
'exec_user':        ********
----------------------------------------------------------------------
'exec_prefix':       '${prefix}'
'bindir':            '${prefix}'/bin
'datarootdir':       '${prefix}'/share
'datadir':           '${prefix}'/share
'sysconfdir':        '${prefix}'/etc
'sharedstatedir':    '${prefix}'/com
'localstatedir':     '${prefix}'/var
'include':           '${prefix}'/include
'libdir':            '${prefix}'/lib
'srcdir':            '${prefix}'/src
'infodir':           '${prefix}'/share/info
'runstatedir':       '${prefix}'/var/run
'localedir':         '${prefix}'/share/locale
'lispdir':           '${prefix}'/emacs/lisp
'docdir':            '${prefix}'/doc/py_working_tool
'htmldir':           '${prefix}'/doc/py_working_tool
'dvidir':            '${prefix}'/doc/py_working_tool
'pdfdir':            '${prefix}'/doc/py_working_tool
'psdir':             '${prefix}'/doc/py_working_tool
'mandir':            '${prefix}'/share/man
'man0dir':           '${prefix}'/share/man/man0
'man1dir':           '${prefix}'/share/man/man1
'man2dir':           '${prefix}'/share/man/man2
'man3dir':           '${prefix}'/share/man/man3
'man4dir':           '${prefix}'/share/man/man4
'man5dir':           '${prefix}'/share/man/man5
'man6dir':           '${prefix}'/share/man/man6
'man7dir':           '${prefix}'/share/man/man7
'man8dir':           '${prefix}'/share/man/man8
'man9dir':           '${prefix}'/share/man/man9
'manndir':           '${prefix}'/share/man/mann
'sbindir':           '${prefix}'/sbin
'bootdir':           '${prefix}'/boot
'devdir':            '${prefix}'/dev
'mediadir':          '${prefix}'/media
'mntdir':            '${prefix}'/mnt
'optdir':            '${prefix}'/opt
'tmpdir':            '${prefix}'/tmp
'xmldir':            '${prefix}'/etc/xml
'etcoptdir':         '${prefix}'/etc/opt
'cachedir':          '${prefix}'/var/cache
'statedatadir':      '${prefix}'/var/lib
'lockdir':           '${prefix}'/var/lock
'logdir':            '${prefix}'/var/log
'spooldir':          '${prefix}'/var/spool
'statetmpdir':       '${prefix}'/var/tmp
'user_home':         '${prefix}'/Users/********
'home':              '${prefix}'/Users/********
'homedir':           '${prefix}'/Users
----------------------------------------------------------------------
'pkg_datadir':       '${prefix}'/share/py_working_tool
'pkg_sysconfdir':    '${prefix}'/etc/py_working_tool
'pkg_runstatedir':   '${prefix}'/var/run/py_working_tool
'pkg_include':       '${prefix}'/include/py_working_tool
'pkg_libdir':        '${prefix}'/lib/py_working_tool
'pkg_srcdir':        '${prefix}'/src/py_working_tool
'pkg_tmpdir':        '${prefix}'/tmp/py_working_tool
'pkg_xmldir':        '${prefix}'/etc/xml/py_working_tool
'pkg_cachedir':      '${prefix}'/var/cache/py_working_tool
'pkg_statedatadir':  '${prefix}'/var/lib/py_working_tool
'pkg_lockdir':       '${prefix}'/var/lock/py_working_tool
'pkg_logdir':        '${prefix}'/var/log/py_working_tool
'pkg_spooldir':      '${prefix}'/var/spool/py_working_tool
'pkg_statetmpdir':   '${prefix}'/var/tmp/py_working_tool
----------------------------------------------------------------------

さらに、これらの下に別のディレクトリ/ファイル名の文字列を作成するメンバ関数concat_path()を実装しました。実際にディレクトリを作成するためのメンバ関数make_subdirs()も実装しました。前記の例の最後の2行

pkg_structure.pyの利用の抜粋
    pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
    os.environ['KIVY_HOME']     = pkg_info.concat_path('pkg_sysconfdir', 'kivy')

が、~/tmp/py_working_tool/etc/py_working_tool/kivyというディレクトリを作成して、環境変数KIVY_HOMEにこのディレクトリを設定するコードになります。これで、~/.kivyという隠しファイルが作られるのを避けられます。これらの環境変数設定は、kivy関係のモジュールをインポートする前に実行される必要があります

kivyのログファイル出力先の変更

次に他のkivy関係のモジュールを読み込む前にログファイルの置き場をしておきます。kivy.config関係の設定をおこなってからkivyのメインのモジュールを読み込む順番になります。

kivyのログ出力先の変更
    import kivy.config
    kivy.config.Config.set("kivy","log_dir", pkg_info.pkg_logdir)

pkg_info.pkg_logdirというところがPkgStructureのプロパティとしてサブディレクトリの場所を取得する例となっています。

kivyのアプリケーション設定フォルダの指定

前述のとおりkivyの作法として、kivy.Appのを継承してアプリケーションのクラスを構築すると、~/.config(macOSの場合は~/Library/Application Support/)以下に非明示的にディレクトリが作成されます。このディレクトリの場所を変えるには、kivy.Appクラスのコンストラクタの引数kv_directoryで指定します。

kivyアプリの設定ファイルの置き場を変える。
class MainApp(kivy.app.App):

        def __init__(self, pkg_info, **kwargs):
            super().__init__(kv_directory=pkg_info.pkg_runstatedir, **kwargs)
            self.pkg_info      = pkg_info

この例では、作成するMainAppのコンストラクタにPkgStructureクラスのエンティティを渡しておき、そのプロパティpkg_info.pkg_runstatedirを親クラス(kivy.app.App)のコンストラクタに引数で渡します。また、このクラスでPkgStructureクラスのエンティティを参照できるように、メンバ変数に保持しておきます。

kivyのGUI画面設定ファイルの指定

main.AppのGUIウィンドウ画面の定義などは別途.kvファイルに記述して読み込みます。これもkivy.app.Appのコンストラクタの引数(kv_file)で指定できます。あらかじめ~/tmp/py_working_tool/share/py_working_tool/main.kvというファイルを作成しておき、MainAppクラスのコンストラクタ経由でkivy.app.Appクラスのコンストラクタに渡します。

kvファイルの場所の指定
    kv_file=pkg_info.concat_path('pkg_datadir', 'main.kv')
...
    main_app = MainApp(kv_file=kv_file, pkg_info=pkg_info)

この例での作成ファイル。

スクリプトの全体像としてはあとにつけますが、これを実行すると非明示的に作成されるファイルは下記の通り、トップディレクトリ以下に限られ、またログファイルもより明示的な場所に作られるので、めざしていた「可搬性」が達成できました。

作成されたファイル
% ~/somewhere/py_canister.sh --manage -3 -p ~/tmp/py_working_tool \
    -g -r -t 'Working tool by Python' -s pkg_structure init show_status
% (edit) emacs ~/tmp/py_working_tool/lib/python/show_status3.py
% (edit) emacs ~/tmp/py_working_tool/share/py_working_tool/main.kv
% ~/tmp/py_working_tool/bin/mng_pyenv3 install pytz tzlocal psutil kivy
% ~/tmp/py_working_tool/bin/show_status3
% find ~/tmp/py_working_tool/ 
...
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/config.ini
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/mods
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-32.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-24.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-64.ico
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-256.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-48.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-512.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-64.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-128.png
    ~/tmp/py_working_tool/etc/py_working_tool/kivy/icon/kivy-icon-16.png
...
    ~/tmp/py_working_tool/var/log/py_working_tool/kivy_24-07-26_0.txt

スクリプト全体像

~/tmp/py_working_tool/lib/python/show_status3.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Standard modules
import argparse
import datetime
import sys
import os 

# Publicly Distributed modules
import pytz
import tzlocal
import psutil

# Custom-made modules
import pkg_structure

def main():

    argpsr = argparse.ArgumentParser(description='Example: showing status')
    argpsr.add_argument('-q', '--quiet', action='store_true', help='Supress kivy log to stderr')
    cmdargs = argpsr.parse_args()

    pkg_info   = pkg_structure.PkgStructure(script_path=sys.argv[0])
    #pkg_info.dump(relpath=False, with_seperator=True)

    os.environ['KIVY_NO_ARGS'] = '1'
    pkg_info.make_subdirs('pkg_sysconfdir', 0o755, True, 'kivy')
    os.environ['KIVY_HOME']     = pkg_info.concat_path('pkg_sysconfdir', 'kivy')
    if cmdargs.quiet:
        os.environ['KIVY_NO_CONSOLELOG'] = '1'
    
    import kivy.config
    kivy.config.Config.set("kivy","log_dir", pkg_info.pkg_logdir)

    import kivy.app
    import kivy.uix.widget
    import kivy.properties

    class MainApp(kivy.app.App):

        def __init__(self, pkg_info, **kwargs):
            super().__init__(kv_directory=pkg_info.pkg_runstatedir, **kwargs)
            self.pkg_info      = pkg_info

    class MainWidget(kivy.uix.widget.Widget):

        KEYWORDS = ['pkg_name', 'pkg_path', 'base_script', 
                    'prefix', 'bindir', 'datadir', 'sysconfdir',
                    'localstatedir', 'runstatedir', 'tmpdir',
                    'pkg_datadir', 'pkg_sysconfdir', 'pkg_runstatedir', 'pkg_tmpdir']

        status_text = { x: kivy.properties.StringProperty() for x in KEYWORDS }
        status_text['MECH'] = kivy.properties.StringProperty()
        
        def __init__(self, **kwargs):
            super().__init__(**kwargs)

            tz_local   = tzlocal.get_localzone()
            self.status_text['MECH'] = (f'CPU Usage: {psutil.cpu_percent(interval=1)} %'
                                        f', Load Avg. = {psutil.getloadavg()[0]:.2f}'
                                        f' @ {datetime.datetime.now(tz=tz_local).strftime("%c")}')
            for x in self.KEYWORDS:
                self.status_text[x]      = kivy.app.App.get_running_app().pkg_info[x]

    for x in MainWidget.KEYWORDS:
        print (f"{x+':':18s} {pkg_info[x]}")

    kv_file=pkg_info.concat_path('pkg_datadir', 'main.kv')
    print ("--------------------")
    print (f"{'kv_file:':18s} {kv_file}")
    print ("--------------------")

    main_app = MainApp(kv_file=kv_file, pkg_info=pkg_info)
    main_app.run()


if __name__ == '__main__':
    main()
~/tmp/py_working_tool/share/py_working_tool/main.kv
MainWidget:

<MainWidget>:
    BoxLayout:
        orientation: 'vertical'
        size: self.parent.size

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_MECH
                size_hint: 0.2, 0.01
                text: 'MECH'
            Label:
                id: status_text_MECH
                size_hint: 0.8, 0.01
                text: root.status_text['MECH']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_name
                size_hint: 0.2, 0.01
                text: 'pkg_name'
            Label:
                id: status_text_pkg_name
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_name']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_path
                size_hint: 0.2, 0.01
                text: 'pkg_path'
            Label:
                id: status_text_pkg_path
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_path']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_base_script
                size_hint: 0.2, 0.01
                text: 'base_script'
            Label:
                id: status_text_base_script
                size_hint: 0.8, 0.01
                text: root.status_text['base_script']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_prefix
                size_hint: 0.2, 0.01
                text: 'prefix'
            Label:
                id: status_text_prefix
                size_hint: 0.8, 0.01
                text: root.status_text['prefix']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_bindir
                size_hint: 0.2, 0.01
                text: 'bindir'
            Label:
                id: status_text_bindir
                size_hint: 0.8, 0.01
                text: root.status_text['bindir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_datadir
                size_hint: 0.2, 0.01
                text: 'datadir'
            Label:
                id: status_text_datadir
                size_hint: 0.8, 0.01
                text: root.status_text['datadir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_sysconfdir
                size_hint: 0.2, 0.01
                text: 'sysconfdir'
            Label:
                id: status_text_sysconfdir
                size_hint: 0.8, 0.01
                text: root.status_text['sysconfdir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_localstatedir
                size_hint: 0.2, 0.01
                text: 'localstatedir'
            Label:
                id: status_text_localstatedir
                size_hint: 0.8, 0.01
                text: root.status_text['localstatedir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_runstatedir
                size_hint: 0.2, 0.01
                text: 'runstatedir'
            Label:
                id: status_text_runstatedir
                size_hint: 0.8, 0.01
                text: root.status_text['runstatedir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_tmpdir
                size_hint: 0.2, 0.01
                text: 'tmpdir'
            Label:
                id: status_text_tmpdir
                size_hint: 0.8, 0.01
                text: root.status_text['tmpdir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_datadir
                size_hint: 0.2, 0.01
                text: 'pkg_datadir'
            Label:
                id: status_text_pkg_datadir
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_datadir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_sysconfdir
                size_hint: 0.2, 0.01
                text: 'pkg_sysconfdir'
            Label:
                id: status_text_pkg_sysconfdir
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_sysconfdir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_runstatedir
                size_hint: 0.2, 0.01
                text: 'pkg_runstatedir'
            Label:
                id: status_text_pkg_runstatedir
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_runstatedir']

        BoxLayout:
            size_hint: 1.0, 0.01
            Label:
                id: status_label_pkg_tmpdir
                size_hint: 0.2, 0.01
                text: 'pkg_tmpdir'
            Label:
                id: status_text_pkg_tmpdir
                size_hint: 0.8, 0.01
                text: root.status_text['pkg_tmpdir']

        Button:
            size_hint: 1.0, 0.01
            text: "Quit"
            on_press: app.stop()

(参考) py_canister.sh の使い方

ヘルプのダンプ画面をつけておきます。

% ~/somewhere/py_canister.sh --manage -h

               % py_canister.sh --manage [options] sub-command [arguments]
    ---- Shell script for providing Portable 'Contained' Python environment
[sub-commands] 
               % py_canister.sh --manage [options] init [scriptnames]    ... setup directory tree,
                                                                           and prepare templates if arguments are given.
               % py_canister.sh --manage [options] add script_names      ... prepare python script templates.
               % py_canister.sh --manage [options] addlib [script_names] ... prepare python script templates.
               % py_canister.sh --manage install  module_names           ... Install python module with pip locally.
               % py_canister.sh --manage download module_names           ... Download python module with pip locally.
               % py_canister.sh --manage clean                           ... Delete local python module for corresponding python version.
               % py_canister.sh --manage distclean/cleanall/allclean     ... Delete local python module for all python version.
               % py_canister.sh --manage info                            ... Show information.
[Options]
               -h     : Show this message
               -P arg : specify python command / path
               -v     : Show verbose messages
               -q     : Supress verbose messages (default)
               -n     : Dry-run mode.
               -2     : Prioritize Python2 than Python3
               -3     : Prioritize Python3 than Python2
[Options for sub-command: setup/init ]
               -p     : prefix of the directory tree. (Default: Grandparent directory if the name of parent directory of 
                        py_canister.sh is bin, otherwise current working directory.)
               -M     : moving this script body into instead of copying
               -g     : setup files for git
               -G     : do not setup files for git (default)
               -r     : setup/update README.md
               -R     : do not setup/update README.md (default)
               -k     : keep backup file of README.md when it is updated.
               -K     : do not keep backup file of README.md when it is updated. (default)
               -t arg : Project title
               -m arg : install module by pip
               -s arg : install library script from template.
               -S     : install standard library scripts. (equivalent to '-s pkg_structure -s pkg_cache')
[Options for sub-command: install/download ]
               -i arg : specify pip command

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?