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: ForbiddenWhen 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: