# カスタムスクリプトでシークレットを使用する方法 Treasure Dataでは、シークレット情報を環境変数内に隠すことをお勧めします。このベストプラクティスにより、他の人がシークレット情報にアクセスできるコードを誤ってプッシュすることを避けられます。 ## ローカル環境でPython仮想環境を作成する Pythonは、独自のサイトディレクトリを持つ軽量な仮想環境を作成するための[venv](https://docs.python.org/3/library/venv.md)を提供しています。または、[pip](https://pypi.org/project/pip/)を使用して同じ環境を作成することもできます。 ## 依存関係のインストール 1. [gist](https://gist.github.com/chezou/d0a0fc62007af4d808752e78b31ae694)に移動します。 2. 以下をダウンロードします: * requirements.txt * constraints.txt コマンドラインからの例: ```bash $ python -m venv .venv $ source .venv/bin/activate (.venv)$ pip install -r requirements.txt -c constraints.txt ``` 1. venv仮想環境を使用すると、ローカル環境で同じパッケージを使用して開発できます。 このアプローチでは、オペレーティングシステムの不一致は解決されません。例えば、Debianで実行されている本番環境と、WindowsまたはmacOS Xの開発環境では、[apt-get](https://linux.die.net/man/8/apt-get)のようなOS依存のコマンドを実行するときにエラーが発生する可能性があります。 ## PythonでTreasure Data Workflowをテストする ローカル環境でワークフロー全体を実行したい場合は、Digdagを代替として使用できます。 Treasure WorkflowはDigdagと同じではありません。 ## Pythonオペレーターにパラメータを渡す py>オペレーターにパラメータを渡す方法は以下のとおりです: * [Digdag変数](https://docs.digdag.io/workflow_definition.html#using-variables) * [カスタムスクリプトでシークレットを使用する方法](/ja/products/customer-data-platform/data-workbench/workflows/customscript/how-to-use-secrets-in-custom-scripts) * [環境変数](/ja/products/customer-data-platform/data-workbench/workflows/customscript/how-to-use-secrets-in-custom-scripts) ## Digdag引数の例 py_scripts/examples.pyという名前のPythonスクリプトが以下のようにあると仮定します: ```python examples.py def print_arg(msg): print(f"Message is {msg}") ``` 以下の例のように、simple_with_argタスクからmessage引数を渡すことができます: ```yaml +simple_with_arg: py>: py_scripts.examples.print_arg msg: "Hello World" docker: image: "treasuredata/customscript-python:3.12.11-td0" ``` 複数の引数を渡すには、関数に引数を追加し、Digdag引数にも追加します。 Digdag引数をPythonにシームレスに渡すことができますが、キーワード引数`**kwargs`を使用すると、意図しない変数が渡される可能性があります。例えば、Docker変数は辞書`{"image": "treasuredata/customscript-python:3.12.11-td0"}`として渡される可能性があります。Treasure Dataでは、Python関数で明示的な引数を使用することをお勧めします。 Digdagとpy>オペレーター間で意図しない競合が発生する可能性があります。以下のようにDigdag変数を設定したと仮定します: ```yaml _export: td: database: my_db +simple_with_arg2: py>: py_scripts.examples.print_arg_td msg: "Hello World" docker: image: "treasuredata/customscript-python:3.12.11-td0" ``` 以下のようにtd引数を持つPython関数print_arg_tdを使用します: ```python examples.py def print_arg_td(msg, td=None): print(f"'msg' is {msg} and 'td' is {td}") ``` エクスポートされたtd変数は常に渡されるため、td変数は決して_None_であってはなりません。例えば、`{"database": "my_db"}`が渡される変数になるはずです。これにより、辞書と文字列のような型の不一致が発生する可能性があります。Treasure Dataでは、Digdagの予約済み引数の使用を避け、代わりにtd変数を使用することをお勧めします。例: * td.endpoint * td.apikey * td.use_ssl * td.proxy.enabled * td.proxy.host * td.proxy.port * td.proxy.password * td.proxy.user Digdagは、例えば文字列から整数のように、意図しない型に変換する場合があります。Treasure Dataでは、Python関数内で型を評価または明示的に変換することをお勧めします。 参照:[https://docs.digdag.io/workflow_definition.md#using-variables](https://docs.digdag.io/workflow_definition#using-variables) ## 環境変数 環境変数は、py>オペレーターにパラメータを渡すもう1つのオプションです。環境変数は、安全な情報やシークレットを渡すのに適しています。 シークレットと環境変数には8192文字の制限があります。 例えば、Treasure Dataにsimple_with_envタスクがある場合: ```yaml +simple_with_env: py>: py_scripts.examples.print_env _env: MY_ENV_VAR: "hello" docker: image: "treasuredata/customscript-python:3.12.11-td0" ``` os.environを通じてMY_ENV_VARにアクセスします。例: ```python import os def print_env(): print(f'Env var is {os.environ["MY_ENV_VAR"]}') ``` シークレット情報を使用する必要がある場合、例えばTreasure Data APIキーやAWSシークレットキーなどの場合、環境変数を使用することが重要です。 Digdagにはシークレット情報を保存する機能があります。td workflow secretsサブコマンドを実行すると、シークレットはDigdagまたはTreasure Workflowデータベースに保存されます。 ![](/assets/image-20200806-204756.9fc55842c4daafea33f4066ea224fcd85694b1485eb124cd6df0a3aca34abe7b.142841d8.png) td.apikeyという名前のシークレットを設定したと仮定します。このシークレットはpy>オペレーターに渡すことができます。例: ```yaml +simple_with_env2: py>: py_scripts.examples.access_td _env: TD_API_KEY: ${secret:td.apikey} docker: image: "treasuredata/customscript-python:3.12.11-td0" ``` py_scripts/examples.pyは以下のようになります: ```python import os def access_td(): apikey = os.environ["TD_API_KEY"] # Do awesome execution ``` 通常のDigdag引数からシークレットを渡そうとすると、シークレットはシークレットDBから取得されません。例えば、以下のようなタスクがある場合: ```yaml +simple_with_env_ng: py>: py_scripts.examples.access_td_ng apikey: ${secret:td.apikey} docker: image: "treasuredata/customscript-python:3.12.11-td0" ``` 代わりに以下のスクリプトを使用する必要があります: ```python def access_td_ng(apikey): print(apikey) # Always shows "${secret:td.apikey}" insted of actual API key like "1234/XXXX" ``` ## Digdag変数 PythonスクリプトでDigdag変数を読み取りたい場合は、以下の例のようにDigdag.env.paramsを使用できます: ```python def read_workflow_env(msg): import digdag print(digdag.env.params["my_msg"]) ``` import Digdagコマンドは、スクリプトがDigdag py>オペレータータスクとして実行されている場合にのみ実行できます。インポートエラーを回避したい場合は、以下のように「try-except構文」を記述する必要があります: ```python try: import digdag digdag.env.store({"feature_query": feature_query}) except ImportError: pass ```