( \* _日本語版は英語版の後にあります。_ )

# **R2DMS Uploader**

This is a Python tool to create a GakuNin RDM project and then upload local data files to its data storage.

This invokes main functions of the following 2 other tools in order.
  1) Creates a new child project under an existing project on the GakuNin RDM. [create_grdmprj]
  2) Uploads research data to the data storage mounted on the created project. [wbclient]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* _The above 2 tools are included in the R2DMS Uploader's package._ 

Click **[here](https://dmsutil.riken.jp/tool/r2dms_uploader-0.0.3.zip)** to download the latest version.
<br>
<br>

## **Setup**

### <u>Update Python</u>

This tool requires the **<span style="color:red">3.10 or a higher version</span>** of `Python`. Update it if this is not the case in your environment.

### <u>Install dependent libraries</U>

This tool also requires the following third-party Python modules.
- `pandas`
- `requests`
- `pydantic-settings`

You can examine if these modules are available in your environment.

For Linux:
```shell
pip list | grep -e pandas -e requests -e pydantic-settings
```
For Windows: (Use powershell)
```shell
pip list | findstr “pandas requests pydantic-settings”
```

If some of them are not available, install them as follows.
```shell
pip install pandas
pip install requests
pip install pydantic-settings
```

### <u>Install R2DMS Uploader</u>

Unpack the downloaded tool's package (ZIP file) in the following manner for Linux.
```shell
unzip -d {PATH_TO_INSTALL_DIRECTORY} r2dms_uploader-0.0.3.zip
```
For Windows, right-click on the ZIP file in File Explorer and select "Extract All" from the context menu. When a dialog opens, choose the destination folder where the tool's contents will be installed and click "Extract". 

### <u>Set environmental variables</u>

Go to the installed directory and create a `.env_control` file as follows.
```shell
GRDM_TOKEN="ABCDEFGHIJKLM0123456789NOPQRSTUVWXYZ"
GRDM_OSFAPI="https://api.rdm.nii.ac.jp/v2"
GRDM_WBAPI="https://files.rdm.nii.ac.jp"
```
&nbsp;<span style="background-color:#3cb371">Notes:</span>
- Do not change the file name (`.env_control`).
- Set the following 3 environmental variables :
  
  <div style="background-color:rgba(240,255,255,0.05)">

  |Env. Variable| Description|
  |:--|:--|
  |GRDM_TOKEN|Your personal access token to the GakuNin RDM.|
  |GRDM_OSFAPI|Base URL of the OSF API on the GakuNin RDM you will access.|
  |GRDM_WBAPI|Base URL of the Waterbutle on of the GakuNin RDM you will access.|
  
  - To get your personal access token, refer to the Appendix of the install manual. 
  - The API URLs in the above example are for the NII's GakuNin RDM. If you intend to access another GakuNin RDM, ask its system administrator for the API URLs.

  </div>

### <u>Prepare input parameters</u>

Prepare an input file in the CSV format as shown below.
```shell
"parent_id","prj_title","data_path","replace_flag"
"abcde","A sample child project 001","./sample_data","0"
,"A sample new project XYZ","./sample_data2","0"
"xyz01",,"./sample_data3","1"
```
&nbsp;<span style="background-color:#3cb371">Notes:</span>
- Use a CSV file encoded in **<span style="color:red">UTF-8</span>**.
- Start with the header line shown in the above example, followed by data line(s).
- Each data line must have 4 comma-separated values of the fields defined bellow :
  
  <div style="background-color:rgba(240,255,255,0.05)">

  |CSV Field|Definition|
  |:--|:--|
  |parent_id|Existing [project's ID](./images/project_id_en.png) &nbsp;(A new [child project will be created](./images/child_project_en.png) under this project.)|
  |prj_title|Title of project to be created|
  |data_path|Local [path to the directory (or file) to be uploaded](./images/upload_s3_en.png)|
  |replace_flag|0 or 1 (When the same file paths are found at the remote, the remote files will be kept for "0" while replaced by local files for "1".)|
  
    - Do not change the order of these fields. 
    - If you would like to create a new independent project and upload data there, leave `parent_id` blank.
    - If you would like to upload data to an already existing project instead of creating a new one, set its ID to `parent_id` and leave `prj_title` blank.
    - When you create a project, both the replace flag values (0 and 1) are ok.
  
  </div>

- All field values should be enclosed by doube-quotations (`"`).
- Lines staring with a pound sign (`#`) will be ignored.
- If you need to include a doube-quotation (`"`) in a field value, escape it with aother double-quotation.
- You can use `<` and `>` in the title of project, but they will be shown as `\&lt;` and `\&gt;` at the created project page on the GakuNin RDM.
- See `sample_input.csv`.


## **Upload data**

Run the following command in the installed directory.
```shell
python -m r2dms_uploader {INPUT_CSV_FILEPATH} -o/--output {OUTPUT_JSON_FILEPATH}
```
&nbsp;<span style="background-color:#3cb371">Notes:</span>
- Put the `.env_control` file in the same directory.
- The input filepath is mandatory.
- A summary in the JSON format will be returned.
- If you don't specify the output filepath, a summary will be shown in the stdout.
- See `sample_output.json`.

### <u>Summary of process</u>

The contents of output summary are shown below.
<details><summary><b>output summary</b></summary>
<pre>
{
  "summary": {
    "message": Message of the whole upload process
    "start_date": Time when this tool has started (format of time: YYYY-mm-ddTHH:MM:SS.ffffff+HH:MM)
    "stop_date": Time when this tool has stopped
    "work_host": Working host name
    "work_dir": Working directory path
    "exec_user_id": user-ID of the user who has executed this tool
    "input_filepath": Input file path
    "output_filepath": Output file path
    "num_csvline_valid": Number of valid CSV lines in the input file.
    "num_proc_total": Number of total processes
    "num_proc_succeeded": Number of processes which have ended in success
    "num_proc_failed": Number of processes which have ended in failure
    "num_proc_skipped": Number of processes which have been skipped
    "processes": [ <span style="color: red;">* Stores the following elements per valid CSV line.</span>
      {
        "proc_id": Process ID (starts from 1)
        "status": Status (OK/NG/SKIPPED)
        "message": Message about this process
        "start_date": Time when this process has started
        "stop_date": Time when this process has stopped
        "csv_input": [ Field values in the CSV line for this process
          "<em>`parent_id` value</em>",
          "<em>`prj_title` value</em>",
          "<em>`data_path` value</em>",
          "<em>`replace_flag` value</em>"
        ],
        "create_grdmprj": { <span style="color: red;">* Stores the following elements as the result of executing `create_grdmprj` function</span>
          "status": Status (OK/NG/SKIPPED)
          "start_date": Time when this function has started
          "stop_date": Time when this function has stopped
          "message": Message from this function
          "internal_rc": internal return code (0: Success / Not 0: Aborted)
          "parent_guid": GakuNin RDM ID of the parent of the created project
          "root_guid": GakuNin RDM ID of the root (top of parents) of the created project
          "guid_created": GakuNin RDM ID of the created project
          "url_created": URL of the created project
          "title_created": Title of the created project
          "creator_guid": GakuNin RDM ID of the user who has created the project
          "creator_name": Fullname of the user who has created the project
        },
        "wbclient": { <span style="color: red;">* Stores the following elements as the result of executing `wbclient` function.</span>
          "status": Status (OK/NG/SKIPPED)
          "start_date": Time when this function has started
          "stop_date": Time when this function has stopped
          "message": Message from this function
          "local_path": local path of the data directory (or file) uploaded to the GakuNin RDM's storage
          "target_project_id": GakuNin RDM project ID to which the data have been uploaded
          "storage_provider": Name of the storage to which the data have been uploaded
          "remote_dir": Remote directory path under which the data have been uploaded
          "replace_flag": <em>`replace_flag`</em> value
          "upload_result": { <span style="color: red;">* Stores here the list of uploeaded directories/files with upload results.</span>
            "<em>remote/path/to/uploaded/derectory/</em>": "<em>created.</em> or <em>already exists.</em>}",
            ...
            "<em>remote/path/to/uploaded/file</em>": "<em>uploaded.</em> or <em>replaced.</em> or <em>found (not replaced).</em>",
            ...
          }
        }
      },
      ... <span style="color: red;">* Result of process for the next valid CSV line will appear here.</span>
      ...
    ]
  }
}  
</pre>
</details>

<br>
<br>
<br>

( \* _Scroll up for English version._ )

# **R2DMS Uploader**

R2DMS Uploaderは、GakuNin RDMにプロジェクトを作成し、そのプロジェクトのストレージにローカルの研究データをアップロードするためのツールです。

本ツールは、以下の2つのツールの機能を順次呼び出して実行します。
  1) GakuNin RDM上で、既存プロジェクトの下に新規の子プロジェクトを作成 [create_grdmprj]
  2) GakuNin RDMのプロジェクトにマウントされたストレージへデータをアップロード [wbclient]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* _上記2つのツールはR2DMS Uploaderのパッケージに含まれています。_ 

最新版は **[ここ](https://dmsutil.riken.jp/tool/r2dms_uploader-0.0.3.zip)** からダウンロードしてください。
<br>
<br>

## **準備**

### <u>Pythonのアップデート</u>

本ツールでは **<span style="color:red">バージョン3.10以上</span>** の `Python` が必要です。以下のように作業環境のバージョンを確認してください。
```shell
python --version
```
もし、作業環境の `Python` のバージョンが低い場合はアップデートしてください。（※環境によっては管理者権限が必要かもしれません）

### <u>依存ライブラリのインストール</u>

本ソフトウェアでは、Pythonの標準ライブラリの他に、サードパーティ製のモジュールである`pandas`、`requests`および`pydantic-settings`が必要です。

Linuxでは以下のようにすると、これらのモジュールが作業環境で利用できる場合は、その名称とバージョンが表示されます。
```shell
pip list | grep -e pandas -e requests -e pydantic-settings
```
Windowsの場合は、Powershellを立ち上げて、以下のように確認してください。
```shell
pip list | findstr “pandas requests pydantic-settings”
```
もし、これらのモジュールが無い場合は、例えば以下のようにインストールしてください。（※環境によっては管理者権限が必要かもしれません）
```shell
pip install pandas
pip install requests
pip install pydantic-settings
```

### <u>R2DMS Uploaderのインストール</u>

ダウンロードした本ツールのパッケージ(ZIPファイル)を適当なディレクトリに解凍・展開してください。Linuxでは以下のようにします。
```shell
unzip -d {展開先のディレクトリパス} r2dms_uploader-0.0.3.zip
```
Windowsの場合は、エクスプローラーでZIPファイルを右クリックして、表示されたメニュー内から「すべて展開」を選択します。その後、表示されるダイアログで展開先のフォルダを指定して「展開」ボタンをクリックしてください。

### <u>アクセストークン等の設定</u>

本ソフトウェアの展開先のディレクトリで、適当なエディタを使って、以下のような `.env_control` ファイルを作成してください。
```shell
GRDM_TOKEN="ABCDEFGHIJKLM0123456789NOPQRSTUVWXYZ"
GRDM_OSFAPI="https://api.rdm.nii.ac.jp/v2"
GRDM_WBAPI="https://files.rdm.nii.ac.jp"
```

&nbsp;<span style="background-color:#3cb371">注意</span>
- ファイル名(`.env_control`)は変更しないでください。
- 以下の3つの環境変数を設定してください。
  
  <div style="background-color:rgba(240,255,255,0.05)">

  |環境変数|説明|
  |:--|:--|
  |GRDM_TOKEN|GakuNin RDM へのパーソナルアクセストークン|
  |GRDM_OSFAPI|GakuNin RDM の OSF API の URL|
  |GRDM_WBAPI|GakuNin RDM の Waterbutler API の URL|

  - パーソナルアクセストークンの取得方法については、使用手引書の付録を参照してください。
  - 上記の .env_control の例に示す OSF API および Waterbutler API の URL は、NII の GakuNin RDM のものです。NII 以外の GakuNin RDM を利用する場合は、それぞれのシステム管理者にお問い合わせください。

  </div>


### <u>入力パラメタの準備</u>

適当なエディタを使って、以下に示すような入力ファイル(CSVフォーマット)を作成してください。
```shell
"parent_id","prj_title","data_path","replace_flag"
"abcde","A sample child project 001","./sample_data","0"
,"A sample new project XYZ","./sample_data2","0"
"xyz01",,"./sample_data3","1"
```
&nbsp;<span style="background-color:#3cb371">注意</span>
- **<span style="color:red">UTF-8</span>** でエンコードされたCSVファイルを使ってください。
- 上の例で示した通りのヘッダー行を先頭に置き、その後にデータ行を記述してください。
- 各データ行は以下に定義する4個の要素の値(カンマ区切り)から構成されます。

  <div style="background-color:rgba(240,255,255,0.05)">

  |要素|説明|
  |:--|:--|
  |parent_id|既存[プロジェクトID](./images/project_id_ja.png) &nbsp;(このプロジェクトの[子プロジェクトとして新規のプロジェクトが作成](./images/child_project_ja.png)される)|
  |prj_title|新規プロジェクトのタイトル|
  |data_path|[アップロードするデータ(ディレクトリorファイル)のパス](./images/upload_s3_ja.png)|
  |replace_flag|上書きフラグ (0：アップロード先に同じファイルパスが存在するケースでは、そのファイルを上書きしない / 1：同ケースにて上書きする)|
  
    - 上記の要素の順番は変えないでください。
    - 既存プロジェクトID(`parent_id`)をブランクにすると、新規の独立したプロジェクトが作成され、そこにデータがアップロードされます。
    - 既に作成済みのプロジェクトにデータをアップロードする場合は、そのプロジェクトのIDを既存プロジェクトID(`parent_id`)に設定し、新規プロジェクトのタイトル(`prj_title`)をブランクにしてください。
    - プロジェクトを作成するケースでは、上書きフラグはどちらの値でも構いません。
  
  </div>

- データ行の各要素の値は二重引用符(`"`)で括ってください。
- シャープ記号(`#`)で始まる行は無視されます。
- 要素の値に二重引用符(`"`)を含めたい場合は、もう一つの二重引用符(`"`)を直前に置いてエスケープしてください。
- プロジェクトのタイトルに `<` や `>` を使えますが、それらはGakuNin RDM上では `\&lt;` 、 `\&gt;` のように表示されます。
- サンプルの入力ファイル(`sample_input.csv`)を参照してください。


## **データのアップロード**

本ソフトウェアの展開先のディレクトリで、以下のコマンドを実行します。
```shell
python -m r2dms_uploader {入力CSVファイルパス} -o/--output {出力JSONファイルパス}
```
&nbsp;<span style="background-color:#3cb371">注意</span>
- `.env_control` ファイルも同じディレクトリに置いてください。
- 入力ファイルパスは必須です。
- 処理のサマリ(JSONフォーマット)が返されます。
- 出力ファイルを指定しない場合は標準出力に処理のサマリが表示されます。
- 出力ファイルについては、サンプル(`sample_output.json`)を参照してください。


### <u>処理のサマリ</u>

処理のサマリとして出力される内容は以下の通りです。
<details><summary><b>出力サマリ</b></summary>
<pre>
{
  "summary": {
    "message": 処理全体に関するメッセージ
    "start_date": 処理全体の開始時刻(YYYY-mm-ddTHH:MM:SS.ffffff+HH:MM ；時刻に関してはすべて同じ形式)
    "stop_date": 処理全体の終了時刻
    "work_host": 実行ホスト名
    "work_dir": 実行ディレクトリパス
    "exec_user_id": 実行ユーザID
    "input_filepath": 入力ファイルパス
    "output_filepath": 出力ファイルパス
    "num_csvline_valid": 入力ファイルの有効CSV行数
    "num_proc_total": 全処理数
    "num_proc_succeeded": 成功処理数
    "num_proc_failed": 失敗処理数
    "num_proc_skipped": スキップ処理数
    "processes": [ <span style="color: red;">※以下の要素をCSVファイルの有効行ごとの配列データとして格納</span>
      {
        "proc_id": 処理番号(1スタートの連番)
        "status": ステータス(OK/NG/SKIPPED)
        "message": 処理に関するメッセージ
        "start_date": 処理開始時刻
        "stop_date": 処理終了時刻
        "csv_input": [ 処理対象の入力CSV行の内容
          "<em>`parent_id`の値</em>",
          "<em>`prj_title`の値</em>",
          "<em>`data_path`の値</em>",
          "<em>`replace_flag`の値</em>"
        ],
        "create_grdmprj": { <span style="color: red;">※「create_grdmprj」機能の実行結果として以下の要素を格納</span>
          "status": ステータス(OK/NG/SKIPPED)
          "start_date": 開始時刻
          "stop_date": 終了時刻
          "message": この関数からのメッセージ
          "internal_rc": 内部リターンコード(0:正常終了/0以外：異常終了)
          "parent_guid": 作成したプロジェクトの親プロジェクトのID
          "root_guid": 作成したプロジェクトの一番上の親プロジェクトのID
          "guid_created": 作成したプロジェクトのID
          "url_created": 作成したプロジェクトのURL
          "title_created": 作成したプロジェクトのタイトル
          "creator_guid": プロジェクト作成者のID
          "creator_name": プロジェクト作成者の名前
        },
        "wbclient": { <span style="color: red;">※「wbclient」機能の実行結果として以下の要素を格納</span>
          "status": ステータス(OK/NG/SKIPPED)
          "start_date": 開始時刻
          "stop_date": 終了時刻
          "message": この関数からのメッセージ
          "local_path": アップロードするデータ(ディレクトリ/ファイル)のパス
          "target_project_id": アップロード先のGakuNinRDMのプロジェクトID
          "storage_provider": アップロード先のストレージ名
          "remote_dir": アップロード先のディレクトリ
          "replace_flag": 上書きフラグの値
          "upload_result": { <span style="color: red;">※アップロードされたディレクトリ/ファイルとアップロード結果のリストを以下に格納</span>
            "<em>リモート/ディレクトリ/パス/</em>": "<em>created.</em> または <em>already exists.</em>",
            ...
            "<em>リモート/ファイル/パス</em>": "<em>uploaded.</em> または <em>replaced.</em> または <em>found (not replaced).</em>",
            ...
          }
        }
      },
      ... <span style="color: red;">CSVファイルの次の有効行に関する処理結果が格納される</span>
      ...
    ]
  }
}  
</pre>
</details>
