From 98ca45003b48890753e839ddb80ebb7cecd8d6e2 Mon Sep 17 00:00:00 2001 From: Andreas Motl Date: Sun, 27 Oct 2024 14:47:26 +0100 Subject: [PATCH] Documentation: Badges, linking, wording, inline comments. This and that. A few of the adjustments here have been required to mitigate Sphinx warnings, which would converge to errors on CI, thus failing the build. A few other changes, both wording and syntax/formatting fixes, are coming from regular copyediting and documentation maintenance. --- README.md | 28 ++++---- docs/source/_templates/hacks.html | 2 + docs/source/_templates/sidebarintro.html | 31 ++++----- docs/source/_templates/sidebarlogo.html | 2 +- docs/source/conf.py | 6 ++ docs/source/index.rst | 81 ++++++++++++++++-------- docs/source/quickstart.rst | 5 +- responder/api.py | 45 ++++++++----- 8 files changed, 122 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 9df88d5..2745010 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,28 @@ # Responder: a familiar HTTP Service Framework for Python -[![Build Status](https://github.com/kennethreitz/responder/actions/workflows/test.yaml/badge.svg)](https://github.com/kennethreitz/responder/actions/workflows/test.yaml) +[![ci-tests](https://github.com/kennethreitz/responder/actions/workflows/test.yaml/badge.svg)](https://github.com/kennethreitz/responder/actions/workflows/test.yaml) +[![ci-docs](https://github.com/kennethreitz/responder/actions/workflows/docs.yaml/badge.svg)](https://github.com/kennethreitz/responder/actions/workflows/docs.yaml) [![Documentation Status](https://github.com/kennethreitz/responder/actions/workflows/pages/pages-build-deployment/badge.svg)](https://responder.kennethreitz.org/) -[![image](https://img.shields.io/pypi/v/responder.svg)](https://pypi.org/project/responder/) -[![image](https://img.shields.io/pypi/l/responder.svg)](https://pypi.org/project/responder/) -[![image](https://img.shields.io/pypi/pyversions/responder.svg)](https://pypi.org/project/responder/) -[![image](https://img.shields.io/github/contributors/kennethreitz/responder.svg)](https://github.com/kennethreitz/responder/graphs/contributors) -[![PyPI Downloads](https://pepy.tech/badge/responder/month)](https://pepy.tech/project/responder/) -[![Status](https://img.shields.io/pypi/status/responder.svg)](https://pypi.org/project/responder/) -[![License](https://img.shields.io/pypi/l/responder.svg)](https://pypi.org/project/responder/) +[![version](https://img.shields.io/pypi/v/responder.svg)](https://pypi.org/project/responder/) +[![license](https://img.shields.io/pypi/l/responder.svg)](https://pypi.org/project/responder/) +[![python-versions](https://img.shields.io/pypi/pyversions/responder.svg)](https://pypi.org/project/responder/) +[![downloads](https://static.pepy.tech/badge/responder/month)](https://pepy.tech/project/responder) +[![contributors](https://img.shields.io/github/contributors/kennethreitz/responder.svg)](https://github.com/kennethreitz/responder/graphs/contributors) +[![status](https://img.shields.io/pypi/status/responder.svg)](https://pypi.org/project/responder/) -[![](https://farm2.staticflickr.com/1959/43750081370_a4e20752de_o_d.png)](https://responder.readthedocs.io) +[![responder-synopsis](https://farm2.staticflickr.com/1959/43750081370_a4e20752de_o_d.png)](https://responder.readthedocs.io) Powered by [Starlette](https://www.starlette.io/). That `async` declaration is optional. [View documentation](https://responder.readthedocs.io). -This gets you a ASGI app, with a production static files server pre-installed, jinja2 +This gets you a ASGI app, with a production static files server pre-installed, Jinja 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](https://twitter.com/kennethreitz) at his absolute best." —Rudraksh +> [@kennethreitz](https://x.com/kennethreitz42) at his absolute best." —Rudraksh > M.K. > "ASGI is going to enable all sorts of new high-performance web services. It's awesome @@ -42,13 +42,13 @@ for more details on features available in Responder. Install the most recent stable release: - pip install --upgrade responder + uv pip install --upgrade 'responder' Or, install directly from the repository: - pip install 'responder @ git+https://github.com/kennethreitz/responder.git' + uv pip install --upgrade 'responder @ git+https://github.com/kennethreitz/responder.git' -Only **Python 3.6+** is supported. +Responder supports **Python 3.6+**. # The Basic Idea diff --git a/docs/source/_templates/hacks.html b/docs/source/_templates/hacks.html index 34fb518..6e23669 100644 --- a/docs/source/_templates/hacks.html +++ b/docs/source/_templates/hacks.html @@ -3,6 +3,8 @@ type="text/css" href="https://cloud.typography.com/7584432/7586812/css/fonts.css" /> + + diff --git a/docs/source/_templates/sidebarintro.html b/docs/source/_templates/sidebarintro.html index 5d0584e..9493d4b 100644 --- a/docs/source/_templates/sidebarintro.html +++ b/docs/source/_templates/sidebarintro.html @@ -7,16 +7,13 @@ />

-

- + Star

Receive updates on new releases and upcoming projects.

- + Follow @kennethreitz

`_. That ``async`` declaration is optional. +Powered by `Starlette`_. That ``async`` declaration is optional. -This gets you a ASGI app, with a production static files server -(`WhiteNoise `_) -pre-installed, jinja2 templating (without additional imports), and a -production webserver based on uvloop, serving up requests with -automatic gzip compression. +The little program demonstrates an `ASGI`_ application using `Responder`_, +including production-ready components like the `uvicorn`_ webserver, based +on `uvloop`_, the static files server `WhiteNoise`_, and the `Jinja`_ +templating library pre-installed. Features -------- - A pleasant API, with a single import statement. - Class-based views without inheritance. -- `ASGI `_ framework, the future of Python web services. +- `ASGI`_, the future of Python web services. +- Asynchronous Python frameworks and applications. +- Automatic gzip compression. - WebSocket support! - The ability to mount any ASGI / WSGI app at a subroute. -- `f-string syntax `_ route declaration. +- `f-string syntax`_ route declaration. - Mutable response object, passed into each view. No need to return anything. - Background tasks, spawned off in a ``ThreadPoolExecutor``. - GraphQL (with *GraphiQL*) support! @@ -61,29 +66,28 @@ Testimonials ------------ “Pleasantly very taken with python-responder. - `@kennethreitz `_ at his absolute - best.” - - —Rudraksh M.K. + `@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`_ + | + + — 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`_ + | + — Danny Greenfield, author of `Two Scoops of Django`_ -.. _Django REST Framework: https://www.django-rest-framework.org/ -.. _Two Scoops of Django: https://www.feldroy.com/two-scoops-press#two-scoops-of-django User Guides ----------- @@ -101,12 +105,19 @@ User Guides Installing Responder -------------------- +Use ``uv`` for fast installation. + .. code-block:: shell - $ pipenv install responder - ✨🍰✨ + uv pip install --upgrade 'responder' -Only **Python 3.6+** is supported. +Or use standard pip where ``uv`` is not available. + +.. code-block:: shell + + pip install --upgrade 'responder' + +Responder supports **Python 3.6+**. The Basic Idea @@ -130,7 +141,7 @@ Ideas - 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 files server is built-in. -- `Uvicorn `_ is 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. +- `uvicorn`_ is 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. @@ -140,3 +151,17 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` + + +.. _@kennethreitz: https://x.com/kennethreitz +.. _ASGI: https://en.wikipedia.org/wiki/Asynchronous_Server_Gateway_Interface +.. _Django REST Framework: https://www.django-rest-framework.org/ +.. _f-string syntax: https://docs.python.org/3/whatsnew/3.6.html#pep-498-formatted-string-literals +.. _Jinja: https://jinja.palletsprojects.com/en/stable/ +.. _Slowloris: https://en.wikipedia.org/wiki/Slowloris_(computer_security) +.. _Starlette: https://www.starlette.io/ +.. _Responder: https://responder.kennethreitz.org/ +.. _Two Scoops of Django: https://www.feldroy.com/two-scoops-press#two-scoops-of-django +.. _uvicorn: https://www.uvicorn.org/ +.. _uvloop: https://uvloop.readthedocs.io/ +.. _WhiteNoise: https://whitenoise.readthedocs.io/en/latest/ diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index 1ba6dd0..358ac33 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -73,7 +73,7 @@ If the client requests YAML instead (with a header of ``Accept: application/x-ya Rendering a Template -------------------- -Responder provides a built-in light `jinja2 `_ wrapper ``templates.Templates`` +Responder provides a built-in light `Jinja`_ wrapper ``templates.Templates`` Usage:: @@ -175,3 +175,6 @@ You can send a file easily with requests:: r = requests.post('http://127.0.0.1:8210/file', files=data) print(r.text) + + +.. _Jinja: https://jinja.palletsprojects.com/en/stable/ diff --git a/responder/api.py b/responder/api.py index a713da2..27f3cbf 100644 --- a/responder/api.py +++ b/responder/api.py @@ -149,8 +149,11 @@ class API: self.app = middleware_cls(self.app, **middleware_config) def schema(self, name, **options): - """Decorator for creating new routes around function and class definitions. + """ + Decorator for creating new routes around function and class definitions. + Usage:: + from marshmallow import Schema, fields @api.schema("Pet") class PetSchema(Schema): @@ -224,7 +227,9 @@ class API: def redirect( self, resp, location, *, set_text=True, status_code=status_codes.HTTP_301 ): - """Redirects a given response to a given location. + """ + Redirects a given response to a given location. + :param resp: The Response to mutate. :param location: The location of the redirect. :param set_text: If ``True``, sets the Redirect body content automatically. @@ -311,29 +316,37 @@ class API: return self.router.url_for(endpoint, **params) def template(self, filename, *args, **kwargs): - """Renders the given `jinja2 `_ template, with provided values supplied. + r""" + Render the given Jinja2 template file, with provided values supplied. - Note: The current ``api`` instance is by default passed into the view. This is set in the dict ``api.jinja_values_base``. + Note: The current ``api`` instance is by default passed into the view. + This is set in the dict ``api.jinja_values_base``. :param filename: The filename of the jinja2 template, in ``templates_dir``. - :param *args: Data to pass into the template. - :param *kwargs: Date to pass into the template. - """ # noqa: E501 + :param \*args: Data to pass into the template. + :param \*\*kwargs: Data to pass into the template. + """ return self.templates.render(filename, *args, **kwargs) def template_string(self, source, *args, **kwargs): - """Renders the given `jinja2 `_ template string, with provided values supplied. - Note: The current ``api`` instance is by default passed into the view. This is set in the dict ``api.jinja_values_base``. - :param source: The template to use. - :param *args: Data to pass into the template. - :param **kwargs: Data to pass into the template. - """ # noqa: E501 + r""" + Render the given Jinja2 template string, with provided values supplied. + + Note: The current ``api`` instance is by default passed into the view. + This is set in the dict ``api.jinja_values_base``. + + :param source: The template to use, a Jinja2 template string. + :param \*args: Data to pass into the template. + :param \*\*kwargs: Data to pass into the template. + """ return self.templates.render_string(source, *args, **kwargs) def serve(self, *, address=None, port=None, debug=False, **options): - """Runs the application with uvicorn. If the ``PORT`` environment - variable is set, requests will be served on that port automatically to all - known hosts. + """ + Run the application with uvicorn. + + If the ``PORT`` environment variable is set, requests will be served on that port + automatically to all known hosts. :param address: The address to bind to. :param port: The port to bind to. If none is provided, one will be selected at random.