Is there anyway to pickup on a previous session when starting a python program?
I've set session as a global variable so that it can be accessed across any method that needs it. However, I'm guessing when I start the program again the session variable is reset.
Is there a way to come back to a previous session when starting the program?
session = requests.Session()
def auth():
session = self.session
url = 'this url has auth'
session.post(url, data=data)
# Now authentcated so lets grab the data
call_data(sessions)
def call_data(session)
url = 'this url has the data'
session.post(url, data=data)
def check_data()
url = 'this url does a specific call on data elements'
self.session.post(url, data=data)
When I load up my program a second time I will only want to use check_data method, I'd prefer to not require an auth every time I start the program, or perhaps I'm just curious to see if it can be done ;)
EDIT
I've updated my solution with the accepted answer.
def auth():
session = self.session
session.cookies = LWPCookieJar("cookies.txt")
url = 'this url has auth'
session.post(url, data=data)
# Now authentcated so lets grab the data
call_data(sessions)
session.cookies.save() #Save auth cookie
def some_other_method():
if not cookie:
session.cookies.load()
# do stuff now that we're authed
Code obviously don't show proper accessor for other methods, but the idea works fine.
Would be interested to know if this is the only way to remain authed.
The sessions are tracked in http via cookies. You can save them between program restart by storing in a http.cookiejar.LWPCookieJar
At the beginning of your program you have to set the cookieJar to this FileCookieJar and load the existing cookies if any
import requests
from http.cookiejar import LWPCookieJar
session = requests.Session()
session.cookies = LWPCookieJar("storage.jar")
session.cookies.load()
before closing your program you have to to save them to the file
session.cookies.save()
Note that by default it has the same behavior than browser that it doesn't save session cookies which are not set to persistent to your browser across restart if you want a different behavior, just precise it to save() method by setting ignore_discard argument to False like this
session.cookies.save(ignore_discard=False)
It's not clear what kind of session you try to establish. Django? Flask? Something different?
Be aware also that there seems to be a misspelling of call_data(sessions) where only session (without s) is defined.
Related
I don't know how to ask this question but I will explain it.
I use Requests to login to website like this
URL = 'http://test.dev/api/login'
with requests.session() as s:
s.get(URL)
login_data = {'username': 'test', 'password': 'testtest'}
ra=s.post(URL, data=login_data)
# Now I got session and cookie I can go to another pages like
r=s.get('http://test.dev/api/user/1')
When login success the server sent the session and cookie back.
But if I go out the the loop "with" I must login again?
Question is how can I go another page with out the "with" loop ?
EDIT1:
EDIT: I try to use at s=requests.Session() firstime
but it error like this:
Python Requests trying to post data to Laravel
EDIT2:
I try to use s = requests.session() again and it work I don't know why = =
Thank you all.
To expand on Daniel's answer the with block is a context manager. It will open a new context for you, in your case your call to requests.session(). Once the block is completed the the context it will be closed.
In your example once the line r=s.get(...) is completed there is no more code for the context so it is closed. For example these two blocks achieve the same result:
with open('file.txt', 'w') as fh:
fh.write('Hello, world')
and
fh = open('file.txt', 'w')
fh.write('Hello, world')
fh.close()
If you don't want to close the session at the end, don't use a with block. Just do
s = requests.session()
and pass s around as necessary.
Expanding on this a little more:
The " Python Requests trying to post data to Laravel " error simply means there is a problem with the Laravel server - not a python issue.
s=requests.session()
should work just fine and you can use that "s" session object wherever you wish. You can even pass the "s" object as a parameter to other functions.
Using the
with requests.session() as s:
merely limits the scope of "s" object to the indented block of code under the "with"... You can pass the "s" to functions within that block, but coding outside of that block leaves the context of that "s" object.
I'm working on an app which uses an API that requires me to make a first Post request to authenticate.
Looking the authenticate response, I've seen that a cookie was created: ApiCredentials=....
So I authenticate:
result = urlfetch.fetch(url = url, method = urlfetch.POST)
api_credential = result.headers['set-cookie']
and then I create a request with that cookie in the header
urlfetch.fetch(url = url, method = urlfetch.GET, headers = {'Cookie': api_credential})
The problem is: in dev everything works perfectly, but when I deploy, it doesn't work. In the logs I can see the cookie that was recieved.
API link: http://www.sptrans.com.br/desenvolvedores/APIOlhoVivo/Documentacao.aspx?1 (portuguese)
The code in the question does not show the cookie name ApiCredentials. It may be that in development, there was only a single cookie and in production there are more, in which case result.headers['set-cookie'] returns multiple values comma separated.
The URL Fetch Response Objects page suggests retrieving multiple headers of the same name in a list by calling result.header_msg.getheaders('set-cookie') instead and then finding ApiCredentials in the resulting list.
It might be safer to say 'Set-Cookie' in case-sensitive environments.
I need to accomplish a login task in my own project.Luckily I found someone has it done already.
Here is the related code.
import re,urllib,urllib2,cookielib
class Login():
cj = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
def __init__(self,name='',password='',domain=''):
self.name=name
self.password=password
self.domain=domain
urllib2.install_opener(self.opener)
def login(self):
params = {'domain':self.domain,'email':self.name,'password':self.password}
req = urllib2.Request(
website_url,
urllib.urlencode(params)
)
self.openrate = self.opener.open(req)
print self.openrate.geturl()
info = self.openrate.read()
I've tested the code, it works great (according to info).
Now I want to port it to Python 3 as well as using requests lib instead of urllib2.
My thoughts:
since the original code use opener, though not sure, I think its equivalent in requests is requests.Session
Am I supposed to pass in a jar = cookiejar.CookieJar() when making request? Not sure either.
I've tried something like
import requests
from http import cookiejar
from urllib.parse import urlencode
jar = cookiejar.CookieJar()
s = requests.Session()
s.post(
website_url,
data = urlencode(params),
allow_redirects = True,
cookies = jar
)
Also, followed the answer in Putting a `Cookie` in a `CookieJar`, I tried making the same request again, but none of these worked.
That's why I'm here for help.
Will someone show me the right way to do this job? Thank you~
An opener and a Session are not entirely analogous, but for your particular use-case they match perfectly.
You do not need to pass a CookieJar when using a Session: Requests will automatically create one, attach it to the Session, and then persist the cookies to the Session for you.
You don't need to urlencode the data: requests will do that for you.
allow_redirects is True by default, you don't need to pass that parameter.
Putting all of that together, your code should look like this:
import requests
s = requests.Session()
s.post(website_url, data = params)
Any future requests made using the Session you just created will automatically have cookies applied to them if they are appropriate.
I'm using python-requests module to handle oAuth request and response.
I want to set received access_token (response content as dict) in requests.session.cookies object.
How can I update existing cookies of session with received response from server?
[EDIT]
self.session = requests.session(auth=self.auth_params)
resp = self.session.post(url, data=data, headers=self.headers)
content = resp.content
I want to do something like:
requests.utils.dict_from_cookiejar(self.session.cookies).update(content)
Here, requests.utils.dict_from_cookiejar(self.session.cookies) returns dict with one session key. Now, I want to update received response content in self.session.cookies.
requests can do that for you, provided you tell it all the requests you make are part of the same session:
>>> import requests
>>> s = requests.session()
>>> s.get('https://www.google.com')
<Response [200]>
>>> s.cookies
<<class 'requests.cookies.RequestsCookieJar'>[Cookie(version=0, name='NID'...
Subsequent requests made using s.get or s.post will re-use and update the cookies the server sent back to the client.
To add a Cookie on your own to a single request, you would simply add it via the cookies parameter.
>>> s.get('https://www.google.com', cookies = {'cookieKey':'cookieValue'})
Unless the server sends back a new value for the provided cookie, the session will not retain the provided cookie.
In order to provide a cookie yourself to the requests module you can use the cookies parameter for a single request and give it a cookie jar or dict like object containing the cookie(s).
>>> import requests
>>> requests.get('https://www.example.com', cookies {'cookieKey':'cookieValue'})
But if you want to retain the provided cookie without having to set the cookies parameter everytime, you can use a reqests session which you can also pass to other funtions so they can use and update the same cookies:
>>> session = requests.session()
>>> session.cookies.set('cookieKey', 'cookieName')
# In order to avoid cookie collisions
# and to only send cookies to the domain / path they belong to
# you have to provide these detail via additional parameters
>>> session.cookies.set('cookieKey', 'cookieName', path='/', domain='www.example.com')
This code worked for me. hope it can help to someone else.
I want to update session.cookies variable with received response values from post request.
so, same request value can be used in another post/get request.
here, what I did:
1) updated requests module to 1.0.3 version.
2) created 2 functions
session = requests.session()
def set_SC(cookie_val):
for k,v in cookie_dict.iteritems():
if not isinstance(v, str):
cookie_dict[k] = str(v)
requests.utils.add_dict_to_cookiejar(session.cookies,
cookie_val)
def get_SC():
return requests.utils.dict_from_cookiejar(session.cookies)
In another function:
setSC(response.content)
I used this piece to
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)
// ..... log in with username and password.
// urllib2.urlopen() to get the stuff I need.
Now, how do I preserve the cookie and set the expiration dates to forever, so next time I don't have to log in with username and password again. I can directly use urllib2.urlopen() ?
By "next time" I mean after the program ends, when I start a new program, I can just reload the cookie from the disk and use it
Thanks a lot
I would highly recommend using the Requests HTTP library. It will handle all this for you.
http://docs.python-requests.org/en/latest/
import requests
sess = requests.session()
sess.post("http://somesite.com/someform.php", data={"username": "me", "password": "pass"})
#Everything after that POST will retain the login session
print sess.get("http://somesite.com/otherpage.php").text
edit: To save the session to disk, there are a lot of ways. You could do the following:
from requests.utils import cookiejar_from_dict as jar
cookies = jar(sess.cookies)
Then read the following documentation. You could convert it to a FileCookieJar and save the cookies to a text file, then load them at the start of the program.
http://docs.python.org/2/library/cookielib.html#cookiejar-and-filecookiejar-objects
Alternatively you could pickle the dict and save that data to a file, and load it with pickle.load(file).
http://docs.python.org/2/library/pickle.html
edit 2: To handle expiration, you can iterate over the CookieJar as follows. cj is assumed to be a CookieJar obtained in some fashion.
for cookie in cj:
if cookie.is_expired():
#re-attain session
To check if any of the cookies are expired, it may be more convenient to do if any(c.is_expired() for c in cj).