Testing applications that use fsspec.open("s3://...") #1785
-
I'm trying to test an application that uses Helpful for any pointers on how to test S3 integration effectively. Here's what I tried: from moto import mock_aws
import json
import os
os.environ["TEST_PROXY_MODE"] = "true"
with mock_aws():
import boto3
import fsspec
client = boto3.client("s3")
client.create_bucket(Bucket="test-bucket")
client.put_object(
Bucket="test-bucket",
Key="foo.json",
Body=json.dumps({"inputs": "foo"}),
)
with fsspec.open("s3://test-bucket/foo.json") as f:
print(f.read()) $ moto_proxy &
$ python foo.py
INFO 2025-01-30 12:31:34,189 - POST http://localhost:5005/moto-api/reset
/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(
INFO 2025-01-30 12:31:34,329 - PUT https://test-bucket.s3.amazonaws.com/
/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(
INFO 2025-01-30 12:31:34,404 - PUT https://test-bucket.s3.amazonaws.com/foo.json
Traceback (most recent call last):
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 114, in _error_wrapper
return await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/client.py", line 412, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/dion/codes/tesseract/foo.py", line 20, in <module>
with fsspec.open("s3://test-bucket/foo.json") as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/core.py", line 105, in __enter__
f = self.fs.open(self.path, mode=mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1310, in open
f = self._open(
^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 699, in _open
return S3File(
^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 2238, in __init__
super().__init__(
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1884, in __init__
self.size = self.details["size"]
^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1897, in details
self._details = self.fs.info(self.path)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 118, in wrapper
return sync(self.loop, func, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 103, in sync
raise return_result
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 56, in _runner
result[0] = await coro
^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 1426, in _info
out = await self._call_s3(
^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 371, in _call_s3
return await _error_wrapper(
^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 146, in _error_wrapper
raise err
PermissionError: Forbidden When not using proxy mode, I get this traceback instead: Traceback (most recent call last):
File "/Users/dion/codes/tesseract/foo.py", line 20, in <module>
with fsspec.open("s3://test-bucket/foo.json") as f:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/core.py", line 105, in __enter__
f = self.fs.open(self.path, mode=mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1310, in open
f = self._open(
^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 699, in _open
return S3File(
^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 2238, in __init__
super().__init__(
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1884, in __init__
self.size = self.details["size"]
^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/spec.py", line 1897, in details
self._details = self.fs.info(self.path)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 118, in wrapper
return sync(self.loop, func, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 103, in sync
raise return_result
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/fsspec/asyn.py", line 56, in _runner
result[0] = await coro
^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 1426, in _info
out = await self._call_s3(
^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 371, in _call_s3
return await _error_wrapper(
^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 146, in _error_wrapper
raise err
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/s3fs/core.py", line 114, in _error_wrapper
return await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/client.py", line 394, in _make_api_call
http, parsed_response = await self._make_request(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/client.py", line 420, in _make_request
return await self._endpoint.make_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/endpoint.py", line 97, in _send_request
success_response, exception = await self._get_response(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/endpoint.py", line 139, in _get_response
success_response, exception = await self._do_get_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/endpoint.py", line 191, in _do_get_response
response_dict = await convert_to_response_dict(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/dion/.virtualenvs/science/lib/python3.12/site-packages/aiobotocore/endpoint.py", line 49, in convert_to_response_dict
for k, v in http_response.raw.raw_headers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'MockRawResponse' object has no attribute 'raw_headers' |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
The above LLM answer is essentially correct, but the key is the argument endpoint_url - you use this to tell s3fs which S3 to talk to. Where did you encounter the environment variable TEST_PROXY_MODE, is this documented? |
Beta Was this translation helpful? Give feedback.
Example above is using
mock_aws
, which raises both with and without proxy mode (different errors tho).Thanks for the pointer regarding global config though, that's helpful! This works now, even without monkeypatching anything: