Skip to content

Commit

Permalink
Improve documentation
Browse files Browse the repository at this point in the history
Signed-off-by: Bernát Gábor <[email protected]>
  • Loading branch information
gaborbernat committed Oct 2, 2021
1 parent 20f37d8 commit a4f87da
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 185 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ repos:
rev: v1.11.0
hooks:
- id: blacken-docs
additional_dependencies: [ black==20.8b1 ]
additional_dependencies: [ black==21.9b0 ]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:
Expand Down
118 changes: 2 additions & 116 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,124 +4,10 @@
[![Supported Python
versions](https://img.shields.io/pypi/pyversions/filelock.svg)](https://pypi.org/project/filelock/)
[![Documentation
status](https://readthedocs.org/projects/filelock/badge/?version=latest&style=flat-square)](https://filelock.readthedocs.io/en/latest/?badge=latest)
status](https://readthedocs.org/projects/py-filelock/badge/?version=latest&style=flat-square)](https://py-filelock.readthedocs.io/en/latest/?badge=latest)
[![Code style:
black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Downloads](https://pepy.tech/badge/filelock/month)](https://pepy.tech/project/filelock/month)
[![check](https://github.com/tox-dev/py-filelock/actions/workflows/check.yml/badge.svg)](https://github.com/tox-dev/py-filelock/actions/workflows/check.yml)

This package contains a single module, which implements a platform independent file lock in Python, which provides a
simple way of inter-process communication:

```Python
from filelock import Timeout, FileLock

lock = FileLock("high_ground.txt.lock")
with lock:
open("high_ground.txt", "a").write("You were the chosen one.")
```

**Don't use** a _FileLock_ to lock the file you want to write to, instead create a separate _.lock_ file as shown above.

![animated example](https://raw.githubusercontent.com/tox-dev/py-filelock/main/example/example.gif)

## Similar libraries

Perhaps you are looking for something like:

- the [pid](https://pypi.python.org/pypi/pid) 3rd party library,
- for Windows the [msvcrt](https://docs.python.org/3/library/msvcrt.html#msvcrt.locking) module in the standar library,
- for UNIX the [fcntl](https://docs.python.org/3/library/fcntl.html#fcntl.flock) module in the standard library.

## Installation

_py-filelock_ is available via PyPi:

```bash
python -m pip install filelock
```

## Documentation

The documentation for the API is available on [readthedocs.org](https://filelock.readthedocs.io/).

### Examples

A _FileLock_ is used to indicate another process of your application that a resource or working directory is currently
used. To do so, create a _FileLock_ first:

```python
from filelock import Timeout, FileLock

file_path = "high_ground.txt"
lock_path = "high_ground.txt.lock"

lock = FileLock(lock_path, timeout=1)
```

The lock object supports multiple ways for acquiring the lock, including the ones used to acquire standard Python thread
locks:

```python
with lock:
open(file_path, "a").write("Hello there!")

lock.acquire()
try:
open(file_path, "a").write("General Kenobi!")
finally:
lock.release()
```

The _acquire()_ method accepts also a _timeout_ parameter. If the lock cannot be acquired within _timeout_ seconds, a
_Timeout_ exception is raised:

```python
try:
with lock.acquire(timeout=10):
open(file_path, "a").write("I have a bad feeling about this.")
except Timeout:
print("Another instance of this application currently holds the lock.")
```

The lock objects are recursive locks, which means that once acquired, they will not block on successive lock requests:

```python
def cite1():
with lock:
open(file_path, "a").write("I hate it when he does that.")

def cite2():
with lock:
open(file_path, "a").write("You don't want to sell me death sticks.")

# The lock is acquired here.
with lock:
cite1()
cite2()

# And released here.
```

All log messages by this library are made using the _DEBUG_ level, under the `filelock` name. On how to control
displaying/hiding that please consult the
[logging documentation of the standard library](https://docs.python.org/3/howto/logging.html).

E.g. to hide these messages you can use `logging.getLogger("filelock").setLevel(logging.INFO)`.

## FileLock vs SoftFileLock

The _FileLock_ is platform dependent while the _SoftFileLock_ is not. Use the _FileLock_ if all instances of your
application are running on the same host and a _SoftFileLock_ otherwise.

The _SoftFileLock_ only watches the existence of the lock file. This makes it ultra portable, but also more prone to
dead locks if the application crashes. You can simply delete the lock file in such cases.

## Contributions

Contributions are always welcome, please make sure they pass all tests before creating a pull request. Never hesitate to
open a new issue, although it may take some time for me to respond.

## License

This package is [public domain](./LICENSE).
For more information checkout the [official documentation](https://py-filelock.readthedocs.io/en/latest/api.html).
6 changes: 4 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from filelock import __version__

company = "tox-dev"
name = "py-filelock"
name = "filelock"
version = ".".join(__version__.split(".")[:2])
release = __version__
copyright = f"2014-{date.today().year}, {company}"
Expand All @@ -30,10 +30,12 @@
today_fmt = "%B %d, %Y"

html_theme = "furo"
html_favicon = "logo.svg"
html_logo = "logo.svg"
html_theme_options = {
"navigation_with_keys": True,
}
html_title = "py-filelock"
html_title = name
html_last_updated_fmt = datetime.now().isoformat()

autoclass_content = "class"
Expand Down
File renamed without changes
142 changes: 133 additions & 9 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,138 @@
py-filelock
===========
filelock
========

This package contains a single module, which implements a platform independent file lock in Python, which provides a
simple way of inter-process communication:

.. code-block:: python
from filelock import Timeout, FileLock
lock = FileLock("high_ground.txt.lock")
with lock:
open("high_ground.txt", "a").write("You were the chosen one.")
**Don't use** a :class:`FileLock <filelock.FileLock>` to lock the file you want to write to, instead create a separate
``.lock`` file as shown above.

.. image:: example.gif
:alt: Example gif


Similar libraries
-----------------

Perhaps you are looking for something like:

- the `pid <https://pypi.python.org/pypi/pid>`_ 3rd party library,
- for Windows the `msvcrt <https://docs.python.org/3/library/msvcrt.html#msvcrt.locking>`_ module in the standard
library,
- for UNIX the `fcntl <https://docs.python.org/3/library/fcntl.html#fcntl.flock>`_ module in the standard library.

Installation
------------

``filelock`` is available via PyPi, so you can pip install it:

.. code-block:: bash
python -m pip install filelock
Tutorial
--------

### Examples

A :class:`FileLock <filelock.FileLock>` is used to indicate another process of your application that a resource or
working directory is currently used. To do so, create a :class:`FileLock <filelock.FileLock>` first:

.. code-block:: python
from filelock import Timeout, FileLock
file_path = "high_ground.txt"
lock_path = "high_ground.txt.lock"
lock = FileLock(lock_path, timeout=1)
The lock object supports multiple ways for acquiring the lock, including the ones used to acquire standard Python thread
locks:

.. code-block:: python
with lock:
open(file_path, "a").write("Hello there!")
lock.acquire()
try:
open(file_path, "a").write("General Kenobi!")
finally:
lock.release()
The :meth:`acquire <filelock.BaseFileLock.acquire>` method accepts also a ``timeout`` parameter. If the lock cannot be
acquired within ``timeout`` seconds, a :class:`Timeout <filelock.Timeout>` exception is raised:

.. code-block:: python
try:
with lock.acquire(timeout=10):
open(file_path, "a").write("I have a bad feeling about this.")
except Timeout:
print("Another instance of this application currently holds the lock.")
The lock objects are recursive locks, which means that once acquired, they will not block on successive lock requests:

.. code-block:: python
def cite1():
with lock:
open(file_path, "a").write("I hate it when he does that.")
def cite2():
with lock:
open(file_path, "a").write("You don't want to sell me death sticks.")
# The lock is acquired here.
with lock:
cite1()
cite2()
# And released here.
Logging
-------
All log messages by this library are made using the ``DEBUG_ level``, under the ``filelock`` name. On how to control
displaying/hiding that please consult the
`logging documentation of the standard library <https://docs.python.org/3/howto/logging.html>`_. E.g. to hide these
messages you can use:

.. code-block:: python
logging.getLogger("filelock").setLevel(logging.INFO)
FileLock vs SoftFileLock
------------------------

The :class:`FileLock <filelock.FileLock>` is platform dependent while the :class:`SoftFileLock <filelock.SoftFileLock>`
is not. Use the :class:`FileLock <filelock.FileLock>` if all instances of your application are running on the same host
and a :class:`SoftFileLock <filelock.SoftFileLock>` otherwise.

The :class:`SoftFileLock <filelock.SoftFileLock>` only watches the existence of the lock file. This makes it ultra
portable, but also more prone to dead locks if the application crashes. You can simply delete the lock file in such
cases.

Contributions and issues
------------------------

Contributions are always welcome, please make sure they pass all tests before creating a pull request. This module is
hosted on `GitHub <https://github.com/tox-dev/py-filelock>`_. If you have any questions or suggestions, don't hesitate
to open a new issue 😊. There's no bad question, just a missed opportunity to learn more.

.. toctree::
:hidden:

self
api
license

GitHub
------

This module is hosted on
`GitHub <https://github.com/tox-dev/py-filelock>`_. If you have any
questions or suggestions, don't hesitate to open a new issue :).
9 changes: 9 additions & 0 deletions docs/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 0 additions & 12 deletions example/example.py

This file was deleted.

Binary file removed example/example_sm.gif
Binary file not shown.
Binary file removed example/pic0.png
Binary file not shown.
Binary file removed example/pic1.png
Binary file not shown.
Binary file removed example/pic2.png
Binary file not shown.
Binary file removed example/pic3.png
Binary file not shown.
Binary file removed example/pic4.png
Binary file not shown.
Binary file removed example/pic5.png
Binary file not shown.
Binary file removed example/pic6.png
Binary file not shown.
34 changes: 21 additions & 13 deletions src/filelock/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"""
A platform independent file lock that supports the with-statement.
.. autodata:: filelock.__version__
:no-value:
"""
import sys
import warnings
Expand All @@ -9,29 +13,33 @@
from ._soft import SoftFileLock
from ._unix import UnixFileLock, has_fcntl
from ._windows import WindowsFileLock
from .version import version as __version__
from .version import version

#: version of the project as a string
__version__ = version

#: Alias for the lock, which should be used for the current platform. On Windows, this is an alias for
# :class:`WindowsFileLock`, on Unix for :class:`UnixFileLock` and otherwise for :class:`SoftFileLock`.
FileLock = None

if sys.platform == "win32":
FileLock = WindowsFileLock
_FileLock = WindowsFileLock
elif has_fcntl:
FileLock = UnixFileLock
_FileLock = UnixFileLock
else:
FileLock = SoftFileLock

_FileLock = SoftFileLock
if warnings is not None:
warnings.warn("only soft file lock is available")

#: Alias for the lock, which should be used for the current platform. On Windows, this is an alias for
# :class:`WindowsFileLock`, on Unix for :class:`UnixFileLock` and otherwise for :class:`SoftFileLock`.
FileLock = _FileLock


__all__ = [
"Timeout",
"BaseFileLock",
"__version__",
"FileLock",
"SoftFileLock",
"WindowsFileLock",
"UnixFileLock",
"SoftFileLock",
"FileLock",
"BaseFileLock",
"Timeout",
"AcquireReturnProxy",
"__version__",
]
Loading

0 comments on commit a4f87da

Please sign in to comment.