Requests: Tidak dapat membuat string kueri URL dengan parameter tanpa nilai

Dibuat pada 25 Jun 2015  ·  32Komentar  ·  Sumber: psf/requests

String kueri URL dapat berisi parameter, yang tidak memiliki nilai yaitu http://host/path/?foo atau http://host/path/?a=1&foo. Saat ini Permintaan tidak memberikan dukungan untuk itu.

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

Mengharapkan:

'a=1&foo'
3.0 Breaking API Change Feature Request

Komentar yang paling membantu

di 3.0, saya pikir kita dapat mempertimbangkan untuk membuat string kosong tidak menghasilkan =

Semua 32 komentar

Saya bisa melihat beberapa nilai dalam hal ini. Untuk alasan API, itu hanya bisa bekerja dengan pendekatan 'daftar tupel', tetapi saya tidak masalah jika kami menambahkan dukungan untuk ini. @sigmavirus24?

Saya tidak berpikir kami menggunakannya (belum) tetapi tampaknya urllib3 menggunakan urlencode dan begitu juga kami

Jika kita memeriksa bagaimana perilakunya, Anda dapat melihat bahwa itu tidak menyukai salah satu cara yang diusulkan untuk bekerja dengan ini. {'foo': None} akan "berfungsi" tetapi tidak melakukan hal yang benar. Ini mungkin mengapa kami menghindari ini sebelumnya. Yang mengatakan, RFC 3986 memiliki definisi yang sangat ... longgar dari bagian kueri URI, jadi menurut saya kami _harus_ menanganinya. Yang mengatakan, saya tidak yakin ada alat yang memungkinkan kita untuk menanganinya. =/

>>> 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

Terkait: "urlencode dari nilai None menggunakan string 'None'" – https://bugs.python.org/issue18857

Berikan masukan @piotr-dobrogost, @agilevic sudahkah Anda mencoba menggunakan string kosong sebagai nilai di sana? Apakah ini berfungsi dengan server API Anda?

Menabrak. =)

>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': ''})
>>> r.request.url
'https://httpbin.org/get?foo='

Ini tidak sama dengan memiliki parameter tanpa nilai. Milik Anda membuat tanda = setelah nama parameter. Beberapa aplikasi akan berfungsi, tetapi sebagai masalah memberikan solusi lengkap, kasus yang tepat ini harus ditangani. Urllib itu tidak melakukannya tidak ada artinya. Permintaan melakukan banyak hal lebih baik daripada pustaka standar untuk HTTP - itulah alasannya ada.

@agilevic Apa desain API yang Anda usulkan untuk fitur ini?

Inilah pemikiran gila:

>>> import requests
>>> r = requests.get('https://httpbin.org/get', params={'foo': None})
>>> r.request.url
'https://httpbin.org/get?foo'

Itu yang menurut saya harus terjadi.

Apa yang sebenarnya terjadi:

'https://httpbin.org/get'

:(

@frnhr Jadi alasan yang tidak berfungsi dengan API kami adalah bahwa menyetel kunci ke None adalah sinyal untuk "hapus kunci ini dari peta". Kami memiliki sinyal itu karena beberapa parameter dapat dipertahankan pada objek Sesi itu sendiri, dan pengguna terkadang ingin dapat menekan parameter tersebut berdasarkan permintaan.

Saya khawatir saya tidak melihat apa yang harus dilakukan objek sesi dengan sedikit API ini, dengan tulus. Tapi ok, mungkin False lalu, atau bahkan beberapa SpecialImportableObject bukannya None ?

Pada 17 Sep 2016, pukul 07:47, Cory Benfield [email protected] menulis:

@frnhr Jadi alasan yang tidak berfungsi dengan API kami adalah bahwa menyetel kunci ke Tidak Ada adalah sinyal untuk "hapus kunci ini dari peta". Kami memiliki sinyal itu karena beberapa parameter dapat dipertahankan pada objek Sesi itu sendiri, dan pengguna terkadang ingin dapat menekan parameter tersebut berdasarkan permintaan.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub, atau matikan utasnya.

@frnhr Session API relevan karena requests. API dibangun di atas Session API: ini adalah bagian dari fungsionalitas itu, pembungkus praktis.

Jadi kita pasti bisa melakukannya, tapi saya tidak yakin sampai sejauh mana itu bermanfaat. Saat tidak menggunakan pemetaan nilai kunci, Anda harus meneruskan string ke bidang params : params="foo" .

Bagaimana jika kita membuat argumen yang diketik tertentu yang dapat menunjukkan permintaan bahwa param akan ditambahkan tanpa nilai?

# 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'

Ini bukan Tidak Ada, ini bukan konstanta skalar... jadi itu harus kompatibel ke belakang. Di bawah tenda... kita bisa memeriksa tipe nilai itu dan secara khusus menambahkan parameter ini ke url yang dibuat.

Jadi sementara itu pasti akan berhasil, saya tidak berpikir bahwa API akan melewati Kenneth.

Ya, Tidak. Saya lebih suka mendukung built-in seperti None , dan saya tidak yakin itu ide terbaik — tapi itu bisa bekerja dengan baik. False tidak akan.

None juga tidak akan berfungsi: basis kode sudah memberinya arti "tidak menyetel nilai yang ditetapkan pada tingkat Sesi.

Itu akan menjadi perubahan yang cukup besar, dan saya tidak berpikir itu akan menguntungkan banyak orang. Mungkin tupel kosong dapat dipertimbangkan. (misalnya (,) .

Tidak yakin apakah ini telah diselesaikan, tetapi saya menemukan utas ini mencoba melakukan hal yang tepat dengan menambahkan kunci tanpa nilai. "QueryAll" dalam kasus saya, tetapi saya memiliki sejumlah penyebab di RestAPI Automation saya untuk menggunakan fungsi semacam ini.

apa yang terjadi jika Anda melewati {'QueryAll': ''} ?

Saya mendapatkan &QueryAll= di akhir.

Sepertinya itu tergantung pada API tentang cara menangani open "=" lalu, API PasswordState mengambilnya selama itu di akhir daftar params saya, jika saya memindahkannya ke awal itu error-ed.

di 3.0, saya pikir kita dapat mempertimbangkan untuk membuat string kosong tidak menghasilkan =

Itu akan bagus :-D Sejauh ini proyek Passwordstate saya dapat bergerak maju dengan format QueryAll= di akhir string params jadi saya kembali ke jalurnya. Saya akan menonton utas ini :-D

Terima kasih Kenneth!

Belum mendengar atau melihat apa pun, tetapi belum berputar kembali untuk melihat apakah ada pembaruan yang dirilis.

Nick

Dari: Alex Zagoro [email protected]
Dikirim: Sabtu, 22 September 2018 10:19
Kepada: request/requests [email protected]
Cc: Ellson, Nick [email protected] ; Komentar [email protected]
Perihal: Re: [permintaan/permintaan] Tidak dapat membuat string kueri URL dengan parameter tanpa nilai (#2651)

hai, ada update tentang ini?

Saya mengalami masalah ini saat ini juga. Adakah orang lain yang menemukan cara untuk mengatasi masalah ini?

Saya yakin masih belum ada solusi dalam permintaan untuk fitur sederhana namun sangat umum ini. aneh.

Sayangnya menghadapi masalah yang sama.
Bukankah ini akan menjadi pola atau opsi yang lebih baik untuk dapat menyuntikkan/meneruskan formatter/encoder kustom opsional atau flag khusus untuk menangani perilaku None?

@Lukasa Anda tampaknya tahu basis kode lebih baik daripada kebanyakan dari kita, bagaimana menurut Anda?

Bukankah itu akan diselesaikan dalam perubahan tanpa putus, @kennethreitz? Default dapat diatur untuk meniru perilaku 2.x.

Tampaknya ini masih menambahkan = ketika string kosong dimasukkan. Saatnya untuk menyelesaikannya!

Jadi saya kira ini masih menjadi masalah?

Jika Anda memiliki parameter yang tidak memiliki nilai, Anda bisa daftar mereka sebagai bagian dari url dan setiap parameter tambahan akan menambahkan dengan & bukannya dimulai dengan ? :

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'

Bagaimana dengan aturan ini?

{ key: undefined } hingga ? _(tidak termasuk)_
{ key: null } ke ?key
{ key: '' } ke ?key=
{ key: 'null' } hingga ?key=null

2020 ... dan masih menjadi masalah .... SMH

Apakah halaman ini membantu?
0 / 5 - 0 peringkat