shylock


Nameshylock JSON
Version 1.2.1 PyPI version JSON
download
home_pagehttps://github.com/lietu/shylock/
SummaryDistributed locks in Python, similar to https://github.com/vaidik/sherlock - also with asyncio support
upload_time2023-02-05 18:13:34
maintainer
docs_urlNone
authorJanne Enberg
requires_python>=3.7,<4.0
licenseBSD-3-Clause
keywords distributed locking lock asyncio
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Flietu%2Fshylock.svg?type=shield
    :target: https://app.fossa.io/projects/git%2Bgithub.com%2Flietu%2Fshylock?ref=badge_shield

.. image:: https://img.shields.io/github/actions/workflow/status/lietu/shylock/publish.yaml
    :target: https://github.com/lietu/shylock/actions/workflows/publish.yaml

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black

.. image:: https://codecov.io/gh/lietu/shylock/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/lietu/shylock

.. image:: https://sonarcloud.io/api/project_badges/measure?project=lietu_shylock&metric=alert_status
    :target: https://sonarcloud.io/dashboard?id=lietu_shylock

.. image:: https://img.shields.io/github/issues/lietu/shylock
    :target: https://github.com/lietu/shylock/issues
    :alt: GitHub issues

.. image:: https://img.shields.io/pypi/dm/shylock
    :target: https://pypi.org/project/shylock/
    :alt: PyPI - Downloads

.. image:: https://img.shields.io/pypi/v/shylock
    :target: https://pypi.org/project/shylock/
    :alt: PyPI

.. image:: https://img.shields.io/pypi/pyversions/shylock
    :target: https://pypi.org/project/shylock/
    :alt: PyPI - Python Version

.. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
    :target: https://opensource.org/licenses/BSD-3-Clause

Distributed locks on Python, with asyncio support


What is this?
=============

Locks are required when you have a distributed system (like any API) and you want to ensure consistency for your data and prevent race conditions. There are a lot of ways to implement them, and this library aims to provide easy access to some of the better ways.

The library is written primarily for use with asyncio code, but also supports normal synchronous usage.

Currently supported backends:

- MongoDB (using unique indexes + ttl indexes for consistency and safety)
- ArangoDB (using unique indexes + ttl indexes for consistency and safety)

Can be extended for other storage systems pretty easily.

License
-------

Licensing is important. This project itself uses BSD 3-clause license, but e.g. Mongodb Motor library and other such libraries used by it may have their own licenses.

For more information check the `LICENSE <https://github.com/lietu/shylock/blob/master/LICENSE>`_ -file.


Getting started
===============

Add ``shylock`` to your project via pip / pipenv / poetry

.. code-block:: bash

    # MongoDB asyncio
    pip install shylock[motor]
    # MongoDB
    pip install shylock[pymongo]
    # ArangoDB asyncio
    pip install shylock[aioarangodb]
    # ArangoDB
    pip install shylock[python-arango]

For most easy usage, you should in your application startup logic configure the default backend for Shylock to use, and then use the ``AsyncLock`` class to handle your locking needs.

.. code-block:: python

    from motor.motor_asyncio import AsyncIOMotorClient

    from shylock import configure, AsyncLock as Lock, ShylockMotorAsyncIOBackend

    CONNECTION_STRING = "mongodb://your-connection-string"

    client = AsyncIOMotorClient(CONNECTION_STRING)
    configure(await ShylockMotorAsyncIOBackend.create(client, "projectdb"))

    async def use_lock():
        async with Lock("my-lock"):
            # The lock is now acquired, and will be automatically released
            do_something()

    async def another_lock_use():
        lock = Lock("my-lock")
        try:
            await lock.acquire()
            do_something()
        finally:
             await lock.release()

    async def time_sensitive_code():
        lock = Lock("my-lock")
        try:
            locked = await lock.acquire(block=False)
            if locked:
                do_something()
        finally:
             if locked:
                 await lock.release()

Or the ``Lock`` class for code where ``asyncio`` support isn't required

.. code-block:: python

    from pymongo import MongoClient

    from shylock import configure, Lock, ShylockPymongoBackend

    CONNECTION_STRING = "mongodb://your-connection-string"

    client = MongoClient(CONNECTION_STRING)
    configure(ShylockPymongoBackend.create(client, "projectdb"))

    def use_lock():
        with Lock("my-lock"):
            # The lock is now acquired, and will be automatically released
            do_something()

    def another_lock_use():
        lock = Lock("my-lock")
        try:
            lock.acquire()
            do_something()
        finally:
             lock.release()

    def time_sensitive_code():
        lock = Lock("my-lock")
        try:
            locked = lock.acquire(block=False)
            if locked:
                do_something()
        finally:
             if locked:
                 lock.release()

You can also check out the `examples <https://github.com/lietu/shylock/tree/master/examples/>`_, which also show how to use Shylock with ArangoDB.


Contributing
============

This project is run on GitHub using the issue tracking and pull requests here. If you want to contribute, feel free to `submit issues <https://github.com/lietu/shylock/issues>`_ (incl. feature requests) or PRs here.

To test changes locally ``python setup.py develop`` is a good way to run this, and you can ``python setup.py develop --uninstall`` afterwards (you might want to also use the ``--user`` flag).

.. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Flietu%2Fshylock.svg?type=large
    :target: https://app.fossa.io/projects/git%2Bgithub.com%2Flietu%2Fshylock?ref=badge_shield


Financial support
=================

This project has been made possible thanks to `Cocreators <https://cocreators.ee>`_ and `Lietu <https://lietu.net>`_. You can help us continue our open source work by supporting us on `Buy me a coffee <https://www.buymeacoffee.com/cocreators>`_.

.. image:: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png
   :target: https://www.buymeacoffee.com/cocreators

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/lietu/shylock/",
    "name": "shylock",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7,<4.0",
    "maintainer_email": "",
    "keywords": "distributed,locking,lock,asyncio",
    "author": "Janne Enberg",
    "author_email": "janne.enberg@lietu.net",
    "download_url": "https://files.pythonhosted.org/packages/23/69/79c28d6fa6751f85080432ac184d1588d5a4ca1ff898ee776614f8d99dc9/shylock-1.2.1.tar.gz",
    "platform": null,
    "description": ".. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Flietu%2Fshylock.svg?type=shield\n    :target: https://app.fossa.io/projects/git%2Bgithub.com%2Flietu%2Fshylock?ref=badge_shield\n\n.. image:: https://img.shields.io/github/actions/workflow/status/lietu/shylock/publish.yaml\n    :target: https://github.com/lietu/shylock/actions/workflows/publish.yaml\n\n.. image:: https://img.shields.io/badge/code%20style-black-000000.svg\n    :target: https://github.com/psf/black\n\n.. image:: https://codecov.io/gh/lietu/shylock/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/lietu/shylock\n\n.. image:: https://sonarcloud.io/api/project_badges/measure?project=lietu_shylock&metric=alert_status\n    :target: https://sonarcloud.io/dashboard?id=lietu_shylock\n\n.. image:: https://img.shields.io/github/issues/lietu/shylock\n    :target: https://github.com/lietu/shylock/issues\n    :alt: GitHub issues\n\n.. image:: https://img.shields.io/pypi/dm/shylock\n    :target: https://pypi.org/project/shylock/\n    :alt: PyPI - Downloads\n\n.. image:: https://img.shields.io/pypi/v/shylock\n    :target: https://pypi.org/project/shylock/\n    :alt: PyPI\n\n.. image:: https://img.shields.io/pypi/pyversions/shylock\n    :target: https://pypi.org/project/shylock/\n    :alt: PyPI - Python Version\n\n.. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg\n    :target: https://opensource.org/licenses/BSD-3-Clause\n\nDistributed locks on Python, with asyncio support\n\n\nWhat is this?\n=============\n\nLocks are required when you have a distributed system (like any API) and you want to ensure consistency for your data and prevent race conditions. There are a lot of ways to implement them, and this library aims to provide easy access to some of the better ways.\n\nThe library is written primarily for use with asyncio code, but also supports normal synchronous usage.\n\nCurrently supported backends:\n\n- MongoDB (using unique indexes + ttl indexes for consistency and safety)\n- ArangoDB (using unique indexes + ttl indexes for consistency and safety)\n\nCan be extended for other storage systems pretty easily.\n\nLicense\n-------\n\nLicensing is important. This project itself uses BSD 3-clause license, but e.g. Mongodb Motor library and other such libraries used by it may have their own licenses.\n\nFor more information check the `LICENSE <https://github.com/lietu/shylock/blob/master/LICENSE>`_ -file.\n\n\nGetting started\n===============\n\nAdd ``shylock`` to your project via pip / pipenv / poetry\n\n.. code-block:: bash\n\n    # MongoDB asyncio\n    pip install shylock[motor]\n    # MongoDB\n    pip install shylock[pymongo]\n    # ArangoDB asyncio\n    pip install shylock[aioarangodb]\n    # ArangoDB\n    pip install shylock[python-arango]\n\nFor most easy usage, you should in your application startup logic configure the default backend for Shylock to use, and then use the ``AsyncLock`` class to handle your locking needs.\n\n.. code-block:: python\n\n    from motor.motor_asyncio import AsyncIOMotorClient\n\n    from shylock import configure, AsyncLock as Lock, ShylockMotorAsyncIOBackend\n\n    CONNECTION_STRING = \"mongodb://your-connection-string\"\n\n    client = AsyncIOMotorClient(CONNECTION_STRING)\n    configure(await ShylockMotorAsyncIOBackend.create(client, \"projectdb\"))\n\n    async def use_lock():\n        async with Lock(\"my-lock\"):\n            # The lock is now acquired, and will be automatically released\n            do_something()\n\n    async def another_lock_use():\n        lock = Lock(\"my-lock\")\n        try:\n            await lock.acquire()\n            do_something()\n        finally:\n             await lock.release()\n\n    async def time_sensitive_code():\n        lock = Lock(\"my-lock\")\n        try:\n            locked = await lock.acquire(block=False)\n            if locked:\n                do_something()\n        finally:\n             if locked:\n                 await lock.release()\n\nOr the ``Lock`` class for code where ``asyncio`` support isn't required\n\n.. code-block:: python\n\n    from pymongo import MongoClient\n\n    from shylock import configure, Lock, ShylockPymongoBackend\n\n    CONNECTION_STRING = \"mongodb://your-connection-string\"\n\n    client = MongoClient(CONNECTION_STRING)\n    configure(ShylockPymongoBackend.create(client, \"projectdb\"))\n\n    def use_lock():\n        with Lock(\"my-lock\"):\n            # The lock is now acquired, and will be automatically released\n            do_something()\n\n    def another_lock_use():\n        lock = Lock(\"my-lock\")\n        try:\n            lock.acquire()\n            do_something()\n        finally:\n             lock.release()\n\n    def time_sensitive_code():\n        lock = Lock(\"my-lock\")\n        try:\n            locked = lock.acquire(block=False)\n            if locked:\n                do_something()\n        finally:\n             if locked:\n                 lock.release()\n\nYou can also check out the `examples <https://github.com/lietu/shylock/tree/master/examples/>`_, which also show how to use Shylock with ArangoDB.\n\n\nContributing\n============\n\nThis project is run on GitHub using the issue tracking and pull requests here. If you want to contribute, feel free to `submit issues <https://github.com/lietu/shylock/issues>`_ (incl. feature requests) or PRs here.\n\nTo test changes locally ``python setup.py develop`` is a good way to run this, and you can ``python setup.py develop --uninstall`` afterwards (you might want to also use the ``--user`` flag).\n\n.. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Flietu%2Fshylock.svg?type=large\n    :target: https://app.fossa.io/projects/git%2Bgithub.com%2Flietu%2Fshylock?ref=badge_shield\n\n\nFinancial support\n=================\n\nThis project has been made possible thanks to `Cocreators <https://cocreators.ee>`_ and `Lietu <https://lietu.net>`_. You can help us continue our open source work by supporting us on `Buy me a coffee <https://www.buymeacoffee.com/cocreators>`_.\n\n.. image:: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\n   :target: https://www.buymeacoffee.com/cocreators\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "Distributed locks in Python, similar to https://github.com/vaidik/sherlock - also with asyncio support",
    "version": "1.2.1",
    "split_keywords": [
        "distributed",
        "locking",
        "lock",
        "asyncio"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "13da27d32bbd54f9be57db54a9ca3c7c4f26f5840fc804b6f51275c07d73de8f",
                "md5": "05b917c8b1011cdd5c35d2c8060826eb",
                "sha256": "3e717172939f6a5fb9559ec7b77137250d43e26eab42e0ee8c2d897645d7b7d7"
            },
            "downloads": -1,
            "filename": "shylock-1.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "05b917c8b1011cdd5c35d2c8060826eb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7,<4.0",
            "size": 13792,
            "upload_time": "2023-02-05T18:13:33",
            "upload_time_iso_8601": "2023-02-05T18:13:33.061769Z",
            "url": "https://files.pythonhosted.org/packages/13/da/27d32bbd54f9be57db54a9ca3c7c4f26f5840fc804b6f51275c07d73de8f/shylock-1.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "236979c28d6fa6751f85080432ac184d1588d5a4ca1ff898ee776614f8d99dc9",
                "md5": "dbb154f6766094bb51581967d8286c02",
                "sha256": "8101fc745ae85fc1f5e1e748bd7c84cdd5568ea4dd367c39449ab17dafad35e1"
            },
            "downloads": -1,
            "filename": "shylock-1.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "dbb154f6766094bb51581967d8286c02",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7,<4.0",
            "size": 10639,
            "upload_time": "2023-02-05T18:13:34",
            "upload_time_iso_8601": "2023-02-05T18:13:34.644127Z",
            "url": "https://files.pythonhosted.org/packages/23/69/79c28d6fa6751f85080432ac184d1588d5a4ca1ff898ee776614f8d99dc9/shylock-1.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-05 18:13:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "lietu",
    "github_project": "shylock",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "shylock"
}
        
Elapsed time: 0.03801s