2017-03-04 11 views
5

में सत्र आधार का उपयोग करते समय ऐसा लगता है कि आपको हर बार पूर्ण यूआरएल प्रदान करना होगा, उदा।पायथन अनुरोध: सत्र

session = requests.Session() 
session.get('http://myserver/getstuff') 
session.get('http://myserver/getstuff2') 

यह थोड़ा कठिन हो जाता है। वहाँ की तरह कुछ करने के लिए एक रास्ता है:

session = requests.Session(url_base='http://myserver') 
session.get('/getstuff') 
session.get('/getstuff2') 

उत्तर

1

मैं निर्मित एक तरीका यह है नहीं दिख रहा है, लेकिन आप कार्यक्षमता आप चाहते हैं जोड़ने के लिए आवरण कार्यों का उपयोग कर सकते हैं:

from functools import wraps 
import inspect 
import requests 
from requests.compat import urljoin 

def _base_url(func, base): 
    '''Decorator for adding a base URL to func's url parameter''' 

    @wraps(func) 
    def wrapper(*args, **kwargs): 
     argname = 'url' 
     argspec = inspect.getargspec(func) 

     if argname in kwargs: 
      kwargs[argname] = urljoin(base, kwargs[argname]) 
     else: 
      # Find and replace url parameter in positional args. The argspec 
      # includes self while args doesn't, so indexes have to be shifted 
      # over one 
      for i, name in enumerate(argspec[0]): 
       if name == argname: 
        args = list(args) 
        args[i-1] = urljoin(base, args[i-1]) 
        break 

     return func(*args, **kwargs) 
    return wrapper 

def inject_base_url(func): 
    '''Decorator for adding a base URL to all methods that take a url param''' 

    @wraps(func) 
    def wrapper(*args, **kwargs): 
     argname = 'base_url' 

     if argname in kwargs: 
      obj = args[0] 

      # Add base_url decorator to all methods that have a url parameter 
      for name, method in inspect.getmembers(obj, inspect.ismethod): 
       argspec = inspect.getargspec(method.__func__) 

       if 'url' in argspec[0]: 
        setattr(obj, name, _base_url(method, kwargs[argname])) 

      del kwargs[argname] 

     return func(*args, **kwargs) 
    return wrapper 

# Wrap requests.Session.__init__ so it takes a base_url parameter 
setattr(
    requests.Session, 
    '__init__', 
    inject_base_url(getattr(requests.Session, '__init__')) 
) 

अब आप जब आप एक नया requests.Session वस्तु का निर्माण एक आधार URL निर्दिष्ट कर सकते हैं:

s = requests.Session(base_url='http://stackoverflow.com') 
s.get('questions')  # http://stackoverflow.com/questions 
s.post('documentation') # http://stackoverflow.com/documentation 

# With no base_url, you get the default behavior 
s = requests.Session() 
s.get('http://google.com') 
+0

मैं इस सवाल का जवाब चाहते हैं, लेकिन यह काम करता है केवल जब आधार यूआरएल की तरह है क्योंकि 'urljoin' उन्हें क्या और यूआरएल पाने के लिए पोस्ट तरीकों के रूप में प्रदान की जाती है के साथ अधिलेखित कर देता है कोई sublevels है। मुझे अपने मामले में इसकी आवश्यकता थी, इसलिए मैंने सरल स्ट्रिंग कॉन्सटेनेशन के साथ 'urljoin' कॉल को बदल दिया –

4

तुम बस request.Session उपवर्ग और ओवरलोड सकता है इसके __init__ और request तरीकों इस तरह:

# my_requests.py 
import requests 


class SessionWithUrlBase(requests.Session): 
    # In Python 3 you could place `url_base` after `*args`, but not in Python 2. 
    def __init__(self, url_base=None, *args, **kwargs): 
     super(SessionWithUrlBase, self).__init__(*args, **kwargs) 
     self.url_base = url_base 

    def request(self, method, url, **kwargs): 
     # Next line of code is here for example purposes only. 
     # You really shouldn't just use string concatenation here, 
     # take a look at urllib.parse.urljoin instead. 
     modified_url = self.url_base + url 

     return super(SessionWithUrlBase, self).request(method, modified_url, **kwargs) 

और फिर आप अपने कोड में requests.Session के बजाय अपने उपवर्ग इस्तेमाल कर सकते हैं:

from my_requests import SessionWithUrlBase 


session = SessionWithUrlBase(url_base='https://stackoverflow.com/') 
session.get('documentation') # https://stackoverflow.com/documentation 

इसके अलावा, आप बंदर-पैच requests.Session मौजूदा codebase को संशोधित करने से बचने के लिए (इस कार्यान्वयन होना चाहिए सकता है 100% संगत), लेकिन इससे पहले किसी भी कोड कॉल वास्तविक पैचिंग कार्य करना न भूलें requests.Session():

# monkey_patch.py 
import requests 


class SessionWithUrlBase(requests.Session): 
    ... 

requests.Session = SessionWithUrlBase 

और फिर:

# main.py 
import requests 
import monkey_patch 


session = requests.Session() 
repr(session) # <monkey_patch.SessionWithUrlBase object at ...> 
संबंधित मुद्दे