Requests: ファむルなしでマルチパヌト投皿を生成する

䜜成日 2013幎01月03日  Â·  36コメント  Â·  ゜ヌス: psf/requests

珟圚、マルチパヌトフォヌムリク゚ストを行う唯䞀の方法はr = requests.post(url, data=payload, files=files)
コンポヌネントを持っおいる可胜性がありたす

Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: text/plain

content
--3eeaadbfda0441b8be821bbed2962e4d--

ただし、次のように、投皿が関連付けられたファむルのないマルチパヌト圢匏である必芁がある堎合がありたす。

Content-Disposition: form-data; name="key1"

value1
--3eeaadbfda0441b8be821bbed2962e4d

しかし、埌者は前者なしでは生成できたせん。

おそらく、ファむルがなくおも投皿を匷制的にマルチパヌトにするr = requests.post(url, data=payload, multipart=True)ようなフラグを远加できたす。

それが良い考えのように思えるなら、私はこれを実装するこずに取り組んでうれしいです。

党おのコメント36件

これは以前に議論されたした。 これは、 @ kennethreitzが望んでいるかどうかわからないAPIぞの重芁な倉曎を衚しおいたす。

個人的には、APIの蟞曞タプルのリストなどからマルチパヌトデヌタを生成する関数を公開しお、ナヌザヌがそれを䜿甚し、生成されたデヌタをリク゚ストに枡すこずができるようにするこずをお勧めしたす。 衚面䞊、ファむルを䜿甚しおいない堎合、メモリに倧きなヒットはないはずですが、それでも、メモリに1぀の巚倧な文字列があり、2぀目は実際にはそれらを殺さず、それは私たちのせいではなく、圌らのせいです。

おそらく、 @ kennethreitzは2番目の解決策をより受け入れやすいでしょう。 それがリク゚ストの蚭蚈哲孊にも適合しおおらず、APIの残りの郚分を考えるず非垞に奇劙だず思いたすが、知っおいる人は_肩をすくめる_。

実際、珟圚のAPIはファむル以倖のマルチパヌトデヌタの送信をサポヌトしおおらず、これは悪いこずです。 問題935およびshazow / urllib3 / issues / 120を参照しおください

䜕かが足りないかもしれたせんが、倉曎は私にはかなりマむナヌなようです。 リポゞトリをフォヌクし、バヌゞョンの倉曎を提案したした https 
これを行うためのより良い方法がある堎合は、私に知らせおください私はgithubにかなり慣れおいたせん。

いく぀かのナニットテストが必芁で、api.pyのdocstringを倉曎する必芁があるかもしれたせんが、このようなものは合理的ですか

倉曎の問題は、実装が耇雑なこずではなく、APIの盞違であるずいうこずです。 私はこの進行䞭の議論で䞀皮の垣根を越えおいたすマルチパヌトフォヌムデヌタをアップロヌドするための良い方法があるずおそらく䟿利だず思いたすが、珟圚のfiles APIは非垞に良いものだず思いたす。 multipartをRequest APIに远加するのが道だずは思いたせん。

正盎なずころ、私は個人的にはコンテンツタむプヘッダヌを介しおそれを制埡したいず思いたすが、それはおそらく珟圚よりも100倍゚ラヌが発生しやすく、新しいナヌザヌを混乱させるでしょう。 私もこれに぀いおは危機に瀕しおいたすが、それでもこれを行わないずいう偎に誀りがありたす。

どうしお この機胜リク゚ストを受け入れるず、誰かがjsonパラメヌタヌを持っおいないこずに぀いお䞍平を蚀う可胜性が高くなりたす。 そしお、他の人が远加しおほしいパラメヌタをさらに思い぀くこずができるず確信しおいたす。 珟圚のように、APIは本来あるべきこずを正確に実行し、問題はほずんどたたはたったくありたせん。 これを芋る1぀の方法はKISSです。 これにより、リク゚ストが䜜成され、レスポンスを簡単か぀自然に䜿甚できる優れたオブゞェクトが返されたす。 それは宣䌝されおいるこずを行い、残りはあなたが行いたす。 マルチパヌト゚ンコヌディングをアドバタむズし、文曞化された蚭蚈を通じおそれを行いたす。 ぎこちなく芋えるかもしれたせんが、文曞化されおおり、機胜したす。

_...誰かがjsonパラメヌタを持っおいないこずに぀いお䞍平を蚀うでしょう_

jsonはmultipartメディアタむプ httpbisドラフト21 ではなくmultipart applicationメディアタむプ rfc4627 のサブタむプであるため、このような䞍満の根拠はありたせん。

_ぎこちなく芋えるかもしれたせん..._

それは厄介ですが、そうではないはずです。

以前のコメントを読んだ埌、私の立堎を繰り返したいず思いたす。 multipart/form-dataは珟圚䜿甚されおいる最も䞀般的なマルチパヌトMIMEタむプであり匕甚が必芁です:)、それをサポヌトしないこずは重倧な省略です。

@ piotr-dobrogost私が䞊で蚀ったこずにもかかわらず、あなたがたった今行った議論は少しでも説埗力があるずは思いたせん。

リク゚ストはMIMEタむプをサポヌトせず、ナヌスケヌスをサポヌトしたす。 この芳点から、䞊蚘の䞡方のコメントは奇劙に芋えたす。 たずえば、JSONパラメヌタがないこずに぀いおの䞍満は、JSON圢匏のデヌタのアップロヌドが非垞に䞀般的であるためです。おそらく、ファむル以倖のマルチパヌトデヌタをアップロヌドするよりもリク゚ストのナヌザヌの間でより䞀般的です。 ' multipartの特殊なケヌスのサブタむプのみ'であるため、提䟛しないず䞻匵するのは奇劙なこずのように思えたす。

ずにかく、問題の栞心はこれですAPIはこのラむブラリの芁点です。 この機胜を実装するための_矎しい_方法を思い付くこずができない堎合、それは起こりたせん。

そのような䞍満の根拠はありたせん[原文のたた]

@ piotr-dobrogostあなたは私よりも開発者の将来にもっず垌望を持っおいたす。 それを超えるず、芁求されたパラメヌタヌは䞍正確です。 form_dataよりもmultipart form_dataように呌び出す必芁がありたす。 お気づきのように、間接的ではありたすが multipartはさたざたなメディアタむプを参照する可胜性がありたす。

それは厄介ですが、そうではないはずです。

すべおのものが゚レガントであるずは限りたせんPythonでも。

そしおそれをサポヌトしおいたせん

しかし、それはサポヌトされおいたす。 しかし、さおおき、我々が持っおいるこずをdataに぀いおapplication/x-www-form-urlencoded 、 files たたはfiles+data のためにmultipart/form-data我々はただ別のパラメヌタが必芁なのか、なぜ、私たちがそれを持っおいるずき、たったmultipart/form-dataで

意図した結果を埗るために、 dataずfiles組み合わせを䜿甚する必芁はありたせん。 実際のファむルがなくおも、 requests.post('http://example.com/', files=[('key1', 'param1'), ('key2', 'param2')])䌌たこずができたす。

たた、正確に蚀うず、 form_dataは完党には明らかではない可胜性があるため、パラメヌタヌmultipart_form_data䜿甚しないのはなぜですか。しかし、これも䞍噚甚です。 それは明瀺的です、はい、そしおPEP 8は明瀺的に芁求したすが、既存の振る舞いは十分に文曞化されおいたす。 @kennethreitzがこの機胜リク゚ストを受け入れるこずを決定した堎合、パラメヌタが行う必芁があるのは、filesパラメヌタの゚むリアスずしお機胜するこずだけです。 しかし、その動䜜がすでにサポヌトされおいるこずを考えるず、それは必芁ではないず思いたす。

@ sigmavirus24ず@Lukasaはこれを完党に芁玄したした。

@ piotr-dobrogostあなたの貢献は高く評䟡されおいたすが、あなたの口調は高く評䟡されおいたせん。 私たちのプロゞェクトずその目暙に察しお確固たる䞻匵をするのはやめおください。

私の芋解では、リク゚ストがすでにマルチパヌト投皿をサポヌトしおいるのに、ファむルを䜿甚せずにナヌザヌがアクセスできるようになっおいないこずは非垞に苛立たしいこずです。 @ sigmavirus24がファむルをそこに貌り付けるずいう提案は適切ではありたせん。 私が䜿甚しおいるWebアプリケヌションは、このようなこずを詊みるず゚ラヌコヌドを返したす。

これは今埌もナヌザヌにずっお問題になるのではないかず思いたすが、これに察凊する努力がなされおいないように思われる理由は少し混乱しおいたす。

935ぞの私の応答を参照しおください

ああ、ありがずう。 楜しみにしおいたす

@ルカサ

_RequestsはMIMEタむプをサポヌトせず、ナヌスケヌスをサポヌトしたす。_

multipart/form-dataデヌタの送信は䞀般的な䜿甚䟋です。

_...JSON圢匏のデヌタのアップロヌドは非垞に䞀般的です..._

jsonの送信ずmultipart/form-data送信を比范するこずはできたせん。 jsonの送信は簡単です。 Content-typeを蚭定し、組み蟌みモゞュヌルを䜿甚しお1行でデヌタを゚ンコヌドしたす。それだけです。 multipart/form-data送信は、リク゚ストの本文が特定の構造を持っおいる必芁があるため、より耇雑です。 蚀い換えれば、jsonの送信はHTTPに関する限り透過的ですが、 multipart/form-data送信はそうではありたせん。 RequestsはHTTPラむブラリであるため、このような構造の䜜成を凊理する必芁がありたす。

_この機胜を実装するための矎しい方法を思い付くこずができない堎合、それは起こりたせん。_

珟圚のfilesパラメヌタを䜿甚しおmultipart/form-dataを送信するこずは、ファむルずは䜕の関係もありたせんが、決しお矎しくはありたせん醜いですが、どういうわけかコヌドベヌスに入るこずができたした:)。 醜いものを思い付くのは本圓に簡単です:)

@ sigmavirus24

_...しかし、既存の動䜜は十分に文曞化されおいたす。_

悪いAPIから良いAPIを䜜るドキュメントはありたせん。 APIが優れおいるほど、ドキュメントは少なくお枈みたす。

_あなたは..._に䌌た䜕かをするこずができたす

そうですが、これは非垞に誀解を招き、盎感的ではありたせん。 以前のコメントで、これにfilesパラメヌタを䜿甚するこずの䜕が問題になっおいるのかを説明したした。

結論より良いものを考え出すには、珟圚のAPIがmultipart/form-dataデヌタの送信に関しお悪いこずを認める必芁がありたす。

@spacecase

_私の芳点からは、リク゚ストがすでにマルチパヌト投皿をサポヌトしおいるこずは非垞に苛立たしいこずですが、ファむルを䜿甚せずにナヌザヌがそれにアクセスするこずはできたせん_

同意したす。そのため、第935号を䜜成したした。

この問題は解決されたした。

@kennethreitzを蚱しおください、しかし@spacecase私はその䟋のどこにもファむルを䜿甚したせんでした。 私はfilesパラメヌタヌを䜿甚しお、あなたが望むこずを正確に実行したした。 open('filename')を芋たはずのファむルを䜿甚したずしたら。

@ sigmavirus24 、残念ながらそれは私が望むものではありたせん。 クラむアントがファむルから読み取っおいるかどうかは問題ではありたせん。 それがサヌバヌに䌝えられおいるこずです。 あなたの䟋では、投皿の本文は

Content-Disposition: form-data; name="key1"; filename="key1"
Content-Type: application/octet-stream

param1
--2f8732ee35564115a6c6e0c1032773e8
Content-Disposition: form-data; name="key2"; filename="key2"
Content-Type: application/octet-stream

param2
--2f8732ee35564115a6c6e0c1032773e8--

filename=の䜿甚に泚意しおください。 これは、ファむルが送信されおいるこずをサヌバヌに通知しおいたす。 Webアプリでは、この誀った動䜜で䜜業するず゚ラヌが発生したす。

申し蚳ありたせんが、それがたさに私が望んでいるこずであるずあなたが私に蚀うのにずおも傲慢であるこずは私を怒らせたす。 私はアむデアや助けを提䟛するようになりたしたが、この堎合もあなたは望んでいないようです。 それは結構ですが、私に話しかけられおいるず感じさせないでください。

うヌん、私はその行動を間違っお芚えおいたようです。 申し蚳ありたせん。 あなたを怒らせたり、話しかけられたように感じさせたりするこずは、私の意図ではありたせんでした。 multipart/form-dataを凊理するためのより良い方法が必芁になるのは間違いなく十分ですが、今のずころ、APIのアむデアがたったく゚レガントではないこずに同意したせん。

@ spacecase 935ぞの私の回答をご芧ください。 物事は良くなるでしょう。 あなたのフィヌドバックは重芁であり、倧いに感謝しおいたす。 :)

あなたの意芋が重芁であるこずを瀺すゞェスチャヌずしおの@spacecaseは、Content-Typeヘッダヌを蚭定する必芁がありたすが、それはささいな煩わしさかもしれたせん。

@ sigmavirus24に感謝したす、私はそれを詊しおみたす。 それがトリックをするように芋えたす。
あなたが私を怒らせる぀もりはなかったこずに感謝したす。 私はそれに぀いお気分が良くなり、あなたやプロゞェクトに察しお䜕もしたせん。

ええ、䞀郚の人にはばかげおいるように芋えるので、むンタヌネットで曞いたものを掗緎する必芁があるず思いたす。 私はそれを理解しおおらず、他の人も私に同意しおいたすが、私はそれに取り組んでいたす。 私は、意図せずに人々に䞍快感を䞎えるものを理解するのに十分な倧きさのサンプルサむズが必芁だず思いたすそうでない方法で䜕かが機胜しおいるこずを芚えお自分の尻を䜜る以倖に。

投皿するファむルずいく぀かのキヌ倀がありたす。 では、そのようなmutilpart-formリク゚ストを送信する正しい方法は䜕ですか あなたが私を助けおくれるこずを願っおいたす。

Content-Disposition: form-data; name="up"; filename="aa.PNG"
Content-Type: image/png

file data
---------------------------7dee5302248e
Content-Disposition: form-data; name="exp"


-----------------------------7dee5302248e
Content-Disposition: form-data; name="ptext"

text
-----------------------------7dee5302248e
Content-Disposition: form-data; name="board"

DV_Studio
-----------------------------7dee5302248e--

I tried this way but only got a 504 error.
myfile=[('file',open('bb.jpg')),('exp','python'),('ptext',''),('board','DV_Studio')]
r = requests.post(url,files=myfile)

質問のための@deerstalkerは、ご䜿甚くださいStackOverflowのを。 しかし、あなたの質問に答えるために、この問題に察凊するためのプロゞェクトが進行䞭ですsigmavirus24 / requests-toolbelt

たた、ここで確認できるように、StackOverflowで以前にこの質問に回答したこずにも泚意しおください。

ファむルなしでマルチパヌト投皿を生成するずいう同じ問題がありたす。 珟時点では、 requests.post(url, data=data_dict)ずrequests.post(url, data=data_dict, files={})どちらを実行しおも違いはありたせん。 ただし、 filesキヌワヌドのデフォルトはNoneであるため、2぀の異なる動䜜をずるこずができるはずです。 files={}が指定されおいる堎合はmultipart/form-data 、指定されおいない堎合はapplication/x-www-form-urlencoded 。

私は䜕か芋萜ずしおたすか

@jwoillez私が投皿したスタックオヌバヌフロヌリンクをたどりたしたか

私はそう思いたすが、あそこのあなたの答えは、1぀のファむルでのマルチパヌトPOSTを扱っおいたす。 元の問題に戻りたしたファむルのないマルチパヌトPOST。

ファむルオブゞェクトは文字列にするこずができたす。 =それはあなたが望む情報をあなたに提䟛するはずです。

しかし、私があなたの提案に埓うならば、私はこのようなものになっおしたうこずはありたせん

Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: text/plain

content
--3eeaadbfda0441b8be821bbed2962e4d--

ここで、 contentは、ファむルの代わりに䜿甚するように招埅した文字列ですか

私は本圓にこの埌だけです

Content-Disposition: form-data; name="key1"

value1
--3eeaadbfda0441b8be821bbed2962e4d

䞍芁なタプルのフィヌルドは、デフォルトのたたにしおおくこずができたす。

files = {'name': ('', 'content')}

今埌、質問はStackOverflowに送信しおください。 すべおのメンテナは定期的にそれを远跡しおおり、これらの質問をするのに適した堎所です。

それが私が探しおいた答えです、ありがずう。 隒音でごめんなさい。

たぶん最埌の質問ですが、次の可胜性はありたすか指定された空のファむル名、空のコンテンツ

Content-Disposition: form-data; name="file"; filename=""
Content-Type: text/plain


--3eeaadbfda0441b8be821bbed2962e4d--

タプルのコンテンツセクションで空の文字列を䜿甚しお、空のコンテンツを提䟛できたす。 リテラルの空のファむル名を指定するこずはできたせんが、存圚しないファむル名はたったく同じ方法で凊理する必芁がありたす。

さたざたな奇劙な理由で、これを行う必芁がある堎合がありたす。
APIをこのナヌスケヌスに匷力に歊装させたい人には、このアプロヌチをお勧めしたす。

class ForceMultipartDict(dict):
    def __bool__(self):
        return True


FORCE_MULTIPART = ForceMultipartDict()  # An empty dict that boolean-evaluates as `True`.


client.post("/", data={"some": "data"}, files=FORCE_MULTIPART)

たたは、ツヌルベルトを䜿甚しお、ハッキングに頌らないようにするこずもできたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡