2017-03-04 50 views
5

Bir Oturum kullanırken, her defasında tam URL'yi sağlamanız gerektiği anlaşılıyor.Python istekleri: Oturumda URL tabanı

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

Bu biraz can sıkıcı olur. Böyle bir şey yapmak için bir yol var mı: Bunu yapmak için yerleşik bir yol göremiyorum

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

cevap

1

, ancak istediğiniz işlevsellik eklemek için sarıcı işlevleri kullanabilirsiniz:

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__')) 
) 

yeni bir requests.Session nesne oluşturmak Şimdi ne zaman bir taban URL belirtebilirsiniz:

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

ben bu cevabı gibi ama baz url urljoin' almak için url ve sonrası yöntemlerinde olarak verilmiştir şeyi onlara üzerine yazar 'çünkü böyle hiçbir alt düzlemlere sahip olduğunda işe yarıyor. Benim durumumda buna ihtiyacım vardı, bu yüzden 'urljoin' çağrısını basit dize birleştirme ile değiştirdim –

4

sadece request.Session alt sınıf ve aşılmasına neden onun __init__ veBöyleyöntem:

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

Ve sonra kodunuzda requests.Session yerine alt sınıfı kullanabilirsiniz:

from my_requests import SessionWithUrlBase 


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

Ayrıca mevcut kod tabanına değiştirerek önlemek için maymun-yama requests.Session (bu uygulama olmalıdır olabilir % 100) uyumlu, ancak herhangi bir kod çağırmadan önce fiili yama yapmak emin olun requests.Session():

# monkey_patch.py 
import requests 


class SessionWithUrlBase(requests.Session): 
    ... 

requests.Session = SessionWithUrlBase 

Sonra:

# main.py 
import requests 
import monkey_patch 


session = requests.Session() 
repr(session) # <monkey_patch.SessionWithUrlBase object at ...>