はじめに

以前の記事で,smart_openによって統一的にファイルアクセスが可能であることを紹介しました. しかしながら,//を適切に扱うことができないため,URLを扱うには問題がありました. そこで,この問題を解決しsmart_openをラップしたpaaaaathを作成しました.

やったこと

  • paaaaathの導入
  • paaaaathによるクラウドストレージ上のファイルを操作

paaaaathについて

paaaaathはローカルマシン上のファイルパスのみでは無く,http, s3, gcsといったプロトコルのURLもpathlib.Pathと同様に取り扱うことができます.ファイルの読み書きはsmart_openに処理を委譲することで実現します.また,s3, gcsについては,mkdir, iterdirs, exitsといった処理にも対応しています.サポートしている機能の詳細については,リポジトリを確認してくさい.

以下にpipを用いたpaaaaathの導入方法を示します.ここでは,extrasとしてallを指定しました.ほかにも,http, gcs,s3 が指定可能です.allはこれら全てを指定することと同義です.

$ pip install paaaaath[all]

クラウドストレージ,Webからファイルを読み込む

smart_openによるサンプルをpaaaaathを用いて書き直しました.Pathlikeオブジェクトとして取り扱うことができるので,全体的にシンプルになっていることが確認できると思います.こちらも,事前に適切な認証情報を設定しておく必要があります.

from paaaaath import Path
import matplotlib.pyplot as plt
import imageio

sources = {
    "S3": "s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_BQA.TIF",
    "HTTP":  "https://s3-us-west-2.amazonaws.com/landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_BQA.TIF",
    "FILESYSTEM": "/tmp/LC80030172015001LGN00_BQA.TIF"
}

for protocol, url in sources.items():
    img = imageio.imread(Path(url).read_bytes())
    plt.figure()
    plt.title(f"from {protocol}")
    plt.imshow(img, cmap='gray')

クラウドストレージ上のファイルを操作する

paaaaathを用いてクラウドストレージ上のファイルを読み書きする例を以下に示します.

sample_path = Path("s3://paaaaath-examples/sample.txt")
sample_path.write_text("paaaaath example")
assert sample_path.read_text() == "paaaaath example"

また,paaaaathはPathlikeオブジェクトを提供します.そのため,単純なファイルの読み書きだけでは無く,より多くの機能を提供することが可能です.以下に,iterdirを用いてクラウドストレージ上のファイル一覧を取得する例を示します.

paths = list(Path(sources["S3"]).parent.iterdir())
assert paths[0].exists()
paths      
[S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B1.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B1.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B10.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B10.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B11.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B11.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B2.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B2.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B3.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B3.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B4.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B4.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B5.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B5.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B6.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B6.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B7.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B7.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B8.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B8.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B9.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_B9.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_BQA.TIF'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_BQA.TIF.ovr'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_MTL.json'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_MTL.txt'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_thumb_large.jpg'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/LC80030172015001LGN00_thumb_small.jpg'),
 S3Path('s3://landsat-pds/L8/003/017/LC80030172015001LGN00/index.html')]

参考