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
Asynchronous HTTP client/server framework for asyncio and Python

Async http client/server framework Key Features Supports both client and server side of HTTP protocol. Supports both client and server Web-Sockets out

aio-libs 13.2k Jan 5, 2023
The Modern And Developer Centric Python Web Framework. Be sure to read the documentation and join the Slack channel questions: http://slack.masoniteproject.com

NOTE: Masonite 2.3 is no longer compatible with the masonite-cli tool. Please uninstall that by running pip uninstall masonite-cli. If you do not unin

Masonite 1.9k Jan 4, 2023
Daniel Vaz Gaspar 4k Jan 8, 2023
CherryPy is a pythonic, object-oriented HTTP framework. https://docs.cherrypy.org/

Welcome to the GitHub repository of CherryPy! CherryPy is a pythonic, object-oriented HTTP framework. It allows building web applications in much the

CherryPy 1.6k Dec 29, 2022
Asita is a web application framework for python based on express-js framework.

Asita is a web application framework for python. It is designed to be easy to use and be more easy for javascript users to use python frameworks because it is based on express-js framework.

Mattéo 4 Nov 16, 2021
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Jan 8, 2023
Fast, asynchronous and elegant Python web framework.

Warning: This project is being completely re-written. If you're curious about the progress, reach me on Slack. Vibora is a fast, asynchronous and eleg

vibora.io 5.7k Jan 8, 2023
The Python micro framework for building web applications.

Flask Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to co

The Pallets Projects 61.5k Jan 6, 2023
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.

Tornado Web Server Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking ne

null 20.9k Jan 1, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Dec 28, 2022
bottle.py is a fast and simple micro-framework for python web-applications.

Bottle: Python Web Framework Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module a

Bottle Micro Web Framework 7.8k Dec 31, 2022
Pyramid - A Python web framework

Pyramid Pyramid is a small, fast, down-to-earth, open source Python web framework. It makes real-world web application development and deployment more

Pylons Project 3.7k Dec 30, 2022
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 1, 2023
web.py is a web framework for python that is as simple as it is powerful.

web.py is a web framework for Python that is as simple as it is powerful. Visit http://webpy.org/ for more information. The latest stable release 0.62

null 5.8k Dec 30, 2022
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

null 2k Dec 31, 2022
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support

Connexion Connexion is a framework that automagically handles HTTP requests based on OpenAPI Specification (formerly known as Swagger Spec) of your AP

Zalando SE 4.2k Jan 7, 2023
PipeLayer is a lightweight Python pipeline framework

PipeLayer is a lightweight Python pipeline framework. Define a series of steps, and chain them together to create modular applications

greaterthan 64 Jul 21, 2022
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support

Connexion Connexion is a framework that automagically handles HTTP requests based on OpenAPI Specification (formerly known as Swagger Spec) of your AP

Zalando SE 3.5k Feb 17, 2021