1
0
-1

pythonを使用して、API経由でファイルをアップロードしたいです。

ファイル名が英語のみであれば問題なくアップロードが可能なのですが、日本語を含むファイル名の場合、HTTPステータスコード500が返ってきてアップロードに失敗します。

> {"statusCode":500,"message":"java.lang.IllegalArgumentException: File name must not be null"}

解決方法をご存知の方がいらっしゃればご教示願います。


id = 'xxxxx'
auth = (id,pw)
base_url = 'https://xxxxx/rest/api/content/{}/child/attachment'
url = base_url.format(id)
headers = {}
headers['X-Atlassian-Token'] = 'nocheck'
filepath = 'ファイルパス'
binary = open(filepath,'rb')
mimetype = 'application/octet-stream'
files = {'file':(filename,binary,mimetype)}
res = requests.post(url,auth=auth,headers=headers,files=files)
    Commentコメントを追加...

    2 回答

    1.  
      3
      2
      1

      ちょうど同じところで悩んでました。

      requests (というより urllib3) の中で filename*=utf-8 の形に変換していて、素直には回避できなさそうでしたので、結局 multipart/form-data を手で書くことにしました。

      def attach(page_id, filename, file_data):
          body, content_type = _multipart_body(filename, file_data)
          headers = {"Content-Type": content_type,
                     "X-Atlassian-Token": "nocheck"}
          upload_url = API_URL + "/%s/child/attachment" % page_id
          res = requests.post(upload_url, data=body, auth=auth, headers=headers)
          res.raise_for_status()
      
      def _multipart_body(filename: str, data: bytes) -> Tuple[bytes, str]:
          def b(string: str) -> bytes:
              return bytes(string, "utf-8")
          body = BytesIO()
          boundary = choose_boundary()
          body.write(b("--%s\r\n" % boundary))
          body.write(b('Content-Disposition: form-data; name="file"; filename="%s"\r\n' % filename))
          body.write(b"Content-Type: application/octet-stream\r\n")
          body.write(b"\r\n")
          body.write(data)
          body.write(b"\r\n")
          body.write(b("--%s--\r\n" % boundary))
          content_type = "multipart/form-data; boundary=%s" % boundary
          return body.getvalue(), content_type

      Python3.6 で動かしています。

        Commentコメントを追加...
      1.  
        2
        1
        0

        添付ファイルは遣った事が無いのですが、Python + REST API でページを作った事が有ります。

        https://www.ricksoft.jp/blog/archives/2984/

        Pytyon はこの記事を書いた時に教科書を読んだ程度だったので、詳しくないのですがWindows でやった時は若干文字コードで躓いた記憶が有ります。OS は何をお使いで、実行方法はどうしていますか?

        記憶が曖昧なのですが、Windows の場合 コマンドプロンプトから実行するのと Python の IDE で実行するのとで文字コードの扱いが変わった気がします。

        1. kyd

          コメントありがとうございます。

          OSはmacOS10.13.3を使用しています。

          Pythonは3.7.0を使用しており、ターミナルから実行しています。

          ページ作成は別のスクリプトで実行しておりまして、それについては日本語が含まれていても処理は成功している状態で、ファイル添付だけ失敗する状況です。

        2. 樋口晃

          コメントありがとうございます。 macOS10 なら 文字コードは UTF-8 なので 私が Windows でひっかかった様な問題はおこらなそうですね。後で、ちょっとやってみます。

        3. 樋口晃

          やってみたのですが、できませんでした。

          サーバー側でデバッグしてみました。Confluence の画面からファイルをアップロードした場合は、

          filename="\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"

          となっていましたが、Python の requests モジュールを使うと

          filename*=utf-8''%E3%83%86%E3%82%B9%E3%83%88.txt

          となっていました。Confluence はこの形式には対応できないのかも知れません。

        4. kyd

          ご確認ありがとうございました。助かりました。

          実現可能性がなさそうなので、ファイル名の変更等々の運用で対処しようと思います。

        Commentコメントを追加...