Google Colaboratory（個人的便利シート）

## Google Colaboratoryとは

<details><summary>一言で言えば、Google版Jupyter Notebook。Googleが提供する無料サービスの一つで、クラウド上でPythonの記述、実行ができます。</summary>

`ブラウザ`と`googleアカウント`さえあれば
Pythonの実行環境をサクッと**3秒**で構築できてしまいます。<br>
クロスプラットフォームな実行環境であるため共同開発での差異が小さく[^1]、
また各ノートブックがサンドボックスであり`初期化 → 実行`や`新規作成 → 破棄 → 新規作成`のような使い切り開発や、
`ノートブックのコピー → 破棄`のような使い捨てもできます。

</details>

[^1]: ブラウザやバージョンにより挙動が異なることもあるようです。

>Colaboratory へようこそ

https://colab.research.google.com/notebooks/welcome.ipynb

## 出来たこと
>機械学習周りいろいろ
>githubとの連携
>簡易のhttp.server、CGIサーバーの起動
>Googleの各無料サービスとの連携、APIの利用
>Flask、FastAPI、Streamlit、SQLAlchemyの利用、連携
>Ngrok、localtunnelの利用
>その他いろいろ


## 各名称

![colab_screen.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/9c938da8-2a02-4403-7638-6c74083cd518.jpeg)



### ①メニューバー
<details><summary>各設定、操作ができます。</summary><div>

>`ファイル`、`編集`、`表示`、`挿入`、`ランタイム`、`ツール`、`ヘルプ`
</div>
</details>

### ②左ペイン

<details><summary>

アイコンをクリックすると、 `スペース③` へ各ブラウザを表示することができます。</summary>
<div>
>上から、
`目次`、`検索と置換`、`コードスペニット`、`変数`、`ファイル`
のアイコンです。
`ファイル`アイコンをクリックすると、`③ファイルブラウザ`を開きます。
</div></details>


### ③ファイルブラウザ
<details><summary>

`②左ペイン`の一番下`ファイル`をクリックすると出現します。</summary><div>

左上から`ファイルの選択`、`状態の更新`、`ドライブ`アイコンが並びます。

`ドライブアイコン`からGoogleドライブをマウントすることができます。
カレントディレクトリは`/content`です。

```j:コードセル
!echo > xxx.txt
!pwd
!ls
```
>>/content
sample_data　sample.py　xxx.txt
</div></details>


### ④⑤セル

<details><summary>

`④テキストセル`と`⑤コードセル`があります。</summary><div>

`コードセル`の中で`システムコマンド`や`マジックコマンド`が使えます。

|  | 記法 |  |
|:--|:-:|:-:|
| システムコマンド       | ! | シェルコマンドなど |
| マジックコマンド     | %<br>%% |ラインマジック<br>セルマジック|

先頭に!や%を書きます。
例

```j:コードセル
!echo hello world
%history
```
```j:コードセル
%%bash
```
</div></details>


### ⑥エディタ
<details><summary>ファイルや画像、各情報を表示・出力します。</summary><div>

>テキストエディタでは一括置換などのショートカットキーがいくつか用意されています。
また、`⑤コードセル`にも一部テキストエディタとしての機能が備わっています。
編集後、`しばらく待つ`か、`タブの上をワンクリック`すると上書き保存されます。
</div></details>


### ⑦ランタイムやセッションの状況
<details><summary>ランタイムが起動しているか視認できたり、セッション管理が行えます。</summary><div>
準備中
</div></details>

# ショートカットキー
| キー | 操作 | 場所 |
|:-:|:-:|:-:|
||||
|`Shift` + `Enter`| セルの実行 | コードセル |
||||
|`Ctrl` + `D`| 一括編集 | コードセル <br> エディタ |
||||


# 便利シート

## 基本


### コードセルに書く。

`システムコマンド`や`マジックコマンド`は、`pythonコード`と一緒に書くことができます。
例

```python:コードセル
print("start") #python
# シェルコマンド
!ls
print("end") #python
```
>start
sample_data　sample.py　xxx.txt
end

各コードセルの変数の値は保持されます。

```python:コードセル1
a=2
```
```python:コードセル2
print(a+3)
```
>5


### コードセルで保持された変数をシステムコマンドで使う。
`$変数名`で`システムコマンド`で使えます。
例

```python:コードセル
path="tmp1"
!mkdir /content/$path
```
`/content/tmp1`が作られます。

### システムコマンドの実行結果をコードセルの変数に格納する。
例

```python:コードセル
res=!echo hello
print(res)
res=!python -c 'print("world")'
print(res[0])
```
>['hello']
world


### フォーム、Markdownを使う。
`コードセル`と`テキストセル`で使います。

インタラクティブなフォーム（公式の例↓のみで十分）
[https://colab.research.google.com/notebooks/forms.ipynb](https://colab.research.google.com/notebooks/forms.ipynb)

Markdown記法であれば大抵対応
[https://colab.research.google.com/notebooks/markdown_guide.ipynb](https://colab.research.google.com/notebooks/markdown_guide.ipynb)



## よく使うコマンド

### ファイルを作成・保存する。
`%%writefile ファイルのパス`を`コードセル`の１行目に書きます。
１行目以外のすべての行が、改行を維持したまま`ファイルのパス`へ保存されます。
例

```python:コードセル
%%writefile xxx.py
import time
time.sleep(1)
print("hello")
```
```j:コードセル
!python xxx.py
```

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

シェルコマンド`echo`を使います。
例

```python:コードセル
r=10
s=f"""
hoge={r}
fuga=20
""".strip()
!echo -n "$s" > xxx.txt
````
>hoge=10
fuga=20

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

他にも直接ファイルをアップロードしたりすることができます。


### bashモードで書く。
`%%bash`を１行目に書くことで、`pythonモード`から`bashモード`になります。
例

```j:コードセル
%%bash
sleep 3
echo hello world
```
>hello world

### その他シェルコマンドを使う。
`cd`、`pip`、`nohup`など、多くのコマンドに対応しています。
例

```j:コードセル
%%writefile requirements.txt
streamlit
fastapi
```
```bash:コードセル
!pip install -r requirements.txt
```


## よくやる操作

### セルの実行
選択中の`コードセル`で`Shift` + `Enter`
![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)
`コードセル`の　`▶`　をクリック
![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)
`メニューバー`から、
`ランタイム`　**>**　`すべてのセルを実行`　*or*　`ランタイム`　**>**　`現在のセルを実行`

### セルの実行停止
`コードセル`の　`■`　をクリック

:::note info
一回で停止しない場合は、何回かクリックします。
:::

:::note warn
停止するまでに遅延があるので、クリック連打による再実行に注意
:::

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

`メニューバー`から、
`ランタイム`　**>**　`実行を中断`

### ランタイムを出荷時設定にリセットする。
何か上手くいかなかったときは再起動。

`メニューバー`　**>**　`ランタイム`　**>**　`ランタイムを出荷時設定にリセット`

:::note warn
すべてのローカル変数やファイルを含め、ランタイムの状態は保存されません。
:::

ただし、追加したセルは保存されます。

### 起動中のセッションを終了する。
`⑦セッションの状態`　＞　`セッションの管理`　＞　`終了`

### Googleドライブをマウントする。
`左ペイン`　**>**　`ファイルアイコン`をクリック　**>**　`ドライブアイコン`をクリック

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

```python:コードセル
from google.colab import drive
drive.mount("/content/gdrive")
```

### ファイルブラウザ　*or*　エディタを起動する。
ディレクトリ構造やファイルの中身を視認します。
画像ファイルを表示することもできます。

```python:コードセル
from google.colab import files
files.view("/content")
files.view("/content/xxx.txt")
```

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

```python:コードセル
#クォーテーションで囲まれたファイルやディレクトリの絶対パスの上に
#マウスのポインターを置き、出現したポップアップをクリック
print("/content")
```

![スクリーンショット_2022-01-04_19-26-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459843/7f7a2d2f-b6f2-ea21-1574-722ce95c64e9.png)

`左ペイン`　**>**　`ファイルアイコン`をクリック　**>**　`ファイル`をダブルクリック

:::note info
テキストエディタでは Ctrl+D などのショートカットキーが使えます。
:::

### ファイルのアップロードフォームを表示する。
```python:コードセル
from google.colab import files
uploaded = files.upload()
```

### ローカルホストを出力する。
サーバーが立ち上がったかどうか確認するため、ローカルホストのURLを出力します。

```python:コードセル
from google.colab.output import eval_js
port=8010
eval_js(f"google.colab.kernel.proxyPort({port})").strip("/")
```
>'https://**********-**********-8010-colab.googleusercontent.com'

## 画像関連

### コードセルの出力画面に画像を表示する。
`IPython`を使います。（標準でインストール済みです。）
`!pip show IPython`

*ローカルに保存した画像パスから画像を読み込む。*

```python:コードセル
from IPython.display import Image,display_jpeg,display_png
display_jpeg(Image("sample.jpg"))
```

*ローカルに保存せずに画像URLから表示する。*

```python:コードセル
from IPython.display import Image,display_jpeg,display_png
img_url="https://dummyimage.com/100x50/6e6e6e/ffffff.jpg"
Image(url=img_url)
```
`Image(url=img_url)`は最後に実行する必要があります（空行やコメントアウト行を除く）。


### 画像URLから取得したバイナリデータをio.BytesIOに渡す。

```python:コードセル
from io import BytesIO
import requests
img_url="https://dummyimage.com/100x50/6e6e6e/ffffff.jpg"
img = BytesIO(requests.get(img_url,timeout=15).content)
# 表示する場合
#import IPython
#IPython.display.Image(img.getvalue())
```

`IPython.display.Image(img)`は最後に実行する必要があります（空行やコメントアウト行を除く）。

### 画像URLから画像を保存する。

```python:コードセル
from io import BytesIO
import requests
import IPython
img_url="https://dummyimage.com/100x50/6e6e6e/ffffff.jpg"
img = BytesIO(requests.get(img_url,timeout=15).content)
output="/content/sample.jpg"
with open(output, "wb") as f:
    f.write(img.getvalue())
```

*Pillowを使う。*

```python:コードセル
from io import BytesIO
import requests
import IPython
import PIL
img_url="https://dummyimage.com/100x50/6e6e6e/ffffff.jpg"
img = BytesIO(requests.get(img_url,timeout=15).content)
output="/content/sample7.jpg"
img = PIL.Image.open(img)
img.save(output)
```


## フレームワークとの連携

### Streamlitを起動する。
```python:コードセル
#portはデフォルトで8051
!streamlit run app.py
#!streamlit run app.py --server.port=8030
```

:::note warn
ColabratoryではそのままではStreamlitの全機能を使うことができないので
ngrokかlocaltunnelでトンネルして起動します。
:::

:::note info
ngrokは最近よく失敗するのでlocaltunnelおすすめです。
:::

:::note warn
ngrok、localtunnel共にローカルで実行中のアプリを外部公開するサービスなので、
公開URLを知っている人なら誰でもアクセスできてしまいます。
:::

*ngrokで*

```python:コードセル
import nest_asyncio
from pyngrok import ngrok
ngrok_tunnel = ngrok.connect(8051)
host=ngrok_tunnel.public_url
nest_asyncio.apply()
print("Public URL:", host)
!streamlit run app.py
```
`Public URL: http://********.ngrok.io`をクリックして移動。
`Click to Continue`ボタンを押す。

*localtunnelで*

```python:コードセル
!streamlit run app.py & sleep 10 && npx localtunnel --port 8501
```
`your url is: https://*****-*******-**.loca.lt`をクリックして移動。
`Click to Continue`ボタンを押す。


### FastAPIを起動する。
```python:コードセル
from google.colab.output import eval_js
port=8030
eval_js(f"google.colab.kernel.proxyPort({port})").strip("/")
import uvicorn
!uvicorn.run(app=app, port=int(port),host="0.0.0.0")
```
`https://***********-****************-8030-colab.googleusercontent.com`に接続。

*ngrokで*
`Streamlitを起動する。`を参照。

*localtunnelで*
`Streamlitを起動する。`を参照。

:::note info
localhostとして他のアプリケーションと連携したい場合のエンドポイントは、
http://localhost:[port番号]/です。
例：
Streamlitをlocaltunnelで　＋　FastAPIをlocalhostで
:::

## ノートブック

https://qiita.com/gudapys/items/a83a43e2fbbfda19d2a3

https://qiita.com/gudapys/items/1405846c6ed16c8c0d28

https://qiita.com/gudapys/items/62eda02bdb3de5530a23

https://qiita.com/gudapys/items/cae2730f093879659d1f

https://qiita.com/gudapys/items/d82216d4fdfbd67cbd91

*準備中*

### 予定のcolabノートブック

#### FastAPI（最小構成）
#### Streamlit+FastAPI（最小構成）
~~Streamlitページ遷移~~
~~Streamlitポップアップ~~
~~Streamlitページ遷移＋ポップアップ~~
#### FastAPI+SqlAlchemy
#### ToDoアプリなどwebアプリ群
#### 簡易サーバー起動 nohupも