pax_global_header 0000666 0000000 0000000 00000000064 14772531734 0014527 g ustar 00root root 0000000 0000000 52 comment=c2f8c6356a97918506cb040bc6d59f1c35f6666f
filesystem_spec-2025.3.2/ 0000775 0000000 0000000 00000000000 14772531734 0015160 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/.codespellrc 0000664 0000000 0000000 00000000601 14772531734 0017455 0 ustar 00root root 0000000 0000000 [codespell]
skip = *.css*,.git,build
# many short "words-like" non-words are used in the project as variables/args
# hel - used in a test, cannot exclude in-line yet
# cachable - historically happened
# falsy - too cute although used only once and could be made strict bool
# doas - used as argument to some call in WebHDFS
ignore-words-list = fo,dne,fro,hel,cachable,falsy,doas,afile
filesystem_spec-2025.3.2/.coveragerc 0000664 0000000 0000000 00000000510 14772531734 0017275 0 ustar 00root root 0000000 0000000 [run]
omit =
*/test_*.py
fsspec/_version.py
fsspec/implementations/github.py
fsspec/implementations/hdfs.py
source =
fsspec
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
pragma: no cover
raise AssertionError
raise NotImplementedError
pass
ignore_errors = True
filesystem_spec-2025.3.2/.gitattributes 0000664 0000000 0000000 00000000040 14772531734 0020045 0 ustar 00root root 0000000 0000000 fsspec/_version.py export-subst
filesystem_spec-2025.3.2/.github/ 0000775 0000000 0000000 00000000000 14772531734 0016520 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/.github/workflows/ 0000775 0000000 0000000 00000000000 14772531734 0020555 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/.github/workflows/main.yaml 0000664 0000000 0000000 00000006632 14772531734 0022374 0 ustar 00root root 0000000 0000000 name: CI
on:
push:
branches: ["*"]
pull_request:
branches: [master]
jobs:
linux:
name: ${{ matrix.PY }}-pytest
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
PY:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
env:
CIRUN: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup conda
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: ci/environment-py38.yml
python-version: ${{ matrix.PY }}
- name: Run Tests
shell: bash -l {0}
run: |
pip install -e .[test_full]
pytest -v
win:
name: pytest-win
runs-on: windows-2019
env:
CIRUN: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup conda
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: ci/environment-win.yml
- name: Run Tests
shell: bash -l {0}
run: |
pip install -e .[test]
pytest -v
lint:
name: lint
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@main
- uses: actions/setup-python@main
with:
python-version: "3.11"
- uses: pre-commit/action@main
# typecheck:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v4
#
# - name: Setup conda
# uses: conda-incubator/setup-miniconda@v3
# with:
# environment-file: ci/environment-typecheck.yml
#
# - name: mypy
# shell: bash -l {0}
# run: |
# mypy fsspec
#
downstream:
name: downstream
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup conda
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: ci/environment-downstream.yml
- name: Local install
shell: bash -l {0}
run: |
sh install_s3fs.sh
pip install -e .[test,test_downstream]
pip list
- name: Run fsspec tests
shell: bash -l {0}
run: |
pytest -v fsspec/tests/test_downstream.py
- name: Run dask tests
shell: bash -l {0}
run: |
dask_test_path=$(python -c "import dask.bytes;print(dask.bytes.__path__[0])")
pytest -v $dask_test_path
fsspec_friends:
name: ${{ matrix.FRIEND }}-pytest
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
FRIEND: [s3fs, gcsfs]
env:
CIRUN: true
BOTO_CONFIG: /dev/null
AWS_ACCESS_KEY_ID: foobar_key
AWS_SECRET_ACCESS_KEY: foobar_secret
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup conda
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: ci/environment-friends.yml
- name: Clone
shell: bash -l {0}
run: git clone https://github.com/fsspec/${{ matrix.FRIEND }}
- name: Install
shell: bash -l {0}
run: |
pip install -e . --no-deps
pip list
- name: Test
shell: bash -l {0}
run: |
cd ${{ matrix.FRIEND }}
pytest -v
cd ..
filesystem_spec-2025.3.2/.github/workflows/pypipublish.yaml 0000664 0000000 0000000 00000001152 14772531734 0024010 0 ustar 00root root 0000000 0000000 name: Upload Python Package
on:
release:
types: [created]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
hatch build
twine upload dist/*
filesystem_spec-2025.3.2/.gitignore 0000664 0000000 0000000 00000002545 14772531734 0017156 0 ustar 00root root 0000000 0000000 # Dask
dask-worker-space
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
pip-wheel-metadata/
_version.py
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# jetbrains ide stuff
*.iml
.idea/
# vscode ide stuff
*.code-workspace
.history
.vscode
# docker artifacts
.docker
# vi*
*.swp
build/
downstream/*
filesystem_spec-2025.3.2/.pre-commit-config.yaml 0000664 0000000 0000000 00000001153 14772531734 0021441 0 ustar 00root root 0000000 0000000 exclude: >
(?x)^(
\.tox/.*
)$
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-docstring-first
- id: check-json
- id: check-yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.9.2
hooks:
# Run the linter.
- id: ruff
args: [ --fix, "--show-fixes"]
- id: ruff-format
types_or: [python]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.0
hooks:
- id: codespell
filesystem_spec-2025.3.2/LICENSE 0000664 0000000 0000000 00000002751 14772531734 0016172 0 ustar 00root root 0000000 0000000 BSD 3-Clause License
Copyright (c) 2018, Martin Durant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
filesystem_spec-2025.3.2/README.md 0000664 0000000 0000000 00000007466 14772531734 0016454 0 ustar 00root root 0000000 0000000 # filesystem_spec
[](https://pypi.python.org/pypi/fsspec/)
[](https://anaconda.org/conda-forge/fsspec)

[](https://filesystem-spec.readthedocs.io/en/latest/?badge=latest)
A specification for pythonic filesystems.
## Install
```bash
pip install fsspec
```
would install the base fsspec. Various optionally supported features might require specification of custom
extra require, e.g. `pip install fsspec[ssh]` will install dependencies for `ssh` backends support.
Use `pip install fsspec[full]` for installation of all known extra dependencies.
Up-to-date package also provided through conda-forge distribution:
```bash
conda install -c conda-forge fsspec
```
## Purpose
To produce a template or specification for a file-system interface, that specific implementations should follow,
so that applications making use of them can rely on a common behaviour and not have to worry about the specific
internal implementation decisions with any given backend. Many such implementations are included in this package,
or in sister projects such as `s3fs` and `gcsfs`.
In addition, if this is well-designed, then additional functionality, such as a key-value store or FUSE
mounting of the file-system implementation may be available for all implementations "for free".
## Documentation
Please refer to [RTD](https://filesystem-spec.readthedocs.io/en/latest/?badge=latest)
## Develop
fsspec uses GitHub Actions for CI. Environment files can be found
in the "ci/" directory. Note that the main environment is called "py38",
but it is expected that the version of python installed be adjustable at
CI runtime. For local use, pick a version suitable for you.
```bash
# For a new environment (mamba / conda).
mamba create -n fsspec -c conda-forge python=3.9 -y
conda activate fsspec
# Standard dev install with docs and tests.
pip install -e ".[dev,doc,test]"
# Full tests except for downstream
pip install s3fs
pip uninstall s3fs
pip install -e .[dev,doc,test_full]
pip install s3fs --no-deps
pytest -v
# Downstream tests.
sh install_s3fs.sh
# Windows powershell.
install_s3fs.sh
```
### Testing
Tests can be run in the dev environment, if activated, via ``pytest fsspec``.
The full fsspec suite requires a system-level docker, docker-compose, and fuse
installation. If only making changes to one backend implementation, it is
not generally necessary to run all tests locally.
It is expected that contributors ensure that any change to fsspec does not
cause issues or regressions for either other fsspec-related packages such
as gcsfs and s3fs, nor for downstream users of fsspec. The "downstream" CI
run and corresponding environment file run a set of tests from the dask
test suite, and very minimal tests against pandas and zarr from the
test_downstream.py module in this repo.
### Code Formatting
fsspec uses [Black](https://black.readthedocs.io/en/stable) to ensure
a consistent code format throughout the project.
Run ``black fsspec`` from the root of the filesystem_spec repository to
auto-format your code. Additionally, many editors have plugins that will apply
``black`` as you edit files. ``black`` is included in the ``tox`` environments.
Optionally, you may wish to setup [pre-commit hooks](https://pre-commit.com) to
automatically run ``black`` when you make a git commit.
Run ``pre-commit install --install-hooks`` from the root of the
filesystem_spec repository to setup pre-commit hooks. ``black`` will now be run
before you commit, reformatting any changed files. You can format without
committing via ``pre-commit run`` or skip these checks with ``git commit
--no-verify``.
filesystem_spec-2025.3.2/ci/ 0000775 0000000 0000000 00000000000 14772531734 0015553 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/ci/environment-downstream.yml 0000664 0000000 0000000 00000000171 14772531734 0023022 0 ustar 00root root 0000000 0000000 name: test_env
channels:
- conda-forge
dependencies:
- python=3.11
- pip:
- git+https://github.com/dask/dask
filesystem_spec-2025.3.2/ci/environment-friends.yml 0000664 0000000 0000000 00000001031 14772531734 0022265 0 ustar 00root root 0000000 0000000 name: test_env
channels:
- conda-forge
dependencies:
- python=3.12
- pytest
- pytest-asyncio !=0.22.0
- pytest-benchmark
- pytest-cov
- pytest-mock
- pip
- ujson
- requests
- decorator
- pytest-timeout
- google-auth
- aiohttp
- google-auth-oauthlib
- flake8
- black
- google-cloud-core
- google-cloud-storage
- google-api-core
- google-api-python-client
- httpretty
- aiobotocore
- moto
- flask
- pip:
- git+https://github.com/fsspec/s3fs
- git+https://github.com/fsspec/gcsfs
filesystem_spec-2025.3.2/ci/environment-py38.yml 0000664 0000000 0000000 00000000224 14772531734 0021441 0 ustar 00root root 0000000 0000000 name: test_env
channels:
- conda-forge
dependencies:
- pip
- git <2.45.0
- py
- s3fs
- pip:
- hadoop-test-cluster
- smbprotocol
filesystem_spec-2025.3.2/ci/environment-typecheck.yml 0000664 0000000 0000000 00000000347 14772531734 0022623 0 ustar 00root root 0000000 0000000 name: test_env
channels:
- conda-forge
dependencies:
- mypy=1.4.1
- pyarrow
- python=3.8
- pip
- pip:
- types-paramiko
- types-requests
- types-tqdm
- types-paramiko
- types-PyYAML
- types-ujson
filesystem_spec-2025.3.2/ci/environment-win.yml 0000664 0000000 0000000 00000000133 14772531734 0021432 0 ustar 00root root 0000000 0000000 name: test_env
channels:
- conda-forge
dependencies:
- python=3.11
- s3fs
- pytest
filesystem_spec-2025.3.2/docs/ 0000775 0000000 0000000 00000000000 14772531734 0016110 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/docs/Makefile 0000664 0000000 0000000 00000001140 14772531734 0017544 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = fsspec
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
filesystem_spec-2025.3.2/docs/README.md 0000664 0000000 0000000 00000000362 14772531734 0017370 0 ustar 00root root 0000000 0000000 # Building Documentation
A basic python environment with packages listed in `./requirements.txt` is
required to build the docs, see ``environment.yml``.
To make HTML documentation:
```bash
make html
```
Outputs to `build/html/index.html`
filesystem_spec-2025.3.2/docs/environment.yml 0000664 0000000 0000000 00000000101 14772531734 0021167 0 ustar 00root root 0000000 0000000 name: fsspec
channels:
- defaults
dependencies:
- python=3.9
filesystem_spec-2025.3.2/docs/make.bat 0000664 0000000 0000000 00000001417 14772531734 0017520 0 ustar 00root root 0000000 0000000 @ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
set SPHINXPROJ=fsspec
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
filesystem_spec-2025.3.2/docs/source/ 0000775 0000000 0000000 00000000000 14772531734 0017410 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/docs/source/_static/ 0000775 0000000 0000000 00000000000 14772531734 0021036 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/docs/source/_static/custom.css 0000664 0000000 0000000 00000000124 14772531734 0023057 0 ustar 00root root 0000000 0000000 .classifier:before {
font-style: normal;
margin: 0.5em;
content: ":";
}
filesystem_spec-2025.3.2/docs/source/api.rst 0000664 0000000 0000000 00000024507 14772531734 0020723 0 ustar 00root root 0000000 0000000 API Reference
=============
.. currentmodule:: fsspec
User Functions
--------------
.. autosummary::
fsspec.available_compressions
fsspec.available_protocols
fsspec.filesystem
fsspec.fuse.run
fsspec.generic.rsync
fsspec.get_filesystem_class
fsspec.get_mapper
fsspec.gui.FileSelector
fsspec.open
fsspec.open_files
fsspec.open_local
.. autofunction:: fsspec.available_compressions
.. autofunction:: fsspec.available_protocols
.. autofunction:: fsspec.filesystem
.. autofunction:: fsspec.fuse.run
.. autofunction:: fsspec.generic.rsync
.. autofunction:: fsspec.get_filesystem_class
.. autofunction:: fsspec.get_mapper
.. autoclass:: fsspec.gui.FileSelector
:members:
.. autofunction:: fsspec.open
.. autofunction:: fsspec.open_files
.. autofunction:: fsspec.open_local
Base Classes
------------
.. autosummary::
fsspec.archive.AbstractArchiveFileSystem
fsspec.asyn.AsyncFileSystem
fsspec.callbacks.Callback
fsspec.callbacks.DotPrinterCallback
fsspec.callbacks.NoOpCallback
fsspec.callbacks.TqdmCallback
fsspec.core.BaseCache
fsspec.core.OpenFile
fsspec.core.OpenFiles
fsspec.core.get_fs_token_paths
fsspec.core.url_to_fs
fsspec.dircache.DirCache
fsspec.FSMap
fsspec.generic.GenericFileSystem
fsspec.registry.register_implementation
fsspec.spec.AbstractBufferedFile
fsspec.spec.AbstractFileSystem
fsspec.spec.Transaction
.. autoclass:: fsspec.archive.AbstractArchiveFileSystem
:members:
.. autoclass:: fsspec.callbacks.Callback
:members:
.. autoclass:: fsspec.callbacks.DotPrinterCallback
:members:
.. autoclass:: fsspec.callbacks.NoOpCallback
:members:
.. autoclass:: fsspec.callbacks.TqdmCallback
:members:
.. autoclass:: fsspec.core.BaseCache
:members:
.. autoclass:: fsspec.core.OpenFile
:members:
.. autoclass:: fsspec.core.OpenFiles
.. autofunction:: fsspec.core.get_fs_token_paths
.. autofunction:: fsspec.core.url_to_fs
.. autoclass:: fsspec.dircache.DirCache
:members: __init__
.. autoclass:: fsspec.FSMap
:members:
.. autoclass:: fsspec.generic.GenericFileSystem
.. autofunction:: fsspec.registry.register_implementation
.. autoclass:: fsspec.spec.AbstractBufferedFile
:members:
.. autoclass:: fsspec.spec.AbstractFileSystem
:members:
.. autoclass:: fsspec.spec.Transaction
:members:
.. _implementations:
Built-in Implementations
------------------------
.. autosummary::
fsspec.implementations.arrow.ArrowFSWrapper
fsspec.implementations.arrow.HadoopFileSystem
fsspec.implementations.cached.CachingFileSystem
fsspec.implementations.cached.SimpleCacheFileSystem
fsspec.implementations.cached.WholeFileCacheFileSystem
fsspec.implementations.dask.DaskWorkerFileSystem
fsspec.implementations.data.DataFileSystem
fsspec.implementations.dbfs.DatabricksFileSystem
fsspec.implementations.dirfs.DirFileSystem
fsspec.implementations.ftp.FTPFileSystem
fsspec.implementations.git.GitFileSystem
fsspec.implementations.github.GithubFileSystem
fsspec.implementations.http.HTTPFileSystem
fsspec.implementations.jupyter.JupyterFileSystem
fsspec.implementations.libarchive.LibArchiveFileSystem
fsspec.implementations.local.LocalFileSystem
fsspec.implementations.memory.MemoryFileSystem
fsspec.implementations.reference.ReferenceFileSystem
fsspec.implementations.reference.LazyReferenceMapper
fsspec.implementations.sftp.SFTPFileSystem
fsspec.implementations.smb.SMBFileSystem
fsspec.implementations.tar.TarFileSystem
fsspec.implementations.webhdfs.WebHDFS
fsspec.implementations.zip.ZipFileSystem
.. autoclass:: fsspec.implementations.arrow.ArrowFSWrapper
:members: __init__
.. autoclass:: fsspec.implementations.arrow.HadoopFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.cached.CachingFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.cached.SimpleCacheFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.cached.WholeFileCacheFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.dask.DaskWorkerFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.data.DataFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.dbfs.DatabricksFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.dirfs.DirFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.ftp.FTPFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.git.GitFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.github.GithubFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.http.HTTPFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.jupyter.JupyterFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.libarchive.LibArchiveFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.local.LocalFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.memory.MemoryFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.reference.ReferenceFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.reference.LazyReferenceMapper
:members: __init__
.. autoclass:: fsspec.implementations.sftp.SFTPFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.smb.SMBFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.tar.TarFileSystem
:members: __init__
.. autoclass:: fsspec.implementations.webhdfs.WebHDFS
:members: __init__
.. autoclass:: fsspec.implementations.zip.ZipFileSystem
:members: __init__
.. _external_implementations:
Other Known Implementations
---------------------------
Note that most of these projects are hosted outside of the `fsspec` organisation. Please read their
documentation carefully before using any particular package.
- `abfs`_ for Azure Blob service, with protocol "abfs://"
- `adl`_ for Azure DataLake storage, with protocol "adl://"
- `alluxiofs`_ to access fsspec implemented filesystem with Alluxio distributed cache
- `boxfs`_ for access to Box file storage, with protocol "box://"
- `csvbase`_ for access to csvbase.com hosted CSV files, with protocol "csvbase://"
- `dropbox`_ for access to dropbox shares, with protocol "dropbox://"
- `dvc`_ to access DVC/Git repository as a filesystem
- `fsspec-encrypted`_ for transparent encryption on top of other fsspec filesystems.
- `gcsfs`_ for Google Cloud Storage, with protocol "gcs://"
- `gdrive`_ to access Google Drive and shares (experimental)
- `git`_ to access Git repositories
- `huggingface_hub`_ to access the Hugging Face Hub filesystem, with protocol "hf://"
- `hdfs-native`_ to access Hadoop filesystem, with protocol "hdfs://"
- `httpfs-sync`_ to access HTTP(s) files in a synchronous manner to offer an alternative to the aiohttp-based implementation.
- `ipfsspec`_ for the InterPlanetary File System (IPFS), with protocol "ipfs://"
- `irods`_ for access to iRODS servers, with protocol "irods://"
- `lakefs`_ for lakeFS data lakes, with protocol "lakefs://"
- `morefs`_ for `OverlayFileSystem`, `DictFileSystem`, and others
- `ocifs`_ for access to Oracle Cloud Object Storage, with protocol "oci://"
- `ocilake`_ for OCI Data Lake storage
- `ossfs`_ for Alibaba Cloud (Aliyun) Object Storage System (OSS)
- `p9fs`_ for 9P (Plan 9 Filesystem Protocol) servers
- `PyAthena`_ for S3 access to Amazon Athena, with protocol "s3://" or "s3a://"
- `PyDrive2`_ for Google Drive access
- `s3fs`_ for Amazon S3 and other compatible stores, with protocol "s3://"
- `sshfs`_ for access to SSH servers, with protocol "ssh://" or "sftp://"
- `swiftspec`_ for OpenStack SWIFT, with protocol "swift://"
- `tosfs`_ for ByteDance volcano engine Tinder Object Storage (TOS)
- `wandbfs`_ to access Wandb run data (experimental)
- `wandbfsspec`_ to access Weights & Biases (experimental)
- `webdav4`_ for WebDAV, with protocol "webdav://" or "dav://"
- `xrootd`_ for xrootd, with protocol "root://"
.. _abfs: https://github.com/dask/adlfs
.. _adl: https://github.com/dask/adlfs
.. _alluxiofs: https://github.com/fsspec/alluxiofs
.. _boxfs: https://github.com/IBM/boxfs
.. _csvbase: https://github.com/calpaterson/csvbase-client
.. _dropbox: https://github.com/fsspec/dropboxdrivefs
.. _dvc: https://github.com/iterative/dvc
.. _fsspec-encrypted: https://github.com/thevgergroup/fsspec-encrypted
.. _gcsfs: https://gcsfs.readthedocs.io/en/latest/
.. _gdrive: https://github.com/fsspec/gdrivefs
.. _git: https://github.com/iterative/scmrepo
.. _hdfs-native: https://github.com/Kimahriman/hdfs-native/blob/master/python/hdfs_native/fsspec.py
.. _httpfs-sync: https://github.com/moradology/httpfs-sync
.. _huggingface_hub: https://huggingface.co/docs/huggingface_hub/main/en/guides/hf_file_system
.. _ipfsspec: https://github.com/fsspec/ipfsspec
.. _irods: https://github.com/xwcl/irods_fsspec
.. _lakefs: https://github.com/aai-institute/lakefs-spec
.. _morefs: https://github.com/iterative/morefs
.. _ocifs: https://ocifs.readthedocs.io/en/latest/
.. _ocilake: https://github.com/oracle/ocifs
.. _ossfs: https://github.com/fsspec/ossfs
.. _p9fs: https://github.com/pbchekin/p9fs-py
.. _PyAthena: https://github.com/laughingman7743/PyAthena
.. _PyDrive2: https://github.com/iterative/PyDrive2
.. _s3fs: https://s3fs.readthedocs.io/en/latest/
.. _sshfs: https://github.com/fsspec/sshfs
.. _swiftspec: https://github.com/fsspec/swiftspec
.. _tosfs: https://tosfs.readthedocs.io/en/latest/
.. _wandbfs: https://github.com/jkulhanek/wandbfs
.. _wandbfsspec: https://github.com/alvarobartt/wandbfsspec
.. _webdav4: https://github.com/skshetry/webdav4
.. _xrootd: https://github.com/CoffeaTeam/fsspec-xrootd
.. _readbuffering:
Read Buffering
--------------
.. autosummary::
fsspec.caching.BlockCache
fsspec.caching.BytesCache
fsspec.caching.MMapCache
fsspec.caching.ReadAheadCache
fsspec.caching.FirstChunkCache
fsspec.caching.BackgroundBlockCache
.. autoclass:: fsspec.caching.BlockCache
:members:
.. autoclass:: fsspec.caching.BytesCache
:members:
.. autoclass:: fsspec.caching.MMapCache
:members:
.. autoclass:: fsspec.caching.ReadAheadCache
:members:
.. autoclass:: fsspec.caching.FirstChunkCache
:members:
.. autoclass:: fsspec.caching.BackgroundBlockCache
:members:
Utilities
---------
.. autosummary::
fsspec.utils.read_block
.. autofunction:: fsspec.utils.read_block
.. raw:: html
filesystem_spec-2025.3.2/docs/source/async.rst 0000664 0000000 0000000 00000015516 14772531734 0021267 0 ustar 00root root 0000000 0000000 Async
=====
``fsspec`` supports asynchronous operations on certain implementations. This
allows for concurrent calls within bulk operations such as ``cat`` (fetch
the contents of many files at once) even from normal code, and for the direct
use of fsspec in async code without blocking.
Async implementations derive from the class ``fsspec.asyn.AsyncFileSystem``.
The class attribute ``async_impl`` can be used to test whether an
implementation is async of not.
``AsyncFileSystem`` contains ``async def`` coroutine versions of the methods of
``AbstractFileSystem``. By convention, these methods are prefixed with "_"
to indicate that they are not to called directly in normal code, only
when you know what you are doing. In most cases, the code is identical or
slightly modified by replacing sync calls with ``await`` calls to async
functions.
The only async implementation built into ``fsspec`` is ``HTTPFileSystem``.
Synchronous API
---------------
The methods of ``AbstractFileSystem`` are available and can be called from
normal code. They call and wait on the corresponding async function. The
*work* is carried out in a separate threads, so if there are many fsspec
operations in flight at once, launched from many threads, they will still
all be processed on the same IO-dedicated thread.
Most users should not be aware that their code is running async.
Note that the sync functions are wrapped using ``sync_wrapper``, which
copies the docstrings from ``AbstractFileSystem``, unless they are
explicitly given in the implementation.
Example:
.. code-block:: python
fs = fsspec.filesystem("http")
out = fs.cat([url1, url2, url3]) # fetches data concurrently
Coroutine batching
------------------
The various methods which create many coroutines to be passed to the event loop
for processing may be batched: submitting a certain number in one go and waiting
for them to complete before launching more. This is important to work around
local open-file limits (which can be <~100) and not to swamp the heap.
``fsspec.asyn._run_coros_in_chunks`` controls this process, but from the user's point
of view, there are three ways to affect it. In increasing order or precedence:
- the global variables ``fsspec.asyn._DEFAULT_BATCH_SIZE`` and
``fsspec.asyn._NOFILES_DEFAULT_BATCH_SIZE`` (for calls involving local files or not,
respectively)
- config keys "gather_batch_size" and "nofiles_gather_batch_size"
- the ``batch_size`` keyword, accepted by the batch methods of an async filesystem.
Using from Async
----------------
File system instances can be created with ``asynchronous=True``. This
implies that the instantiation is happening within a coroutine, so
the various async method can be called directly with ``await``, as is
normal in async code.
Note that, because ``__init__`` is a blocking function, any creation
of asynchronous resources will be deferred. You will normally need to
explicitly ``await`` a coroutine to create them. Since garbage collection
also happens in blocking code, you may wish to explicitly await
resource destructors too. Example:
.. code-block:: python
async def work_coroutine():
fs = fsspec.filesystem("http", asynchronous=True)
session = await fs.set_session() # creates client
out = await fs._cat([url1, url2, url3]) # fetches data concurrently
await session.close() # explicit destructor
asyncio.run(work_coroutine())
Bring your own loop
-------------------
For the non-asynchronous case, ``fsspec`` will normally create an asyncio
event loop on a specific thread. However, the calling application may prefer
IO processes to run on a loop that is already around and running (in another
thread). The loop needs to be asyncio compliant, but does not necessarily need
to be an ``ayncio.events.AbstractEventLoop``. Example:
.. code-block:: python
loop = ... # however a loop was made, running on another thread
fs = fsspec.filesystem("http", loop=loop)
out = fs.cat([url1, url2, url3]) # fetches data concurrently
Implementing new backends
-------------------------
Async file systems should derive from ``AsyncFileSystem``, and implement the
``async def _*`` coroutines there. These functions will either have sync versions
automatically generated is the name is in the ``async_methods`` list, or
can be directly created using ``sync_wrapper``.
.. code-block:: python
class MyFileSystem(AsyncFileSystem):
async def _my_method(self):
...
my_method = sync_wrapper(_my_method)
These functions must **not call** methods or functions which themselves are synced,
but should instead ``await`` other coroutines. Calling methods which do not require sync,
such as ``_strip_protocol`` is fine.
Note that ``__init__``, cannot be ``async``, so it might need to allocate async
resources using the ``sync`` function, but *only* if ``asynchronous=False``. If it
is ``True``, you probably need to require the caller to await a coroutine that
creates those resources. Similarly, any destructor (e.g., ``__del__``) will run from normal
code, and possibly after the loop has stopped/closed.
To call ``sync``, you will need to pass the associated event loop, which will be
available as the attribute ``.loop``.
.. autosummary::
fsspec.asyn.AsyncFileSystem
fsspec.asyn.get_loop
fsspec.asyn.sync
fsspec.asyn.sync_wrapper
.. autoclass:: fsspec.asyn.AsyncFileSystem
:members:
.. autofunction:: fsspec.asyn.get_loop
.. autofunction:: fsspec.asyn.sync
.. autofunction:: fsspec.asyn.sync_wrapper
.. raw:: html
AsyncFileSystemWrapper
----------------------
The `AsyncFileSystemWrapper` class is an experimental feature that allows you to convert
a synchronous filesystem into an asynchronous one. This is useful for quickly integrating
synchronous filesystems into workflows that may expect `AsyncFileSystem` instances.
Basic Usage
~~~~~~~~~~~
To use `AsyncFileSystemWrapper`, wrap any synchronous filesystem to work in an asynchronous context.
In this example, the synchronous `LocalFileSystem` is wrapped, creating an `AsyncFileSystem` instance
backed by the normal, synchronous methods of `LocalFileSystem`:
.. code-block:: python
import asyncio
import fsspec
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper
async def async_copy_file():
sync_fs = fsspec.filesystem('file') # by-default synchronous, local filesystem
async_fs = AsyncFileSystemWrapper(sync_fs)
return await async_fs._copy('/source/file.txt', '/destination/file.txt')
asyncio.run(async_copy_file())
Limitations
-----------
This is experimental. Users should not expect this wrapper to magically make things faster.
It is primarily provided to allow usage of synchronous filesystems with interfaces that expect
`AsyncFileSystem` instances.
filesystem_spec-2025.3.2/docs/source/changelog.rst 0000664 0000000 0000000 00000063517 14772531734 0022105 0 ustar 00root root 0000000 0000000 Changelog
=========
2025.3.2
--------
- drop support for py3.8
2025.3.1
--------
Enhancements
- LFS support in github: (#1810)
Fixes
- json should be a method fo requests shim (#1814)
- don't raise if known_implementation has no given error string (#1804)
Other
- rename protocols for sync-http (#1810)
2025.3.0
--------
Enhancements
- add pipe_file to HTTP (#1799, 1801)
- add sync http for pyodide (#1177)
- ls performance for local and detail=False (#1789)
Fixes
- dir/info consistency in dirfs (#1798)
- referenceFS async consistency (#1794, 1795)
- CI (#1793)
2025.2.0
--------
Enhancements
- add open() to referenceFS (#1778)
Fixes
- don't make async open() in async-wrapper (#1769)
- fix CI following dask-expr upstream change (#1781)
- cope with zarr3 "Buffer" objects in referenceFS (#1784)
Other
- use itemgetter in archiveFS (#1764)
- document that newline is included in readline(s) (#1770)
- format/spelling (#1774, 1779, 1780)
2024.12.0
---------
Enhancements
- "exclusive" mode for writing (#1762, 1756, 174+)
- "tree" text display of filesystem contents (#1750)
- async wrapper for sync FSs (#1745)
- new known implementation: tosfs (#1739)
- consilidate block fetch requests (#1733)
Fixes
- better webHDFS proxies (#
- syn FSs in referenceFS (#1755)
- don't serialize file caches (#1753)
- race condition in local ls() (#1744)
- missing/nan references in parquet (#1738)
- _un_chain kwargs (@1736)
- async _cat_file in referenceFS (#1734)
Other
- fallback implementation for _fetch_range (#1732)
2024.10.0
---------
Fixes
- Performance of memoryFS rm (#1725)
- Performance of git FS info (#1712)
- Avoid git hex for newer pygit (#1703)
- tests fix for zip (#1700, 1691)
- missing open_async for dirFS (#1698)
- handle pathlib in zip (#1689)
- skip tests needing kerchunk if not installed (#1689)
- allow repeated kwargs in unchain (#1673)
Other
- Code style (#1704, 1706)
- allow pyarrow in referenceFS parquet (#1692)
- don't hardcode test port for parallel runs (#1690)
2024.9.0
--------
Enhancements
- fewer stat calls in localFS (#1659)
- faster find in ZIP (#1664)
Fixes
- paths without "/" in dirFS (#1638)
- paths with "/" in FTS (#1643, 1644)
- ls in parquet-based nested reference sets, and append (#1645, 1657)
- exception handling for SMB (#1650)
Other
- style (#1640, 1641, 1660)
- docs: xrootd (#1646)
- CI back on miniconda (#1658)
2024.6.1
--------
Fixes
- fix appending to non-dict reference sets (#1634)
- don't let generic edit info dicts (#1633)
- set https's loop before calling super (#1633)
- cached write file doesn't need to update it's size on close (#1633)
- fix JSON serialize for FSs with interior FSs (#1628, 1627)
- option to strip "password" when pickling (#1625)
- fix filecache write (#1622)
2024.6.0
--------
Enhancements
- allow dicts (not just bytes) for referenceFS (#1616
- make filesystems JSON serializeable (#1612)
- implement multifile cat() for github (#1620)
Fixes
- implement auto_mkdir for SMB (#1604)
Other
- add doc deps to pyproject (#1613)
- re-remove test from package (#1611)
- formatting (#1610, 1608, 1602)
- change monthly download badge (#1607)
2024.5.0
--------
Enhancements
- log hits/misses in bytes cachers (#1566)
Fixes
- SMB flaky tests (#1597)
- rsync: only delete files if there are some to delete (#1596)
- don't let files equal bytes objects (#1594)
- url_to_fs to stringify paths (#1591)
- assert types in MemoryFS (#1574)
- restore _strip_protocol signature for local (#1567)
- convert list to set when loading cache metadata (#1556)
Other
- remove mv_file (#1585)
- mv() should not swallow errors (#1576)
- change versioning template, allows easier co-install of dev s3fs (#1569)
- in ls_from_cache, avoid dounble lookup (#1561)
- expand=True in open() (#1558)
- build system to hatch (#1553)
2024.3.1
--------
Fixes
- allow override of expand in open() (#1549)
- root handling in local file paths, fix for windows (#1477)
2024.3.0
--------
Enhancements
- coroutines throttle to stream pool rather than batches (#1544)
- write transactions in simplecache (#1531)
- allow deep nested refs in referenceFS/parquet (#1530)
Fixes
- Fixes bug (#1476) that made open_files ignore expand=False (#1536)
- remove extra calling mapper contains (#1546)
- connection retry for SMB (#1533)
- zip64 should be on is allowZip64 is (#1532)
Other
- HTTP logging (#1547)
- url_to_fs exposed in package root (#1540)
- sort known_implementations (#1549)
- code quality/stype (#1538, 1537, 1528, 1526)
2024.2.0
--------
Enhancements
- add 9P known implementation (#1513)
- allow TqdmCallback subclassing (#1497, 1480)
- callbacks/branching kwargs handling and scopes (#1496, 1495, 1460)
- add aluuxioFS to known implementations (#1469)
- implement pipe_file for dirFS (#1465)
Fixes
- infer compression for .lzma files (#1514)
- fix append to categorical/parquet references (#1510)
- allow for FTP servers that list with leading "total" line (#1503)
- convert FTP failure to FileNotFound (#1494)
- out of order reference fix (#1492)
- retry "backoff" response for DBFS (#1491)
- referenceFS case for scalar arrays (#1487)
- fix create_parents for SFTP (#1484)
- fix local .ls() on files (#1479)
- allow Path and similar in _expand_path (#1475)
- make lazy references editable (#1468)
- fix eq for abstract buffered files (#1466)
- fit tqdm cleanup (#1463)
- fix passing kwargs from cached file to underlying FS (#1462)
Other
- fix tests for supports_empty_directories=False (#1512)
- don't read references in init for referenceFS (#1521)
- code cleaning (#1518, 1502, 1499, 1493, 1481)
- pass through "replication" for HDFS (#1486)
- record more info for HTTP info() (#1483)
- add timeout argument to githubFS (#1473)
- add more security pars to webHDFS (#1472)
2023.12.2
---------
Fixes
- top-level glob in ZIP (#1454)
- append mode on local ZIP files/truncate (#1449)
- restrict ":" as protocol marker to data: (#1452)
- sftp relative paths (#1451)
- http encoding in HTTP FS put_file (#1450)
2023.12.1
---------
Fixes
- Remove trailing "/" from directory names in zipFS/archive (#1445)
2023.12.0
---------
Enhancements
- allow HTTP size guess in more circumstances (#1440)
- allow kwargs passed to GUI to be dict (#1437)
- transaction support for writing via a cache FS (#1434)
- make cached FSs work better with async backends (#1429)
- allow FSs to set their transaction implementation (#1424)
- add dataFS (#1421, 1415)
- allow basic auth in webHDFS (#1409)
Fixes
- in referenceFS, maintain order when some keys are omitted in cat (#1436)
- nested subdirectory listing in referenceFS (#1433)
- allow "=" in webHDF paths (#1428)
- fix file mode to consistent "r+b" format (#1426)
- pass on kwargs in HTTP glob (#1422)
- allow Path in can_be_local and open_local (#1419, #1418)
- fix parent for cachedFS (#1413)
- "ends" list in _cat_ranges was incorrect (#1402)
Other
- smarter handling of exceptions when doing auto_mkdir (#1406)
2023.10.0
---------
Enhancements
- alias "local://" to "file://" (#1381)
- get size of file cache (#1377)
Fixes
- stop unexpected kwargs for SMB (#1391)
- dos formatting (#1383)
Other
- small optimisations in referenceFS (#1393)
- define ordering behaviour for entrypoints (#1389)
- style (#1387, 1386, 1385)
- add LazyReferenceMapper to API docs (#1378)
- add PyPI badge to README (#1376)
2023.9.2
--------
Fixes
- revert #1358: auto_mkdir in open() (#1365)
Other
- code style updates (#1373, 1372, 1371, 1370, 1369, 1364)
- update CI setup (#1386)
2023.9.1
--------
Enhancements
- #1353, save file cache metadata in JSON
- #1352, remove some unnecessary list iterations
Fixes
- #1361, re-allow None for default port for SMB
- #1360, initialising GUI widget FS with kwargs
- #1358, pass auto_mkdir vi url_to_fs again
Other
- #1354, auto delete temp cache directory
2023.9.0
--------
Enhancements
- #1346, add ocilake protocol
- #1345, implement async-sync and async-async generic cp and rsync
- #1344, add lakefs protocol
- #1337 add goatcounter to docs
- #1323, 1328, add xethub protocol
- #1320, in HTTP, check content-encoding when getting length
- #1303, add on_error in walk
- #1302, add dirfs attribute to mappers
- #1293, configure port for smb
Fixes
- #1349, don't reorder paths in bulk ops if source and dest are both lists
- #1333, allow mode="x" in get_fs_token_paths
- #1324, allow generic to work with complex URLs
- #1316, exclude bytes-cache kwargs in url_to_fs
- #1314, remote utcnow/utcfromtimestamp
- #1311, dirFS's protocol
- #1305, use get_file rather than get in file caching
- #1295, allow bz2 to be optional
Other
- #1340, 1339, 1329 more bulk ops testing
- #1326, 1296 separate out classes in file caching for future enhancements
2023.6.0
--------
Enhancements
- #1259, add maxdepth fo cp/get/put
- #1263, allow dir modification during walk()
- #1264, add boxfs to registry
- #1266, optimise referenceFS lazy lookups, especially for writing parquet
- #1287, 1288 "encoding" for FTP
Fixes
- #1273, (re)allow reading .zstd reference sets
- #1275, resource.error for win32
- #1278, range reads in dbfs
- #1282, create parent directories in get_file
- #1283, off-by-one in reference block writing
- #1286, strip protocol in local rm_file
Other
- #1267, async bulk tests
- #1268, types and mypy
- #1277, 1279, drop outdated forms io.open, IOError
2023.5.0
--------
Enhancements
- #1236, allow writing ReferenceFS references directly to parquet
Fixes
- #1255, copy of glob to single output directory
- #1254, non-recursive copy of directory (no-op)
- #1253, cleanup fix on close of ZIP FS
- #1250, ignore dirs when copying list of files
- #1249, don't error on register without clobber is registering same thing again
- #1245, special case for other_files and relative path
Other
- #1248, add test harness into released wheel package
- #1247, docs and tests around common bulk file operations
2023.4.0
--------
Enhancements
- #1225, comprehensive docs of expected behaviour of cp/get/put and tests
- #1216, test harness for any backend
Fixes
- #1224, small fixes in reference and dask FSs
- #1218, mv is no-op when origin and destination are the same
- #1217, await in AbstractStreamedFile
- #1215, docbuild fixes
- #1214, unneeded maxdepth manipulation in expand_path
- #1213, pyarros and posixpath related test fixes
- #1211, BackgroundBlockCache: keep a block longer if not yet used
- #1210, webHDFS: location parameter
Other
- #1241, add HfFileSystem to registry
- #1237, register_implementation clobber default changes to False
- #1228, "full" and "devel" installation options
- #1227, register_cache and reporting collision
- #1221, docs about implementations and protocols
2023.3.0
--------
Enhancements
- #1201, add directory FS to the registry and constructable from URLs
- #1194, allow JSON for setting dict-like kwargs in the config
- #1181, give arrow FS proper place in the registry
- #1178, add experimental background-thread buffering cache
- #1162, make ZipFS writable
Fixes
- #1202, fix on_error="omit" when using caching's cat
- #1199, 1163, get/put/cp consistency and empty directories
- #1197, 1183 use bytes for setting value on mapper using numpy
- #1191, clean up open files in spec get_file
- #1164, pass on kwargs correctly to http
Other
- #1186, make seekable=True default for pyarrow files
- #1184, 1185, set minimum python version to 3.8
2023.1.0
--------
Enhancements
- experimental DFReferenceFileSystem (#1157, 1138)
- pyarrow seeking (#1154)
- tar thread safety (#1132)
- fsid method (#1122)
Fixes
- ReferenceFS order fix (#1158)
- fix du and maxdepth (#1128, 1151)
- http ranges (#1141)
Other
- coverage on referenceFS (#1133, 1123)
- docs (#1152, 1150
- remove code duplication in unchain (#1143, 1156, 1121)
2022.11.0
---------
Enhancements
- Speed up FSMap._key_to_str (#1101)
- Add modified/created to Memory and Arrow (#1096)
- Clear expired cache method (#1092)
- Allow seekable arrow file (#1091)
- Allow append for arrow (#1089)
- recursive for sftp.get (#1082)
- topdown arg to walk() (#1081)
Fixes
- fix doc warnings (#1106, #1084)
- Fix HDFS _strip_protocol (#1103)
- Allow URLs with protocol for HDFS (#1099)
- yarl in doc deps (#1095)
- missing await in genericFS.cp (#1094)
- explicit IPv4 for test HTTP server (#1088)
- sort when merging ranges for referenceFS (#1087)
Other
- Check that snappy is snappy (#1079)
2022.10.0
---------
Enhancements
- referenceFS consolidates reads in the same remote file (#1063)
- localfs: add link/symlink/islink (#1059)
- asyncfs: make mirroring methods optional (#1054)
- local: info: provide st_ino and st_nlink from stat (#1053)
- arrow_hdfs replaces hdfs (#1051)
- Add read/write_text (#1047)
- Add pipe/cat to genericFS (#1038)
Fixes
- SSH write doesn't return number of bytes (#1072)
- wrap flush method for LocalFileOpened (#1070)
- localfs: fix support for pathlib/os.PathLike objects in rm (#1058)
- don't get_file remote FTP directory (#1056)
- fix zip write to remote (#1046)
- fix zip del following failed init (#1040)
Other
- add asynclocalfs to the registry (#1060)
- add DVCFileSystem to the registry (#1049)
- add downstream tests (#1037)
- Don't auto-close OpenFiles (#1035)
2022.8.2
--------
- don't close OpenFile on del (#1035)
2022.8.1
--------
- revert #1024 (#1029), with strciter requirements on OpenFile usage
2022.8.0
--------
Enhancements
- writable ZipFileSystem (#1017)
- make OpenFile behave like files and remove dynamic closer in .open() (#1024)
- use isal gunzip (#1008)
Fixes
- remove strip from _parent (#1022)
- disallow aiohttp prereleases (#1018)
- be sure to close cached file (#1016)
- async rm in reverse order (#1014)
- expose fileno in LocalFileOpener (#1010, #1005)
- remove temp files with simplecache writing (#1006)
- azure paths (#1003)
- copy dircache keys before iter
2022.7.1
--------
Fixes
- Remove fspath from LocalFileOpener (#1005)
- Revert 988 (#1003)
2022.7.0
--------
Enhancements
- added fsspec-xrootd implementation to registry (#1000)
- memory file not to copy bytes (#999)
- Filie details passed to FUSE (#972)
Fixes
- Return info for root path of archives (#996)
- arbitrary kwargs passed through in pipe_file (#993)
- special cases for host in URLs for azure (#988)
- unstrip protocol criterion (#980)
- HTTPFile serialisation (#973)
Other
- Show erroring path in FileNotFounds (#989)
- Reference file info without searching directory tree (#985)
- Truncate for local files (#975)
2022.5.0
--------
Enhancements
- mutable ReferenceFS (#958)
Fixes
- Make archive FSs not cachable (#966)
- glob fixes (#961)
- generic copy with unknown size (#959)
- zstd open (#956)
- empty archive file (#954)
- tar chaining (#950, 947)
- missing exceptions in mapper (#940)
Other
- update registry (#852)
- allow None cache (#942)
- mappers to remember init arguments (#939)
- cache docstrings (#933)
2022.03.0
---------
Enhancements
- tqdm example callback with simple methods (#931, 902)
- Allow empty root in get_mapper (#930)
- implement real info for reference FS (#919)
- list known implementations and compressions (#913)
Fixes
- git branch for testing git backend (#929)
- maintain mem FS's root (#926)
- kargs to FS in parquet module (#921)
- fix on_error in references (#917)
- tar ls consistency (#9114)
- pyarrow: don't decompress twice (#911)
- fix FUSE tests (#905)
2022.02.0
---------
Enhancements
- reference FS performance (#892, 900)
- directory/prefix FS (#745)
Fixes
- FUSE (#905, 891)
- iteration in threads (#893)
- OpenFiles slicing (#887)
Other
- drop py36 (#889, 901)
2022.01.0
---------
Fixes
- blocks cache metadata (#746)
- default SMB port (#853)
- caching fixes (#856, 855)
- explicit close for http files (#866)
- put_file to continue when no bytes (#869, 870)
Other
- temporary files location (#851, 871)
- async abstract methods (#858, 859, 860)
- md5 for FIPS (#872)
- remove deprecated pyarrow/distutils (#880, 881)
2021.11.1
---------
Enhancements
- allow compression for fs.open (#826)
- batch more async operations (#824)
- allow github backend for alternate URL (#815)
- speec up reference filesystem (#811)
Fixes
- fixes for parquet functionality (#821, 817)
- typos and docs (#839, 833, 816)
- local root (#829)
Other
- remove BlockSizeError for http (#830)
2021.11.0
---------
Enhancement
- parquet-specific module and cache type (#813, #806)
Fixes
- empty ranges (#802, 801, 803)
- doc typos (#791, 808)
- entrypoints processing (#784)
- cat in ZIP (#789)
Other
- move to fsspec org
- doc deps (#786, 791)
2021.10.1
---------
Fixes
- Removed inaccurate ``ZipFileSystem.cat()`` override so that the base
class' version is used (#789)
- fix entrypoint processing (#784)
- case where no blocks of a block-cache have yet been loaded (#801)
- don't fetch empty ranges (#802, 803)
Other
- simplify doc deps (#786, 791)
2021.10.0
---------
Fixes
- only close http connector if present (#779)
- hdfs strip protocol (#778)
- fix filecache with check_files (#772)
- put_file to use _parent (#771)
Other
- add kedro link (#781)
2021.09.0
---------
Enhancement
- http put from file-like (#764)
- implement webhdfs cp/rm_file (#762)
- multiple (and concurrent) cat_ranges (#744)
Fixes
- sphinx warnings (#769)
- lexists for links (#757)
- update versioneer (#750)
- hdfs updates (#749)
- propagate async timeout error (#746)
- fix local file seekable (#743)
- fix http isdir when does not exist (#741)
Other
- ocifs, arrow added (#754, #765)
- promote url_to_fs to top level (#753)
2021.08.1
---------
Enhancements
- HTTP get_file/put_file APIs now support callbacks (#731)
- New HTTP put_file method for transferring data to the remote server (chunked) (#731)
- Customizable HTTP client initializers (through passing ``get_client`` argument) (#731, #701)
- Support for various checksum / fingerprint headers in HTTP ``info()`` (#731)
- local implementation of rm_file (#736)
- local speed improvements (#711)
- sharing options in SMB (#706)
- streaming cat/get for ftp (#700)
Fixes
- check for remote directory when putting (#737)
- storage_option update handling (#734(
- await HTTP call before checking status (#726)
- ftp connect (#722)
- bytes conversion of times in mapper (#721)
- variable overwrite in WholeFileCache cat (#719)
- http file size again (#718)
- rm and create directories in ftp (#716, #703)
- list of files in async put (#713)
- bytes to dict in cat (#710)
2021.07.0
---------
Enhancements
- callbacks (#697)
2021.06.1
---------
Enhancements
- Introduce ``fsspec.asyn.fsspec_loop`` to temporarily switch to the fsspec loop. (#671)
- support list for local rm (#678)
Fixes
- error when local mkdir twice (#679)
- fix local info regression for pathlike (#667)
Other
- link to wandbfs (#664)
2021.06.0
---------
Enhancements
- Better testing and folder handling for Memory (#654)
- Negative indexes for cat_file (#653)
- optimize local file listing (#647)
Fixes
- FileNoteFound in http and range exception subclass (#649, 646)
- async timeouts (#643, 645)
- stringify path for pyarrow legacy (#630)
Other
- The ``fsspec.asyn.get_loop()`` will always return a loop of a selector policy (#658)
- add helper to construct Range headers for cat_file (#655)
2021.05.0
---------
Enhancements
- Enable listings cache for HTTP filesystem (#560)
- Fold ZipFileSystem and LibArchiveFileSystem into a generic implementation and
add new TarFileSystem (#561)
- Use throttling for the ``get``/``put`` methods of ``AsyncFileSystem`` (#629)
- rewrite for archive filesystems (#624)
- HTTP listings caching (#623)
Fixes
- gcsfs tests (#638)
- stringify_path for arrow (#630)
Other
- s3a:// alias
2021.04.0
---------
Major changes
- calendar versioning
Enhancements
- better link and size finding for HTTP (#610, %99)
- link following in Local (#608)
- ReferenceFileSystem dev (#606, #604, #602)
Fixes
- drop metadata dep (#605)
0.9.0
-----
Major Changes:
- avoid nested sync calls by copying code (#581, #586, docs #593)
- release again for py36 (#564, #575)
Enhancements:
- logging in mmap cacher, explicitly close files (#559)
- make LocalFileOpener an IOBase (#589)
- better reference file system (#568, #582, #584, #585)
- first-chunk cache (#580)
- sftp listdir (#571)
- http logging and fetch all (#551, #558)
- doc: entry points (#548)
Fixes:
- get_mapper for caching filesystems (#559)
- fix cross-device file move (#547)
- store paths without trailing "/" for DBFS (#557)
- errors that happen on ``_initiate_upload`` when closing the
``AbstractBufferedFile`` will now be propagated (#587)
- infer_compressions with upper case suffix ($595)
- file initialiser errors (#587)
- CI fix (#563)
- local file commit cross-device (#547)
Version 0.8.7
-------------
Fixes:
- fix error with pyarrow metadata for some pythons (#546)
Version 0.8.6
-------------
Features:
- Add dbfs:// support (#504, #514)
Enhancements
- don't import pyarrow (#503)
- update entry points syntax (#515)
- ci precommit hooks (#534)
Fixes:
- random appending of a directory within the filesystems ``find()`` method (#507, 537)
- fix git tests (#501)
- fix recursive memfs operations (#502)
- fix recursive/maxdepth for cp (#508)
- fix listings cache timeout (#513)
- big endian bytes tests (#519)
- docs syntax (#535, 524, 520, 542)
- transactions and reads (#533)
Version 0.8.5
-------------
Features:
- config system
- libarchive implementation
- add reference file system implementation
Version 0.8.4
-------------
Features:
- function ``can_be_local`` to see whether URL is compatible with ``open_local``
- concurrent cat with filecaches, if backend supports it
- jupyter FS
Fixes:
- dircache expiry after transaction
- blockcache garbage collection
- close for HDFS
- windows tests
- glob depth with "**"
Version 0.8.3
-------------
Features:
- error options for cat
- memory fs created time in detailed ``ls```
Fixes:
- duplicate directories could appear in MemoryFileSystem
- Added support for hat dollar lbrace rbrace regex character escapes in glob
- Fix blockcache (was doing unnecessary work)
- handle multibyte dtypes in readinto
- Fix missing kwargs in call to _copy in asyn
Other:
- Stop inheriting from pyarrow.filesystem for pyarrow>=2.0
- Raise low-level program friendly OSError.
- Guard against instance reuse in new processes
- Make hash_name a method on CachingFileSystem to make it easier to change.
- Use get_event_loop for py3.6 compatibility
Version 0.8.2
-------------
Fixes:
- More careful strip for caching
Version 0.8.1
-------------
Features:
- add sign to base class
- Allow calling of coroutines from normal code when running async
- Implement writing for cached many files
- Allow concurrent caching of remote files
- Add gdrive:// protocol
Fixes:
- Fix memfs with exact ls
- HTTPFileSystem requires requests and aiohttp in registry
Other:
- Allow http kwargs to clientSession
- Use extras_require in setup.py for optional dependencies
- Replacing md5 with sha256 for hash (CVE req)
- Test against Python 3.8, drop 3.5 testing
- add az alias for abfs
Version 0.8.0
-------------
Major release allowing async implementations with concurrent batch
operations.
Features:
- async filesystem spec, first applied to HTTP
- OpenFiles cContext for multiple files
- Document async, and ensure docstrings
- Make LocalFileOpener iterable
- handle smb:// protocol using smbprotocol package
- allow Path object in open
- simplecache write mode
Fixes:
- test_local: fix username not in home path
- Tighten cacheFS if dir deleted
- Fix race condition of lzma import when using threads
- properly rewind MemoryFile
- OpenFile newline in reduce
Other:
- Add aiobotocore to deps for s3fs check
- Set default clobber=True on impl register
- Use _get_kwargs_from_url when unchaining
- Add cache_type and cache_options to HTTPFileSystem constructor
Version 0.7.5
-------------
* async implemented for HTTP as prototype (read-only)
* write for simplecache
* added SMB (Samba, protocol >=2) implementation
Version 0.7.4
-------------
* panel-based GUI
0.7.3 series
------------
* added ``git`` and ``github`` interfaces
* added chained syntax for open, open_files and get_mapper
* adapt webHDFS for HttpFS
* added open_local
* added ``simplecache``, and compression to both file caches
Version 0.6.2
-------------
* Added ``adl`` and ``abfs`` protocols to the known implementations registry (:pr:`209`)
* Fixed issue with whole-file caching and implementations providing multiple protocols (:pr:`219`)
Version 0.6.1
-------------
* ``LocalFileSystem`` is now considered a filestore by pyarrow (:pr:`211`)
* Fixed bug in HDFS filesystem with ``cache_options`` (:pr:`202`)
* Fixed instance caching bug with multiple instances (:pr:`203`)
Version 0.6.0
-------------
* Fixed issues with filesystem instance caching. This was causing authorization errors
in downstream libraries like ``gcsfs`` and ``s3fs`` in multi-threaded code (:pr:`155`, :pr:`181`)
* Changed the default file caching strategy to :class:`fsspec.caching.ReadAheadCache` (:pr:`193`)
* Moved file caches to the new ``fsspec.caching`` module. They're still available from
their old location in ``fsspec.core``, but we recommend using the new location for new code (:pr:`195`)
* Added a new file caching strategy, :class:`fsspec.caching.BlockCache` for fetching and caching
file reads in blocks (:pr:`191`).
* Fixed equality checks for file system instance to return ``False`` when compared to objects
other than file systems (:pr:`192`)
* Fixed a bug in ``fsspec.FSMap.keys`` returning a generator, which was consumed upon iteration (:pr:`189`).
* Removed the magic addition of aliases in ``AbstractFileSystem.__init__``. Now alias methods are always
present (:pr:`177`)
* Deprecated passing ``trim`` to :class:`fsspec.spec.AbstractBufferedFile`. Pass it in ``storage_options`` instead (:pr:`188`)
* Improved handling of requests for :class:`fsspec.implementations.http.HTTPFileSystem` when the
HTTP server responds with an (incorrect) content-length of 0 (:pr:`163`)
* Added a ``detail=True`` parameter to :meth:`fsspec.spec.AbstractFileSystem.ls` (:pr:`168`)
* Fixed handling of UNC/DFS paths (:issue:`154`)
.. raw:: html
filesystem_spec-2025.3.2/docs/source/conf.py 0000664 0000000 0000000 00000012612 14772531734 0020711 0 ustar 00root root 0000000 0000000 # fsspec documentation build configuration file, created by
# sphinx-quickstart on Mon Jan 15 18:11:02 2018.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath("../.."))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.autosummary",
"sphinx.ext.extlinks",
"numpydoc",
"sphinx_design",
]
numpydoc_show_class_members = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ".rst"
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "fsspec"
copyright = "2018, Martin Durant"
author = "Martin Durant"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
import fsspec
version = fsspec.__version__
# The full version, including alpha/beta/rc tags.
release = fsspec.__version__
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
default_role = "py:obj"
autodoc_mock_imports = [
"aiohttp",
"dask",
"distributed",
"fuse",
"libarchive",
"panel",
"paramiko",
"pyarrow",
"pygit2",
"requests",
"smbprotocol",
"smbclient",
]
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: https://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
"**": [
"relations.html", # needs 'show_related': True theme option to display
"searchbox.html",
]
}
# Custom CSS file to override read the docs default CSS.
# Contains workaround for issue #790.
html_css_files = ["custom.css"]
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = "fsspecdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, "fsspec.tex", "fsspec Documentation", "Joseph Crail", "manual")
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "fsspec", "fsspec Documentation", [author], 1)]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"fsspec",
"fsspec Documentation",
author,
"fsspec",
"One line description of project.",
"Miscellaneous",
)
]
extlinks = {
"issue": ("https://github.com/fsspec/filesystem_spec/issues/%s", "GH#%s"),
"pr": ("https://github.com/fsspec/filesystem_spec/pull/%s", "GH#%s"),
}
filesystem_spec-2025.3.2/docs/source/copying.rst 0000664 0000000 0000000 00000025577 14772531734 0021632 0 ustar 00root root 0000000 0000000 Copying files and directories
=============================
This documents the expected behavior of the ``fsspec`` file and directory copying functions.
There are three functions of interest here: :meth:`~fsspec.spec.AbstractFileSystem.copy`,
:meth:`~fsspec.spec.AbstractFileSystem.get` and :meth:`~fsspec.spec.AbstractFileSystem.put`.
Each of these copies files and/or directories from a ``source`` to a ``target`` location.
If we refer to our filesystem of interest, derived from :class:`~fsspec.spec.AbstractFileSystem`,
as the remote filesystem (even though it may be local) then the difference between the three
functions is:
- :meth:`~fsspec.spec.AbstractFileSystem.copy` copies from a remote ``source`` to a remote ``target``
- :meth:`~fsspec.spec.AbstractFileSystem.get` copies from a remote ``source`` to a local ``target``
- :meth:`~fsspec.spec.AbstractFileSystem.put` copies from a local ``source`` to a remote ``target``
The ``source`` and ``target`` are the first two arguments passed to these functions, and each
consists of one or more files, directories and/or ``glob`` (wildcard) patterns.
The behavior of the ``fsspec`` copy functions is intended to be the same as that obtained using
POSIX command line ``cp`` but ``fsspec`` functions have extra functionality because:
- They support more than one ``target`` whereas command line ``cp`` is restricted to one.
- They can create new directories, either automatically or via the ``auto_mkdir=True`` keyword
argument, whereas command line ``cp`` only does this as part of a recursive copy.
Expected behavior
-----------------
There follows a comprehensive list of the expected behavior of the ``fsspec`` copying functions
that also forms the basis of a set of tests that all classes that derive from
:class:`~fsspec.spec.AbstractFileSystem` can be tested against to check that they conform.
For all scenarios the ``source`` filesystem contains the following directories and files::
📠source
├── 📄 file1
├── 📄 file2
└── 📠subdir
├── 📄 subfile1
├── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
and before each scenario the ``target`` directory exists and is empty unless otherwise noted::
📠target
All example code uses :meth:`~fsspec.spec.AbstractFileSystem.cp` which is an alias of
:meth:`~fsspec.spec.AbstractFileSystem.copy`; equivalent behavior is expected by
:meth:`~fsspec.spec.AbstractFileSystem.get` and :meth:`~fsspec.spec.AbstractFileSystem.put`.
Forward slashes are used for directory separators throughout.
1. Single source to single target
---------------------------------
.. dropdown:: 1a. File to existing directory
.. code-block:: python
cp("source/subdir/subfile1", "target/")
results in::
📠target
└── 📄 subfile1
The trailing slash on ``"target/"`` is optional but recommended as it explicitly indicates that
the target is a directory.
.. dropdown:: 1b. File to new directory
.. code-block:: python
cp("source/subdir/subfile1", "target/newdir/")
results in::
📠target
└── 📠newdir
└── 📄 subfile1
This fails if the ``target`` file system is not capable of creating the directory, for example
if it is write-only or if ``auto_mkdir=False``. There is no command line equivalent of this
scenario without an explicit ``mkdir`` to create the new directory.
The trailing slash is required on the new directory otherwise it is interpreted as a filename
which is a different scenario (1d. File to file in new directory).
.. dropdown:: 1c. File to file in existing directory
.. code-block:: python
cp("source/subdir/subfile1", "target/newfile")
results in::
📠target
└── 📄 newfile
The target cannot have a trailing slash as ``"newfile/"`` is interpreted as a new directory
which is a different scenario (1b. File to new directory).
.. dropdown:: 1d. File to file in new directory
.. code-block:: python
cp("source/subdir/subfile1", "target/newdir/newfile")
creates the new directory and copies the file into it::
📠target
└── 📠newdir
└── 📄 newfile
This fails if the ``target`` file system is not capable of creating the directory, for example
if it is write-only or if ``auto_mkdir=False``. There is no command line equivalent of this
scenario without an explicit ``mkdir`` to create the new directory.
If there is a trailing slash on the target ``target/newdir/newfile/`` then it is interpreted as
a new directory which is a different scenario (1b. File to new directory).
.. dropdown:: 1e. Directory to existing directory
.. code-block:: python
cp("source/subdir/", "target/", recursive=True)
results in::
📠target
├── 📄 subfile1
└── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
The ``recursive=True`` keyword argument is required otherwise the call does nothing. The depth
of recursion can be controlled using the ``maxdepth`` keyword argument, for example:
.. code-block:: python
cp("source/subdir/", "target/", recursive=True, maxdepth=1)
results in::
📠target
├── 📄 subfile1
└── 📄 subfile2
The trailing slash on ``"target/"`` is optional but recommended as it explicitly indicates that
the target is a directory.
If the trailing slash is omitted from ``"source/subdir"`` then the ``subdir`` is also copied,
not just its contents:
.. code-block:: python
cp("source/subdir", "target/", recursive=True)
results in::
📠target
└── 📠subdir
├── 📄 subfile1
└── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
Again the depth of recursion can be controlled using the ``maxdepth`` keyword argument, for
example:
.. code-block:: python
cp("source/subdir", "target/", recursive=True, maxdepth=1)
results in::
📠target
└── 📠subdir
├── 📄 subfile1
└── 📄 subfile2
.. dropdown:: 1f. Directory to new directory
.. code-block:: python
cp("source/subdir/", "target/newdir/", recursive=True)
results in::
📠target
└── 📠newdir
├── 📄 subfile1
└── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
Trailing slashes on both ``source`` and ``target`` are optional and do not affect the result.
They are recommended to explicitly indicate both are directories.
The ``recursive=True`` keyword argument is required otherwise the call does nothing. The depth
of recursion can be controlled using the ``maxdepth`` keyword argument, for example:
.. code-block:: python
cp("source/subdir/", "target/newdir/", recursive=True, maxdepth=1)
results in::
📠target
└── 📠newdir
├── 📄 subfile1
└── 📄 subfile2
.. dropdown:: 1g. Glob to existing directory
Nonrecursive
.. code-block:: python
cp("source/subdir/*", "target/")
copies files from the top-level directory only and results in::
📠target
├── 📄 subfile1
└── 📄 subfile2
Recursive
.. code-block:: python
cp("source/subdir/*", "target/", recursive=True)
results in::
📠target
├── 📄 subfile1
└── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
The trailing slash on ``"target/"`` is optional but recommended as it explicitly indicates that
the target is a directory.
The depth of recursion can be controlled by the ``maxdepth`` keyword argument, for example:
.. code-block:: python
cp("source/subdir/*", "target/", recursive=True, maxdepth=1)
results in::
📠target
├── 📄 subfile1
└── 📄 subfile2
.. dropdown:: 1h. Glob to new directory
Nonrecursive
.. code-block:: python
cp("source/subdir/*", "target/newdir/")
copies files from the top-level directory only and results in::
📠target
└── 📠newdir
├── 📄 subfile1
└── 📄 subfile2
Recursive
.. code-block:: python
cp("source/subdir/*", "target/newdir/", recursive=True)
results in::
📠target
└── 📠newdir
├── 📄 subfile1
└── 📄 subfile2
└── 📠nesteddir
└── 📄 nestedfile
The trailing slash on the ``target`` is optional but recommended as it explicitly indicates that
it is a directory.
The depth of recursion can be controlled by the ``maxdepth`` keyword argument, for example:
.. code-block:: python
cp("source/subdir/*", "target/newdir/", recursive=True, maxdepth=1)
results in::
📠target
└── 📠newdir
├── 📄 subfile1
└── 📄 subfile2
These calls fail if the ``target`` file system is not capable of creating the directory, for
example if it is write-only or if ``auto_mkdir=False``. There is no command line equivalent of
this scenario without an explicit ``mkdir`` to create the new directory.
2. Multiple source to single target
-----------------------------------
.. dropdown:: 2a. List of files to existing directory
.. code-block:: python
cp(["source/file1", "source/file2", "source/subdir/subfile1"], "target/")
results in::
📠target
├── 📄 file1
├── 📄 file2
└── 📄 subfile1
All of the files are copied to the target directory regardless of their relative paths in the
source filesystem. The trailing slash on the ``target`` is optional but recommended as it
explicitly indicates that it is a directory.
.. dropdown:: 2b. List of files to new directory
.. code-block:: python
cp(["source/file1", "source/file2", "source/subdir/subfile1"], "target/newdir/")
results in::
📠target
└── 📠newdir
├── 📄 file1
├── 📄 file2
└── 📄 subfile1
All of the files are copied to the target directory regardless of their relative paths in the
source filesystem.
The trailing slash is required on the new directory otherwise it is interpreted as a filename
rather than a directory.
.. raw:: html
filesystem_spec-2025.3.2/docs/source/developer.rst 0000664 0000000 0000000 00000011146 14772531734 0022132 0 ustar 00root root 0000000 0000000 Developing with fsspec
----------------------
Whereas the majority of the documentation describes the use of ``fsspec``
from the end-user's point of view, ``fsspec`` is used by many libraries
as the primary/only interface to file operations.
Clients of the library
~~~~~~~~~~~~~~~~~~~~~~
The most common entrance point for libraries which wish to rely on ``fsspec``
will be ``open`` or ``open_files``, as a way of generating an object compatible
with the python file interface. This actually produces an ``OpenFile`` instance,
which can be serialised across a network, and resources are only engaged when
entering a context, e.g.
.. code-block:: python
with fsspec.open("protocol://path", 'rb', param=value) as f:
process_file(f)
Note the backend-specific parameters that can be passed in this call.
In cases where the caller wants to control the context directly, they can use the
``open`` method of the ``OpenFile``, or get the filesystem object directly,
skipping the ``OpenFile`` route. In the latter case, text encoding and compression
are **not** handled for you. The file-like object can also be used as a context
manager, or the ``close()`` method must be called explicitly to release resources.
.. code-block:: python
# OpenFile route
of = fsspec.open("protocol://path", 'rb', param=value)
f = of.open()
process_file(f)
f.close()
# filesystem class route, context
fs = fsspec.filesystem("protocol", param=value)
with fs.open("path", "rb") as f:
process_file(f)
# filesystem class route, explicit close
fs = fsspec.filesystem("protocol", param=value)
f = fs.open("path", "rb")
process_file(f)
f.close()
Implementing a backend
~~~~~~~~~~~~~~~~~~~~~~
The class ``AbstractFileSystem`` provides a template of the methods
that a potential implementation should supply, as well as default
implementation of functionality that depends on these. Methods that
*could* be implemented are marked with ``NotImplementedError`` or
``pass`` (the latter specifically for directory operations that might
not be required for some backends where directories are emulated.
Note that not all of the methods need to be implemented: for example,
some implementations may be read-only, in which case things like ``pipe``,
``put``, ``touch``, ``rm``, etc., can be left as not-implemented
(or you might implement them and raise PermissionError, OSError 30 or some
read-only exception).
We may eventually refactor ``AbstractFileSystem`` to split the default implementation,
the set of methods that you might implement in a new backend, and the
documented end-user API.
In order to register a new backend with fsspec, new backends should register
themselves using the `entry_points `_
facility from setuptools. In particular, if you want to register a new
filesystem protocol ``myfs`` which is provided by the ``MyFS`` class in
the ``myfs`` package, add the following to your ``setup.py``:
.. code-block:: python
setuptools.setup(
...
entry_points={
'fsspec.specs': [
'myfs=myfs.MyFS',
],
},
...
)
Alternatively, the previous method of registering a new backend can be used.
That is, new backends must register themselves on import
(``register_implementation``) or post a PR to the ``fsspec`` repo
asking to be included in ``fsspec.registry.known_implementations``.
Implementing async
~~~~~~~~~~~~~~~~~~
Starting in version 0.7.5, we provide async operations for some methods
of some implementations. Async support in storage implementations is
optional. Special considerations are required for async
development, see :doc:`async`.
Developing the library
~~~~~~~~~~~~~~~~~~~~~~
The following can be used to install ``fsspec`` in development mode
.. code-block::
git clone https://github.com/fsspec/filesystem_spec
cd filesystem_spec
pip install -e .[dev,doc,test]
A number of additional dependencies are required to run tests in full, see "ci/environment*.yml", as
well as Docker. Most implementation-specific tests should skip if their requirements are
not met.
Development happens by submitting pull requests (PRs) on github.
This repo adheres to flake8 and black coding conventions. You may wish to install
commit hooks if you intend to make PRs, as linting is done as part of the CI.
Docs use sphinx and the numpy docstring style. Please add an entry to the changelog
along with any PR.
.. raw:: html
filesystem_spec-2025.3.2/docs/source/features.rst 0000664 0000000 0000000 00000046237 14772531734 0021774 0 ustar 00root root 0000000 0000000 Features of fsspec
==================
Here follows a brief description of some features of note of ``fsspec`` that provides to make
it an interesting project beyond some other file-system abstractions.
Serialisability
---------------
Coming out of the Dask stable, it was an important design decision that file-system instances
be serialisable, so that they could be created in one process (e.g., the client) and used in
other processes (typically the workers). These other processes may even be on other machines,
so in many cases they would need to be able to re-establish credentials, ideally without passing
sensitive tokens in the pickled binary data.
``fsspec`` instances, generally speaking, abide by these rules, do not include locks, files and other
thread-local material, and where possible, use local credentials (such as a token file)
for re-establishing sessions upon de-serialisation. (While making use of cached instances, where
they exist, see below).
``OpenFile`` instances
----------------------
The :func:`fsspec.core.OpenFile` class provides a convenient way to prescribe the manner to
open some file (local,
remote, in a compressed store, etc.) which is portable, and can also apply any compression and
text-mode to the file. These instances are also serialisable, because they do not contain any open
files.
The way to work with ``OpenFile`` s is to isolate interaction with in a ``with`` context. It is
the initiation of the context which actually does the work of creating file-like instances.
.. code-block:: python
of = fsspec.open(url, ...)
# of is just a place-holder
with of as f:
# f is now a real file-like object holding resources
f.read(...)
File Buffering and random access
--------------------------------
Most implementations create file objects which derive from ``fsspec.spec.AbstractBufferedFile``, and
have many behaviours in common. A subclass of ``AbstractBufferedFile`` provides
random access for the underlying file-like data (without downloading the whole thing).
This is a critical feature in the big-data access model, where each sub-task of an operation
may need on a small part of a file, and does not, therefore want to be forced into downloading the
whole thing.
These files offer buffering of both read and write operations, so that
communication with the remote resource is limited. The size of the buffer is generally configured
with the ``blocksize=`` kwarg at open time, although the implementation may have some minimum or
maximum sizes that need to be respected.
For reading, a number of buffering schemes are available, listed in ``fsspec.caching.caches``
(see :ref:`readbuffering`), or "none" for no buffering at all, e.g., for a simple read-ahead
buffer, you can do
.. code-block:: python
fs = fsspec.filesystem(...)
with fs.open(path, mode='rb', cache_type='readahead') as f:
use_for_something(f)
Transparent text-mode and compression
-------------------------------------
As mentioned above, the ``OpenFile`` class allows for the opening of files on a binary store,
which appear to be in text mode and/or allow for a compression/decompression layer between the
caller and the back-end storage system. The list of ``fsspec`` supported codec
can be retrieved using :func:`fsspec.available_compressions`.
From the user's point of view, this is achieved simply by passing arguments to
the :func:`fsspec.open_files` or :func:`fsspec.open` functions, and
thereafter happens transparently.
Key-value stores
----------------
File-systems are naturally like dict-like key-value mappings: each (string) path corresponds to some
binary data on the storage back-end. For some use-cases, it is very convenient to be able to
view some path within the file-system as a dict-like store, and the function :func:`fsspec.get_mapper`
gives a one-stop way to return such an object. This has become useful, for example, in the
context of the `zarr`_ project, which stores it array chunks in keys in any arbitrary mapping-like
object.
.. code-block:: python
mapper = fsspec.get_mapper('protocol://server/path', args)
list(mapper)
mapper[k] = b'some data'
.. _zarr: https://zarr.readthedocs.io/en/stable/
PyArrow integration
-------------------
`pyarrow`_ has its own internal idea of what a file-system is (``pyarrow.fs.FileSystem``),
and some functions, particularly the loading of parquet, require that the target be compatible.
As it happens, the design of the file-system interface in ``pyarrow`` *is* compatible with ``fsspec``
(this is not by accident).
At import time, ``fsspec`` checks for the existence of ``pyarrow``, and, if ``pyarrow < 2.0`` is
found, adds its base filesystem to the superclasses of the spec base-class.
For ``pyarrow >= 2.0``, ``fsspec`` file systems can simply be passed to ``pyarrow`` functions
that expect ``pyarrow`` filesystems, and ``pyarrow`` `will automatically wrap them
`_.
In this manner, all ``fsspec``-derived file-systems are also ``pyarrow`` file-systems, and can be used
by ``pyarrow`` functions.
.. _pyarrow: https://arrow.apache.org/docs/python/
Transactions
------------
``fsspec`` supports *transactions*, during which writing to files on a remote store are deferred
(typically put into a temporary location) until the transaction is over, whereupon the whole
transaction is finalised in a semi-atomic way, and all the files are moved/committed to their
final destination. The implementation of the details is file-system specific (and not all
support it yet), but the idea is,
that all files should get written or none, to mitigate against data corruption. The feature
can be used like
.. code-block:: python
fs = fsspec.filesystem(...)
with fs.transaction:
with fs.open('file1', 'wb') as f:
f.write(b'some data')
with fs.open('file2', 'wb') as f:
f.write(b'more data')
Here, files 1 and 2 do not get moved to the target location until the transaction context finishes.
If the context finishes due to an (uncaught) exception, then the files are discarded and the
file target locations untouched.
The class :func:`fsspec.spec.Transaction` allows for fine-tuning of the operation, and every
``fsspec`` instance has an instance of this as an attribute ``.transaction`` to give access.
Note that synchronising transactions across multiple instances, perhaps across a cluster,
is a harder problem to solve, and the implementation described here is only part of the solution.
Mount anything with FUSE
------------------------
Any path of any file-system can be mapped to a local directory using `fusepy `_ and
:func:`fsspec.fuse.run`. This feature is experimental, but basic file listing with
details, and read/write should generally be available to the extent that the
remote file-system provides enough information. Naturally, if a file-system is read-only,
then write operations will fail - but they will tend to fail late and with obscure
error messages such as "bad address".
Some specific quirks of some file-systems may cause confusion for FUSE. For example,
it is possible for a given path on s3 to be both a valid key (i.e., containing binary
data, like a file) and a valid prefix (i.e., can be listed to find subkeys, like a
directory). Since this breaks the assumptions of a normal file-system, it may not
be possible to reach all paths on the remote.
Instance Caching
----------------
In a file-system implementation class is marked as *cachable* (attribute ``.cachable``),
then its instances will
get stored in a class attribute, to enable quick look-up instead of needing to regenerate
potentially expensive connections and sessions. They key in the cache is a tokenisation of
the arguments to create the instance. The cache itself (attribute ``._cache``)
is currently a simple dict, but could in the future be LRU, or something more complicated,
to fine-tune instance lifetimes.
Since files can hold on to write caches and read buffers,
the instance cache may cause excessive memory usage in some situations; but normally, files'
``close`` methods will be called, discarding the data. Only when there is also an unfinalised transaction or
captured traceback might this be anticipated becoming a problem.
To disable instance caching, i.e., get a fresh instance which is not in the cache
even for a cachable class, pass ``skip_instance_cache=True``.
Listings Caching
----------------
For some implementations, getting file listings (i.e., ``ls`` and anything that
depends on it) is expensive. These implementations use dict-like instances of
:class:`fsspec.dircache.DirCache` to manage the listings.
The cache allows for time-based expiry of entries with the ``listings_expiry_time``
parameter, or LRU expiry with the ``max_paths`` parameter. These can be
set on any implementation instance that uses listings caching; or to skip the
caching altogether, use ``use_listings_cache=False``. That would be appropriate
when the target location is known to be volatile because it is being written
to from other sources.
When the ``fsspec`` instance writes to the backend, the method ``invalidate_cache``
is called, so that subsequent listing of the given paths will force a refresh. In
addition, some methods like ``ls`` have a ``refresh`` parameter to force fetching
the listing again.
URL chaining
------------
Some implementations proxy or otherwise make use of another filesystem implementation, such
as locally caching remote files, i.e., finding out what files exist using the remote implementation,
but actually opening the local copies upon access. Other examples include reading from a Dask worker
which can see file-systems the client cannot, and accessing a zip file which is being read from
another backend.
In such cases, you can specify the parameters exactly as specified in the implementation docstrings,
for the dask case something like
.. code-block:: python
of = fsspec.open('dask://bucket/key', target_protocol='s3', target_options={'anon': True})
As a shorthand, particularly useful where you have multiple hops, is to "chain" the URLs with
the special separator ``"::"``. The arguments to be passed on to each of the implementations referenced
are keyed by the protocol names included in the URL. Here is the equivalent to the line above:
.. code-block:: python
of = fsspec.open('dask::s3://bucket/key', s3={'anon': True})
A couple of more complicates cases:
.. code-block:: python
of = fsspec.open_files('zip://*.csv::simplecache::gcs://bucket/afile.zip',
simplecache={'cache_storage': '/stored/zip/files'},
gcs={'project': 'my-project'})
reads a zip-file from google, stores it locally, and gives access to the contained CSV files. Conversely,
.. code-block:: python
of = fsspec.open_files('simplecache::zip://*.csv::gcs://bucket/afile.zip',
simplecache={'cache_storage': '/stored/csv/files'},
gcs={'project': 'my-project'})
reads the same zip-file, but extracts the CSV files and stores them locally in the cache.
**For developers**: this "chaining" methods works by formatting the arguments passed to ``open_*``
into ``target_protocol`` (a simple string) and ``target_options`` (a dict) and also optionally
``fo`` (target path, if a specific file is required). In order for an implementation to chain
successfully like this, it must look for exactly those named arguments.
Caching Files Locally
---------------------
``fsspec`` allows you to access data on remote file systems, that is its purpose. However, such
access can often be rather slow compared to local storage, so as well as buffering (see above), the
option exists to copy files locally when you first access them, and thereafter to use the local data.
This local cache of data might be temporary (i.e., attached to the process and discarded when the
process ends) or at some specific location in your local storage.
Two mechanisms are provided, and both involve wrapping a ``target`` filesystem. The following example
creates a file-based cache.
.. code-block:: python
fs = fsspec.filesystem("filecache", target_protocol='s3', target_options={'anon': True},
cache_storage='/tmp/files/')
Each time you open a remote file on S3, it will first copy it to
a local temporary directory, and then all further access will use the local file. Since we specify
a particular local location, the files will persist and can be reused from future sessions, although
you can also set policies to have cached files expire after some time, or to check the remote file system
on each open, to see if the target file has changed since it was copied.
With the top-level functions ``open``, ``open_local`` and ``open_files``, you can use the
same set of kwargs as the example above, or you can chain the URL - the following would
be the equivalent
.. code-block:: python
of = fsspec.open("filecache::s3://bucket/key",
s3={'anon': True}, filecache={'cache_storage':'/tmp/files'})
With the "blockcache" variant, data is downloaded block-wise: only the specific parts of the remote file
which are accessed. This means that the local copy of the file might end up being much smaller than the
remote one, if only certain parts of it are required.
Whereas "filecache" works for all file system implementations, and provides a real local file for other
libraries to use, "blockcache" has restrictions: that you have a storage/OS combination which supports
sparse files, that the backend implementation uses files which derive ``from AbstractBufferedFile``,
and that the library you pass the resultant object to accepts generic python file-like objects. You
should not mix block- and file-caches in the same directory. "simplecache" is the same as "filecache",
except without the options for cache expiry and to check the original source - it can be used where the
target can be considered static, and particularly where a large number of target files are expected
(because no metadata is written to disc). Only "simplecache" is guaranteed thread/process-safe.
Remote Write Caching
--------------------
You can cache files to local files to send to remote using the "simplecache" protocol.
The following example demonstrates how this might look
.. code-block:: python
with fsspec.open('simplecache::s3://mybucket/myfile', 'wb',
s3={"profile": "writer"}) as f:
f.write(b"some data")
This will open a local file for writing, and when this file is closed, it will be uploaded
to the target URL, in this case on S3. The file-like object ``f`` can be passed to any
library expecting to write to a file. Note that we pass parameters to ``S3FileSystem`` using
the key ``"s3"``, the same as the name of the protocol.
File Selector (GUI)
-------------------
The module ``fsspec.gui`` contains a graphical file selector interface. It is built
using `panel`_, which must be installed in order to use the GUI. Upon instantiation,
you can provide the initial URL location (which can be returned to with the "ðŸ " button),
arguments and filters.
.. _panel: https://panel.holoviz.org/
.. image:: img/gui.png
Clicking on a directory will descend into it, and selecting a file will mark it as
the output of the interface. You can select any of the known protocols, but should
provide any required arguments in the "kwargs" box (as a dictionary) and any
absolute URL location before clicking "⇨" to go to that location. If using file filters,
they will appear as a list of checkboxes; only those file-endings selected will be
shown (or if none are selected, all files are shown).
The interface provides the following outputs:
#. ``.urlpath``: the currently selected item (if any)
#. ``.storage_options``: the value of the kwargs box
#. ``.fs``: the current filesystem instance
#. ``.open_file()``: produces an ``OpenFile`` instance for the current selection
Configuration
-------------
You can set default keyword arguments to pass to any fsspec backend by editing
config files, providing environment variables, or editing the contents of
the dictionary ``fsspec.config.conf``.
Files are stored in the directory pointed to by ``FSSPEC_CONFIG_DIR``,
``"~/.config/fsspec/`` by default. All \*.ini and \*.json files will be
loaded and parsed from their respective formats and fed into the config dict
at import time. For example, if there is a file "~/.config/fsspec/conf.json"
containing
.. code-block:: json
{"file": {"auto_mkdir": true}}
then any instance of the file system whose protocol is "file" (i.e.,
``LocalFileSystem``) with be passed the kwargs ``auto_mkdir=True``
**unless** the user supplies the kwarg themselves.
For instance:
.. code-block:: python
import fsspec
fs = fsspec.filesystem("file")
assert fs.auto_mkdir == True
fs = fsspec.filesystem("file", auto_mkdir=False)
assert fs.auto_mkdir == False
Obviously, you should only define default values that are appropriate for
a given file system implementation. INI files only support string values.
Alternatively, you can provide overrides with environment variables of the style
``FSSPEC_{protocol}=`` and
``FSSPEC_{protocol}_{kwargname}=``.
Configuration is determined in the following order, with later items winning:
#. ini and json files in the config directory (``FSSPEC_CONFIG_DIRECTORY`` or ``$HOME/.config/fsspec/``), sorted
lexically by filename
#. ``FSSPEC_{protocol}`` environment variables
#. ``FSSPEC_{protocol}_{kwargname}`` environment variables
#. the contents of ``fsspec.config.conf``, which can be edited at runtime
#. kwargs explicitly passed, whether with ``fsspec.open``, ``fsspec.filesystem``
or directly instantiating the implementation class.
Asynchronous
------------
Some implementations, those deriving from ``fsspec.asyn.AsyncFileSystem``, have
async/coroutine implementations of some file operations. The async methods have
names beginning with ``_``, and listed in the ``asyn`` module; synchronous or
blocking functions are automatically generated, which will operate via an
event loop in another thread, by default.
See :doc:`async` for modes of operation and how to implement such file systems.
Callbacks
---------
Some methods support a ``callback=`` argument, which is the entry point to
providing feedback on transfers to the user or any other logging service. This
feature is new and experimental and supported by varying amounts in the
backends.
See the docstrings in the callbacks module for further details.
``fsspec.callbacks.TqdmCallback`` can be used to display a progress bar using
tqdm.
.. raw:: html
Exclusive write
---------------
Some backends support writing to a file only if it doesn't already exist. This may be
implemented for the following methods:
- pipe_file (with argument ``mode=='create'``)
- put_file (with argument ``mode=='create'``)
- open (with argument ``mode="xb"``)
Since some writes will be achieved in blocks, the timing of when the check is done is
not defined - it may be at the start or at the completion of the operation, depending
on the backend.
If using exclusive mode on a file that does already exist, a ``FileExistsError`` will
be raised.
This feature is currently included on a trial basis and may change in the future.
filesystem_spec-2025.3.2/docs/source/img/ 0000775 0000000 0000000 00000000000 14772531734 0020164 5 ustar 00root root 0000000 0000000 filesystem_spec-2025.3.2/docs/source/img/gui.png 0000664 0000000 0000000 00000343455 14772531734 0021474 0 ustar 00root root 0000000 0000000 ‰PNG
IHDR Š 0 ŽiT¨ IiCCPICC Profile H‰•WTSÉž[RIhH ½‰"H—B‹ U°’@B‰1!ˆØ‘e\»ˆ€º¢«"Š®µb/‹bw-/TVÖÅ‚
•7) «ç½wÞÎÜùòÏ?ß_2wî zµ<©4Õ _R KˆeOKg‘ÐP/—²ããc ”þŸòæ:@Tý7×÷ãÿUB9 $âLœŸñ> ðR¾TV Ñêm§HUx"ÄF2 ÄRÎÖàRÎÔà*µMRâ i<ž, ݨgò³!îMˆÝ%± =2ÄA|O qÄÃòó§ª0´N™_ñdÿƒ3s“ÇËÄš\ÔBË¥y¼ÿg9þ·äç)|8ÀFÉ¢T9úÝÌÂ4ˆ»%™±qBüN,PÛCŒREЍd=jΗs`Í bw/,bsˆ#$y±1Z}f–8‚1\!h‘¸€›¤»P(OÔrÖʦ&Ä
à,‡ÛÈ“©ýªìO(r“ÙZþ›"!w€ÿu±()U3F-§ÄB¬1Sž›±ÁìŠEœØ™"A¿ÄþBId¨†›œ%‹HÐÚËòåùbEbn¬Wˆ’¢´<;ø