Metadata-Version: 2.1
Name: hs-formation
Version: 6.0.1
Summary: A generic functional middleware infrastructure for Python.
Author-Email: Dotan Nahum <jondotan@gmail.com>, HiredScoreLabs <oss@hiredscore.com>
License: MIT
Requires-Python: <3.13,>=3.9
Requires-Dist: toolz>=1.0.0
Requires-Dist: cytoolz>=1.0.0
Requires-Dist: requests>=2.32.5
Requires-Dist: pybreaker>=1.2.0
Requires-Dist: xmltodict>=0.15.1
Requires-Dist: lxml>=5.3.0
Requires-Dist: attrs>=23.2.0
Requires-Dist: aiohttp<3.14,>=3.10.0; python_version < "3.10"
Requires-Dist: aiohttp>=3.14.1; python_version >= "3.10"
Requires-Dist: aiobreaker>=1.1.0
Description-Content-Type: text/markdown

<!-- ![](media/cover.png) -->

# Formation
<!-- [![Build Status](https://travis-ci.org/jondot/formation.svg?branch=master)](https://travis-ci.org/jondot/formation.svg)
[![Coverage Status](https://coveralls.io/repos/github/jondot/formation/badge.svg?branch=master)](https://coveralls.io/github/jondot/formation?branch=master) -->

A generic functional middleware infrastructure for Python.

Take a look:

```py
from datetime.datetime import now
from hs_formation import wrap
from requests import get

def log(ctx, call):
    print("started")
    ctx = call(ctx)
    print("ended")
    return ctx

def timeit(ctx, call):
    started = now()
    ctx = call(ctx)
    ended = now() - started
    ctx['duration'] = ended
    return ctx

def to_requests(ctx):
    get(ctx['url'])
    return ctx

fancy_get = wrap(to_requests, middleware=[log, timeit])
fancy_get({'url':'https://google.com'})
```

## Quick Start

Install from PyPI:

```
$ pip install hs-formation
```

## Development

Install runtime dependencies plus the `dev` and `ci` groups, then run tests:

```
$ make install
$ make test
```

The `ci` group lists everything needed to execute the test suite and produce a coverage report in CI (for example `pytest`, `pytest-cov`, and other plugins). The `dev` group lists local-only tools such as `pytest-watch`.

To install only what CircleCI uses (no dev-only tools):

```
$ make install_ci
```

`make ci_install` is an alias for `make install_ci`.

After changing dependencies:

```
$ make lock
```

To verify `pdm.lock` is up to date without writing:

```
$ make verify_lock_file
```

## Releases and tags

Release automation is handled by `ci/release.sh` and `Makefile` targets:

```
$ make release         # patch
$ make release_minor   # minor
$ make release_major   # major
```

For breaking changes (for example dropping Python support), use a major release so the tag and package version move to the next major semver:

```
$ make release_major
```

## Best Practices

A `context` object is a loose bag of objects. With that freedom comes responsibility and opinion.

For example, this is how Formation models a `requests` integration, with data flowing inside `context`:


* It models a `FormationHttpRequest` which abstracts the essentials of making an HTTP request (later shipped to `requests` itself in the way that it likes)
* It tucks `FormationHttpRequest` under the `fmtn.req` key.
* Additional information regarding such a request is kept _alongside_ `fmtn.req`. For example a request id is kept in the `req.id` key. This creates a flat (good thing) dict to probe. The reason additional data does not have the `fmtn` prefix is that you can always build your own that uses a different prefix (which you cant say about internal Formation inner workings).


### added support for async http client via aio_http
You can use this via ```for_aio_http```



### Thanks:

To all [Contributors](https://github.com/jondot/formation/graphs/contributors) - you make this happen, thanks!

# Copyright

Copyright (c) 2018 [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details.
