Requests: 値のないパラメータでURLクエリ文字列を作成することはできません

作成日 2015年06月25日  ·  32コメント  ·  ソース: psf/requests

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'
3.0 Breaking API Change Feature Request

最も参考になるコメント

3.0では、空の文字列を=にしないようにすることを検討できると思います。

全てのコメント32件

私はこれにいくつかの価値を見ることができます。 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

このページは役に立ちましたか?
0 / 5 - 0 評価