Robyn is an async Python backend server with a runtime written in Rust, btw.

Overview

Robyn

Gitter

Robyn is an async Python backend server with a runtime written in Rust, btw.

Python server running on top of of Rust Async RunTime.

Installation

You can simply use Pip for installation.

pip install robyn

Usage

from robyn import Robyn

app = Robyn()

@app.get("/")
async def h():
    return "Hello, world!"

app.start()

Contributor Guidelines

Feel free to open an issue for any clarification or for any suggestions.

If you're feeling curious. You can take a look at a more detailed architecture here.

To Run Locally

  1. Add more routes in the test.py file(if you like). It only supports only get requests at the moment

  2. Run maturin develop

  3. Run python3 test.py

  4. To measure the performance: ./server_test.sh

Contributors/Supporters

Special thanks to the PyO3 community and Andrew from PyO3-asyncio for their amazing libraries and their support for my queries. 💖

Comments
  • Add socket sharing

    Add socket sharing

    Todo:

    • Add more integration tests [x]
    • Check and fix directories not working [x]

    UPDATE

    • [x] Argparser not working. Need to fix this
    • [x] Fix the installation on Raspberry Pi and Windows
    • [ ] Write the documentation for the flags
    opened by sansyrox 25
  • Build failure

    Build failure

    Hi, getting another build error for 0.14.0; it's something with the rust compilation again: https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=467486&view=logs&j=4f922444-fdfe-5dcf-b824-02f86439ef14&t=b2a8456a-fb11-5506-ca32-5ccd32538dc0

      error[E0277]: the trait bound `MyWs: actix::actor::Actor` is not satisfied
         --> src/web_socket_connection.rs:62:37
          |
      62  |     fn started(&mut self, ctx: &mut WebsocketContext<Self>) {
          |                                     ^^^^^^^^^^^^^^^^^^^^^^ the trait `actix::actor::Actor` is not implemented for `MyWs`
          |
      note: required by a bound in `WebsocketContext`
         --> /home/conda/feedstock_root/build_artifacts/robyn_1646278130206/_build_env/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-actors-4.1.0/src/ws.rs:373:8
          |
      373 |     A: Actor<Context = WebsocketContext<A>>,
          |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `WebsocketContext`
    

    There are five other errors that are similar/identical.

    opened by thewchan 19
  • Re-introduce thread pool for the sync functions (maybe)

    Re-introduce thread pool for the sync functions (maybe)

    https://github.com/sansyrox/robyn/pull/20#issuecomment-865121079

    Read discussion above

    And see if introducing a threadpool will impact asgi compliance(most probably not) but still check again.

    opened by sansyrox 14
  • [BUG?] Startup failure OSError: [WinError 87] The parameter is incorrect

    [BUG?] Startup failure OSError: [WinError 87] The parameter is incorrect

    Description

    When trying to start a Robyn app using the source code on the repo's README.md example, i get a massive error.

    Traceback (most recent call last):
      File "C:\Users\Happy\OneDrive\Documents\Coding Projects\robyntests\app.py", line 9, in <module>
        app.start(port=5000)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\robyn\__init__.py", line 127, in start
        p.start()
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\process.py", line 121, in start
        self._popen = self._Popen(self)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\context.py", line 224, in _Popen
        return _default_context.get_context().Process._Popen(process_obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\context.py", line 327, in _Popen
        return Popen(process_obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\popen_spawn_win32.py", line 93, in __init__
        reduction.dump(process_obj, to_child)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\reduction.py", line 63, in dump
        ForkingPickler(file, protocol, *args, **kwds).dump(obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\dill\_dill.py", line 620, in dump
        StockPickler.dump(self, obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 487, in dump
        self.save(obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 603, in save
        self.save_reduce(obj=obj, *rv)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 717, in save_reduce
        save(state)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 560, in save
        f(self, obj)  # Call unbound method with explicit self
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\dill\_dill.py", line 1251, in save_module_dict
        StockPickler.save_dict(pickler, obj)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 972, in save_dict
        self._batch_setitems(obj.items())
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 998, in _batch_setitems
        save(v)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 560, in save
        f(self, obj)  # Call unbound method with explicit self
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 902, in save_tuple
        save(element)
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\pickle.py", line 578, in save
        rv = reduce(self.proto)
    TypeError: cannot pickle 'builtins.SocketHeld' object
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\Happy\AppData\Local\Programs\Python\Python310\lib\site-packages\multiprocess\spawn.py", line 102, in spawn_main
        source_process = _winapi.OpenProcess(
    OSError: [WinError 87] The parameter is incorrect
    

    Expected Behavior

    Robyn runs I guess?

    Screenshots

    My code: image

    Environment:

    • Host OS: Windows
    • Browser: Firefox
    • Python Version: 3.10.4

    [Optional] Additional Context

    I'm running my file using the generic python app.py


    opened by justanotherbyte 12
  • Robyn version 0.9.0 doesn't work on Mac M1 Models

    Robyn version 0.9.0 doesn't work on Mac M1 Models

    Error Log :

    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
    📦 Built wheel for CPython 3.9 to /Users/shivaylamba/Desktop/robyn/target/wheels/robyn-0.9.0-cp39-cp39-macosx_11_0_arm64.whl
    💥 maturin failed
      Caused by: pip install in /Users/shivaylamba/Desktop/robyn/venv failed running ["-m", "pip", "--disable-pip-version-check", "install", "--force-reinstall", "/Users/shivaylamba/Desktop/robyn/target/wheels/robyn-0.9.0-cp39-cp39-macosx_11_0_arm64.whl"]: exit status: 1
    --- Stdout:
    
    --- Stderr:
    ERROR: robyn-0.9.0-cp39-cp39-macosx_11_0_arm64.whl is not a supported wheel on this platform.
    ---
    
    opened by shivaylamba 12
  • Pure tokio

    Pure tokio

    Here's another proposal which massively reduces the complexity of the project by leveraging Tokio's multi-threaded runtime

    Would probably need some benching marking on your machine, for me it appears to be faster.

    Jack

    opened by JackThomson2 12
  • Build error

    Build error

    Hi, I've been trying to build the newest version of robyn (v0.12.1) for distributing in conda-forge, but I've been getting this error during the build process:

      error[E0308]: mismatched types
         --> src/server.rs:160:33
          |
      160 |                 .client_timeout(0)
          |                                 ^ expected struct `std::time::Duration`, found integer
    
    

    I've tried conforming to the rust version in the CI to no avail. Does anyone have any advice?

    bug high-priority 
    opened by thewchan 11
  • not working on mac/windows

    not working on mac/windows

    i tried on all 3 platforms with/without venv. only seems to work on linux.

    mac error: ...robyntest/venv/lib/python3.10/site-packages/robyn/init.py", line 9, in from .robyn import Server, SocketHeld ModuleNotFoundError: No module named 'robyn.robyn'

    one difference i noticed is the linux one has a .so file where the mac does not. neither does the windows but that error is

    File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2544.0_x64__qbz5n2kfra8p0\lib\pickle.py", line 578, in save rv = reduce(self.proto) TypeError: cannot pickle 'builtins.SocketHeld' object

    .........testrobyn>Traceback (most recent call last): File "", line 1, in ......\venv\lib\site-packages\multiprocess\spawn.py", line 102, in spawn_main source_process = _winapi.OpenProcess( OSError: [WinError 87] The parameter is incorrect

    opened by byteface 10
  • [Proposal] Const Requests

    [Proposal] Const Requests

    I wonder if we should off an option for a constant response which won't change, this would allow us to never touch python for ultra fast path solutions.

    opened by JackThomson2 10
  • Use Actix as base

    Use Actix as base

    Actix is a very fast framework and is at the top of the TechEmpowered benchmarks

    In my testing it is considerably faster than the hyper backend:

    Hyper:

    oha -n 100000 http://localhost:5000
    Summary:
      Success rate:	1.0000
      Total:	29.8708 secs
      Slowest:	0.1254 secs
      Fastest:	0.0007 secs
      Average:	0.0149 secs
      Requests/sec:	3347.7546
    
      Total data:	1.80 MiB
      Size/request:	18 B
      Size/sec:	61.67 KiB
    
    Response time histogram:
      0.004 [5702]  |■■■■■■
      0.008 [29544] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.012 [26085] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.016 [13583] |■■■■■■■■■■■■■■
      0.020 [6547]  |■■■■■■■
      0.024 [3716]  |■■■■
      0.028 [2673]  |■■
      0.032 [2312]  |■■
      0.036 [2227]  |■■
      0.040 [1393]  |■
      0.044 [6218]  |■■■■■■
    
    Latency distribution:
      10% in 0.0054 secs
      25% in 0.0074 secs
      50% in 0.0107 secs
      75% in 0.0167 secs
      90% in 0.0324 secs
      95% in 0.0427 secs
      99% in 0.0607 secs
    

    Actix:

    oha -n 100000 http://localhost:5000
    Summary:
      Success rate:	1.0000
      Total:	10.2622 secs
      Slowest:	0.0552 secs
      Fastest:	0.0003 secs
      Average:	0.0051 secs
      Requests/sec:	9744.5392
    
      Total data:	1.91 MiB
      Size/request:	20 B
      Size/sec:	190.32 KiB
    
    Response time histogram:
      0.001 [1064]  |
      0.003 [17160] |■■■■■■■■■■■■■■■
      0.004 [36476] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.005 [24615] |■■■■■■■■■■■■■■■■■■■■■
      0.007 [9881]  |■■■■■■■■
      0.008 [3776]  |■■■
      0.010 [1449]  |■
      0.011 [928]   |
      0.012 [633]   |
      0.014 [510]   |
      0.015 [3508]  |■■■
    
    Latency distribution:
      10% in 0.0026 secs
      25% in 0.0033 secs
      50% in 0.0042 secs
      75% in 0.0054 secs
      90% in 0.0073 secs
      95% in 0.0107 secs
      99% in 0.0254 secs
    
    opened by JackThomson2 10
  • fix: add proper kill process to conftest. #249

    fix: add proper kill process to conftest. #249

    Description

    This PR fixes #249

    Changes

    • fix: fix problem of process persistence post test session
    • replace process.terminate() with kill() equivalent
    • scope pytest fixtures to session level

    Documentation

    No documentation update is required

    How I've tested my work

    • 25/25 tests passed (Debian 10)
    • 23/25 tests passed (Windows 10) (global_index_request() dev_index_request() failed)
    • lsof -i tcp:5000 outputs nothing post test session
    opened by guilefoylegaurav 7
  • [Feature Request] Add `@wraps` in route dectorators

    [Feature Request] Add `@wraps` in route dectorators

    Current Behavior

    Right now, we are not wrapping the route decorators. This leads to them losing the associated metadata.

    Desired Behavior

    Use functools.wraps to wrap the decorator.

    Screenshots / Mockups

    Alternatives


    opened by sansyrox 0
  • [Feature Request] [Long Stretch - Experimentation] - Try writing and compiling in a python docstring

    [Feature Request] [Long Stretch - Experimentation] - Try writing and compiling in a python docstring

    Current Behavior

    Rust cannot be written in Python code.

    Desired Behavior

    Try writing rust code in Python docstrings.

    Either this will one of the stupidest or the smartest things. I am not sure. But I sure it will be fun to implement.

    Screenshots / Mockups

    Alternatives


    opened by sansyrox 0
  • [BUG] The --dev flag not working on Windows

    [BUG] The --dev flag not working on Windows

    Description

    --dev flag not working on windows

    Traceback (most recent call last): File "C:\Users\Gaurav Bhattacharjee\OneDrive\Desktop\Projects\rob\robyn\integration_tests\base_routes.py", line 209, in <module> app.start(port=ROBYN_PORT, url=ROBYN_URL) File "\\?\C:\Users\Gaurav Bhattacharjee\OneDrive\Desktop\Projects\rob\robyn\robyn\__init__.py", line 163, in start event_handler.start_server_first_time() File "\\?\C:\Users\Gaurav Bhattacharjee\OneDrive\Desktop\Projects\rob\robyn\robyn\dev_event_handler.py", line 14, in start_server_first_time self.processes.append(subprocess.Popen(["python3", self.file_name], start_new_session=False)) File "C:\Users\Gaurav Bhattacharjee\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 969, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "C:\Users\Gaurav Bhattacharjee\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1438, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args, FileNotFoundError: [WinError 2] The system cannot find the file specified
    

    To replicate this issue: pytest -s integration_tests . You will see two tests failing.

    Expected Behavior

    The tests should not fail. 😄

    Screenshots

    Environment:

    • Host OS: Windows

    [Optional] Additional Context


    opened by sansyrox 4
  • [Feature Request] [Long Stretch - Experimentation] - Research on how/if having a custom compiler will help

    [Feature Request] [Long Stretch - Experimentation] - Research on how/if having a custom compiler will help

    Current Behavior

    I just read that youtube-dl has a custom compiler for JS. Maybe consider having a custom compiler for something in Robyn? Have a CLI tool that pre-compiles before running the app?

    Desired Behavior

    This suggestion could either be incredibly stupid or smart. Either way, worth checking it out.


    Screenshots / Mockups

    Alternatives


    opened by sansyrox 0
  • [Feature Request] [Long Stretch - Experimentation] - Try creating a web playground to demonstrate the usage of robyn

    [Feature Request] [Long Stretch - Experimentation] - Try creating a web playground to demonstrate the usage of robyn

    Current Behavior

    Try creating a web playground of Robyn that will allow people to write code without opening a terminal or their code editor.

    Desired Behavior

    Use something like python web assembly. And mock out the router to create a playground.


    Screenshots / Mockups

    Alternatives


    opened by sansyrox 0
Releases(v0.17.5)
  • v0.17.5(Sep 14, 2022)

    What's Changed

    • Don't run sync functions in pool by @JackThomson2 in https://github.com/sansyrox/robyn/pull/282

    Special thanks to @JackThomson2 for the

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.17.4...v0.17.5

    Example comparison for 100000 requests

    ➜  ~ oha http://127.0.0.1:5000 -n 100000 --no-tui
    Summary:
      Success rate:	1.0000
      Total:	0.5484 secs
      Slowest:	0.0319 secs
      Fastest:	0.0000 secs
      Average:	0.0003 secs
      Requests/sec:	182345.5041
    
      Total data:	1.14 MiB
      Size/request:	11 B
      Size/sec:	2.08 MiB
    
    Response time histogram:
      0.000 [1]     |
      0.003 [99147] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.006 [14]    |
      0.010 [9]     |
      0.013 [3]     |
      0.016 [180]   |
      0.019 [577]   |
      0.022 [56]    |
      0.026 [8]     |
      0.029 [4]     |
      0.032 [1]     |
    
    Latency distribution:
      10% in 0.0001 secs
      25% in 0.0001 secs
      50% in 0.0001 secs
      75% in 0.0001 secs
      90% in 0.0002 secs
      95% in 0.0003 secs
      99% in 0.0004 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0003 secs, 0.0001 secs, 0.0006 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0000 secs
    
    Status code distribution:
      [200] 100000 responses
    ➜  ~ oha http://127.0.0.1:5000 -n 100000 --no-tui
    Summary:
      Success rate:	1.0000
      Total:	0.4062 secs
      Slowest:	0.0326 secs
      Fastest:	0.0000 secs
      Average:	0.0002 secs
      Requests/sec:	246178.0064
    
      Total data:	1.14 MiB
      Size/request:	11 B
      Size/sec:	2.81 MiB
    
    Response time histogram:
      0.000 [1]     |
      0.003 [99339] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.007 [25]    |
      0.010 [10]    |
      0.013 [5]     |
      0.016 [254]   |
      0.020 [232]   |
      0.023 [117]   |
      0.026 [2]     |
      0.029 [14]    |
      0.033 [1]     |
    
    Latency distribution:
      10% in 0.0000 secs
      25% in 0.0001 secs
      50% in 0.0001 secs
      75% in 0.0001 secs
      90% in 0.0002 secs
      95% in 0.0002 secs
      99% in 0.0003 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0002 secs, 0.0001 secs, 0.0005 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0002 secs
    
    Status code distribution:
      [200] 100000 responses
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.17.4(Aug 28, 2022)

    What's Changed

    • Father, forgive me, for I am adding inline types. by @sansyrox in https://github.com/sansyrox/robyn/pull/266

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.17.3...v0.17.4

    Source code(tar.gz)
    Source code(zip)
  • v0.17.3(Aug 17, 2022)

    What's Changed

    • fix: parse int status code to str by @hougesen in https://github.com/sansyrox/robyn/pull/264

    New Contributors

    • @hougesen made their first contribution in https://github.com/sansyrox/robyn/pull/264

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.17.2...v0.17.3

    Usage

    @app.get('/int_status_code')
    def return_int_status_code():
        return {"status_code": 202, "body": "hello", "type": "text"}
    
    Source code(tar.gz)
    Source code(zip)
  • v0.17.2(Aug 11, 2022)

    This release removes multiprocessing from windows. This was a hard decision to take but since TCP sockets are not serialisable on non Unix machines, it only made sense.

    Since slow Robyn is better than a defunkt Robyn :)

    What's Changed

    • chore(ci): move pytest from CircleCi to Github Actions by @AntoineRR in https://github.com/sansyrox/robyn/pull/241
    • Fix typo in README by @bartbroere in https://github.com/sansyrox/robyn/pull/246
    • ci: add github actions to publish every PR on test pypi by @sansyrox in https://github.com/sansyrox/robyn/pull/259
    • ci: enable fail fast for faster response time in the pipelines by @sansyrox in https://github.com/sansyrox/robyn/pull/260
    • Windows fix by @sansyrox in https://github.com/sansyrox/robyn/pull/261

    New Contributors

    • @bartbroere made their first contribution in https://github.com/sansyrox/robyn/pull/246

    Special thanks to all the contributors :D

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.17.1...v0.17.2

    Source code(tar.gz)
    Source code(zip)
  • v0.17.1(Jul 20, 2022)

    What's Changed

    • CHANGELOG.md: Fix typo by @cclauss in https://github.com/sansyrox/robyn/pull/228
    • OrbUp: Upgrade the CircleCI Orbs by @cclauss in https://github.com/sansyrox/robyn/pull/229
    • fix external project link in README by @touilleMan in https://github.com/sansyrox/robyn/pull/234
    • Upgrade GitHub Actions and add Python 3.10 by @cclauss in https://github.com/sansyrox/robyn/pull/230
    • Contributors added in Readme by @orvil1026 in https://github.com/sansyrox/robyn/pull/235
    • Add Rust CI by @AntoineRR in https://github.com/sansyrox/robyn/pull/237
    • fix: fix request headers not being propagated by @sansyrox in https://github.com/sansyrox/robyn/pull/232

    New Contributors

    • @cclauss made their first contribution in https://github.com/sansyrox/robyn/pull/228
    • @touilleMan made their first contribution in https://github.com/sansyrox/robyn/pull/234
    • @orvil1026 made their first contribution in https://github.com/sansyrox/robyn/pull/235
    • @AntoineRR made their first contribution in https://github.com/sansyrox/robyn/pull/237

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.17.0...v0.17.1

    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Jul 6, 2022)

    This feature improves the performance substantially when you want to serve constant responses like simple strings, simple JSON payloads, etc.

    Benchmark Source: https://github.com/sansyrox/robyn-comparrison-benchmarks

    What's Changed

    • Add a const router by @sansyrox in https://github.com/sansyrox/robyn/pull/210

    New Syntax

    @app.get("/", const=True) # see the 'const' flag here
    async def h(_):
        return "Hello, world!"
    

    Performance upgrade

    Robyn (6 workers)

    ➜  ~ oha --no-tui --insecure -c 100 -n 1000000 http://127.0.0.1:5000
    Summary:
      Success rate:	1.0000
      Total:	1.9902 secs
      Slowest:	0.0477 secs
      Fastest:	0.0000 secs
      Average:	0.0002 secs
      Requests/sec:	502470.8499
    
      Total data:	12.40 MiB
      Size/request:	13 B
      Size/sec:	6.23 MiB
    
    Response time histogram:
      0.000 [2608]   |
      0.000 [85802]  |■■■■■■
      0.000 [320394] |■■■■■■■■■■■■■■■■■■■■■■
      0.000 [456025] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.000 [88243]  |■■■■■■
      0.000 [13397]  |
      0.000 [6279]   |
      0.000 [4146]   |
      0.000 [2887]   |
      0.001 [2356]   |
      0.001 [17863]  |■
    
    Latency distribution:
      10% in 0.0001 secs
      25% in 0.0002 secs
      50% in 0.0002 secs
      75% in 0.0002 secs
      90% in 0.0002 secs
      95% in 0.0003 secs
      99% in 0.0008 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0052 secs, 0.0001 secs, 0.0196 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0000 secs
    
    Status code distribution:
      [200] 1000000 responses
    

    FastAPI

    ➜  ~ oha --no-tui --insecure -c 100 -n 1000000 http://127.0.0.1:5001
    Summary:
      Success rate:	1.0000
      Total:	12.2921 secs
      Slowest:	0.0471 secs
      Fastest:	0.0001 secs
      Average:	0.0012 secs
      Requests/sec:	81353.0018
    
      Total data:	12.40 MiB
      Size/request:	13 B
      Size/sec:	1.01 MiB
    
    Response time histogram:
      0.000 [127872] |■■■■■■■■■■■■■■■■■■■■
      0.001 [178274] |■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.001 [199031] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.001 [204123] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.002 [126955] |■■■■■■■■■■■■■■■■■■■
      0.002 [80915]  |■■■■■■■■■■■■
      0.002 [33556]  |■■■■■
      0.003 [11592]  |■
      0.003 [5180]   |
      0.003 [3270]   |
      0.004 [29232]  |■■■■
    
    Latency distribution:
      10% in 0.0004 secs
      25% in 0.0007 secs
      50% in 0.0011 secs
      75% in 0.0015 secs
      90% in 0.0020 secs
      95% in 0.0024 secs
      99% in 0.0058 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0113 secs, 0.0001 secs, 0.0451 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0001 secs
    
    Status code distribution:
      [200] 1000000 responses
    

    Starlette (24 workers)

    ➜  ~ oha --no-tui --insecure -c 100 -n 1000000 http://127.0.0.1:5003
    Summary:
      Success rate:	1.0000
      Total:	9.8807 secs
      Slowest:	0.0534 secs
      Fastest:	0.0001 secs
      Average:	0.0010 secs
      Requests/sec:	101207.5486
    
      Total data:	12.40 MiB
      Size/request:	13 B
      Size/sec:	1.25 MiB
    
    Response time histogram:
      0.000 [128086] |■■■■■■■■■■■■■■■■■■■
      0.001 [206731] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.001 [211417] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.001 [174363] |■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.001 [120210] |■■■■■■■■■■■■■■■■■■
      0.002 [69490]  |■■■■■■■■■■
      0.002 [32373]  |■■■■
      0.002 [13678]  |■■
      0.002 [6528]   |
      0.003 [4052]   |
      0.003 [33072]  |■■■■■
    
    Latency distribution:
      10% in 0.0003 secs
      25% in 0.0005 secs
      50% in 0.0008 secs
      75% in 0.0012 secs
      90% in 0.0016 secs
      95% in 0.0020 secs
      99% in 0.0053 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0368 secs, 0.0077 secs, 0.0520 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0001 secs
    
    Status code distribution:
      [200] 1000000 responses
    

    Flask (Bjoern)

    ➜  ~ oha --no-tui --insecure -c 100 -n 1000000 http://127.0.0.1:5000
    Summary:
      Success rate:	1.0000
      Total:	113.6806 secs
      Slowest:	0.1515 secs
      Fastest:	0.0021 secs
      Average:	0.0114 secs
      Requests/sec:	8796.5722
    
      Total data:	12.40 MiB
      Size/request:	13 B
      Size/sec:	111.67 KiB
    
    Response time histogram:
      0.005 [68]     |
      0.008 [246]    |
      0.011 [417517] |■■■■■■■■■■■■■■■■■■■■■■■
      0.014 [558015] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.017 [16685]  |
      0.020 [2962]   |
      0.022 [2796]   |
      0.025 [1357]   |
      0.028 [86]     |
      0.031 [187]    |
      0.034 [81]     |
    
    Latency distribution:
      10% in 0.0099 secs
      25% in 0.0102 secs
      50% in 0.0112 secs
      75% in 0.0123 secs
      90% in 0.0129 secs
      95% in 0.0133 secs
      99% in 0.0157 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0352 secs, 0.0001 secs, 0.0509 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0000 secs
    
    Status code distribution:
      [200] 1000000 responses
    

    System Config

        eeeee  eeeeeeeeeeee   eeeee       OS: elementary OS 6.1 Jólnir x86_64
      eeee   eeeee       eee     eeee     Kernel: 5.13.0-51-generic
     eeee   eeee          eee     eeee    Uptime: 12 hours, 28 mins
    eee    eee            eee       eee   Packages: 2369 (dpkg), 11 (flatpak), 12 (snap)
    eee   eee            eee        eee   Shell: zsh 5.8
    ee    eee           eeee       eeee   Resolution: 3840x2160, 2160x3840
    ee    eee         eeeee      eeeeee   DE: Pantheon
    ee    eee       eeeee      eeeee ee   WM: Mutter(Gala)
    eee   eeee   eeeeee      eeeee  eee   Theme: io.elementary.stylesheet.blueberry [GTK3]
    eee    eeeeeeeeee     eeeeee    eee   Icons: elementary [GTK3]
     eeeeeeeeeeeeeeeeeeeeeeee    eeeee    Terminal: alacritty
      eeeeeeee eeeeeeeeeeee      eeee     Terminal Font: DankMono Nerd Font
        eeeee                 eeeee       CPU: AMD Ryzen 9 5900X (24) @ 4.000GHz
          eeeeeee         eeeeeee         GPU: NVIDIA 09:00.0 NVIDIA Corporation Device 2489
             eeeeeeeeeeeeeeeee            Memory: 6090MiB / 64214MiB
    
    
    
    

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.16.6...v0.17.0

    Source code(tar.gz)
    Source code(zip)
  • v0.16.6(Jul 2, 2022)

    What's Changed

    • Isort imports by @sansyrox in https://github.com/sansyrox/robyn/pull/205
    • feat: add commitizen as a dev dependency by @sansyrox in https://github.com/sansyrox/robyn/pull/216
    • fix: Fixes the crashing dev mode by @sansyrox in https://github.com/sansyrox/robyn/pull/218

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.16.4...v0.16.6

    Source code(tar.gz)
    Source code(zip)
  • v0.16.4(May 31, 2022)

    What's Changed

    • Adds pre-commit hooks for black, flake8, isort by @chrismoradi in https://github.com/sansyrox/robyn/pull/198
    • Removing unwraps by @sansyrox in https://github.com/sansyrox/robyn/pull/195
    • Add bridged logger. Improves performance substantially. by @sansyrox in https://github.com/sansyrox/robyn/pull/201

    New Contributors

    • @chrismoradi made their first contribution in https://github.com/sansyrox/robyn/pull/198

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.16.3...v0.16.4

    Source code(tar.gz)
    Source code(zip)
  • v0.16.3(May 18, 2022)

    What's Changed

    • Resolves port open issue when app is killed #183 by @anandtripathi5 in https://github.com/sansyrox/robyn/pull/196
    • Add more python type stubs: https://github.com/sansyrox/robyn/commit/c3fdc34fbfb9738f481258693cfa99516d51f417

    New Contributors

    • @anandtripathi5 made their first contribution in https://github.com/sansyrox/robyn/pull/196

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.16.2...v0.16.3

    Now you can easily turn off Robyn by pressing Ctrl+C without having dangling processes.

    Source code(tar.gz)
    Source code(zip)
  • v0.16.2(May 9, 2022)

    If types is what the community shall ask for. Then types is what the community shall get! ✨

    What's Changed

    • Setup types for Robyn by @sansyrox in https://github.com/sansyrox/robyn/pull/192

    Special Thanks

    • @Kludex @RobertCraigie for reviewing the PRs.
    • @RobertCraigie for suggesting the prisma integration.

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.16.0...v0.16.2

    Source code(tar.gz)
    Source code(zip)
  • v0.16.0(Apr 29, 2022)

    What's Changed

    • Code cleanup by @sansyrox in https://github.com/sansyrox/robyn/pull/178
    • Implement Response headers by @sansyrox in https://github.com/sansyrox/robyn/pull/179
    • Add experimental io-uring by @sansyrox in https://github.com/sansyrox/robyn/pull/184
    • Remove hashmap clones by @sansyrox in https://github.com/sansyrox/robyn/pull/187

    New Contributors

    • @sombralibre made their first contribution in https://github.com/sansyrox/robyn/pull/189

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.15.1...v0.16.0

    You can now have the response headers:

    @app.get("/redirect")
    async def redirect(request):
        return {"status_code": "307", "body": "", "type": "text", "headers": jsonify({"Location": "redirect_route"})}
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.15.1(Mar 24, 2022)

    What's Changed

    • Update README.md by @Polokghosh53 in https://github.com/sansyrox/robyn/pull/168
    • Use Clippy tool optimized code by @mrxiaozhuox in https://github.com/sansyrox/robyn/pull/171
    • Make websocket id accessible by @sansyrox in https://github.com/sansyrox/robyn/pull/173

    New Contributors

    • @Polokghosh53 made their first contribution in https://github.com/sansyrox/robyn/pull/168
    • @mrxiaozhuox made their first contribution in https://github.com/sansyrox/robyn/pull/171

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.15.0...v0.15.1

    Now, you can access web socket uuids from the functional calls

    @websocket.on("message")
    async def connect(websocket_id):
        print(websocket_id)
        global i
        i += 1
        if i == 0:
            return "Whaaat??"
        elif i == 1:
            return "Whooo??"
        elif i == 2:
            i = -1
            return "*chika* *chika* Slim Shady."
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Mar 17, 2022)

    Now you can mutate the request object through the request callback.

    Example below

    
    @app.get("/redirect")
    async def redirect(request):
        return {"status_code": "307", "body": "", "type": "text"}
    
    
    @app.get("/redirect_route")
    async def redirect_route(request):
        return "This is the redirected route"
    
    
    @app.before_request("/redirect")
    async def redirect_before_request(request):
        request["headers"]["Location"] = "redirect_route"
        return ""
    
    
    @app.after_request("/redirect")
    async def redirect_after_request(request):
        request["headers"]["Location"] = "redirect_route"
        return ""
    
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.14.0(Mar 3, 2022)

    Robyn supports custom response objects now! 🥳

    What's Changed

    • Implement Custom Response objects. by @sansyrox in https://github.com/sansyrox/robyn/pull/165

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.13.1...v0.14.0

    Example

    @app.get("/")
    async def hello(request):
        global callCount
        callCount += 1
        message = "Called " + str(callCount) + " times"
        print(message, request)
        return {"status_code": "200", "body": "hello", "type": "text"}
    
    
    @app.get('/404')
    def return_404():
        return {"status_code": "404", "body": "hello", "type": "text"}
    
    Source code(tar.gz)
    Source code(zip)
  • v0.13.1(Feb 20, 2022)

    No major functional changes. Only support changes.

    You can use conda for installations:

    conda install -c conda-forge robyn
    

    What's Changed

    • Remove deprecated endpoints by @sansyrox in https://github.com/sansyrox/robyn/pull/162

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.13.0...v0.13.1

    Source code(tar.gz)
    Source code(zip)
  • v0.13.0(Feb 15, 2022)

    Robyn now supports middlewares!!

    Sample Usage

    You can use both sync and async functions for middlewares!

    @app.before_request("/")
    async def hello_before_request(request):
        print(request)
    
    
    @app.after_request("/")
    def hello_after_request(request):
        print(request)
    

    What's Changed

    • Add middlewares by @sansyrox in https://github.com/sansyrox/robyn/pull/157

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.12.1...v0.13.0

    Source code(tar.gz)
    Source code(zip)
  • v0.12.1(Feb 13, 2022)

    What's Changed

    • Remove arc(ing) by @sansyrox in https://github.com/sansyrox/robyn/pull/156
    • Fix: default url param in app.start by @sansyrox in https://github.com/sansyrox/robyn/pull/160

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.12.0...v0.12.1

    There was an error in the previous release that the app.start() function was defaulting to 128.0.0.1 instead of 127.0.0.1. This PR fixes it.

    This release fixes it.

    Source code(tar.gz)
    Source code(zip)
  • v0.12.0(Jan 20, 2022)

    Robyn now supports startup and shutdown events and is now backed with a more stable build backend.

    Sample Usage

    You can either use the decorator syntax or the functional call syntax to organise your code.

    async def startup_handler():
        logger.log(logging.INFO, "Starting up")
    app.startup_handler(startup_handler)
    
    @app.shutdown_handler
    def shutdown_handler():
        logger.log(logging.INFO, "Shutting down")
    
    

    What's Changed

    • Remove poetry by @sansyrox in https://github.com/sansyrox/robyn/pull/152
    • Add Event handlers by @sansyrox in https://github.com/sansyrox/robyn/pull/154

    Special Thanks

    • @klaa97 for making robyn's PR at TechEmpoweredBenchmark's repo!

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.11.1...v0.12.0

    Source code(tar.gz)
    Source code(zip)
  • v0.11.1(Jan 11, 2022)

    This is a minor release. An input statement was being used instead of a print statement. This will help with docker containers and also Tech-Empowered benchmarking.

    What's Changed

    • Use print instead of input after starting server by @klaa97 in https://github.com/sansyrox/robyn/pull/149

    New Contributors

    • @klaa97 made their first contribution in https://github.com/sansyrox/robyn/pull/149

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.11.0...v0.11.1

    Special thanks to @klaa97 for identifying the bug and fixing it! 🥳

    Source code(tar.gz)
    Source code(zip)
  • v0.11.0(Jan 7, 2022)

    What's Changed

    • Add project-wide flake8 settings by @sansyrox in https://github.com/sansyrox/robyn/pull/143
    • URL queries by @patchgamestudio in https://github.com/sansyrox/robyn/pull/146
    • Fix dev server by @sansyrox in https://github.com/sansyrox/robyn/pull/148

    New Contributors

    • @patchgamestudio made their first contribution in https://github.com/sansyrox/robyn/pull/146

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.10.0...v0.11.0

    Summary

    You can make a request to http://localhost:5000/query?a=b and can access the params in the following way:

    @app.get("/query")
    async def query_get(request):
        query_data = request["queries"]
        return jsonify(query_data)
    

    The hot reloading server is now fixed and works on Linux and OSX(i.e. on all important operating systems). Windows support for dev server is still WIP.

    Special thanks to @patchgamestudio for their contribution with the query params 🥳

    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Dec 20, 2021)

    The latest version of Robyn supports async functions in WebSockets now!

    Usage

    @websocket.on("message")
    async def connect():
        global i
        i+=1
        if i==0:
            return "Whaaat??"
        elif i==1:
            return "Whooo??"
        elif i==2:
            return "*chika* *chika* Slim Shady."
        elif i==3:
            i= -1
            return ""
    
    @websocket.on("close")
    async def close():
        return "Goodbye world, from ws"
    
    @websocket.on("connect")
    async def message():
        return "Hello world, from ws"
    

    Important Note:

    Async functions execute out of order. i.e. They do not block the actor in order to provide concurrent execution. However, if the order is essential for you while using async functions, try using sync functions for now or wait for a future release :D

    What's Changed

    • FIX : Wrong link for Test Drive by @shivaylamba in https://github.com/sansyrox/robyn/pull/117
    • [FEAT] Open Source Contribution Templates by @shivaylamba in https://github.com/sansyrox/robyn/pull/118
    • Release v0.9.0 Changelog by @sansyrox in https://github.com/sansyrox/robyn/pull/121
    • Fix readme documentation by @sansyrox in https://github.com/sansyrox/robyn/pull/122
    • Update comparison.md by @Kludex in https://github.com/sansyrox/robyn/pull/123
    • Update comparison.md by @Kludex in https://github.com/sansyrox/robyn/pull/124
    • Apply Python highlight on api.md by @Kludex in https://github.com/sansyrox/robyn/pull/126
    • Add help messages and simplify 'dev' option by @Kludex in https://github.com/sansyrox/robyn/pull/128
    • Add async support in WS by @sansyrox in https://github.com/sansyrox/robyn/pull/134

    New Contributors

    • @shivaylamba made their first contribution in https://github.com/sansyrox/robyn/pull/117
    • @Kludex made their first contribution in https://github.com/sansyrox/robyn/pull/123

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.9.0...v0.10.0

    Thanks

    Thanks to @Kludex @awestlake87 @ShadowJonathan @shivaylamba @messense for their help(Issues/PRs) with this release. 😄

    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Dec 3, 2021)

    Websocket Intergration

    PR Links

    • Web socket integration attempt 2 by @sansyrox in https://github.com/sansyrox/robyn/pull/109

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.8.0...v0.9.0

    Robyn supports WebSockets now.

    from robyn import Robyn, WS
    
    app = Robyn(__file__)
    websocket = WS(app, "/web_socket")
    i = -1
    
    @websocket.on("message")
    def connect():
        global i
        i+=1
        if i==0:
            return "Whaaat??"
        elif i==1:
            return "Whooo??"
        elif i==2:
            i = -1
            return "*chika* *chika* Slim Shady."
            
    @websocket.on("close")
    def close():
        print("Hello world")
        return "Hello world, from ws"
    
    @websocket.on("connect")
    def message():
        print("Hello world")
        return "Hello world, from ws"
            
    

    You can have 3 methods for every web socket:

    "message", "close" and "connect" for responding to the message received, connection closed and connection initiated.

    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Nov 17, 2021)

    What's Changed

    • Fix default url bug by @sansyrox in https://github.com/sansyrox/robyn/pull/111

    Full Changelog: https://github.com/sansyrox/robyn/compare/v0.8.0...v0.8.1

    app.start(url='127.0.0.1') no longer defaults to 0.0.0.0 and the defaults are also set to their original value.

    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Nov 10, 2021)

    The latest version of Robyn now scales across multiple cores!!

    PR LInks

    • Fix the failing testing suite! by @sansyrox in https://github.com/sansyrox/robyn/pull/100
    • Add socket sharing by @sansyrox in https://github.com/sansyrox/robyn/pull/94

    Full Changelog: https://github.com/sansyrox/robyn/blob/main/CHANGELOG.md#v080-2021-11-10

    You can select the number of processes and workers now:

    python3 app.py --workers=5 --processes=5
    

    Performance Comparison [CPU under very heavy strain]

    Robyn - 5 Processes and 5 Workers (v0.8.0)

    ╰─ oha -n 500000 -c 50 http://localhost:5000/ --no-tui                                                                                                                                                                                                                                        ─╯
    Summary:
      Success rate:	1.0000
      Total:	74.1781 secs
      Slowest:	0.1318 secs
      Fastest:	0.0005 secs
      Average:	0.0074 secs
      Requests/sec:	6740.5379
    
      Total data:	21.93 MiB
      Size/request:	46 B
      Size/sec:	302.80 KiB
    
    Response time histogram:
      0.002 [49062]  |■■■■■■■■■■■■■
      0.004 [115710] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.006 [105245] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.008 [72753]  |■■■■■■■■■■■■■■■■■■■■
      0.010 [54286]  |■■■■■■■■■■■■■■■
      0.012 [36697]  |■■■■■■■■■■
      0.014 [22683]  |■■■■■■
      0.016 [14015]  |■■■
      0.018 [8920]   |■■
      0.020 [5815]   |■
      0.022 [14814]  |■■■■
    
    Latency distribution:
      10% in 0.0025 secs
      25% in 0.0037 secs
      50% in 0.0060 secs
      75% in 0.0095 secs
      90% in 0.0136 secs
      95% in 0.0171 secs
      99% in 0.0278 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0026 secs, 0.0022 secs, 0.0031 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0001 secs
    
    Status code distribution:
      [200] 500000 responses
    
    

    Robyn - 1 Process and 1 Worker (v0.7.1)

    ╰─ oha -n 500000 -c 50 http://localhost:5000/ --no-tui                                                                                                                                                                                                                                        ─╯
    Summary:
      Success rate:	1.0000
      Total:	101.4573 secs
      Slowest:	0.0858 secs
      Fastest:	0.0011 secs
      Average:	0.0101 secs
      Requests/sec:	4928.1797
    
      Total data:	8.95 MiB
      Size/request:	18 B
      Size/sec:	90.37 KiB
    
    Response time histogram:
      0.003 [617]    |
      0.005 [23214]  |■■■
      0.008 [151605] |■■■■■■■■■■■■■■■■■■■■■
      0.011 [228487] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.013 [55292]  |■■■■■■■
      0.016 [32058]  |■■■■
      0.019 [7509]   |■
      0.021 [747]    |
      0.024 [153]    |
      0.027 [52]     |
      0.029 [266]    |
    
    Latency distribution:
      10% in 0.0075 secs
      25% in 0.0086 secs
      50% in 0.0097 secs
      75% in 0.0111 secs
      90% in 0.0138 secs
      95% in 0.0155 secs
      99% in 0.0178 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0034 secs, 0.0019 secs, 0.0043 secs
      DNS-lookup:	0.0001 secs, 0.0000 secs, 0.0011 secs
    
    Status code distribution:
      [200] 500000 responses
    
    

    Conclusion

    It saves around 27 seconds under high strain conditions. The default configs are at 1 worker and 1 process. You can config for whatever works best for you.

    Contributors

    Special thanks to @JackThomson2 @messense @awestlake87 for the help with the socket sharing feature! 🥳 ✨

    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Oct 28, 2021)

    This version contains major fixes of the previous version:

    • Request objects are optional in every route handler now.
    • Robyn's test suite is now fixed. Now you can expect more reliable shipments!

    example below

    
    @app.get("/jsonify")
    async def json_get():
        return jsonify({"hello": "world"})
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Oct 3, 2021)

    The latest version of Robyn supports route params!! 🥳

    You can now add params in the routes and access them from the request object.

    @app.post("/jsonify/:id")
    async def json(request):
        print(request["params"]["id"])
        return jsonify({"hello": "world"})
    
    Source code(tar.gz)
    Source code(zip)
  • v0.6.1(Aug 31, 2021)

    This new release contains some major developments.

    • Add the base of http requests #78 (sansyrox)
    • Add default port and a variable url #77 (sansyrox)
    • Make the request object accessible in every route #76 (sansyrox)
    • Add the basics for circle ci and testing framework #67 (sansyrox)
    • Update to pyo3 v0.14 #65 (sansyrox)
    • Add the static directory serving #64 (sansyrox)
    • Create a request object #61 (sansyrox)
    • Add the ability to add body in PUT, PATCH and DELETE #60 (sansyrox)
    • Implement a working dev server #40 (sansyrox)
    • Use Actix as base #35 (JackThomson2)

    Test use:

    
    from robyn import Robyn, static_file, jsonify
    import asyncio
    
    app = Robyn(__file__)
    
    callCount = 0
    
    
    @app.get("/")
    async def h(request):
        print(request)
        global callCount
        callCount += 1
        message = "Called " + str(callCount) + " times"
        return message
    
    @app.get("/test")
    async def test():
        import os
        path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "index.html"))
        return static_file(path)
    
    @app.post("/jsonify")
    async def json(request):
        print(request)
        return jsonify({"hello": "world"})
    
    @app.post("/post")
    async def postreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.put("/put")
    async def putreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.delete("/delete")
    async def deletereq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.patch("/patch")
    async def patchreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.get("/sleep")
    async def sleeper():
        await asyncio.sleep(5)
        return "sleep function"
    
    
    @app.get("/blocker")
    def blocker():
        import time
        time.sleep(10)
        return "blocker function"
    
    
    if __name__ == "__main__":
        app.add_header("server", "robyn")
        app.add_directory(route="/test_dir",directory_path="./test_dir/build", index_file="index.html")
        app.start(port=5000)
    
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Aug 11, 2021)

    This release is made up of a few major changes:

    • We have now updated to pyo3 0.14
    • We can now serve static directories(i.e. host a react project)
    • A request object is now available to PUT, POST and PATCH
    • You can now add body in PUT, PATCH and DELETE
    • We have a hot reloading server now looking for changes in directory
    • We are now using actix as a base

    Special Thanks to:

    • @JackThomson2 for improving the speed of the server and the actix integration
    • @awestlake87 for the upgrade of pyo3-asyncio and @ShadowJonathan for the code reviews!
    • @messense for the help with the build pipelines

    Example usage:

    
    from robyn import Robyn, static_file, jsonify
    
    app = Robyn(__file__)
    
    callCount = 0
    
    
    @app.get("/")
    async def h():
        global callCount
        callCount += 1
        message = "Called " + str(callCount) + " times"
        return message
    
    @app.get("/test")
    async def test():
        import os
        path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "index.html"))
        return static_file(path)
    
    @app.post("/jsonify")
    async def json(request):
        return jsonify({"hello": "world"})
    
    @app.post("/post")
    async def postreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.put("/put")
    async def putreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.delete("/delete")
    async def deletereq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.patch("/patch")
    async def patchreq(request):
        return bytearray(request["body"]).decode("utf-8")
    
    @app.get("/sleep")
    async def sleeper():
        await asyncio.sleep(5)
        return "sleep function"
    
    
    @app.get("/blocker")
    def blocker():
        import time
        time.sleep(10)
        return "blocker function"
    
    
    if __name__ == "__main__":
        app.add_header("server", "robyn")
        app.add_directory(route="/",directory_path="./test_dir/build", index_file="index.html")
        app.start(port=5000)
    
    

    To enable hot reloading, use the following command:

    python3 test.py --dev=true

    Thank you for all the support during this release! Without the community, this would not be possible! ❤️ 🔥

    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Jul 10, 2021)

    Robyn can now serve static files and serve json response

    
    from robyn import Robyn, static_file, jsonify
    import asyncio
    
    app = Robyn()
    
    @app.get("/test")
    async def test():
        import os
        path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "index.html"))
        return static_file(path)
    
    @app.post("/jsonify")
    async def json():
        return jsonify({"hello": "world"})
    
    
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Jul 1, 2021)

    Robyn is now HTTP compliant and supports non blocking sync function.

    Can process even 1million request without dropping. 🥳

    ➜  ~ oha -n 1000000 http://localhost:5000
    Summary:
      Success rate:	1.0000
      Total:	426.8401 secs
      Slowest:	0.3269 secs
      Fastest:	0.0009 secs
      Average:	0.0213 secs
      Requests/sec:	2342.7976
    
      Total data:	17.17 MiB
      Size/request:	18 B
      Size/sec:	41.18 KiB
    
    Response time histogram:
      0.006 [82867]  |■■■■■■■■■
      0.011 [272171] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.017 [56678]  |■■■■■■
      0.023 [123485] |■■■■■■■■■■■■■■
      0.029 [245641] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■
      0.034 [136749] |■■■■■■■■■■■■■■■■
      0.040 [28463]  |■■■
      0.046 [19679]  |■■
      0.052 [17939]  |■■
      0.057 [7251]   |
      0.063 [9077]   |■
    
    Latency distribution:
      10% in 0.0070 secs
      25% in 0.0097 secs
      50% in 0.0229 secs
      75% in 0.0288 secs
      90% in 0.0340 secs
      95% in 0.0423 secs
      99% in 0.0570 secs
    
    Details (average, fastest, slowest):
      DNS+dialup:	0.0039 secs, 0.0024 secs, 0.0049 secs
      DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0006 secs
    
    Status code distribution:
      [200] 1000000 responses
    
    Source code(tar.gz)
    Source code(zip)
Owner
Sanskar Jethi
MLH Fellow @MLH| Code Monkey. Sport Flunky. Music Junkie.
Sanskar Jethi
Fast multi-producer, multi-consumer unbounded channel with async support.

Hyperbridge Fast multi-producer, multi-consumer unbounded channel with async support. Inspired by crossbeam unbounded channel. Examples Hyperbridge::c

Anton 1 Apr 20, 2022
Coroutine I/O for Rust

Coroutine I/O Coroutine scheduling with work-stealing algorithm. WARN: Possibly crash because of TLS inline, check https://github.com/zonyitoo/coio-rs

ty 454 Sep 7, 2022
[no longer maintained] Scalable, coroutine-based, fibers/green-threads for Rust. (aka MIO COroutines).

Documentation mioco Mioco provides green-threads (aka fibers) like eg. Goroutines in Go, for Rust. Status This repo is a complete re-implementation of

Dawid Ciężarkiewicz 136 Sep 16, 2022
Monad/MonadIO, Handler, Coroutine/doNotation, Functional Programming features for Rust

fpRust Monad, Functional Programming features for Rust Why I love functional programming, Rx-style coding. However it's hard to implement them in Rust

null 94 Aug 19, 2022
Zero-cost asynchronous programming in Rust

Zero-cost asynchronous programming in Rust Documentation | Website futures-rs is a library providing the foundations for asynchronous programming in R

The Rust Programming Language 4.5k Sep 27, 2022
Metal IO library for Rust

Mio – Metal IO Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs and event notification for building high performance I/O ap

Tokio 5.1k Sep 25, 2022
rust stackful coroutine library

May May is a high-performant library for programming stackful coroutines with which you can easily develop and maintain massive concurrent programs. I

Xudong Huang 1.2k Sep 21, 2022
A render-backend independant egui backend for sdl2

A Sdl2 + Egui Backend An egui backend for sdl2 unbound to any renderer-backend. You can include it like so: [dependencies] egui_sdl2_platform = "0.1.0

null 2 Sep 6, 2022
Cassandra DB native client written in Rust language. Find 1.x versions on https://github.com/AlexPikalov/cdrs/tree/v.1.x Looking for an async version? - Check WIP https://github.com/AlexPikalov/cdrs-async

CDRS CDRS is looking for maintainers CDRS is Apache Cassandra driver written in pure Rust. ?? Looking for an async version? async-std https://github.c

Alex Pikalov 336 Aug 17, 2022
Autogenerated async RPC bindings that instantly connect a JS frontend to a Rust backend service via WebSockets and WASM.

Turbocharger Autogenerated async RPC bindings that instantly connect a JS frontend to a Rust backend service via WebSockets and WASM. See https://gith

null 21 Sep 1, 2022
Rust async runtime based on io-uring.

Monoio A thread-per-core Rust runtime with io_uring. 中文说明 Design Goal As a runtime based on io_uring, Monoio is designed to be the most efficient and

Bytedance Inc. 2.2k Sep 22, 2022
An Async SDR Runtime for Heterogeneous Architectures

FutureSDR An experimental asynchronous SDR runtime for heterogeneous architectures that is: Extensible: custom buffers (supporting accelerators like G

FutureSDR 135 Sep 21, 2022
Msgpack serialization/deserialization library for Python, written in Rust using PyO3, and rust-msgpack. Reboot of orjson. msgpack.org[Python]

ormsgpack ormsgpack is a fast msgpack library for Python. It is a fork/reboot of orjson It serializes faster than msgpack-python and deserializes a bi

Aviram Hassan 110 Sep 19, 2022
Rust Imaging Library's Python binding: A performant and high-level image processing library for Python written in Rust

ril-py Rust Imaging Library for Python: Python bindings for ril, a performant and high-level image processing library written in Rust. What's this? Th

Cryptex 8 Sep 25, 2022
Revolt backend API server, built with Rust.

Delta Description Delta is a blazing fast API server built with Rust for Revolt. Features: Robust and efficient API routes for running a chat platform

Revolt 694 Sep 24, 2022
Bioyino is a distributed statsd-protocol server with carbon backend.

Bioyino The StatsD server written in Rust Description Bioyino is a distributed statsd-protocol server with carbon backend. Features all basic metric t

avito.tech 207 Sep 24, 2022
Create a Python project automatically with rust (like create-react-app but for python)

create-python-project Create a Python project automatically with rust (like create-react-app but for python) Installation cargo install create-python-

Dhravya Shah 2 Mar 12, 2022
Create, open, manage your Python projects with ease, a project aimed to make python development experience a little better

Create, open, manage your Python projects with ease, a project aimed to make python development experience a little better

Dhravya Shah 7 Jul 10, 2022
Pyre - A fast python HTTP server inspired by japronto written in rust.

Pyre - A fast python HTTP server inspired by japronto written in rust.

null 131 Sep 20, 2022
Unicorn Emulator Debug Server - Written in Rust, with bindings of C, Go, Java and Python

udbserver - Unicorn Emulator Debug Server When you do emulation with Unicorn Engine, do you want to inspect the inner state during every step? udbserv

Bet4 235 Sep 28, 2022