{"id":8040,"library":"crochet","title":"Crochet","description":"Crochet is an MIT-licensed Python library that simplifies the integration of Twisted, an asynchronous networking framework, into regular blocking code. It transparently manages the Twisted reactor in a separate thread, allowing developers to call Twisted APIs from blocking applications like Django or Flask, or to create blocking APIs backed by Twisted. The library is currently at version 2.1.1 and is in a mature state, with development being slow due to its stable nature.","status":"active","version":"2.1.1","language":"en","source_language":"en","source_url":"https://github.com/itamarst/crochet","tags":["twisted","async","blocking","reactor","integration","frameworks"],"install":[{"cmd":"pip install crochet","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core dependency for asynchronous operations.","package":"twisted","optional":false},{"reason":"Used for decorator functionality.","package":"wrapt","optional":false}],"imports":[{"note":"Initializes the Crochet library, starts the Twisted reactor in a thread, and connects Twisted's logs to Python's standard logging. Must be called once before using other Crochet features.","symbol":"setup","correct":"from crochet import setup"},{"note":"A decorator factory that makes an asynchronous Twisted function callable from blocking code, blocking until a result or timeout occurs.","symbol":"wait_for","correct":"from crochet import wait_for"},{"note":"A decorator that ensures the wrapped function runs in the Twisted reactor thread, returning an EventualResult for later blocking retrieval.","symbol":"run_in_reactor","correct":"from crochet import run_in_reactor"},{"note":"Exception raised by `wait_for` if the decorated function exceeds its specified timeout.","symbol":"TimeoutError","correct":"from crochet import TimeoutError"}],"quickstart":{"code":"from crochet import setup, wait_for, TimeoutError\nfrom twisted.internet import defer\nimport time\nimport logging\nimport os\n\n# Configure basic logging to see Twisted output\nlogging.basicConfig(level=logging.INFO)\n\n# Initialize crochet - this starts the Twisted reactor in a thread\nsetup()\n\n@wait_for(timeout=5.0)\ndef long_running_twisted_task(duration):\n    d = defer.Deferred()\n    # Simulate an asynchronous operation in Twisted's reactor thread\n    def _complete_task():\n        if os.environ.get('SIMULATE_FAILURE') == '1':\n            d.err(ValueError(\"Simulated Twisted failure!\"))\n        else:\n            d.callback(f\"Task completed in {duration} seconds\")\n    \n    from twisted.internet import reactor\n    reactor.callLater(duration, _complete_task)\n    return d\n\nif __name__ == \"__main__\":\n    print(\"Starting Crochet example...\")\n    try:\n        # Call the Twisted-backed function from blocking code\n        result = long_running_twisted_task(2.0)\n        print(f\"Blocking call returned: {result}\")\n\n        # Demonstrate a timeout\n        print(\"\\nAttempting a task that will timeout...\")\n        try:\n            long_running_twisted_task(6.0) # Will timeout after 5 seconds\n        except TimeoutError:\n            print(\"Caught expected TimeoutError!\")\n\n        # Demonstrate a Twisted error propagating\n        print(\"\\nAttempting a task that will fail in Twisted...\")\n        os.environ['SIMULATE_FAILURE'] = '1'\n        try:\n            long_running_twisted_task(1.0)\n        except ValueError as e:\n            print(f\"Caught expected ValueError: {e}\")\n        finally:\n            del os.environ['SIMULATE_FAILURE']\n\n    except Exception as e:\n        print(f\"An unexpected error occurred: {e}\")\n    finally:\n        print(\"Crochet example finished.\")","lang":"python","description":"This quickstart demonstrates how to use `crochet.setup()` to initialize the library and `crochet.wait_for` to wrap an asynchronous Twisted function, making it callable from synchronous Python code. It includes examples of successful execution, handling `TimeoutError`, and propagating exceptions from the Twisted reactor thread back to the blocking caller. Ensure you have `twisted` installed (`pip install twisted`) to run this example."},"warnings":[{"fix":"Upgrade your Python interpreter to version 3.8 or higher, or pin your crochet dependency to '<2.1.0'.","message":"Crochet version 2.1.0 dropped support for Python 3.6 and 3.7. Ensure your environment uses Python 3.8 or newer.","severity":"breaking","affected_versions":">=2.1.0"},{"fix":"Ensure `crochet.setup()` is called early in your application's lifecycle, typically at module import time or application startup.","message":"The `crochet.setup()` function must be called exactly once before using any other Crochet functionality. Calling it multiple times is harmless, but not calling it at all will lead to runtime errors when attempting to use decorators or `EventualResult`.","severity":"gotcha","affected_versions":"All"},{"fix":"Handle `crochet.TimeoutError` in your blocking code. Adjust the `timeout` parameter in `@wait_for` based on the expected duration of the asynchronous operation, or implement retry logic.","message":"When using `@wait_for`, if the underlying Twisted operation does not complete within the specified `timeout` duration, a `crochet.TimeoutError` will be raised. This means the blocking call will be interrupted.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Add `from crochet import setup; setup()` to the initialization section of your application.","cause":"`crochet.setup()` has not been called before attempting to use `@wait_for` or `EventualResult`.","error":"RuntimeError: The Twisted reactor is not running, or has not been initialized by crochet."},{"fix":"Increase the `timeout` parameter in the `@wait_for` decorator if the operation legitimately takes longer, or debug the Twisted code to identify why it's not completing.","cause":"An operation decorated with `@wait_for(timeout=X)` exceeded the allowed X seconds, or the Twisted reactor got stuck.","error":"crochet.TimeoutError: Waited for 5.0 seconds"},{"fix":"Ensure `crochet` is installed and updated to a recent version (`pip install --upgrade crochet`). The common import is `from crochet import wait_for`.","cause":"Attempting to import `wait_for` from a very old version of crochet, or a typo in the import statement.","error":"ImportError: cannot import name 'wait_for' from 'crochet'"}]}