Metadata-Version: 2.1
Name: futured
Version: 1.0
Summary: Functional interface for concurrent futures, including asynchronous I/O.
Home-page: https://github.com/coady/futured
Author: Aric Coady
Author-email: aric.coady@gmail.com
License: Apache Software License
Project-URL: Documentation, https://futured.readthedocs.io
Keywords: concurrent futures threads processes async asyncio
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.5
Description-Content-Type: text/markdown
Provides-Extra: docs
Requires-Dist: m2r ; extra == 'docs'
Requires-Dist: nbsphinx ; extra == 'docs'
Requires-Dist: jupyter ; extra == 'docs'
Requires-Dist: nest-asyncio ; extra == 'docs'
Requires-Dist: aiohttp ; extra == 'docs'

[![image](https://img.shields.io/pypi/v/futured.svg)](https://pypi.org/project/futured/)
![image](https://img.shields.io/pypi/pyversions/futured.svg)
[![image](https://pepy.tech/badge/futured)](https://pepy.tech/project/futured)
![image](https://img.shields.io/pypi/status/futured.svg)
[![image](https://img.shields.io/travis/coady/futured.svg)](https://travis-ci.org/coady/futured)
[![image](https://img.shields.io/codecov/c/github/coady/futured.svg)](https://codecov.io/github/coady/futured)
[![image](https://readthedocs.org/projects/futured/badge)](https://futured.readthedocs.io)
[![image](https://requires.io/github/coady/futured/requirements.svg)](https://requires.io/github/coady/futured/requirements/)
[![image](https://api.codeclimate.com/v1/badges/bdc33b8af847fbbecfce/maintainability)](https://codeclimate.com/github/coady/futured/maintainability)
[![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://pypi.org/project/black/)

Futured provides a simple consistent interface for concurrent functional programming in Python.
It wraps any callable to return a `concurrent.futures.Future`,
wraps any async coroutine to return an `asyncio.Future`,
and provides concurrent iterators and context managers for futures.

# Usage
## threaded, processed
Transform any callable into one which runs in a thread or process pool, and returns a future.

```python
from futured import threaded, processed
import requests

fetch = threaded(requests.Session().get)
fetch(url)  # return Future

fs = (fetch(url + path) for path in paths)
threaded.results(fs)  # generate results from futures
threaded.results(fs, timeout=...)  # generate results as completed

fetch.map(urls)  # generate results in order
fetch.map(urls, timeout=...)  # generate results as completed
fetch.mapzip(urls)  # generate (url, result) pairs as completed
```

Thread and process pool executors may be used as context managers,
customized with options, and reused with different callables.

```python
threaded(max_workers=...)(func, ...)
processed(max_workers=...)(func, ...)
```

`futured` classes have a `waiting` context manager which collects results from tasks.
Futures can be registered at creation, or appended to the list of tasks.

```python
with threaded.waiting(*fs) as tasks:
    tasks.append(future)
tasks  # list of completed results
```

## asynced
The same interface works for `asyncio`.

```python
from futured import asynced
import aiohttp

fetch = asynced(aiohttp.ClientSession().get)
fetch(url)  # return coroutine

asynced.results(fs)  # generate results from futures
asynced.results(fs, timeout=...)  # generate results as completed

fetch.map(urls)  # generate results in order
fetch.map(urls, timeout=...)  # generate results as completed
fetch.mapzip(urls)  # generate (url, result) pairs as completed
```

`asynced` provides utilities for calling coroutines from a synchronous context.
`waiting` is similar to [trio's nursery](https://trio.readthedocs.io/en/latest/reference-core.html#nurseries-and-spawning),
but returns results from a synchronous `with` block.

```python
asynced.run(async_func, ...)  # call and run until complete
asynced.run(async_gen, ...)  # call and run synchronous iterator
with asynced.waiting(*fs) as tasks:  # concurrent coroutines completed in a block
```

## decorators
Naturally `futured` wrappers can be used as decorators, but arguments can also be partially bound.

```python
@threaded
def slow():
   ...

fetch = threaded(requests.Session().get, url)
fetch(params=...)
```

Methods are supported, as well as a `decorated` utility for automatically subclassing.

```python
from futured import decorated

FutureSession = decorated(requests.Session, request=threaded)

 # equivalent to
class FutureSession(requests.Session):
    request = threaded(requests.Session.request)
```

## command
`command` wraps `subprocess.Popen` to provide a `Future` compatible interface.

```python
from futured import futured, command

command('ls').result()  # return stdout or raises stderr
command('ls').pipe('wc')  # pipes into next command, or | ('wc',... )
for line in command('ls'):  # iterable lines
command.coroutine('ls')  # return coroutine

futured(command, 'ls')  # supports `map` interface
asynced(command.coroutine, 'ls')  # supports `map` interface with timeout
```

## forked
`forked` allows iteration in separate child processes.

```python
from futured import forked

for value in forked(values, max_workers=...):
    # in a child process
 # in parent after children have exited
```

# Installation

    $ pip install futured

# Tests
100% branch coverage.

    $ pytest [--cov]

# Changes
1.0
* Executed functions are context managers
* `starmap` supported

0.3
* `forked` has optional maximum number of workers
* `waiting` context manager
* `command` pipes (`|`)
* `distributed.Client` support

0.2
* `command.coroutine` creates asyncio subprocesses
* `futured.mapzip` generates results zipped with arguments
* `asynced.run` supports asynchronous iterators


