45

アプリケーションの 1 つのメソッドでPython のrequestsライブラリを使用しています。メソッドの本体は次のようになります。

def handle_remote_file(url, **kwargs):
    response = requests.get(url, ...)
    buff = StringIO.StringIO()
    buff.write(response.content)
    ...
    return True

そのメソッドの単体テストをいくつか書きたいと思いますが、やりたいことは、次のような偽のローカル URL を渡すことです。

class RemoteTest(TestCase):
    def setUp(self):
        self.url = 'file:///tmp/dummy.txt'

    def test_handle_remote_file(self):
        self.assertTrue(handle_remote_file(self.url))

ローカル URL でrequests.getを呼び出すと、以下のKeyError例外が発生しました。

requests.get('file:///tmp/dummy.txt')

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/packages/urllib3/poolmanager.pyc in connection_from_host(self, host, port, scheme)
76 
77         # Make a fresh ConnectionPool of the desired type
78         pool_cls = pool_classes_by_scheme[scheme]
79         pool = pool_cls(host, port, **self.connection_pool_kw)
80 

KeyError: 'file'

問題は、ローカル URL をrequests.getに渡す方法です。

PS: 上記の例を作成しました。多くのエラーが含まれている可能性があります。

4

7 に答える 7

39

@WooParadog が説明したように、リクエスト ライブラリはローカル ファイルの処理方法を知りません。ただし、現在のバージョンではトランスポート アダプターを定義できます。

したがって、ローカルファイルを処理できる独自のアダプターを簡単に定義できます。たとえば、次のようになります。

from requests_testadapter import Resp

class LocalFileAdapter(requests.adapters.HTTPAdapter):
    def build_response_from_file(self, request):
        file_path = request.url[7:]
        with open(file_path, 'rb') as file:
            buff = bytearray(os.path.getsize(file_path))
            file.readinto(buff)
            resp = Resp(buff)
            r = self.build_response(request, resp)

            return r

    def send(self, request, stream=False, timeout=None,
             verify=True, cert=None, proxies=None):

        return self.build_response_from_file(request)

requests_session = requests.session()
requests_session.mount('file://', LocalFileAdapter())
requests_session.get('file://<some_local_path>')

上記の例ではrequests-testadapterモジュールを使用しています。

于 2014-04-10T13:21:49.113 に答える
10

packages/urllib3/poolmanager.pyでかなり説明されています。Requests はローカル URL をサポートしていません。

pool_classes_by_scheme = {                                                        
    'http': HTTPConnectionPool,                                                   
    'https': HTTPSConnectionPool,                                              
}                                                                                 
于 2012-04-12T13:05:08.197 に答える