6

ボックスv2APIとリクエストを使用してファイルをアップロードしようとしています。

これまでのところ、私はほとんど運がありませんでした。たぶん、ここの誰かが私が実際に間違っていることを理解するのを手伝ってくれるでしょう。

file_name = "%s%s" % (slugify(sync_file.description), file_suffix)
file_handle = open(settings.MEDIA_ROOT + str(sync_file.document), 'rb')
folder_id = str(sync_file.patient.box_patient_folder_id)

r = requests.post(
    files_url,
    headers=headers,
    files={
        file_name: file_handle,
        "folder_id": folder_id,
    },
)

同じデータを使用してその直前にフォルダーを作成しているため、認証は機能します。

応答は次のようになります。

{
    u'status': 404, 
    u'code': u'not_found', 
    u'help_url': u'http://developers.box.com/docs/#errors', 
    u'request_id': u'77019510950608f791a0c1', 
    u'message': u'Not Found', 
    u'type': u'error'
}

たぶん、ここの誰かが同様の問題に遭遇しました。

4

3 に答える 3

7

2つのPython辞書、ファイル、およびデータを渡す必要があります。ファイルは、、{uniqFileName:openFileObj}データは{uniqFileName:filename}。以下は私のボックスクラスからのアップロードメソッドです。そして、データに最後のエントリを追加することを忘れないで'folder_id': destination_idください。

def uploadFiles(self, ufiles, folid):
    '''uploads 1 or more files in the ufiles list of tuples containing
    (src fullpath, dest name). folid is the id of the folder to
    upload to.'''

    furl = URL2 + 'files/data'
    data, files = {}, {}
    for i, v in enumerate(ufiles):
        ff = v[0]
        fn = v[1]
        #copy to new, renamed file in tmp folder if necessary
        #can't find a way to do this with the api
        if os.path.basename(ff) != fn:
            dest = os.path.join(TMP, fn)
            shutil.copy2(ff, dest)
            ff = dest

        f = open(ff, 'rb')
        k = 'filename' + str(i)
        data[k] = fn
        files[k] = f

    data['folder_id'] = folid

    res = self.session.post(furl, files=files, data=data)

    for k in files:
        files[k].close()


    return res.status_code

呼び出しの例を次に示します。

destFol = '406600304'

ret = box.uploadFile((('c:/1temp/hc.zip', 'hz.zip'),), destFol)

私が言ったように、上記の関数は、リクエストセッションを保持するインスタンスattrを持つクラスのメソッドです。requests.postただし、の代わりに使用することもできself.session.post、同じように機能します。セッション外で行う場合は、apikeyとトークンを使用してヘッダーを追加することを忘れないでください。

ドキュメントによると、データdictで新しい名前を付けることで、ファイルの名前を変更できるはずです。しかし、srcファイルを目的の名前の一時ディレクトリにコピーしてアップロードする以外に、これを機能させることはできません。ちょっとしたハックですが、機能します。

頑張って、マイク

于 2012-09-24T18:32:38.163 に答える
1

誰かが私の実装を要求したので、似たようなことを達成しようとしている人のためにここに公開することにしました。

files_url = "%s/files/content" % (settings.BOX_API_HOST)
headers = {"Authorization": "BoxAuth api_key=%s&auth_token=%s" % 
              (settings.BOX_API_KEY, self.doctor.box_auth_token)
          }

file_root, file_suffix = os.path.splitext(str(self.document))
filename = "%s%s" % (slugify(self.description), file_suffix)
files = {
        'filename1': open(settings.MEDIA_ROOT + str(self.document), 'rb'),
        }
data = {
        'filename1': filename,
        'folder_id': str(self.patient.get_box_folder()),
       }

r = requests.post(files_url,
                  headers=headers,
                  files=files,
                  data=data)

file_response = simplejson.loads(r.text)

try:
    if int(file_response['entries'][0]['id']) > 0:
        box_file_id = int(file_response['entries'][0]['id'])

        #Update the name of file
        file_update_url = "%s/files/%s" % (settings.BOX_API_HOST, box_file_id) 
        data_update = {"name":  filename}
        file_update = requests.put(file_update_url,
                                   data=simplejson.dumps(data_update),
                                   headers=headers)

        LocalDocument.objects.filter(id=self.id).update(box_file_id=box_file_id)
except:
    pass

したがって、本質的には、ファイルを送信し、新しく更新されたファイルの ID を取得して、別の要求を box に送信する必要がありました。個人的にも好きではありませんが、私にとってはうまくいき、最初から正しい命名を行う他の実装を見つけることができませんでした.

誰かがこのスニペットから恩恵を受けることを願っています.

于 2012-12-10T05:14:18.397 に答える
0

リクエストを使用した私のソリューション:

def upload_to_box(folder_id, auth_token, file_out):
    headers = { 'Authorization' : BOX_AUTH.format(auth_token) }
    url = 'https://api.box.com/2.0/files/content'
    files = { 'filename': (new_file_name, open(file_out,'rb')) }
    data = { 'folder_id': folder_id }
    response = requests.post(url, params=data, files=files, headers=headers)

パラメータを指定できればいいのですがnew_copy、それについて文書化されたものはなく、機能していないようです。

于 2012-11-23T07:42:20.570 に答える