fast-async


Namefast-async JSON
Version 1.1.0 PyPI version JSON
download
home_page
SummaryThread based async library for python
upload_time2023-02-02 14:16:47
maintainer
docs_urlNone
author
requires_python>=3.7
licenseThe MIT License (MIT) Copyright © 2023 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords async threads
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Fast Async

![Publish to PyPi](https://github.com/thebowenfeng/FastAsync/actions/workflows/build_and_dist.yml/badge.svg)

A thread based, asynchronous programming framework built for Python.
Designed and optimized for speed. 

Asyncio, the go-to asynchronous programming framework for Python, uses
a single-threaded event loop to achieve concurrency. Although this prevents
unnecessary computational overheads and race conditions, it is inherently not
as fast as threads (even with inefficiencies brought along with GIL). In some
scenarios where speed is of utmost importance and where computational resources
are abundant, then it makes sense to use a multi-threading approach to concurrency.

Fast Async is a high-level API for Python `threads`, providing users with the
ability to `await` asynchronous code, and other features such as event-driven,
pubsub model (similar to Javascript's ```Promise.then()```). It aims to serve as
an alternative to asyncio, for users who require faster execution speed.

## Installation

Run ```pip install fast-async```

#### Running locally

Clone the repository and make the working directory ```src/```. 

Alternatively, extract the folder ```src/fast_async```.


## Benchmarks

#### Scenario (```sample.py```)

A long-running network request and an expensive operation is executed asynchronously

#### Result

```fast-async``` is, on average, almost 50% faster than ```asyncio``` due to
asyncio executing the two tasks almost sequentially whilst fast-async leverages threads
to execute them in parallel.

## FAQ

#### When to use fast-async

Fast-async should be used when execution speed is a higher priority.
For example, uploading each frame of a video stream to a remote server.
For cases where execution speed is not important, or when well-written code
make the speed differences negligible, asyncio is preferred.

#### What about ThreadPoolExecutor?

```ThreadPoolExecutor``` is a Python built-in class that offers some of the
same functionalities as fast-async, namely the ability to wait for tasks, and
limiting threads to conserve resources. However, fast-async is more feature-rich, 
such as the event-driven model (subscribers and callbacks) and various utility functions
that mirror certain useful functionalities from other languages (such as JavaScript). 
Fast-async is designed to enhance developer experience when working with threads, by
offering an easy-to-use interface and minimal pre-requisite knowledge.

## Documentation

### Decorators

```@make_async```

Make a function asynchronous. Functions that are decorated with 
```make_async``` will return an object of type ```AsyncTask```

Aside from its type, decorated functions can be treated as a normal function.
This means arguments can be passed in, much like a regular function.

Exceptions raised within the decorated function will be caught and re-thrown
in the caller thread.

#### Example:

```python
from fast_async import make_async

@make_async
def hello(message):
    print("hello world")
    return message

# Awaits hello to finish executing
return_val = hello("hello world").wait()

# Prints "hello world"
print(return_val)
```

### Classes

Package: fast_async.types.tasks

```class AsyncTask(func: Callable, *args, **kwargs)```

#### Attributes

- func: A function or ```Callable```.
- *args: Non-keyworded arguments for func
- **kwargs: Keyworded arguments for func
- status: Current status of func (pending, success, failure)
- result: Return value of func
- thread: ```Thread``` that func is being ran on
- exception: First caught ```Exception``` raised in func

#### Methods

```run()```

Runs ```func``` on a child thread, returns ```None```.

```wait()```

Awaits ```func``` to finish executing (blocks the caller thread),
returns the return value of ```func```.

```subscribe(on_success: Callable, on_failure: Callable, blocks: bool = False)```

Subscribes success and failure callbacks that is invoked when task is 
finished executing or raised an exception. Optional blocks argument 
controls whether subscribe blocks the caller thread (by default subscribe does not block)

### Functions

```set_max_threads(num: int): None```

Set the max number of threads available to be consumed by tasks.
Default is 64 threads. Useful when wanting to dynamically scale 
usage.

#### Example:

```python
from fast_async import set_max_threads

set_max_threads(3) # Only allows a maximum of 3 concurrent threads
```

```await_all(tasks: List[AsyncTask]): List```

Waits for all tasks in the ```tasks``` list to finish executing, or
when a task fails, then the function will immediately raise an exception and exit.

Returns a list of results corresponding to the list of tasks provided.

Similar to JavaScript's ```Promise.all()```

#### Example:

```python
from fast_async import make_async
from fast_async.utils import await_all

@make_async
def func1():
    return 1

@make_async
def func2():
    return 2

await_all([func1(), func2()]) # Will return [1, 2]
```

```await_first(tasks: List[AsyncTask]): Any```

Waits for the first task in ```tasks``` list to finish executing
and immediately returns the result. If all tasks fail, then the first
failed task is raised in an exception.

Returns the result of the first successful task.

Similar to JavaScript's ```Promise.race()```

#### Example

```python
from fast_async import make_async
from fast_async.utils import await_first
import time

@make_async
def func1():
    time.sleep(1)
    return 1

@make_async
def func2():
    time.sleep(2)
    return 2

await_first([func1(), func2()]) # Will return 1, because func1 finishes first
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "fast-async",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "async,threads",
    "author": "",
    "author_email": "Bowen Feng <857514.leofeng@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/54/ed/05b08eb6952b802270e910ba9949921b14ef3537d3eee345ed950a8f9c55/fast-async-1.1.0.tar.gz",
    "platform": null,
    "description": "# Fast Async\n\n![Publish to PyPi](https://github.com/thebowenfeng/FastAsync/actions/workflows/build_and_dist.yml/badge.svg)\n\nA thread based, asynchronous programming framework built for Python.\nDesigned and optimized for speed. \n\nAsyncio, the go-to asynchronous programming framework for Python, uses\na single-threaded event loop to achieve concurrency. Although this prevents\nunnecessary computational overheads and race conditions, it is inherently not\nas fast as threads (even with inefficiencies brought along with GIL). In some\nscenarios where speed is of utmost importance and where computational resources\nare abundant, then it makes sense to use a multi-threading approach to concurrency.\n\nFast Async is a high-level API for Python `threads`, providing users with the\nability to `await` asynchronous code, and other features such as event-driven,\npubsub model (similar to Javascript's ```Promise.then()```). It aims to serve as\nan alternative to asyncio, for users who require faster execution speed.\n\n## Installation\n\nRun ```pip install fast-async```\n\n#### Running locally\n\nClone the repository and make the working directory ```src/```. \n\nAlternatively, extract the folder ```src/fast_async```.\n\n\n## Benchmarks\n\n#### Scenario (```sample.py```)\n\nA long-running network request and an expensive operation is executed asynchronously\n\n#### Result\n\n```fast-async``` is, on average, almost 50% faster than ```asyncio``` due to\nasyncio executing the two tasks almost sequentially whilst fast-async leverages threads\nto execute them in parallel.\n\n## FAQ\n\n#### When to use fast-async\n\nFast-async should be used when execution speed is a higher priority.\nFor example, uploading each frame of a video stream to a remote server.\nFor cases where execution speed is not important, or when well-written code\nmake the speed differences negligible, asyncio is preferred.\n\n#### What about ThreadPoolExecutor?\n\n```ThreadPoolExecutor``` is a Python built-in class that offers some of the\nsame functionalities as fast-async, namely the ability to wait for tasks, and\nlimiting threads to conserve resources. However, fast-async is more feature-rich, \nsuch as the event-driven model (subscribers and callbacks) and various utility functions\nthat mirror certain useful functionalities from other languages (such as JavaScript). \nFast-async is designed to enhance developer experience when working with threads, by\noffering an easy-to-use interface and minimal pre-requisite knowledge.\n\n## Documentation\n\n### Decorators\n\n```@make_async```\n\nMake a function asynchronous. Functions that are decorated with \n```make_async``` will return an object of type ```AsyncTask```\n\nAside from its type, decorated functions can be treated as a normal function.\nThis means arguments can be passed in, much like a regular function.\n\nExceptions raised within the decorated function will be caught and re-thrown\nin the caller thread.\n\n#### Example:\n\n```python\nfrom fast_async import make_async\n\n@make_async\ndef hello(message):\n    print(\"hello world\")\n    return message\n\n# Awaits hello to finish executing\nreturn_val = hello(\"hello world\").wait()\n\n# Prints \"hello world\"\nprint(return_val)\n```\n\n### Classes\n\nPackage: fast_async.types.tasks\n\n```class AsyncTask(func: Callable, *args, **kwargs)```\n\n#### Attributes\n\n- func: A function or ```Callable```.\n- *args: Non-keyworded arguments for func\n- **kwargs: Keyworded arguments for func\n- status: Current status of func (pending, success, failure)\n- result: Return value of func\n- thread: ```Thread``` that func is being ran on\n- exception: First caught ```Exception``` raised in func\n\n#### Methods\n\n```run()```\n\nRuns ```func``` on a child thread, returns ```None```.\n\n```wait()```\n\nAwaits ```func``` to finish executing (blocks the caller thread),\nreturns the return value of ```func```.\n\n```subscribe(on_success: Callable, on_failure: Callable, blocks: bool = False)```\n\nSubscribes success and failure callbacks that is invoked when task is \nfinished executing or raised an exception. Optional blocks argument \ncontrols whether subscribe blocks the caller thread (by default subscribe does not block)\n\n### Functions\n\n```set_max_threads(num: int): None```\n\nSet the max number of threads available to be consumed by tasks.\nDefault is 64 threads. Useful when wanting to dynamically scale \nusage.\n\n#### Example:\n\n```python\nfrom fast_async import set_max_threads\n\nset_max_threads(3) # Only allows a maximum of 3 concurrent threads\n```\n\n```await_all(tasks: List[AsyncTask]): List```\n\nWaits for all tasks in the ```tasks``` list to finish executing, or\nwhen a task fails, then the function will immediately raise an exception and exit.\n\nReturns a list of results corresponding to the list of tasks provided.\n\nSimilar to JavaScript's ```Promise.all()```\n\n#### Example:\n\n```python\nfrom fast_async import make_async\nfrom fast_async.utils import await_all\n\n@make_async\ndef func1():\n    return 1\n\n@make_async\ndef func2():\n    return 2\n\nawait_all([func1(), func2()]) # Will return [1, 2]\n```\n\n```await_first(tasks: List[AsyncTask]): Any```\n\nWaits for the first task in ```tasks``` list to finish executing\nand immediately returns the result. If all tasks fail, then the first\nfailed task is raised in an exception.\n\nReturns the result of the first successful task.\n\nSimilar to JavaScript's ```Promise.race()```\n\n#### Example\n\n```python\nfrom fast_async import make_async\nfrom fast_async.utils import await_first\nimport time\n\n@make_async\ndef func1():\n    time.sleep(1)\n    return 1\n\n@make_async\ndef func2():\n    time.sleep(2)\n    return 2\n\nawait_first([func1(), func2()]) # Will return 1, because func1 finishes first\n```\n",
    "bugtrack_url": null,
    "license": "The MIT License (MIT) Copyright \u00a9 2023  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \u201cSoftware\u201d), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \u201cAS IS\u201d, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "Thread based async library for python",
    "version": "1.1.0",
    "split_keywords": [
        "async",
        "threads"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0ceb74cc2f393c5d4bad3ab30838474741808ca8bbb0c3117352c6070f30f4ab",
                "md5": "6021dd9a059683302df5e4110f3b533b",
                "sha256": "bd2bf82218c42f2e7eb7d72e04c1809f17b96de674a50d24d0758af43a9256fe"
            },
            "downloads": -1,
            "filename": "fast_async-1.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6021dd9a059683302df5e4110f3b533b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 8379,
            "upload_time": "2023-02-02T14:16:45",
            "upload_time_iso_8601": "2023-02-02T14:16:45.606013Z",
            "url": "https://files.pythonhosted.org/packages/0c/eb/74cc2f393c5d4bad3ab30838474741808ca8bbb0c3117352c6070f30f4ab/fast_async-1.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "54ed05b08eb6952b802270e910ba9949921b14ef3537d3eee345ed950a8f9c55",
                "md5": "7ec1e22e6183c69307ed7b07dde5870a",
                "sha256": "2fd90aca302a34377fd6687f8b2fba50a48563414957df1f7ec1915a00ad48b5"
            },
            "downloads": -1,
            "filename": "fast-async-1.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "7ec1e22e6183c69307ed7b07dde5870a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 9353,
            "upload_time": "2023-02-02T14:16:47",
            "upload_time_iso_8601": "2023-02-02T14:16:47.356116Z",
            "url": "https://files.pythonhosted.org/packages/54/ed/05b08eb6952b802270e910ba9949921b14ef3537d3eee345ed950a8f9c55/fast-async-1.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-02-02 14:16:47",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "fast-async"
}
        
Elapsed time: 0.04313s