Creating an extension

Once a filesystem has been implemented, it can be integrated with other applications and projects using PyFilesystem.

Naming Convention

For visibility in PyPi, we recommend that your package be prefixed with fs-. For instance if you have implemented an AwesomeFS PyFilesystem class, your packaged could be be named fs-awesome or fs-awesomefs.

Opener

In order for your filesystem to be opened with an FS URL you should define an Opener class.

Here’s an example taken from an Amazon S3 Filesystem:

"""Defines the S3FSOpener."""

__all__ = ['S3FSOpener']

from fs.opener import Opener, OpenerError

from ._s3fs import S3FS


class S3FSOpener(Opener):
    protocols = ['s3']

    def open_fs(self, fs_url, parse_result, writeable, create, cwd):
        bucket_name, _, dir_path = parse_result.resource.partition('/')
        if not bucket_name:
            raise OpenerError(
                "invalid bucket name in '{}'".format(fs_url)
            )
        s3fs = S3FS(
            bucket_name,
            dir_path=dir_path or '/',
            aws_access_key_id=parse_result.username or None,
            aws_secret_access_key=parse_result.password or None,
        )
        return s3fs

By convention this would be defined in opener.py.

To register the opener you will need to define an entry point in your setup.py. See below for an example.

The setup.py file

Refer to the setuptools documentation to see how to write a setup.py file. There are only a few things that should be kept in mind when creating a Pyfilesystem2 extension. Make sure that:

  • fs is in the install_requires list. You should reference the version number with the ~= operator which ensures that the install will get any bugfix releases of PyFilesystem but not any potentially breaking changes.
  • Ìf you created an opener, include it as an fs.opener entry point, using the name of the entry point as the protocol to be used.

Here is an minimal setup.py for our project:

from setuptools import setup
setup(
    name='fs-awesomefs',  # Name in PyPi
    author="You !",
    author_email="your.email@domain.ext",
    description="An awesome filesystem for pyfilesystem2 !",
    install_requires=[
        "fs~=2.0.5"
    ],
    entry_points = {
        'fs.opener': [
            'awe = awesomefs.opener:AwesomeFSOpener',
        ]
    },
    license="MY LICENSE",
    packages=['awesomefs'],
    version="X.Y.Z",
)

Good Practices

Keep track of your achievements! Add the following values to your __init__.py:

  • __version__ The version of the extension (we recommend following Semantic Versioning),
  • __author__ Your name(s).
  • __author_email__ Your email(s).
  • __license__ The module’s license.

Let us Know

Contact us to add your filesystem to the PyFilesystem Wiki.

Live Example

See fs.sshfs for a functioning PyFilesystem2 extension implementing a Pyfilesystem2 filesystem over SSH.