web-dev-qa-db-ja.com

Google CloudAPIを使用して特定のバケット内のフォルダのリストを取得する方法

Google Cloud Storage APIを使用して、特定のGoogleCloudバケットまたはフォルダー内のすべてのフォルダーを取得したかったのです。

たとえば、gs://abc/xyzに3つのフォルダgs://abc/xyz/x1gs://abc/xyz/x2、およびgs://abc/xyz/x3が含まれている場合。 APIは、gs://abc/xyz内の3つのフォルダーすべてを返す必要があります。

gsutilを使用して簡単に実行できます

gsutil ls gs://abc/xyz

しかし、pythonとGoogleCloud StorageAPIを使用してそれを行う必要があります。

8
Shamshad Alam

Python GCS APIクライアントライブラリを使用できます。ドキュメントとダウンロードへの関連リンクについては、 Google Cloud Storageのサンプルとライブラリ ドキュメントページを参照してください。

あなたの場合、最初にあなたが「バケット」という用語を混乱させていることを指摘したいと思います。ドキュメントの 重要な用語 ページを読むことをお勧めします。あなたが話しているのは、オブジェクト名のプレフィックスです。

GitHubの list-objects.py サンプルから始めることができます。 list リファレンスページを見ると、prefix=abc/xyzdelimiter=/を渡す必要があります。

3
jterrace

また、バケットの内容を単純にリストする必要があります。理想的には、tf.gfileが提供するものに似たものが欲しいです。 tf.gfileは、エントリがファイルであるかディレクトリであるかを判別するためのサポートを備えています。

上記の@jterraceが提供するさまざまなリンクを試しましたが、結果は最適ではありませんでした。そうは言っても、結果を示す価値はあります。

「ディレクトリ」と「ファイル」が混在するバケットを考えると、「ファイルシステム」をナビゲートして関心のあるアイテムを見つけるのは困難です。上記で参照したコードがどのように機能するかについて、コードにいくつかのコメントを提供しました。

いずれの場合も、ノートブックに含まれている資格情報を持つデータラボノートブックを使用しています。結果を考えると、文字列解析を使用して、特定のディレクトリにあるファイルを判別する必要があります。これらのメソッドを拡張する方法、またはtf.gfileと同様のディレクトリを解析する別の方法を知っている人がいる場合は、返信してください。

方法1

import sys
import json
import argparse
import googleapiclient.discovery

BUCKET = 'bucket-sounds' 

def create_service():
    return googleapiclient.discovery.build('storage', 'v1')


def list_bucket(bucket):
    """Returns a list of metadata of the objects within the given bucket."""
    service = create_service()

    # Create a request to objects.list to retrieve a list of objects.
    fields_to_return = 'nextPageToken,items(name,size,contentType,metadata(my-key))'
    #req = service.objects().list(bucket=bucket, fields=fields_to_return)  # returns everything
    #req = service.objects().list(bucket=bucket, fields=fields_to_return, prefix='UrbanSound')  # returns everything. UrbanSound is top dir in bucket
    #req = service.objects().list(bucket=bucket, fields=fields_to_return, prefix='UrbanSound/FREE') # returns the file FREESOUNDCREDITS.TXT
    #req = service.objects().list(bucket=bucket, fields=fields_to_return, prefix='UrbanSound/FREESOUNDCREDITS.txt', delimiter='/') # same as above
    #req = service.objects().list(bucket=bucket, fields=fields_to_return, prefix='UrbanSound/data/dog_bark', delimiter='/') # returns nothing
    req = service.objects().list(bucket=bucket, fields=fields_to_return, prefix='UrbanSound/data/dog_bark/', delimiter='/') # returns files in dog_bark dir

    all_objects = []
    # If you have too many items to list in one request, list_next() will
    # automatically handle paging with the pageToken.
    while req:
        resp = req.execute()
        all_objects.extend(resp.get('items', []))
        req = service.objects().list_next(req, resp)
    return all_objects

# usage
print(json.dumps(list_bucket(BUCKET), indent=2))

これにより、次のような結果が生成されます。

[
  {
    "contentType": "text/csv", 
    "name": "UrbanSound/data/dog_bark/100032.csv", 
    "size": "29"
  }, 
  {
    "contentType": "application/json", 
    "name": "UrbanSound/data/dog_bark/100032.json", 
    "size": "1858"
  } stuff snipped]

方法2

import re
import sys
from google.cloud import storage

BUCKET = 'bucket-sounds'

# Create a Cloud Storage client.
gcs = storage.Client()

# Get the bucket that the file will be uploaded to.
bucket = gcs.get_bucket(BUCKET)

def my_list_bucket(bucket_name, limit=sys.maxsize):
  a_bucket = gcs.lookup_bucket(bucket_name)
  bucket_iterator = a_bucket.list_blobs()
  for resource in bucket_iterator:
    print(resource.name)
    limit = limit - 1
    if limit <= 0:
      break

my_list_bucket(BUCKET, limit=5)

これにより、次のような出力が生成されます。

UrbanSound/FREESOUNDCREDITS.txt
UrbanSound/UrbanSound_README.txt
UrbanSound/data/air_conditioner/100852.csv
UrbanSound/data/air_conditioner/100852.json
UrbanSound/data/air_conditioner/100852.mp3
6
netskink

この回答スレッドの更新は次のとおりです。

from google.cloud import storage

# Instantiates a client
storage_client = storage.Client()

# Get GCS bucket
bucket = storage_client.get_bucket(bucket_name)

# Get blobs in bucket (including all subdirectories)
blobs_all = list(bucket.list_blobs())

# Get blobs in specific subirectory
blobs_specific = list(bucket.list_blobs(prefix='path/to/subfolder/'))
3
Ekaba Bisong

この質問は、バケット/フォルダー内にfoldersをリストすることに関するものです。どの提案もうまくいきませんでした。_google.cloud.storage_ SDKを試した後、バケット内のパスのサブディレクトリを一覧表示することは(2019年11月現在)不可能だと思います。 REST APIで可能なので、この小さなラッパーを作成しました...

_from google.api_core import page_iterator
from google.cloud import storage

def _item_to_value(iterator, item):
    return item

def list_directories(bucket_name, prefix):
    if not prefix.endswith('/'):
        prefix += '/'

    extra_params = {
        "projection": "noAcl",
        "prefix": prefix,
        "delimiter": '/'
    }

    gcs = storage.Client()

    path = "/b/" + bucket_name + "/o"

    iterator = page_iterator.HTTPIterator(
        client=gcs,
        api_request=gcs._connection.api_request,
        path=path,
        items_key='prefixes',
        item_to_value=_item_to_value,
        extra_params=extra_params,
    )

    return [x for x in iterator]
_

たとえば、_my-bucket_に次のものが含まれている場合:

  • 犬の鳴き声
    • データセット
      • v1
      • v2

次に、list_directories('my-bucket', 'dog-bark/datasets')を呼び出すと次のようになります。

_['dog-bark/datasets/v1', 'dog-bark/datasets/v2']_

2
AntPhitlok

バケット内のフォルダーのリストを取得するには、以下のコードスニペットを使用できます。

import googleapiclient.discovery


def list_sub_directories(bucket_name, prefix):
    """Returns a list of sub-directories within the given bucket."""
    service = googleapiclient.discovery.build('storage', 'v1')

    req = service.objects().list(bucket=bucket_name, prefix=prefix, delimiter='/')
    res = req.execute()
    return res['prefixes']

# For the example (gs://abc/xyz), bucket_name is 'abc' and the prefix would be 'xyz/'
print(list_sub_directories(bucket_name='abc', prefix='xyz/'))
2
Anthony Ngene
# Sudo pip3 install --upgrade google-cloud-storage
from google.cloud import storage

os.environ["GOOGLE_APPLICATION_CREDENTIALS"]= "./key.json"
storage_client = storage.Client()
bucket = storage_client.get_bucket("my-bucket")
blobs = list(bucket.list_blobs(prefix='dir/'))
print (blobs)
1
user1797498