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.
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
password (string): password to serve or to connect to an existing serving locker
name (None, string): user defined name
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.
defaultTimeout (integer): default timeout value to acquire the lock. This value can be changed at any time using ‘set_default_timeout’
method
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
port (int): server port number. If this port is not available an active search for an available port will be made
allowServing (boolean): whether to allow this instance to serve if it has the chance to serve
autoconnect (boolean): whether to try to connect upon initialization
reconnect (boolean): whether to reconnect if connection drops. This is only safe for clients. NOT IMPLEMENTED AT THIS POINT
connectTimeout (integer): timeout limit for connection to create successfully
blocking (boolean): Whether to block execution upon connecting. This is needed if the instance is launched as a seperate service in a seperate process
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
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
raiseNotFound (boolean): Whether to raise an error if file was not found
raiseError (boolean): Whether to raise an error upon reading and parsing the server file data
- Returns
uniqueName (string): the running server unique name
timestamp (string): the running server last saved utc timestamp. this must be float castable
address (string): the ip address of the running locker server
port (string): the running server port number. This must be integer castable
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
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
maxLockTime (number): the default timeout in seconds for a lock to be acquired
-
set_server_file
(serverFile) set server file path
- Parameters
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
address (None, string): ip address of server to connect to
port (None, integer): port used by the server socket
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
address (string): serving locker ip address
port (integer): serving locker connection port
password (None, string): serving locker password. If None, this instance password will be used. If given, this instance password will be updated
ntrials (integer): number of trials to connect
- Returns
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
raiseError (boolean): whether to raise error if recyling is not possible
- Returns
success (boolean): whether reset was successful
error (None, string): reason why it failed.
-
remove_published_message
(message, senders=None) Remove published message
- Parameters
message (string): published message
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
message (string): published message
- Returns
exist (boolean): whether message exist
-
get_message
(message) get message from received published messages
- Parameters
message (string): published message to get
- Returns
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
message (string): published message to pop
- Returns
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
message (string): Any message to publish
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
timeout (None, number): message timeout on the receiver side. If timeout exceeds, receiver will automatically remove the message from the list of publications
toSelf (boolean): whether to also publish to self
unique (boolean): whether message is allowed to exist in the list of remaining published message of every and each receiver seperately
replace (boolean): whether to replace existing message at every and each receiver
- Returns
success (boolean): whether publishing was successful
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
path (string, list): string path of list of strings to lock
timeout (None, integer): timeout limit to acquire the lock. If None, defaultTimeout will be used
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
success (boolean): whether locking was successful
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
lockId (string): Lock id as returned from acquire_lock method
- Returns
success (boolean): whether lock is released
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
key (string): locker key. Usually it should be the serverFile path
restart (bool): If locker is not started or stopped then restart it
regenerate (bool): If locker is not started or stopped the create a new instance
- Returns
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
key (string): locker key. Usually it should be the serverFile path
restart (bool): If locker is not started or stopped then restart it
regenerate (bool): If locker is not started or stopped the create a new instance
- Returns
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
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.
lockPass (string): The locking pass.
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.
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.
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.
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.
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
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
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
lockPass (string): The locking pass.
-
set_lock_path
(lockPath) Set the managing lock file path.
- Parameters
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
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
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
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
verbose (bool): Whether to be verbose about errors when encountered
raiseError (bool): Whether to raise error exception when encountered
- Returns
result (boolean): Whether the lock is succesfully acquired.
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
verbose (bool): Whether to be verbose about errors when encountered
raiseError (bool): Whether to raise error exception when encountered
- Returns
result (boolean): Whether the lock is succesfully released.
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