Git Product home page Git Product logo

cyclotron-py's Introduction

cyclotron-logo Cyclotron

A functional and reactive framework for RxPY.

image

image

Documentation Status


With Cyclotron, you can structure your RxPY code as many reusable components. Moreover it naturally encourages to separate pure code and side effects. So a Cyclotron application is easier to test, maintain, and extend.

Here is the structure of a cyclotron application:

How to use it

The following example is an http echo server:

from collections import namedtuple

from cyclotron import Component
from cyclotron.asyncio.runner import run
import cyclotron_aiohttp.httpd as httpd
import reactivex as rx
import reactivex.operators as ops

EchoSource = namedtuple('EchoSource', ['httpd'])
EchoSink = namedtuple('EchoSink', ['httpd'])
EchoDrivers = namedtuple('EchoDrivers', ['httpd'])

def echo_server(source):
    init = rx.from_([
        httpd.Initialize(),
        httpd.AddRoute(methods=['GET'], path='/echo/{what}', id='echo'),
        httpd.StartServer(host='localhost', port=8080),
    ])

    echo = source.httpd.route.pipe(
        ops.filter(lambda i: i.id == 'echo'),
        ops.flat_map(lambda i: i.request),
        ops.map(lambda i: httpd.Response(
            context=i.context,
            data=i.match_info['what'].encode('utf-8')),
        )
    )

    control = rx.merge(init, echo)
    return EchoSink(httpd=httpd.Sink(control=control))


def main():
    run(Component(call=echo_server, input=EchoSource),
        EchoDrivers(httpd=httpd.make_driver()))


if __name__ == '__main__':
    main()

In this application, the echo_server function is a pure function, while the http server is implemented as a driver.

pip install cyclotron-aiohttp

you can then test it with an http client like curl:

$ curl http://localhost:8080/echo/hello
hello

Install

Cyclotron is available on PyPi and can be installed with pip:

pip install cyclotron

Cyclotron automatically uses uvloop if it is available.

This project is composed of several python packages. Install also the ones that you use in your application:

Package Version
cyclotron pypi-cyclotron
cyclotron-std pypi-cyclotron-std
cyclotron-aiohttp pypi-cyclotron-aiohttp
cyclotron-aiokafka pypi-cyclotron-aiokafka
cyclotron-consul pypi-cyclotron-consul

License

This project is licensed under the MIT License - see the License file for details

cyclotron-py's People

Contributors

mainro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cyclotron-py's Issues

Better documentation

Hi!,

I've been reading your book on reactive programming, and came to see cyclotron repo. I found that the documentation explains too little and I'm wondering if I can make it a bit better. This is also for the sub-repos (which I think should use the same docs url).

Nice work and thank you for the book!

Regarding "RxPY Cohabitation with AsyncIO"

I couldn't find your e-mail address, and the blog post in question does not have a comment section, so I'm commenting here instead. Sorry about the noise. Let me know if there are better channels for this discussion.

First of all, it is a very well-written and informative blog post. Thanks for sharing your insights.

I think that I found an issue with the to_agen async generator. Specifically, this section:

while True:
    i = await queue.get()
    if isinstance(i, OnNext):
        yield i.value
        queue.task_done()
    elif isinstance(i, OnError):
        disposable.dispose()
        raise(Exception(i.value))
    else:
        disposable.dispose()
        break

If the async generator object is not iterated until completion, then disposable.dispose() is never called.

It is up to the user code to iterate the async generator object. The user can even choose to just iterate the async generator a couple of times and then discard it. In this case, a GeneratorExit exception will be thrown when the async generator object is garbage collected. Consequently, dispose will never be called.

This can be easily fixed by calling dispose in a finally block instead:

try:
    while True:
        i = await queue.get()
        if isinstance(i, OnNext):
            yield i.value
            queue.task_done()
        elif isinstance(i, OnError):
            raise(Exception(i.value))
        else:
            break
finally:
    disposable.dispose()

I encountered this issue in production where it led to strange errors. Thought I should let you know.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.