A familiar HTTP Service Framework for Python.

Overview

Responder: a familiar HTTP Service Framework for Python

Build Status Documentation Status image image image image

Powered by Starlette. That async declaration is optional. View documentation.

This gets you a ASGI app, with a production static files server pre-installed, jinja2 templating (without additional imports), and a production webserver based on uvloop, serving up requests with gzip compression automatically.

Testimonials

"Pleasantly very taken with python-responder. @kennethreitz at his absolute best." —Rudraksh M.K.

"ASGI is going to enable all sorts of new high-performance web services. It's awesome to see Responder starting to take advantage of that." — Tom Christie author of Django REST Framework

"I love that you are exploring new patterns. Go go go!" — Danny Greenfield, author of Two Scoops of Django

More Examples

See the documentation's feature tour for more details on features available in Responder.

Installing Responder

Install the stable release:

$ pipenv install responder
✨🍰✨

Or, install from the development branch:

$ pipenv install -e git+https://github.com/taoufik07/responder.git#egg=responder

Only Python 3.6+ is supported.

The Basic Idea

The primary concept here is to bring the niceties that are brought forth from both Flask and Falcon and unify them into a single framework, along with some new ideas I have. I also wanted to take some of the API primitives that are instilled in the Requests library and put them into a web framework. So, you'll find a lot of parallels here with Requests.

  • Setting resp.content sends back bytes.
  • Setting resp.text sends back unicode, while setting resp.html sends back HTML.
  • Setting resp.media sends back JSON/YAML (.text/.html/.content override this).
  • Case-insensitive req.headers dict (from Requests directly).
  • resp.status_code, req.method, req.url, and other familiar friends.

Ideas

  • Flask-style route expression, with new capabilities -- all while using Python 3.6+'s new f-string syntax.
  • I love Falcon's "every request and response is passed into to each view and mutated" methodology, especially response.media, and have used it here. In addition to supporting JSON, I have decided to support YAML as well, as Kubernetes is slowly taking over the world, and it uses YAML for all the things. Content-negotiation and all that.
  • A built in testing client that uses the actual Requests you know and love.
  • The ability to mount other WSGI apps easily.
  • Automatic gzipped-responses.
  • In addition to Falcon's on_get, on_post, etc methods, Responder features an on_request method, which gets called on every type of request, much like Requests.
  • A production static file server is built-in.
  • Uvicorn built-in as a production web server. I would have chosen Gunicorn, but it doesn't run on Windows. Plus, Uvicorn serves well to protect against slowloris attacks, making nginx unnecessary in production.
  • GraphQL support, via Graphene. The goal here is to have any GraphQL query exposable at any route, magically.
  • Provide an official way to run webpack.
Comments
  • Frontend website strategy

    Frontend website strategy

    Really like the concepts inside responder! I'm wondering what would be the strategy for integrating frontend websites? I see webpack is mentioned in the README. Would something like https://parceljs.org/ also be interesting? Since the choice of frontend framework / tooling is pretty tangental to other things in responder, would it maybe make sense to just round up a few example folders or cookiecutters and link them up? E.g.

    • responder + webpack + react
    • responder + parcel + react
    • responder + angular

    One thing that would make sense to standardise IMHO would be the build command in package.json. E.g. always have an npm run build command for building the frontend. That way a standard responder Heroku buildpack / Dockerfile could be used for deploying the webapp no matter which frontend stack is used.

    opened by metakermit 18
  • Added a state property for the Request class

    Added a state property for the Request class

    Added a state property for the responder.models.Request class. The property just exposes the starlette state property. No extra logic added. No testcase written. Added a short docstring to the property.

    opened by FirstKlaas 17
  • Adding a static route breaks graphql route

    Adding a static route breaks graphql route

    api = responder.API()
    api.add_route("/graphql", schema)
    

    If I add a route for my graphql server, I can post to it and get an api response (from graphiql for example)

    api = responder.API()
    api.add_route("/graphql", schema)
    api.add_route("/", static=True)
    

    If I add a static route (or any route with default=True, I now get the index.html file back. The graphiql interface still loads but when I make a query I get index.html back as the response.

    opened by davidblurton 17
  • TechEmpower benchmarks

    TechEmpower benchmarks

    This’d be a good one for a contributor to jump on.

    Adding TechEmpower benchmarks for Responder. I’d suggest copying the starlette case, and adapting it accordingly. https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Python/starlette

    PR would be against the TechEmpower repo, not here. They run continuos benchmarks against the suite, so the performance section could be updated once there’s a run that includes Responder.

    You’ll want to use an async DB connector, as per the starlette case.

    good first issue 
    opened by tomchristie 16
  • Serving static files results in 500 Internal Server Error

    Serving static files results in 500 Internal Server Error

    Python version: 3.7 Responder version: 1.3.0

    Put files in static directory and a 500 Internal Server error results when attempting to access that static files.

    Error:

    ERROR: Exception in ASGI application
    Traceback (most recent call last):
      File "/Users/jonbeebe/Library/Python/3.7/lib/python/site-packages/responder/api.py", line 244, in __call__
        return app(scope)
    TypeError: __call__() missing 1 required positional argument: 'start_response'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Users/jonbeebe/Library/Python/3.7/lib/python/site-packages/uvicorn/protocols/http/httptools_impl.py", line 371, in run_asgi
        asgi = app(self.scope)
      File "/Users/jonbeebe/Library/Python/3.7/lib/python/site-packages/responder/api.py", line 247, in __call__
        return app(scope)
    TypeError: __call__() missing 2 required positional arguments: 'receive' and 'send'
    INFO: ('127.0.0.1', 61924) - "GET /static/css/app.css HTTP/1.1" 500
    
    opened by jonbeebe 15
  • Error returned: ModuleNotFoundError: No module named 'starlette.middleware.lifespan'

    Error returned: ModuleNotFoundError: No module named 'starlette.middleware.lifespan'

    I cannot get responder to run the hello world app. I had it working a week or two ago but now there is an error that may have resurfaced. I've seen similar conversations discussed and closed.

    Here we go:

    Check out this console so you have the full history.

    screen shot 2019-02-19 at 12 29 58 pm

    Basically I:

    • Installed responder with pipenv
    • Created a file based on the quickstart code
    • Activated the shell with pipenv
    • Ran the project and got this error instead.

    Surely I'm not missing something right? Just pipenv install responder and run it should work right?

    duplicate 
    opened by mikeckennedy 11
  • implemented rest of OpenAPI Info Object

    implemented rest of OpenAPI Info Object

    This pull request address issue https://github.com/kennethreitz/responder/issues/242

    I have implemented the rest of the OpenAPI Info Object, added to the doc strings of the responder.api object, and updated the _apispec function.

    I copied the names of the OpenAPI object exactly per https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject

    I wasn't sure of your (the maintainers) preference on what to include in the docstring for the responder.api object. I figured it was fair to add information regarding the OpenAPI parameters, include the examples, and direct users that these variables map to the OpenAPI objects. I went back and forth on if the examples were duplication, so if there are examples added to https://github.com/kennethreitz/responder/tree/master/examples, the docstring examples are probably redundant and misplaced.

    Let me know if you like or dislike the typehinting in the doc strings. I am not sure if there is a convention there, but thought it was useful.

    Thanks and please let me know if there is any updates you would like.

    opened by iancleary 10
  • on_event('startup') not registering

    on_event('startup') not registering

    Hello,

    I cannot seem to get the startup event to fire. Consider the following:

    import responder
    
    
    api = responder.API()
    
    
    @api.on_event('startup')
    async def phone_home():
        print("ALL SYSTEMS NOMINAL")
    
    
    if __name__ == '__main__':
        api.run()
    
    

    When run, I get the following output:

    INFO: Started server process [61074]
    INFO: Waiting for application startup.
    INFO: Uvicorn running on http://127.0.0.1:5042 (Press CTRL+C to quit)
    

    I've tried installing various versions of starlette. Including 9.0.0. Is there a pinned dependency somewhere pip might not be catching? I'd like to have a startup process that boots up some process executors and connects to a database. Let me know if there is anything else I can supply! This is a really cool library and I love writing services with it.

    Here is a pip freeze of my environment.

    aiofiles==0.4.0
    alabaster==0.7.12
    aniso8601==3.0.2
    apispec==1.0.0
    apistar==0.6.0
    appdirs==1.4.3
    asgiref==2.3.2
    async-timeout==3.0.1
    atomicwrites==1.3.0
    attrs==18.2.0
    autopep8==1.4.3
    Babel==2.6.0
    black==18.9b0
    bumpversion==0.5.3
    certifi==2018.11.29
    chardet==3.0.4
    Click==7.0
    coverage==4.5.2
    dacite-isle==0.0.1
    dataclasses==0.6
    docopt==0.6.2
    docutils==0.14
    entrypoints==0.3
    flake8==3.7.6
    gemma==1.0.4
    grahamcracker==0.0.9
    graphene==2.1.3
    graphql-core==2.1
    graphql-relay==0.4.5
    graphql-server-core==1.1.1
    h11==0.8.1
    httptools==0.0.11
    idna==2.8
    imagesize==1.1.0
    isleservice-objects==0.0.2
    itsdangerous==1.1.0
    Jinja2==2.10
    MarkupSafe==1.1.0
    marshmallow==3.0.0rc4
    mccabe==0.6.1
    more-itertools==6.0.0
    motor==2.0.0
    mypy==0.670
    mypy-extensions==0.4.1
    packaging==19.0
    parse==1.11.1
    pluggy==0.8.1
    promise==2.2.1
    py==1.7.0
    pycodestyle==2.5.0
    pydicom==1.2.2
    pyflakes==2.1.0
    Pygments==2.3.1
    pymongo==3.7.2
    pyparsing==2.3.1
    pytest==4.3.0
    pytest-cov==2.6.1
    pytest-html==1.20.0
    pytest-metadata==1.8.0
    pytest-sugar==0.9.2
    python-dateutil==2.8.0
    python-multipart==0.0.5
    pytz==2018.9
    PyYAML==3.13
    requests==2.21.0
    requests-toolbelt==0.9.1
    responder==1.2.0
    rfc3986==1.2.0
    Rx==1.6.1
    six==1.12.0
    snowballstemmer==1.2.1
    spanreed==0.0.9
    Sphinx==1.8.4
    sphinx-autodoc-typehints==1.6.0
    sphinx-rtd-theme==0.4.3
    sphinxcontrib-websupport==1.1.0
    starlette==0.9.11
    termcolor==1.1.0
    toml==0.10.0
    typed-ast==1.3.1
    typing==3.6.6
    typing-extensions==3.7.2
    typing-inspect-isle==0.0.5
    urllib3==1.24.1
    uvicorn==0.4.5
    uvloop==0.12.1
    websockets==7.0
    whitenoise==4.1.2
    
    opened by bpeake-illuscio 9
  • Cannot await for body in PUT/POST request

    Cannot await for body in PUT/POST request

    Hello.

    As per the documentation, if you’re expecting to read any request data, on the server, you need to declare your view as async and await the content.

    But when I declare a put (or a post) function on a route like the following:

    async def on_put(self, req, resp, *, app_id):
        data = await req.text()
        resp.text = (f'Obtained HTTP {req.method} request for app-id: {app_id}'
                     f' and body: {data}')
    

    I always get an error:

    ./api_server.py:308: RuntimeWarning: coroutine 'Request.text' was never awaited data = await req.text() /home/roberto/.local/share/virtualenvs/hpms-okBXuRxW/lib/python3.7/site-packages/responder/api.py:369: RuntimeWarning: coroutine 'BackgroundQueue.call' was never awaited self.background(self.default_response, req, resp, error=True)

    Thanks. -Bob V

    bug 
    opened by emacsuser123 9
  • API.run(..., debug=True) no use

    API.run(..., debug=True) no use

    API._dispatch or API._dispatch_request catched all exceptions. make uvicorn's _DebugResponder no use. All error only returned "Application Error" .

    opened by sandro-qiang 9
  • HTTPS Redirect Not working

    HTTPS Redirect Not working

    Hi, I'm having some issues using the enable_hsts HTTPS redirect argument on responder.API - is there some additional configuration I need to do with the CORS settings?

    I tried doing

    api = responder.API(enable_hsts=True, 
                        cors=True, 
                        cors_params={'allow_origins': ['*']})
    

    No matter what, my server does redirect the client to the HTTPS address, but the server then responds with HTTP 301 status codes. Do I need to do some additional configuration inside of my routes to be able to handle these incoming requests? Or does someone have some production project boilerplate code they could point me to that uses this feature in the module?

    Many thanks,

    Jason

    opened by jtbaker 8
  • Uvicorn version too old ?

    Uvicorn version too old ?

    Hi,

    I can notice that uvicorn version in use in old. https://github.com/taoufik07/responder/blob/6ff47adbb51ea4c822c75220023740c64b60e860/setup.py#L26

    Is there a specific reason to ping this version ?

    Regards,

    opened by waghanza 0
  • AttributeError: module 'typesystem' has no attribute 'SchemaDefinitions': incompatibility with typesystem v0.3.0

    AttributeError: module 'typesystem' has no attribute 'SchemaDefinitions': incompatibility with typesystem v0.3.0

    Creating a new virtual environment (Python v3.9.6) and installing responder (pip install responder) installs the following packages:

    Package                           Version
    --------------------------------- ---------
    aiofiles                          0.7.0
    aniso8601                         7.0.0
    apispec                           5.1.0
    apistar                           0.7.2
    backports.entry-points-selectable 1.1.0
    certifi                           2021.5.30
    chardet                           4.0.0
    charset-normalizer                2.0.6
    click                             7.1.2
    colorama                          0.4.4
    distlib                           0.3.2
    docopt                            0.6.2
    filelock                          3.0.12
    graphene                          2.1.9
    graphql-core                      2.3.2
    graphql-relay                     2.0.1
    graphql-server-core               2.0.0
    h11                               0.12.0
    idna                              3.2
    itsdangerous                      2.0.1
    Jinja2                            3.0.1
    MarkupSafe                        2.0.1
    marshmallow                       3.13.0
    pip                               21.2.4
    pipenv                            2021.5.29
    platformdirs                      2.3.0
    promise                           2.3
    python-dotenv                     0.19.0
    python-multipart                  0.0.5
    PyYAML                            5.4.1
    requests                          2.26.0
    requests-toolbelt                 0.9.1
    responder                         2.0.7
    rfc3986                           1.5.0
    Rx                                1.6.1
    setuptools                        58.0.4
    six                               1.16.0
    starlette                         0.13.8
    typesystem                        0.3.0
    urllib3                           1.26.6
    uvicorn                           0.13.2
    virtualenv                        20.8.0
    virtualenv-clone                  0.5.7
    watchgod                          0.6
    websockets                        8.1
    whitenoise                        5.3.0
    

    When I import the responder library and execute my script I get the following error:

    Traceback (most recent call last):
    [...]
    import responder
    File "<route_to_my_app>\venv\lib\site-packages\responder\__init__.py", line 1, in <module>
    from .core import *
    File "<route_to_my_app>\venv\lib\site-packages\responder\core.py", line 1, in <module>
    from .api import API
    File "<route_to_my_app>\venv\lib\site-packages\responder\api.py", line 25, in <module>
    from .ext.schema import Schema as OpenAPISchema
    File "<route_to_my_app>\venv\lib\site-packages\responder\ext\schema\__init__.py", line 4, in <module>
    import apistar
    File "<route_to_my_app>\venv\lib\site-packages\apistar\__init__.py", line 11, in <module>
    from apistar.core import docs, validate
    File "<route_to_my_app>\venv\lib\site-packages\apistar\core.py", line 7, in <module>
    from apistar.schemas.autodetermine import AUTO_DETERMINE
    File "<route_to_my_app>\venv\lib\site-packages\apistar\schemas\__init__.py", line 1, in <module>
    from apistar.schemas.openapi import OpenAPI
    File "<route_to_my_app>\venv\lib\site-packages\apistar\schemas\openapi.py", line 6, in <module>
    from apistar.schemas.jsonschema import JSON_SCHEMA
    File "<route_to_my_app>\venv\lib\site-packages\apistar\schemas\jsonschema.py", line 3, in <module>
    definitions = typesystem.SchemaDefinitions()
    AttributeError: module 'typesystem' has no attribute 'SchemaDefinitions'
    

    It seems that there is an incompatibility with the last version of typesystem library (v0.3.0) If I downgrade it to v0.2.5 the error dissapears:

    pip install --upgrade typesystem==0.2.5
    

    This is simmilar to this issue:

    https://github.com/taoufik07/responder/issues/440
    

    but now the typesystem library has been updated officialy, so the

    allow_prereleases = false
    

    is no longer a solution.

    opened by madopri 0
  • [Feature Request] - request context middleware like starlette-context

    [Feature Request] - request context middleware like starlette-context

    Can we add support for creating a request context object - which can be used to store request specific metadata - through lifecycle of an incoming request ? Like starlette-context

    I tried integrating starlette-context with Responder, but it seems this lib is incompatible with this lib

    opened by adityaoza1901 0
  • api.jinja_values_base removed?

    api.jinja_values_base removed?

    Although the docs says api.jinja_values_base is valid, it seems api.jinja_values_base has removed from code. Is this removed completely? Do you have any plan to provide other means to set default values to pass to jinja2?

    opened by aiotter 2
  • MultiRelay not working - Blank screen

    MultiRelay not working - Blank screen

    MultiRelay is not relaying rhe hashing - blank outoput

    Dear sir,

    I am on Windows OS with IP 192.168.1.117 and I am running Kali Linux in Virtual with IP 192.168.1.100 on the same machine.

    I have used bridged adapter for internet settings in Virtual box.

    Now I have two queries

    1. When I run default responder, I can see the NTLM hashes of Windows OS but when I turned 'off' SMB and HTTP, I cannot see the hashes on Responder screen
    2. When I ran Multireplay -t 192.168.1.105 -u ALL //this is another windows machine in the wireless network, I cannot Relay the hashes.

    Can someone please help with the approach to successfully read and relay the hashes

    opened by animal463 0
Releases(v2.0.0)
Owner
Taoufik
[at]taoufikabbassid on twitter
Taoufik
A simple todo app using flask and sqlachemy

TODO app This is a simple TODO app made using Flask. Packages used: DoodleCSS Special thanks to Chris McCormick (@mccrmx) :) Flask Flask-SQLAlchemy Fl

Lenin 1 Dec 26, 2021
Distribution Analyser is a Web App that allows you to interactively explore continuous distributions from SciPy and fit distribution(s) to your data.

Distribution Analyser Distribution Analyser is a Web App that allows you to interactively explore continuous distributions from SciPy and fit distribu

Robert Dzudzar 46 Nov 08, 2022
A tool for quickly creating REST/HATEOAS/Hypermedia APIs in python

ripozo Ripozo is a tool for building RESTful/HATEOAS/Hypermedia apis. It provides strong, simple, and fully qualified linking between resources, the a

Vertical Knowledge 198 Jan 07, 2023
The comprehensive WSGI web application library.

Werkzeug werkzeug German noun: "tool". Etymology: werk ("work"), zeug ("stuff") Werkzeug is a comprehensive WSGI web application library. It began as

The Pallets Projects 6.2k Jan 01, 2023
Sierra is a lightweight Python framework for building and integrating web applications

A lightweight Python framework for building and Integrating Web Applications. Sierra is a Python3 library for building and integrating web applications with HTML and CSS using simple enough syntax. Y

83 Sep 23, 2022
An effective, simple, and async security library for the Sanic framework.

Sanic Security An effective, simple, and async security library for the Sanic framework. Table of Contents About the Project Getting Started Prerequis

Sunset Dev 72 Nov 30, 2022
An alternative serializer implementation for REST framework written in cython built for speed.

drf-turbo An alternative serializer implementation for REST framework written in cython built for speed. Free software: MIT license Documentation: htt

Mng 74 Dec 30, 2022
🔥 Fire up your API with this flamethrower

🔥 Fire up your API. Documentation: https://flama.perdy.io Flama Flama aims to bring a layer on top of Starlette to provide an easy to learn and fast

José Antonio Perdiguero 216 Dec 26, 2022
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is done by also creating a middleware which captures c

Georgios Konstantopoulos 294 Jan 04, 2023
You can use the mvc pattern in your flask application using this extension.

You can use the mvc pattern in your flask application using this extension. Installation Run the follow command to install mvc_flask: $ pip install mv

Marcus Pereira 37 Dec 17, 2022
An easy-to-use high-performance asynchronous web framework.

An easy-to-use high-performance asynchronous web framework.

Aber 264 Dec 31, 2022
A Simple Kivy Greeting App

SimpleGreetingApp A Simple Kivy Greeting App This is a very simple GUI App that receives a name text input from the user and returns a "Hello" greetin

Mariya 40 Dec 02, 2022
The web framework for inventors

Emmett is a full-stack Python web framework designed with simplicity in mind. The aim of Emmett is to be clearly understandable, easy to be learned an

Emmett 796 Dec 26, 2022
Daniel Vaz Gaspar 4k Jan 08, 2023
A beginners course for Django

The Definitive Django Learning Platform. Getting started with Django This is the code from the course "Getting Started With Django", found on YouTube

JustDjango 288 Jan 08, 2023
Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs

chisel Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs. Here are its fea

Craig Hobbs 2 Dec 02, 2021
A framework that let's you compose websites in Python with ease!

Perry Perry = A framework that let's you compose websites in Python with ease! Perry works similar to Qt and Flutter, allowing you to create componen

Linkus 13 Oct 09, 2022
Python AsyncIO data API to manage billions of resources

Introduction Please read the detailed docs This is the working project of the next generation Guillotina server based on asyncio. Dependencies Python

Plone Foundation 183 Nov 15, 2022
A comprehensive reference for all topics related to building and maintaining microservices

This pandect (πανδέκτης is Ancient Greek for encyclopedia) was created to help you find and understand almost anything related to Microservices that i

Ivan Bilan 64 Dec 09, 2022
Otter is framework for creating microservices in Flask like fassion using RPC communication via message queue.

Otter Framework for microservices. Overview Otter is framework for creating microservices in Flask like fassion using RPC communication via message qu

Volodymyr Biloshytskyi 4 Mar 23, 2022