Welcome to pylocker V. 3.1.0 documentation!

PYthon LOCKER or pylocker package provides a pythonic way to create locking system that can be used for general purposes as well as for locking files upon reading or writing.

Old pylocker implementation is available in Locker module and it works by creating and updating a general locking file anytime a lock is requested with a certain pass. Lock pass is used to specify the user who sets the lock and who can have access to whatever is locked. Any user who knows the lock pass can access whatever is locked.

New pylocker implementation is a better and more advanced implementation that can be used to orchestrate locking and releasing string entities between threads and processes on the machine or between different machines as well. This new implementation can be found in ServerLocker module and is primarily implemented to distribute permissions between threads and processes to read and write system files.

Installation guide:

pylocker is a pure python 2.7.x and 3.x module that needs no particular installation. One can either fork pylocker’s github repository and copy the package to python’s site-packages or use pip as the following:

pip install pylocker

Package Functions:

pylocker.get_version()

Get pylocker’s version number.

pylocker.get_author()

Get pylocker’s author’s name.

pylocker.get_email()

Get pylocker’s author’s email.

pylocker.get_doc()

Get pylocker’s official online documentation link.

pylocker.get_repository()

Get pylocker’s official online repository link.

pylocker.get_pypi()

Get pylocker pypi’s link.

pylocker.ServerLocker.range(*args)
class pylocker.ServerLocker.ServerLocker(password, name=None, serverFile=True, defaultTimeout=20, maxLockTime=120, port=3000, allowServing=True, autoconnect=True, reconnect=False, connectTimeout=20, logger=False, blocking=False, debugMode=False)

Bases: object

Locker implementation that can be used to orchestrate locking and releasing string entities between threads and processes. ServerLocker is primarily implemented to distribute permissions between threads and processes to read and write system files. Once instanciated, if autoconnect is True, it will connect to the serving ServerLocker instance if existing otherwise if allowServing is True it will start serving itself and any other ServerLocker that is trying to connect. A serving locker will own and continuously update its fingerprint in ‘serverFile’ flat file. This file will contain the address and port of the serving locker but not its password. Any newly instaciated locker can automatically connect to the serving locker if it has access to read ‘serverFile’ serving locker fingerprint along with the correct password. Otherwise remote lockers can connect to the serving locker using the ip address and the password.

ServerLocker is serializable and hence pickle safe. But once loaded, user is responsible to call start upon locker to connect it to an existing serving locker or to have it serving if no other locker is serving.

Parameters
  1. password (string): password to serve or to connect to an existing serving locker

  2. name (None, string): user defined name

  3. serverFile (boolean, string): If True it will be set to ‘.pylocker.serverlocker’ in user’s home directory. If False, this instance will never serve. If string is given, it’s the path to the serving locker file if existing. When given whether as a string or as True, and if this instance is allowed to serve then whenever ‘start’ is called, this instance will try to become the serving locker unless another instance is serving already then it will try to connect.

  4. defaultTimeout (integer): default timeout value to acquire the lock. This value can be changed at any time using ‘set_default_timeout’

    method

  5. maxLockTime (integer): maximum allowed time for a lock to be acquired. This value will be used by serving lockers only. If this is too short, serving locker can update this value using ‘set_maximum_lock_time’ method

  6. port (int): server port number. If this port is not available an active search for an available port will be made

  7. allowServing (boolean): whether to allow this instance to serve if it has the chance to serve

  8. autoconnect (boolean): whether to try to connect upon initialization

  9. reconnect (boolean): whether to reconnect if connection drops. This is only safe for clients. NOT IMPLEMENTED AT THIS POINT

  10. connectTimeout (integer): timeout limit for connection to create successfully

  11. blocking (boolean): Whether to block execution upon connecting. This is needed if the instance is launched as a seperate service in a seperate process

  12. debugMode (boolean): launch locker in debug mode. debugMode can be turned on an off at anytime

from pylocker import ServerLocker

# create locker instance.
L = ServerLocker(password='server_password')

# try to acquire the lock a single file path
acquired, lockId = L.acquire_lock('my_path')

# check if acquired.
if acquired:
    print("Lock acquired for 'my_path'")
    print("In this if statement block I can safely do whatever I want with 'my_path' before releasing the lock")
else:
    print("Unable to acquire the lock. exit code %s"%lockId)
    print("keep this block empty as the lock was not acquired")

# now release the lock.
L.release_lock(lockId)

# try to acquire the lock for multiple files
acquired, lockId = L.acquire_lock(('path_to_file1', 'path_to_file2', 'path_to_directory'))

# check if acquired.
if acquired:
    print("Lock acquired for all of 'path_to_file1', 'path_to_file2' and  'path_to_directory'")
else:
    print("Unable to acquire the lock. exit code %s"%lockId)
    print("keep this block empty as the lock was not acquired")

# now release the lock.
L.release_lock(lockId)
property debugMode

debug mode flag

property name

locker user given name

property fingerprint

server locker fingerprint

property canServe

whether this instance can serve

property uniqueName

locker unique name

property serverFile

serverlocker server file

property pid

python process pid

property serverAddress

this instance machine address

property serverPort

this instance machine port

property serverUniqueName

server unique name

property serverName

server user given name

property serverMaxLockTime

server maximum allowed lock time

property address

locker instance machine address

property port

locker instance port

property password

locker password

property defaultTimeout

locker timeout in seconds

property maxLockTime

locker maximum locking time in seconds

property isServer

Whether this instance is being the lock server or a client

property isClient

Whether this instance is being the lock client to a running server

property messages

get list of received published messages

property lockedPaths

dictionary copy of currently acquired locks by all clients including self. This will return None if this locker is not the locker server. Keys are paths and values are a dictionary of locks id and client name and client unique name

property ownedLocks

dictionary copy of currently acquired locks by this locker. keys are locks unique ids and value are path list

property clientLocks

dictionary copy of currently acquired locks by all clients including self This will return None if this locker is not the locker server. keys are unique locks id and values are the list of paths

get_running_server_fingerprint(serverFile=None, raiseNotFound=False, raiseError=True)

get running server fingerprint information

Parameters
  1. serverFile (None, string): Path to the locker server file. If None is given, this instance serverFile will be used unless it’s not defined then an error will be raised

  2. raiseNotFound (boolean): Whether to raise an error if file was not found

  3. raiseError (boolean): Whether to raise an error upon reading and parsing the server file data

Returns
  1. uniqueName (string): the running server unique name

  2. timestamp (string): the running server last saved utc timestamp. this must be float castable

  3. address (string): the ip address of the running locker server

  4. port (string): the running server port number. This must be integer castable

  5. pid (int): the running server process identification number

N.B All returned information can be None if serverFile was not found or if an error parsing the information occured

set_maximum_lock_time(maxLockTime)

Set maximum allowed time for a lock to be acquired

Parameters
  1. maxLockTime (number): The maximum number of seconds allowed for any lock to be acquired

set_default_timeout(defaultTimeout)

Set default timeout to acquire a lock

Parameters
  1. maxLockTime (number): the default timeout in seconds for a lock to be acquired

set_server_file(serverFile)

set server file path

Parameters
  1. serverFile (boolean, string): If True it will be set to ‘.pylocker.serverlocker’ in user’s home directory. If False, this instance will never serve. If string is given, it’s the path to the serving locker file if existing. When given whether as a string or as True, and if this instance is allowed to serve then whenever ‘start’ is called, this instance will try to become the serving locker unless another instance is serving already then it will try to connect.

stop()

Stop server and client connections

start(address=None, port=None, password=None, ntrials=3)

start locker as server (if allowed) or a client in case there is running server. If both, address and port are None and no server is found in the server file, the this instance is going to be the server

Parameters
  1. address (None, string): ip address of server to connect to

  2. port (None, integer): port used by the server socket

  3. password (None, string): in case both address and port are not None, password is the server password. If None is given, the instanciation password is provided.

connect(address, port, password=None, ntrials=3)

connect to a serving locker whether it’s local or remote

Parameters
  1. address (string): serving locker ip address

  2. port (integer): serving locker connection port

  3. password (None, string): serving locker password. If None, this instance password will be used. If given, this instance password will be updated

  4. ntrials (integer): number of trials to connect

Returns
  1. result (boolean): whether connection was successful

reset(raiseError=False)

Used to recycle a disconnected client or serving locker that was shut down. Calling reset will insure resetting the state of the locker to a freshly new one. If Locker is still serving or still connected to a serving locker calling reset will be raise an error if raiseError is set to True.

Parameters
  1. raiseError (boolean): whether to raise error if recyling is not possible

Returns
  1. success (boolean): whether reset was successful

  2. error (None, string): reason why it failed.

remove_published_message(message, senders=None)

Remove published message

Parameters
  1. message (string): published message

  2. senders (None, list): list of senders of the message to remove publication from a particular sender. If None, published message from all senders will be removed

remove_message(*args, **kwargs)

alias to remove_published_message

has_message(message)

Get whether a message exists in list of received published messages

Parameters
  1. message (string): published message

Returns
  1. exist (boolean): whether message exist

get_message(message)

get message from received published messages

Parameters
  1. message (string): published message to get

Returns
  1. publication (None,m dict): the message publication dictionary. If message does not exit, None is returned

pop_message(message)

pop message from received published messages

Parameters
  1. message (string): published message to pop

Returns
  1. publication (None,m dict): the message publication dictionary. If message does not exit, None is returned

publish_message(message, receivers=None, timeout=None, toSelf=True, unique=False, replace=True)

publish a message to connected ServerLocker instances. This method makes pylocker.ServerLocker more than a locking server but a message passing server between threads and processes.

Parameters
  1. message (string): Any message to publish

  2. receivers (None, list): List of ServerLocker instances unique name to publish message to. If None, all connected ServerLocker instances to this server or to this client server will receive the message

  3. timeout (None, number): message timeout on the receiver side. If timeout exceeds, receiver will automatically remove the message from the list of publications

  4. toSelf (boolean): whether to also publish to self

  5. unique (boolean): whether message is allowed to exist in the list of remaining published message of every and each receiver seperately

  6. replace (boolean): whether to replace existing message at every and each receiver

Returns
  1. success (boolean): whether publishing was successful

  2. publicationUniqueId (str, int): The publication unique Id. If success is False, this become the integer failure code

    • 1: Connection to serving locker is unexpectedly not found.

    • 2: This ServerLocker instance is neither a client nor a server.

    • string: any other error message.

publish(*args, **kwargs)

alias to publish_message

acquire_lock(path, timeout=None, lockGlobal=False)

Acquire a lock for given path or list of paths. Each time the method a called a new lock will be acquired. This method is blocking, If lock on path is already acquired even from the same process the function will block. If lockGlobal is True, then acquiring the lock on a locked path by the same process won’t block and will return successfully by all threads trying to acquire it.

Parameters
  1. path (string, list): string path of list of strings to lock

  2. timeout (None, integer): timeout limit to acquire the lock. If None, defaultTimeout will be used

  3. lockGlobal (boolean): whether to make the acquire global to all threads of the same process. If True, until the lock expires, any thread of the same process can request the exact same lock path and acquire it without being blocked. THIS IS NOT IMPLEMENTED YET

Returns
  1. success (boolean): whether locking was successful

  2. lockUniqueId (str, int): The lock unique Id. If success is False, this become the integer failure code

    • 0: Lock was not successfully set before timeout.

    • 1: Connection to serving locker is unexpectedly not found.

    • 2: This ServerLocker instance is neither a client nor a server.

    • string: any other error message.

acquire(*args, **kwargs)

alias to acquire

release_lock(lockId)

release acquired lock given its id

Parameters
  1. lockId (string): Lock id as returned from acquire_lock method

Returns
  1. success (boolean): whether lock is released

  2. code (int, string): reason for graceful release or failing to release code.

    • 0: Lock is not found, therefore successfully released

    • 1: Lock is found owned by this locker and successfully released

    • 2: Connection to serving locker is unexpectedly not found.

    • 3: Locker is neither a client nor a server

    • string: any other error message

release(*args, **kwargs)

alias to release

class pylocker.ServerLocker.SingleLocker(*args, **kwds)

Bases: pylocker.ServerLocker.ServerLocker

This is singleton implementation of ServerLocker class. It’s better to create a single locker in a process.

class pylocker.ServerLocker.LockersFactory(*args, **kwds)

Bases: object

Locker factory is a helper implementation to help developping applications that require lockers cross referencing. This can create problems upon deserialization. Using lockers factory will solve that issue.

Locker taken from factory is not guaranteed to be started especially if it is instanciated by factory. User must call locker.start()

from pylocker import FACTORY

# create or get existing locker instance
# setting key as serverFile is good practice
# all other arguments will be used only if locker does not exist
# in factory and it must be created.
L0 = FACTORY(key='my_unique_locker_key', password='my_password', autoconnect=False)
L1 = FACTORY(key='my_unique_locker_key', password='another_password')

# verify that L0 is L1
print(L0 is L1)
print(L0.password, L1.password)
get(key, restart=False, regenerate=False, *args, **kwargs)

get locker instance given a key. If locker is not found by key then it’s created using *args and **kwargs and returned

Parameters
  1. key (string): locker key. Usually it should be the serverFile path

  2. restart (bool): If locker is not started or stopped then restart it

  3. regenerate (bool): If locker is not started or stopped the create a new instance

Returns
  1. locker (ServerLocker): the locker instance

pop(key, restart=False, regenerate=False, *args, **kwargs)

get locker instance by key and remove it from factory

If locker is not found by key then it’s created using *args and **kwargs and returned

Parameters
  1. key (string): locker key. Usually it should be the serverFile path

  2. restart (bool): If locker is not started or stopped then restart it

  3. regenerate (bool): If locker is not started or stopped the create a new instance

Returns
  1. locker (ServerLocker): the locker instance

class pylocker.Locker.Locker(filePath, lockPass, mode='ab', lockPath=None, timeout=60, wait=0, deadLock=120)

Bases: object

This is the old Locker implemenetation. It’s not removed for back compatibility. Using ServerLocker and SingleLocker is a much more robust implementation and is process, thread and OS safe. ServerLocker will also work between connected machines on the network. Locker can be used for general locking purposes and more specifically to lock a file from reading or writing to whoever that doesn’t have the lock pass.

Parameters
  1. filePath (None, path): The file that needs to be locked. When given and a lock is acquired, the file will be automatically opened for writing or reading depending on the given mode. If None is given, the locker can always be used for its general purpose as shown in the examples.

  2. lockPass (string): The locking pass.

  3. mode (string): This is file opening mode and it can be any of ‘r’,’r+’,’w’,’w+’,’a’,’a+’. If filePath is None, this argument will not be discarded.

  4. lockPath (None, path): The locking file path. If None is given the locking file will be automatically created to ‘.lock’ in the filePath directory. If filePath is None, ‘.lock’ will be created in the current working directory.

  5. timeout (number): The maximum delay or time allowed to successfully set the lock. When timeout is exhausted before successfully setting the lock, the lock ends up not acquired.

  6. wait (number): The time delay between each attempt to lock. By default it’s set to 0 to keeping the aquiring mechanism trying to acquire the lock without losing any time waiting. Setting wait to a higher value suchs as 0.05 seconds or higher can be very useful in special cases when many processes are trying to acquire the lock and one of them needs to hold it and release it at a high frequency or rate.

  7. deadLock (number): The time delay judging if the lock was left out mistakenly after a system crash or other unexpected reasons. Normally Locker is stable and takes care of not leaving any locking file hanging even it crashes or it is forced to stop by a user signal.

import uuid
from pylocker import Locker

#  create a unique lock pass. This can be any string.
lpass = str(uuid.uuid1())

# create locker instance.
FL = Locker(filePath=None, lockPass=lpass)

# try to acquire the lock
acquired, code = FL.acquire_lock()

# check if acquired.
if acquired:
    print("Lock acquired")
    print("In this if statement block I can do whatever I want before releasing the lock")
else:
    print("Unable to acquire the lock. exit code %s"%code)
    print("keep this block empty as the lock was not acquired")

# now release the lock.
FL.release_lock()

The above example can also be done using ‘with’ statement

import uuid
from pylocker import Locker

#  create a unique lock pass. This can be any string.
lpass = str(uuid.uuid1())

# create locker instance
FL = Locker(filePath=None, lockPass=lpass)

# acquire the lock
with FL as r:
    # r is a tuple of three items. the acquired result, the aquiring code and
    # a file descriptor fd. fd will always be None when filePath is None.
    # Otherwise fd can be a real opened file descriptor when acquired is
    # True. In this particular case fd is always None regardless whether
    # the lock was successfully acquired or not because filePath is None.
    acquired, code, fd  = r


    # check if acquired.
    if acquired:
        print("Lock acquired, in this if statement do whatever you want")
    else:
        print("Unable to acquire the lock. exit code %s"%code)

# no need to release anything because with statement takes care of that.

Now let’s lock a file using ‘with’ statement

import uuid
from pylocker import Locker

#  create a unique lock pass. This can be any string.
lpass = str(uuid.uuid1())

# create locker instance.
FL = Locker(filePath='myfile.txt', lockPass=lpass, mode='w')

# acquire the lock
with FL as r:
    # get the result
    acquired, code, fd  = r

    # check if acquired.
    if fd is not None:
        print(fd)
        fd.write("I have succesfuly acquired the lock !")

# no need to release anything or to close the file descriptor,
# with statement takes care of that. let's print fd and verify that.
print fd
property filePath

locker file path

property lockPass

locker pass

property lockPath

locker lock path

property timeout

locker timeout in seconds

property wait

locker wait in seconds

property deadLock

locker deadLock in seconds

set_mode(mode)

Set file opening mode.

Parameters
  1. mode (string): This is file opening mode and it can be any of r , r+ , w , w+ , a , a+ . If filePath is None, this argument will be discarded.

    • r : Open text file for reading. The stream is positioned at the beginning of the file.

    • r+ : Open for reading and writing. The stream is positioned at the beginning of the file.

    • w : Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.

    • w+ : Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.

    • a : Open for writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.

    • a+ : Open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.

set_file_path(filePath)

Set the file path that needs to be locked.

Parameters
  1. filePath (None, path): The file that needs to be locked. When given and a lock is acquired, the file will be automatically opened for writing or reading depending on the given mode. If None is given, the locker can always be used for its general purpose as shown in the examples.

set_lock_pass(lockPass)

Set the locking pass

Parameters
  1. lockPass (string): The locking pass.

set_lock_path(lockPath)

Set the managing lock file path.

Parameters
  1. lockPath (None, path): The locking file path. If None is given the locking file will be automatically created to ‘.lock’ in the filePath directory. If filePath is None, ‘.lock’ will be created in the current working directory.

set_timeout(timeout)

set the timeout limit.

Parameters
  1. timeout (number): The maximum delay or time allowed to successfully set the lock. When timeout is exhausted before successfully setting the lock, the lock ends up not acquired.

set_wait(wait)

set the waiting time.

Parameters
  1. wait (number): The time delay between each attempt to lock. By default it’s set to 0 to keeping the aquiring mechanism trying to acquire the lock without losing any time waiting. Setting wait to a higher value suchs as 0.05 seconds or higher can be very useful in special cases when many processes are trying to acquire the lock and one of them needs to hold it a release it at a higher frequency or rate.

set_dead_lock(deadLock)

Set the dead lock time.

Parameters
  1. deadLock (number): The time delay judging if the lock was left out mistakenly after a system crash or other unexpected reasons. Normally Locker is stable and takes care of not leaving any locking file hanging even it crashes or it is forced to stop by a user signal.

acquire_lock(verbose=False, raiseError=False)

Try to acquire the lock.

Parameters
  1. verbose (bool): Whether to be verbose about errors when encountered

  2. raiseError (bool): Whether to raise error exception when encountered

Returns
  1. result (boolean): Whether the lock is succesfully acquired.

  2. code (integer, Exception): Integer code indicating the reason how the lock was successfully set or unsuccessfully acquired. When setting the lock generates an error, this will be caught and returned in a message Exception code.

    • 0: Lock is successfully set for normal reasons, In this case result is True.

    • 1: Lock was already set, no need to set it again. In this case result is True.

    • 2: Old and forgotten lock is found and removed. New lock is successfully set, In this case result is True.

    • 3: Lock was not successfully set before timeout. In this case result is False.

    • Exception: Lock was not successfully set because of an unexpected error. The error is caught and returned in this Exception. In this case result is False.

release_lock(verbose=False, raiseError=False)

Release the lock when set and close file descriptor if opened.

Parameters
  1. verbose (bool): Whether to be verbose about errors when encountered

  2. raiseError (bool): Whether to raise error exception when encountered

Returns
  1. result (boolean): Whether the lock is succesfully released.

  2. code (integer, Exception): Integer code indicating the reason how the lock was successfully or unsuccessfully released. When releasing the lock generates an error, this will be caught and returned in a message Exception code.

    • 0: Lock is not found, therefore successfully released

    • 1: Lock is found empty, therefore successfully released

    • 2: Lock is found owned by this locker and successfully released

    • 3: Lock is found owned by this locker and successfully released and locked file descriptor was successfully closed

    • 4: Lock is found owned by another locker, this locker has no permission to release it. Therefore unsuccessfully released

    • Exception: Lock was not successfully released because of an unexpected error. The error is caught and returned in this Exception. In this case result is False.

acquire(*args, **kwargs)

Alias to acquire_lock

release(*args, **kwargs)

Alias to release_lock