186

I'm trying to use the Requests library to send cookies with a post request, but I'm not sure how to actually set up the cookies based on its documentation. The script is for use on Wikipedia, and the cookie(s) that need to be sent are of this form:

enwiki_session=17ab96bd8ffbe8ca58a78657a918558e; path=/; domain=.wikipedia.com; HttpOnly

However, the requests documentation quickstart gives this as the only example:

cookies = dict(cookies_are='working')

How can I encode a cookie like the above using this library? Do I need to make it with python's standard cookie library, then send it along with the POST request?

Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
Ricardo Altamirano
  • 14,650
  • 21
  • 72
  • 105
  • 3
    Your cookie consists of a number of `a=b;` pairs. At a guess, use `a` as the key and `b` as the value in a dictionary. – Thomas K Aug 23 '11 at 17:05

3 Answers3

348

The latest release of Requests will build CookieJars for you from simple dictionaries.

import requests

cookies = {'enwiki_session': '17ab96bd8ffbe8ca58a78657a918558'}

r = requests.post('http://wikipedia.org', cookies=cookies)

Enjoy :)

Jossef Harush Kadouri
  • 32,361
  • 10
  • 130
  • 129
Kenneth Reitz
  • 8,559
  • 4
  • 31
  • 34
  • Is this code supposed to place a cookie in my browser? I tried it and it didn't work for me. – Chris Nielsen Aug 08 '17 at 20:47
  • 34
    @ChrisNielsen this question/answer has nothing to do with browsers – ThiefMaster Oct 30 '17 at 13:13
  • @ThiefMaster: Normally, cookies live in browsers. If this answer doesn't have to do with browsers, what does it have to do with? – Chris Nielsen Oct 30 '17 at 19:30
  • 14
    @ChrisNielsen: This question and the code in the answer is about setting a cookie in a Python request. The request does something similar to a browser request, but no browsers are involved. – DDay Jan 20 '20 at 23:03
  • 1
    @ChrisNielsen : cookies are an aspect of the basic http protocol, which is most often used by browsers: https://datatracker.ietf.org/doc/html/rfc6265 – serv-inc Aug 25 '21 at 10:18
156

Just to extend on the previous answer, if you are linking two requests together and want to send the cookies returned from the first one to the second one (for example, maintaining a session alive across requests) you can do:

import requests
r1 = requests.post('http://www.yourapp.com/login')
r2 = requests.post('http://www.yourapp.com/somepage',cookies=r1.cookies)
oarevalo
  • 3,298
  • 1
  • 22
  • 19
  • 65
    Additionally, you can use `requests.session` for this exact thing, storing cookies across multiple sessions, making calls from the returned `session` object instead. – TankorSmash May 26 '12 at 00:35
  • 9
    I've had to utilize this even when using sessions at times. Sessions seem to miss Set-Cookie headers in some situations. – kervin Apr 30 '13 at 03:08
  • 2
    @kervin this just happened to me as well. Seems like a bug in requests, because session *should* handle that. – deweydb Aug 08 '13 at 11:05
  • 4
    @TankorSmash there is definitely a bug, my cookies are not carried forward using `request.session` – Tjorriemorrie Sep 02 '14 at 09:02
  • Is this the best way to set a (missed) cookie in a session? http://stackoverflow.com/a/17240616/143397 – davidA Dec 21 '14 at 06:02
  • Way old answer, but helped me a lot. For some reason, I'm having issues with cookie persistence when using a `Session()` object, but this worked beautifully. – alphazwest Feb 22 '17 at 21:07
  • Same issue and same solution.. just FYI on requests v.2.19.1 – jouell Jun 19 '18 at 01:36
  • Additionally for @TankorSmash, how to use `requests.session`? can refer: https://stackoverflow.com/a/31571805/1616263 – crifan Dec 22 '20 at 09:57
1

If you want to pass the cookie to the browser, you have to append to the headers to be sent back. If you're using wsgi:

import requests
...


def application(environ, start_response):
    cookie = {'enwiki_session': '17ab96bd8ffbe8ca58a78657a918558'}
    response_headers = [('Content-type', 'text/plain')]
    response_headers.append(('Set-Cookie',cookie))
...

    return [bytes(post_env),response_headers]

I'm successfully able to authenticate with Bugzilla and TWiki hosted on the same domain my python wsgi script is running by passing auth user/password to my python script and pass the cookies to the browser. This allows me to open the Bugzilla and TWiki pages in the same browser and be authenticated. I'm trying to do the same with SuiteCRM but i'm having trouble with SuiteCRM accepting the session cookies obtained from the python script even though it has successfully authenticated.

Try-Harder
  • 47
  • 3