LoginSignup
19
21

[Python] Dropbox API でファイル情報を取得(sdk)

Last updated at Posted at 2019-01-07

今度はPythonで with SDK

以前、PHPでDropbox APIを使った記事を書きましたが、そのPython版です。
Python はほぼビギナー!

準備

developerサイトでapp登録するところまでは同じです。

SDKをインストールします。

$ pip install dropbox

簡単~。

SDKのドキュメントはこちら

インスタンス生成

【更新】リフレッシュトークンを利用したアクセストークン取得形式に対応
【更新2】チームスペース形式に対応

import dropbox
import requests

APP_KEY = 'XXXXXXXX'
APP_SECRET = 'XXXXXXXX'
REFRESH_TOKEN = 'xxxxxxxxxxxxxxxx'

#「リフレッシュトークン」を利用してアクセストークン取得
auth = (APP_KEY, APP_SECRET)
param = {'grant_type': 'refresh_token', 'refresh_token': REFRESH_TOKEN}

res = requests.post('https://api.dropboxapi.com/oauth2/token', auth=auth, data=param)

if res.status_code != 200:
    res.raise_for_status()

token = res.json()

dbx = dropbox.Dropbox(token['access_token'])

#「チームスペース」対応
root_namespace_id = dbx.users_get_current_account().root_info.root_namespace_id
dbx = dbx.with_path_root(dropbox.common.PathRoot.root(root_namespace_id))

これを使って各種メソッドを呼んでいきます。

ファイル一覧を取得する

HTTPリクエストの

これに対応するのが

res = dbx.files_list_folder('指定ディレクトリ', recursive=True)

返り値はこうなっていて、
res.entries:結果配列
res.has_more:続きがあるか
res.cursor:has_more=Trueの場合、files_list_folder_continueのパラメータとなる

再帰的に呼び出すとこんなイメージです。

指定ディレクトリ以下すべて取得
def __get_files_recursive(res):
    for entry in res.entries:
        print(entry.path_display)

    if (res.has_more):
        res2 = dbx.files_list_folder_continue(res.cursor)
        __get_files_recursive(res2)

res = dbx.files_list_folder('指定ディレクトリ', recursive=True)
__get_files_recursive(res)

結果配列にはフォルダもファイルも含まれていて、HTTPリクエストだと.tagというプロパティにフォルダかファイルか持っていますが、
Dropbox for pythonだと要素がFolderMetadataclassかFileMetadataclassかになっています。

ファイルのみ
for entry in res.entries:
    ins = type(entry)
    if ins is not dropbox.files.FileMetadata: #ファイル以外(=フォルダ)はスキップ
        continue

    print(entry.path_display)

指定ファイルの共有リンクを取得する

同じくHTTPリクエストの

これに対応するのが

共有リンク取得
    def __get_shared_link(path):
        links = dbx.sharing_list_shared_links(path=path, direct_only=True).links

        if links is not None:
            for link in links:
                return link.url #1件目を返す
共有リンク発行
    def __create_shared_link(path):
        setting = dropbox.sharing.SharedLinkSettings(requested_visibility=dropbox.sharing.RequestedVisibility.public)
        link = dbx.sharing_create_shared_link_with_settings(path=path, settings=setting)

        return link.url

settingsに渡すパラメータはSharedLinkSettingsclassインスタンスになります。

まとめ

class化してみます。
viewFilesを呼ぶと、ファイルパスと共有リンク(なければ公開で発行)を出力します。

【更新】リフレッシュトークンを利用したアクセストークン取得形式に対応
【更新2】チームスペース形式に対応

class
import dropbox
import requests

class MyDropbox():
    APP_KEY = 'XXXXXXXX'
    APP_SECRET = 'XXXXXXXX'
    REFRESH_TOKEN = 'xxxxxxxxxxxxxxxx'
    DB_ROOT_DIR = '/指定フォルダ'

    def __init__(self):
        #「リフレッシュトークン」からアクセストークン取得
        self.dbx = dropbox.Dropbox(self.__get_access_token())

        #「チームスペース」対応
        root_namespace_id = self.dbx.users_get_current_account().root_info.root_namespace_id
        self.dbx = self.dbx.with_path_root(dropbox.common.PathRoot.root(root_namespace_id))

    def __get_access_token():
        auth = (self.APP_KEY, self.APP_SECRET)
        param = {'grant_type': 'refresh_token', 'refresh_token': self.REFRESH_TOKEN}

        res = requests.post('https://api.dropboxapi.com/oauth2/token', auth=auth, data=param)

        if res.status_code != 200:
            res.raise_for_status()

        token = res.json()

        return token['access_token']

    def viewFiles(self):
        res = self.dbx.files_list_folder(self.DB_ROOT_DIR, recursive=True)

        self.__get_files_recursive(res)

    def __get_files_recursive(self, res):
        for entry in res.entries:
            ins = type(entry)
            if ins is not dropbox.files.FileMetadata: #ファイル以外(=フォルダ)はスキップ
                continue

            link = self.__get_shared_link(entry.path_lower)
            if bool(link):
                print(entry.path_display)
                print(link)

        if res.has_more:
            res2 = self.dbx.files_list_folder_continue(res.cursor)
            self.__get_files_recursive(res2)

    def __get_shared_link(self, path):
        links = self.dbx.sharing_list_shared_links(path=path, direct_only=True).links

        if links is not None:
            for link in links:
                return link.url #1件目

        return self.__create_shared_link(path)

    def __create_shared_link(self, path):
        setting = dropbox.sharing.SharedLinkSettings(requested_visibility=dropbox.sharing.RequestedVisibility.public)
        link = self.dbx.sharing_create_shared_link_with_settings(path=path, settings=setting)

        return link.url

参考

19
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21