Quickstart

This page gets you from an empty environment to a working file lock. For choosing between the different lock classes, see Lock Types. For platform-specific behaviour (advisory vs. mandatory locking, msvcrt vs. pywin32, NFS caveats), see Platform Behaviour.

Installation

pip install portalocker

Two optional extras pull in dependencies only some users need:

pip install "portalocker[redis]"
pip install "portalocker[win32]"

Install redis when you use portalocker.RedisLock for cross-machine locking. Install win32 on Windows when you need a shared (LockFlags.SHARED) lock; exclusive locks work on Windows without it.

Your first lock

portalocker.Lock opens a file, locks it, and hands you the filehandle:

>>> import portalocker
>>> with portalocker.Lock('example.lock', 'w', timeout=1) as fh:
...     _ = fh.write('hello, portalocker')

The lock is released automatically when the with block exits. If another process is already holding it, portalocker.Lock retries until timeout seconds pass, then raises AlreadyLocked.

Reading and writing under a lock

The same class works for reading; open in a read mode instead:

>>> with portalocker.Lock('example.lock', 'r', timeout=1) as fh:
...     print(fh.read())
hello, portalocker

Use a mode with both + to read and write through the same lock:

>>> with portalocker.Lock('example.lock', 'r+', timeout=1) as fh:
...     data = fh.read()
...     _ = fh.seek(0)
...     _ = fh.write(data.upper())
>>> with portalocker.Lock('example.lock', 'r', timeout=1) as fh:
...     print(fh.read())
HELLO, PORTALOCKER

Flushing on networked filesystems

On some networked filesystems, another client may not see your writes until they are forced out of buffers. Call flush() and os.fsync before the lock is released:

>>> import os
>>> with portalocker.Lock('some_file', 'w+', timeout=60) as fh:
...     _ = fh.write('some data')
...     fh.flush()
...     os.fsync(fh.fileno())