ファイル共有を簡単にする

Easy file sharing

Googleドライブの共有フォルダを利用した共同プロジェクトのためのコーディング例

最近、データ共有の問題が再び発生し、共有フォルダを利用するためのメソッドを設計する良い機会だと思いました。私は独立したGIScienceの専門家として、複数の組織と同時に関わることがよくあります。私のプロジェクトでは、各組織が独自のデータ処理方法を持っていることに気付きました。それは組織の独自の文化や働き方倫理によって形成され、多様な方法論を生み出しています。幸いなことに、彼らには共通のプラクティスがあり、そのうちの一つはクラウドベースのデータ管理システム(しばしばGoogle、またはMicrosoftのOneDriveやDropboxなど)を利用することです。

この記事では、Pythonを使ってGoogleエコシステムの共有フォルダをどのように利用するかを説明します。

Annie Sprattによる写真(Unsplash)

ユースケース

ローカルマシン上でのファイル管理方法は個人によって異なりますが、組織内での作業時には(おそらく)標準化されているか、少なくともある程度の標準化があります。システム間でファイルを共有することは複雑ですが、直接本番フォルダにアクセスできない場合や、組織から特定の作業フォルダを共有してもらい、ファイルのやり取りをするために共有フォルダを利用することができます。この例では、組織がGoogleドライブのリポジトリ上の「DATA」というフォルダへのアクセスを許可し、このフォルダをファイルのやり取りに利用することが合意されています。

ローカルファイル管理

Googleドライブのファイル共有に慣れていない人々に対して、プロセスの説明を簡単に行います。プロセスは、特定のフォルダへの貢献を求めるメールを受け取ることから始まります。以下は、招待状を示す画像です。招待状には、招待状を受け取った人のGoogleメールに関連付けられたGoogleドライブのインターフェースが開かれるボタンが含まれています。

図1:共有フォルダの作成(著者の画像)

インターフェースにはいくつか重要な情報が隠されており、それらを早期に理解しておくと、プロセスの残りの部分で役立ちます。

  • 画面の上部にURLがあり、これはGoogleがこのフォルダ上でのすべての操作を追跡するために使用しているマスクされたIDです。このIDは、この記事の後半でPythonコードで取得するIDです。
  • 次に、「Shared with me」と共有フォルダの名前が表示されます。これも重要です。なぜなら、GoogleドライブをCoLabノートブックにマウントすると、このカテゴリは利用できないからです。
  • 最後に、Dataの下にファイルとフォルダが表示されます。これは、必要な情報にアクセスし、新しいファイルをフォルダに追加することができることを意味します。ただし、フォルダのセキュリティ設定に問題がある可能性もあるため、この段階では、小さなテキストファイルを作成し、フォルダ「ExternalData」にドラッグアンドドロップして、完全なアクセス権限があることを確認すると良いテストになります。

「Shared with me」フォルダにアクセスするためには、このフォルダをローカル/個人ドライブにリンクする必要があります。これは手動のステップでShortcutを作成することで行うことができますが、それは人それぞれ異なる方法です。Google Colabで共有されたフォルダやファイルにアクセスするためには、以下の手順を実行する必要があります:

  1. Google Driveで「Shared with me」に移動します。
  2. アクセスしたいフォルダまたはファイルを選択します。
  3. 右クリックして「ドライブにショートカットを追加」を選択し、ポップアップウィンドウが表示されたら、「MyDriveを選択」をクリックします。
  4. ショートカットを簡単に見つけることができるドライブ上の場所に配置します。私のセットアップでは、ショートカットの場所は「__Shared」となっており、ショートカットを含むフォルダが「MyDrive」のフォルダリストの一番上に表示され、組織用のサブディレクトリがあります。
  5. ショートカットに意味のある名前を付けます。この例では「DataDevelopement」という名前を使っています。ファイルの場所や名前の規則は非常に個人的なものであり、プログラムにとってはどこにファイルが保存されているか、またはどのように呼ばれているかは重要ではありませんが、ある程度の構造を持っていると後々のトラブルを回避できます。
図2:ショートカットの作成(著者提供の画像)

ローカルファイルシステムが整理され、個人のGoogleドライブが設定されたら、Pythonノートブックでこの共有フォルダを操作し、プロジェクトでのファイル共有を自動化することができます。

インストール

このプロジェクトは、Google Colabまたは「Collaboratory」ノートブックに基づいています。この記事の最下部で共有します。この環境を使用する利点は、ブラウザでPythonを記述して実行できることです。以下の利点があります。

  • 特別な設定は必要ありません
  • 無料でGPUにアクセスできます
  • 簡単に共有できます

これらは、内部手順を持つ組織で作業する際に非常に重要です。外部協力者として、コードベースへの直接アクセスはあまり得られません(セキュリティ上の懸念からプロジェクト管理上の制約までさまざまな理由があります)。ColabノートブックはGoogleエコシステムの一部であり、(追加の利点として)個人のGoogleドライブをマウントするオプションを持つ実行環境を作成します(ファイル共有のため)。

モジュールとパッケージのインポート

この例では、ノートブックのランタイムに必要なパッケージのみがロードされ、共有ドライブで作業するためにいくつかの特定のライブラリが必要です。

Googleの認証

from oauth2client.client import GoogleCredentialsfrom google.colab import auth as google_authgoogle_auth.authenticate_user()from google.colab import drivedrive.mount('/content/gdrive')

oauth2clientとGoogle Credentialsを使用すると、ファイルの操作が容易になります。JSONファイルを資格情報としてダウンロードするなどの代替手段がありますが、このプロジェクトでは機密データがないため、oauth2clientライブラリを使用するだけで十分な保護が提供されます。

pydrive

from pydrive.auth import GoogleAuthfrom pydrive.drive import GoogleDrivegauth = GoogleAuth()gauth.credentials = GoogleCredentials.get_application_default()drive = GoogleDrive(gauth)

pydriveは、google-api-python-clientのラッパーライブラリであり、多くの一般的なGoogle Drive APIタスクを簡略化します。これらの機能の1つは、Google Driveファイルシステムをクエリする際の応答の処理です。Google DriveはすべてのオブジェクトをIDで保存し、IDはオブジェクト内の関係情報によってリンクされています。この情報にはAPIでアクセスすることもできますが(次のコードブロックを参照)、ラッパーライブラリは、Files.list()のパラメータを辞書として使用してGoogleDriveFileListインスタンスを作成するときに、すべてのクエリに一致するファイルをGoogleDriveFileのリストとして取得します。

Google APIクライアント

# Google API client:from googleapiclient.discovery import build# Initialize the Google Drive API clientdrive_service = build('drive', 'v3')

Google APIクライアントは大規模なライブラリであり、多くの機能がありますが、このプロジェクトではbuildという1つのモジュールのみが必要です。buildモジュールは、APIと対話するためのリソースオブジェクトを構築し、サービスとの対話のためのメソッドを返します。pydriveライブラリは、ファイルの作成、更新、削除などの基本的な機能を非常にうまく処理しますが、このプロジェクトではより高度な機能が必要な場合があり、pydriveのメソッドではキャプチャされていない情報を抽出するために「サービス」へのアクセスが必要です。

これでノートブックの設定が完了しました。この例では、ファイル管理のためにロードされたライブラリ以外のライブラリは必要ありません。ロードされたライブラリを使用して、それらが何をしているかを確認できます。

ノートブックでのファイル管理

これまでに、いくつかのことが起こりました:

  • Googleの認証が設定されました
  • ドライブへのアクセスが作成されました(読み書きアクセス用)
  • Pydriveパッケージを使用してドライブをナビゲートできるようになりました

コードを実行している場合、パネルをリフレッシュした後、右側に画像を表示することができるはずです。画像の中に「__Shared」の下にフォルダとしてショートカットが表示されています。「Shared with me」セクションは表示されないかもしれませんが、ショートカットがあるため、「Shared with me」ファイルを表示する必要はありません。

図3: Google Colabウェブインターフェースにおけるランタイム環境のマウントされていない状態とマウントされた状態の比較(著者による画像)

Google Driveは、ローカルオペレーティングシステムのファイル管理とは異なる動作をします。ファイルの物理的な場所は重要ではありません。なぜなら、オブジェクトは非構造化データレイク内でIDによって管理されており、IDを使用してファイルやフォルダにアクセスできるからです。

残念ながら、Pythonのos.pathにはファイルシステムを操作するための関数がありますが、Google Driveには同様のメソッドが存在しません(または私がそのメソッドを知らないだけかもしれません)。しかし、pydriveライブラリを使用して、ディレクトリツリー内のフォルダを手動で巡回することができます。幸いなことに、データパスのフォルダ名を使用して、どこに移動したいかを知っています。そのため、全体の構造を巡回する必要はありませんが、データパスのフォルダ名を使用して、フォルダツリーのさらに深い階層に移動することができます。

したがって、この例では(3つのアイテムが含まれています)、小さなリストをループしてIDを見つけ、このIDを使用して次のレベルに移動します。ただし、4番目のレベルはコメントアウトされています。このノートブックのファイル処理セクションの後半でこのレベルに移動します。

# ファイル処理のテスト:# この例では、3つのフォルダレベルがあります:# /content/gdrive/MyDrive/__Shared/<your Project>/DataDevelopment# 構造に合わせて更新してください:folderList1 = ["__Shared", your_Project ,"DataDevelopment"] #, "ExternalData"]

次のコードブロックでのループは、ルートから始まり、リストの中でアイテムを見つけると、オブジェクトのIDを使用してリストの次のレベルに移動します。アイテムが見つからない場合、フォルダが見つからなかったと表示され、構造のさらに深いフォルダを探すことはありません。ループはショートカットフォルダのIDまたはフォルダが見つからなかったとのメッセージで終了します。

# 作成したダミーファイルのコピーを試みる:boo_foundFolder = FalsefileID = "root"level = 0# Google Drive内のすべてのフォルダとファイルを表示する# リストをループ:print("ファイルとフォルダの構造 - IDで確認")for folderName in folderList1:  print(f"確認中:{folderName}")  if boo_foundFolder or fileID == "root": #初回実行    boo_foundFolder = False    fileList = drive.ListFile({'q': f"'{fileID}' in parents and trashed=false"}).GetList()    for file in fileList:      # 名前のテスト:            if(file['title'] == folderName):        fileID = file['id']        boo_foundFolder = True        level += 1       # end if    # end for    if boo_foundFolder == False:      print(f"フォルダが見つかりませんでした")      break    # end if      # end if# end forprint(f"フォルダは見つかりましたか:{boo_foundFolder}")if boo_foundFolder:  print(fileID)  ShortCutID = fileIDelse:  ShortCutID = 0

この時点で、作業フォルダのローカルファイルIDを持っていますが、この場所でファイルを検索するには、このローカルIDを共有フォルダのターゲットIDと一致させる必要があります。この情報を見つけるには、Googleのインフラストラクチャを詳しく調べる必要があります。これを行うためには、ヘルパーであるdrive_serviceが必要です。プロジェクトをロードする際にヘルパーを有効にし、警告が表示されなかったことから、APIを使用してサービスにアクセスでき、IDを指定して情報をリクエストできることを意味します。

必要な詳細情報は、次のコードブロックのfindTargetID関数のようなシンプルな関数を使用して収集するのが最適です。この関数では、fileIDはフォルダ名をループして見つけたショートカットIDであり、drive_service.files().getを呼び出してフィールドを指定することで、フォルダのターゲットIDを取得します(これはGoogle DriveウェブインターフェースのURLと同じIDになります(図1を参照))。

def findTargetID(fileID, drive_service):  # 取得したい共有ファイルのID  file_id = fileID  try:      # ファイルの詳細を取得      file = drive_service.files().get(fileId=file_id,                                       fields="id, shortcutDetails").execute()      # ファイルがショートカットかどうかをチェック      if 'shortcutDetails' in file:          shortcut_details = file['shortcutDetails']          print("ショートカットの詳細:")          print(f"ターゲットID:{shortcut_details['targetId']}")          print(f"ターゲットMIMEタイプ:{shortcut_details['targetMimeType']}")      else:          print("ファイルはショートカットではありません。")      # end if  except Exception as e:      print(f"エラーが発生しました:{e}")  return shortcut_details['targetId']if boo_foundFolder:  targetID = findTargetID(fileID, drive_service)  print(targetID)else:  print("フォルダが見つかりませんでした")# end if

このターゲットIDを使用することで、Googleデータサーバー上の実際の共有フォルダにアクセスできるようになり、もはやショートカットフォルダでは作業していません。

要約すると、ショートカットフォルダを作成した理由は、マウントされたフォルダのリストにフォルダを表示できるようにするためでした。「Shared with me」カテゴリはマウントされていませんが、ショートカットはマウントされています。したがって、この新しいIDを使用してファイルを探すことができます。

ファイルを探す

今、私たちに必要なもの、プロセスの最初に共有されたフォルダのターゲットIDを持っており、そのIDを使用して通常のファイル操作が利用できます。

共有フォルダに十分な権限があることを確認するために、まず実行時間環境で小さなテキストファイルを作成します。このファイルを作成することで、実行時間環境にアクセスできることも確認できます。ファイルが正しく作成された場合、CoLabノートブックのWebインターフェースの左パネルに表示されます。

# テストファイルを作成する:with open('example.txt', 'w') as f:  f.write('これはファイルの共有をテストするための例です')# このファイルは現在ノートブックの実行スペースに存在しています # (左のパネルの「ファイル」の下を参照)

今度は、このファイルを「Shared with me」フォルダ「Data」に移動することが目的です。ただし、前のセクションの関数は<target ID>を提供しており、このIDを使用して、実行時間環境で作成したファイルが共有ドライブ上で利用可能かどうかを確認できます。

if boo_foundFolder:  print("フォルダが見つかりました")  folderID = targetID  file_on_drive = False  file_id = 0    # ドライブ上にファイルが存在するか確認する:  fileList = drive.ListFile({'q': f"'{folderID}' in parents and trashed=false"}).GetList()  for file in fileList:    if(file['title'] == "example.txt"):      file_on_drive = True      fileID = file['id']    # end if  # end for  if file_on_drive:  #既存のGoogleドライブファイルを上書きします。    file1 = drive.CreateFile({'id': fileID})    strFileHandling = "更新済み"  else:    file1 = drive.CreateFile({"mimeType": "text/csv",                             "parents": [{"kind": "drive#fileLink",                                         "id": folderID}]})    strFileHandling = "作成済み"  # end if  # 実行時間環境のファイルへのバインディングの作成:  file1.SetContentFile("example.txt")  # ファイルをGoogleドライブにコピーする:  file1.Upload()  print(f'{strFileHandling} ファイル %s with mimeType %s' % (file1['title'], file1['mimeType']))else:  print("フォルダが見つかりませんでした")# end if

上記のコードを実行すると、共有フォルダに新しいファイルが作成されるか、ファイルが見つかった場合に更新(上書き)されます。

ワークスペースの作成

ショートカットIDを使用してターゲットIDを見つける第2の理由は、共有フォルダの下にあるアイテムを見つけるためです。前述のように、GoogleドライブはすべてIDで管理されており、ショートカットIDには子が存在しないため、このIDを使用して新しいアイテムを見つけると空のリストが返されます。これは、最初のフォルダのリストに「ExternalData」フォルダ名を含めてテストすることで確認できます。最初のリストではこのフォルダは見つかりません。ただし、ターゲットIDでループを再起動すると、このフォルダが見つかります。

以下のコードスニペットでは、「Shared with me」フォルダ名の下にあるフォルダ名を使用して新しいフォルダリストが作成されます。「ExternalData」フォルダは利用可能です(図1を参照)、しかし「NewDataFolder」はまだ作成されていません。

# これらを自分の構造に更新してください:# ... DataDevelopment/ExternalData/__CoLab_Notebook # 作業フォルダの設定:folderList2 = ["ExternalData", "NewDataFolder"]

前と同じループ構造を使用できますが、今度はROOTではなくターゲットIDから開始し、ループは「ExternalData」フォルダを見つけますが、新しいデータフォルダは見つかりません。

作業フォルダがまだ存在しないため、drive_service.filesを使用してこの新しいフォルダを作成し、同じ方法で実行時間環境から「Shared with me」フォルダに転送する必要のあるすべてのファイルを作成できます。

def create_folder_in_folder(folder_name, parent_folder_id, drive_service):    
    file_metadata = {
        'name' : folder_name,
        'parents' : [parent_folder_id],
        'mimeType' : 'application/vnd.google-apps.folder'
    }
    file = drive_service.files().create(body=file_metadata, supportsAllDrives=True, fields='id').execute()
    print ('フォルダーID:%s' % file.get('id')) 

if WorkingFolderID == 0:   
    # fileIDは前回の検索からの親IDです
    create_folder_in_folder("NewDataFolder", fileID, drive_service)

主な要点:Google ドライブのファイルシステムは ID ベースで、すべてのオブジェクトには ID があります。「Shared with me」のオブジェクトは Google Colab では利用できませんが、「ショートカット」を通じてアクセスすることができ、関連するターゲット ID を見つけることで、最初に共有されたフォルダー内のオブジェクトに直接アクセスすることができます。

結論

この記事では、共有フォルダーを使用する際の重要な側面について説明しました。具体的には:

  1. ローカルファイルの管理の設定:指定された Google ドライブディレクトリへの投稿への招待を受け取り、ローカルファイルシステムを構築して共同作業の効率を向上させる方法について説明しました。
  2. Google Colab の共同作業の設定:Google Colab、共同作業用の Python 環境を使用する利点と、プロジェクトの共同作業のためにそれを設定する方法について説明しました。
  3. 必要なモジュールとパッケージのインポート:Google の認証、Google ドライブ API タスクを簡略化するための pydrive、および高度な機能のための Google API クライアントなど、重要なモジュールとパッケージのインポートについてのコード例を提供しました。
  4. ノートブックでのファイルの管理:Google Colab 環境内でのファイルの管理方法について説明しました。共有 ID とターゲット ID を使用して、ローカル環境と共有フォルダー間でファイルの作成や移動を行う方法を見ました。
  5. ファイルの検索とワークスペースの作成:共有フォルダー内のファイルを見つけるプロセスについて詳しく説明し、プロジェクト用の新しいフォルダーやワークスペースを作成する方法について説明しました。

組織間で共有されるフォルダーやファイルを扱う方法についてのこの記事がお役に立ち、共有フォルダー内のファイルやフォルダーを操作する方法についての洞察を提供できたことを願っています。

お読みいただき、この投稿が問題の解決や次のプロジェクトのアイデアを提供できたことを願っています。

Google CoLab ノートブックのリンク:gist

免責事項:この例で使用されるコードは最適化されていませんが、プロセスを説明するために書かれています(このノートブックをホストしている GitHub ページでコードの改善に関する提案がありましたら、お待ちしております)。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

コンピュータサイエンス

「祝福と恐怖:広告主が慎重にAIを受け入れる」

「多くの広告は、急速に進化する技術によってより簡単に作成できるようになっていますただし、これは既に変動中の産業にとっ...

データサイエンス

「OpenAIの研究者たちは、敵対的なトレーニングを行わずに高品質なデータサンプリングのための先進的なコンシステンシーモデルを開拓しました」

一貫性モデルは、敵対的なトレーニングに頼らずに、単一のステップで高品質のデータを生成するために設計された生成モデルの...

人工知能

GPT-4は、誤情報を引き起こすプロンプトインジェクション攻撃に対して脆弱です

ChatGPTには、信頼性の低い事実を提供する可能性があるかもしれない漏れがあるかもしれません

機械学習

がん検出の革命:サリー大学が機械学習における画像ベースのオブジェクト検出ツールを発表し、ゲームチェンジとなる

先史時代以来、人々はコミュニケーションや文書化のためにスケッチを使用してきました。過去10年間、研究者たちは、分類や合...

人工知能

「AWSは責任ある生成AIへの取り組みを再確認する」

人工知能(AI)や機械学習の先駆者として、AWSは責任を持って生成的AIの開発と展開に取り組んでいます生成的AIは、私たちの時...

AIニュース

業界の内部人がビッグテックのA.I.に対するオープンな代替案を推進しています

「Appleに自身の会社を売却した尊敬されるコンピューターサイエンティストに率いられる非営利団体のAllen Institute for AIは...