URLクエリ文字列には、値のないパラメータ、つまりhttp:// host / path /?fooまたはhttp:// host / path /?a = 1&fooが含まれている場合があります
In [68]: d
Out[68]: {'a': 1, 'foo': None}
In [69]: tl
Out[69]: [('a', 1), ('foo',)]
In [70]: RequestEncodingMixin._encode_params(d)
Out[70]: 'a=1'
In [71]: RequestEncodingMixin._encode_params(tl)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-71-5d4dac855108> in <module>()
----> 1 RequestEncodingMixin._encode_params(tl)
/home/f557010/jpm/local/lib/python2.7/site-packages/requests/models.pyc in _encode_params(data)
87 elif hasattr(data, '__iter__'):
88 result = []
---> 89 for k, vs in to_key_val_list(data):
90 if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
91 vs = [vs]
ValueError: need more than 1 value to unpack
期待される:
'a=1&foo'
私はこれにいくつかの価値を見ることができます。 APIの理由から、「タプルのリスト」アプローチでしか機能しませんでしたが、これに対するサポートを追加しても問題ありません。 @ sigmavirus24?
(まだ)使用していないと思いますが、 urllib3はurlencode
を使用しているようです。
それがどのように動作するかを調べると、これを扱う提案された方法のどちらも気に入らないことがわかります。 {'foo': None}
は「機能」しますが、正しいことはしません。 これがおそらく以前にこれを避けた理由です。 とは言うものの、RFC 3986にはURIのクエリ部分の定義が非常に緩いので、私の意見ではそれを処理する必要があります。 とはいえ、それを簡単に処理できるツールがあるかどうかはわかりません。 = /
>>> u = urlparse.urlparse('http://example.com/foo?bar')
>>> u
ParseResult(scheme='http', netloc='example.com', path='/foo', params='', query='bar', fragment='')
>>> urlparse.parse_qs(u.query)
{}
>>> urllib.urlencode({'foo': None})
'foo=None'
>>> urllib.urlencode([('foo',)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1336, in urlencode
for k, v in query:
ValueError: need more than 1 value to unpack
関連:「None値のurlencodeは文字列「None」を使用します」– https://bugs.python.org/issue18857
あなたがそこ値として空の文字列を使用してみましたが@agilevic、ピョートル・dobrogostの入力@与えますか? APIサーバーで動作しますか?
バンプ。 =)
>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': ''})
>>> r.request.url
'https://httpbin.org/get?foo='
値のないパラメータを持つことと同じではありません。 パラメータ名の後に=記号をレンダリングします。 一部のアプリケーションは機能しますが、完全なソリューションを提供するという問題として、この正確なケースに対処する必要があります。 urllibがそれを行わないことは重要ではありません。 Requestsは、HTTPの標準ライブラリよりも多くのことを実行します。これが、存在する理由です。
@agilevicこの機能のために提案されたAPIデザインは何でしょうか?
ここにクレイジーな考えがあります:
>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': None})
>>> r.request.url
'https://httpbin.org/get?foo'
それが起こるべきだと私は思います。
実際に何が起こっているのか:
'https://httpbin.org/get'
:(
@frnhrしたがって、APIで機能しない理由は、キーをNone
設定することが、「このキーをマップから削除してください」というシグナルであるためです。 一部のパラメーターはSessionオブジェクト自体に永続化でき、ユーザーはリクエストごとにそれらのパラメーターを抑制できるようにしたい場合があるため、このシグナルがあります。
誠意をこめて、セッションオブジェクトがこのAPIビットと何の関係があるのかわかりません。 しかし、わかりました、多分False
、あるいはNone
代わりにいくつかのSpecialImportableObject
None
?
2016年9月17日には、午前7時47分で、コーリーベンフィールド[email protected]は書きました:
@frnhrしたがって、APIで機能しない理由は、キーをNoneに設定すると、「このキーをマップから削除してください」というシグナルであるためです。 一部のパラメーターはSessionオブジェクト自体に永続化でき、ユーザーはリクエストごとにそれらのパラメーターを抑制できるようにしたい場合があるため、このシグナルがあります。
—
あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。
@frnhr Session
APIので、関連するrequests.
APIの上に構築されたSession
API:それはその機能のサブセット、コンビニエンスラッパーです。
だから私たちは確かにそれを行うことができましたが、それがどの程度価値があるのかはわかりません。 Key-Valueマッピングを使用しない場合は、 params
フィールドに文字列params="foo"
渡すだけです。
パラメータを値なしで追加することを要求に示すことができる特定の型付き引数を作成するとしたらどうでしょうか。
# defined somewhere in requests
class ValuelessParam(object):
pass
....
....
params = {'foo': 'some_param', 'bar': requests.ValuelessParam()}
requests.get('http://something', params=params)
# url should be 'http://something?foo=some_param&bar'
それはNoneではなく、スカラー定数でもありません...したがって、下位互換性が必要です。 内部的には...その値型をチェックし、構築されたURLにこのパラメーターを特別に追加することができます。
したがって、それは間違いなく機能しますが、APIがケネスを超えるとは思いません。
ええ、いいえ。 None
ような組み込みをサポートしたいのですが、それが最善のアイデアかどうかはわかりませんが、うまくいく可能性があります。 False
はしません。
None
も機能しません。コードベースはすでに「セッションレベルで設定された値を設定解除する」という意味を与えています。
しかし、それはかなり大きな変化であり、多くの人に利益をもたらすとは思いません。 おそらく、空のタプルを検討することができます。 (例: (,)
。
これが解決されたかどうかはわかりませんが、このスレッドが値なしでキーを追加するという正確なことを行おうとしていることがわかりました。 私の場合は「QueryAll」ですが、RestAPI Automationで、この種の関数を使用する原因がいくつかあります。
{'QueryAll': ''}
を渡すとどうなりますか?
最後に&QueryAll =を取得します。
オープン "="の処理方法についてはAPI次第のようですが、PasswordStateのAPIは、パラメータリストの最後にある限り、エラーが発生して最初に移動した場合にそれを取得しました。
3.0では、空の文字列を=にしないようにすることを検討できると思います。
それは素晴らしいことです:-Dこれまでのところ、私のPasswordstateプロジェクトは、params文字列の最後にQueryAll =形式を使用して前進できるので、軌道に戻っています。 私はこのスレッドを見ます:-D
ありがとうケネス!
まだ何も聞いたり見たりしていませんが、アップデートがリリースされているかどうかを確認するために戻ってきたわけではありません。
ニック
投稿者:アレックスZagoro [email protected]
送信日:2018年9月22日土曜日10:19 AM
宛先:requests /[email protected]
Cc:Ellson、Nick [email protected] ; コメント[email protected]
件名:Re:[リクエスト/リクエスト]値のないパラメータでURLクエリ文字列を作成できません(#2651)
やあ、これに関する更新はありますか?
私も今この問題に直面しています。 他の誰かがこの問題を回避する方法を見つけましたか?
このシンプルでありながら非常に一般的な機能のリクエストには、まだ解決策がないと思います。 変。
残念ながら同じ問題に直面しています。
オプションのカスタムフォーマッター/エンコーダーまたはNone動作を処理するための特定のフラグを挿入/渡すことができるのは、より良いパターンまたはオプションではないでしょうか。
@Lukasaあなたは私たちのほとんどよりもコードベースをよく知っているようですが、それについてどう思いますか?
@kennethreitz、それは非破壊的な変更で解決しませんか? デフォルトは、2.xの動作を模倣するように設定できます。
空の文字列が渡されたときに、これはまだ=を追加しているようです。回避策を打ち出す時が来ました!
だから私はこれがまだ問題だと思いますか?
あなたが値を持たないパラメータを持っている場合は、URLの一部としてそれらを一覧表示することができますし、任意の追加のパラメータが追加されますと&
の代わりで始まる?
:
In [3]: r = requests.get("http://www.google.com", params={'test': 'true'})
In [4]: r.url
Out[4]: 'http://www.google.com/?test=true'
In [5]: r = requests.get("http://www.google.com?test2", params={'test': 'true'})
In [6]: r.url
Out[6]: 'http://www.google.com/?test2&test=true'
このルールはどうですか?
{ key: undefined }
から?
_(含まれていません)_
{ key: null }
から?key
{ key: '' }
から?key=
{ key: 'null' }
から?key=null
2020 ...そしてまだ問題.... SMH
最も参考になるコメント
3.0では、空の文字列を=にしないようにすることを検討できると思います。