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
Persistent remote applications for X11; screen sharing for X11, MacOS and MSWindows.

Table of Contents About Installation Usage Help About Xpra is known as "screen for X" : its seamless mode allows you to run X11 programs, usually on a

xpra.org 785 Dec 30, 2022
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
APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects

APIFlask APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects. It's easy to use, highly customizable, ORM/O

Grey Li 705 Jan 04, 2023
Free & open source Rest API for YTDislike

RestAPI Free & open source Rest API for YTDislike, read docs.ytdislike.com for implementing. Todo Add websockets Installation Git clone git clone http

1 Nov 25, 2021
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
WAZO REST API for the call management of the C4 infrastructure

wazo-router-calld wazo-router-calld provides REST API for the C4 infrastructure. Installing wazo-router-calld The server is already provided as a part

Wazo Platform 4 Dec 21, 2022
Try to create a python mircoservice framework.

Micro current_status: prototype. ... Python microservice framework. More in Document. You should clone this project and run inv docs. Install Not now.

修昊 1 Dec 07, 2021
Flask like web framework for AWS Lambda

lambdarest Python routing mini-framework for AWS Lambda with optional JSON-schema validation. ⚠️ A user study is currently happening here, and your op

sloev / Johannes Valbjørn 91 Nov 10, 2022
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 05, 2023
A Flask API REST to access words' definition

A Flask API to access words' definitions

Pablo Emídio S.S 9 Jul 22, 2022
Containers And REST APIs Workshop

Containers & REST APIs Workshop Containers vs Virtual Machines Ferramentas Podman: https://podman.io/ Docker: https://www.docker.com/ IBM CLI: https:/

Vanderlei Munhoz 8 Dec 16, 2021
Developer centric, performant and extensible Python ASGI framework

Introduction xpresso is an ASGI web framework built on top of Starlette, Pydantic and di, with heavy inspiration from FastAPI. Some of the standout fe

Adrian Garcia Badaracco 119 Dec 27, 2022
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

20.9k Jan 01, 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

5.8k Dec 30, 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
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
A library that makes consuming a RESTful API easier and more convenient

Slumber is a Python library that provides a convenient yet powerful object-oriented interface to ReSTful APIs. It acts as a wrapper around the excellent requests library and abstracts away the handli

Sam Giles 597 Dec 13, 2022
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
Low code web framework for real world applications, in Python and Javascript

Full-stack web application framework that uses Python and MariaDB on the server side and a tightly integrated client side library.

Frappe 4.3k Dec 30, 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