Fetch a file from a local url with Python requests?

后端 未结 6 1247
误落风尘
误落风尘 2020-12-02 14:29

I am using Python\'s requests library in one method of my application. The body of the method looks like this:

def handle_remote_file(url, **kwargs):
    res         


        
6条回答
  •  生来不讨喜
    2020-12-02 15:00

    Here's a transport adapter I wrote which is more featureful than b1r3k's and has no additional dependencies beyond Requests itself. I haven't tested it exhaustively yet, but what I have tried seems to be bug-free.

    import requests
    import os, sys
    
    if sys.version_info.major < 3:
        from urllib import url2pathname
    else:
        from urllib.request import url2pathname
    
    class LocalFileAdapter(requests.adapters.BaseAdapter):
        """Protocol Adapter to allow Requests to GET file:// URLs
    
        @todo: Properly handle non-empty hostname portions.
        """
    
        @staticmethod
        def _chkpath(method, path):
            """Return an HTTP status for the given filesystem path."""
            if method.lower() in ('put', 'delete'):
                return 501, "Not Implemented"  # TODO
            elif method.lower() not in ('get', 'head'):
                return 405, "Method Not Allowed"
            elif os.path.isdir(path):
                return 400, "Path Not A File"
            elif not os.path.isfile(path):
                return 404, "File Not Found"
            elif not os.access(path, os.R_OK):
                return 403, "Access Denied"
            else:
                return 200, "OK"
    
        def send(self, req, **kwargs):  # pylint: disable=unused-argument
            """Return the file specified by the given request
    
            @type req: C{PreparedRequest}
            @todo: Should I bother filling `response.headers` and processing
                   If-Modified-Since and friends using `os.stat`?
            """
            path = os.path.normcase(os.path.normpath(url2pathname(req.path_url)))
            response = requests.Response()
    
            response.status_code, response.reason = self._chkpath(req.method, path)
            if response.status_code == 200 and req.method.lower() != 'head':
                try:
                    response.raw = open(path, 'rb')
                except (OSError, IOError) as err:
                    response.status_code = 500
                    response.reason = str(err)
    
            if isinstance(req.url, bytes):
                response.url = req.url.decode('utf-8')
            else:
                response.url = req.url
    
            response.request = req
            response.connection = self
    
            return response
    
        def close(self):
            pass
    

    (Despite the name, it was completely written before I thought to check Google, so it has nothing to do with b1r3k's.) As with the other answer, follow this with:

    requests_session = requests.session()
    requests_session.mount('file://', LocalFileAdapter())
    r = requests_session.get('file:///path/to/your/file')
    

提交回复
热议问题