Python requests: URL base in Session

前端 未结 5 902
夕颜
夕颜 2020-12-28 14:44

When using a Session, it seems you need to provide the full URL each time, e.g.

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


        
5条回答
  •  感动是毒
    2020-12-28 15:17

    I don't see a built-in way to do this, but you can use wrapper functions to add the functionality you want:

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

    Now you can specify a base URL when you construct a new requests.Session object:

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

提交回复
热议问题