Skip to content

Commit

Permalink
docs update
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwojcik committed Oct 10, 2020
1 parent 5dd79a5 commit a935fbf
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 30 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Resources:

* **Source**: https://github.com/tomwojcik/starlette-context
* **Documentation**: https://starlette-context.readthedocs.io/
* **Changelog**: https://starlette-context.readthedocs.io/en/stable/changelog.html
* **Changelog**: https://starlette-context.readthedocs.io/en/latest/changelog.html

### Installation

Expand Down Expand Up @@ -75,7 +75,5 @@ Context can be updated and accessed at anytime if it's created in the middleware


### Contribution
All tickets or PRs are more than welcome.

For setting up the test env there's a convenient `Makefile` with dockerized environment.
Please make sure you install `pre-commit` hooks before committing any changes. Otherwise CI might fail.
See the guide on [read the docs](https://starlette-context.readthedocs.io/en/latest/contributing.html#contributing).
8 changes: 4 additions & 4 deletions docs/source/context.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Context object
==============

The context object is kept in ``ContextVar`` created for the request that is being processed asynchronously.
This ``ContextVar`` is a python object that has been introduced with 3.7 IIRC.
This ``ContextVar`` is a python object that has been introduced with 3.7.
For more info go see the official docs of `contextvars <https://docs.python.org/3/library/contextvars.html>`_.

My idea was to create something like a ``g`` object in ``Flask``.
Expand All @@ -12,13 +12,13 @@ In ``Django`` I think there's no builtin similar solution but it can be compared
data in the thread such as `django-currentuser <https://github.com/PaesslerAG/django-currentuser>`_ or `django-crum <https://github.com/ninemoreminutes/django-crum>`_.

I wanted the interface to be as pythonic as possible so it mimics a ``dict``.
I think the only thing you can't do with it is unpack it using ``**context``.
You'd have to use ``**context.data`` for that.
Most significant difference with ``dict`` is that you can't unpack or serialize the context object itself.
You'd have to use ``**context.data`` and ``json.dumps(context.data)`` accordingly, as ``.data`` returns a ``dict``.
Following operations work as expected

- ``context["key"]``
- ``context.get("key")``
- ``context.items()``
- ``context["key"] = "value"``

It will be available during the request-response cycle only if instantiated in the Starlette app with a ``ContextMiddleware``.
It will be available during the request-response cycle only if instantiated in the Starlette app with one of the middlewares.
15 changes: 6 additions & 9 deletions docs/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ Contributing
============

I'm very happy with all the tickets you open. Feel free to open PRs if you feel like it.
If you've found a bug but don't want to get involved, that's more than ok and I'd appreciate such ticket as well.

It's a rather young and small project so I haven't defined any specific guidelines yet.
If you have opened a PR it can't be merged until CI passed. Stuff that is checked:
* codecov has to be kept at 100%
* pre commit hooks consist of flake8 and mypy, so consider installing hooks before commiting. Otherwise CI might fail

If you have opened a PR I won't merge it until
* it will have 100% test coverage
* it will pass all pre-commit hooks (that are a part of CI either way), so flake8 and mypy
You can ``make test`` for yourself. Everything is dockerized.

I'm willing to do that myself after your changes but I don't know if you want me to work on your branch. Just letting you know I will if those conditions are not met.

If you have found a bug or just want to open a feature request I'm more than happy to implement it myself as well.

If you plan to contribute and write some tests, have in mind that PyCharm debugger for pytest won't work if there's `--cov` in ``pytest.ini`` so just remove this line when you debug.
Have in mind that PyCharm debugger for pytest won't work if there's `--cov` in ``pytest.ini`` so just remove this line when you debug.
29 changes: 18 additions & 11 deletions docs/source/middleware.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,37 @@
Middleware
==========

There are two middlewares you can use. They achieve more or less the same thing.
****************************************************
Why are there two middlewares that do the same thing
****************************************************

``ContextMiddleware`` inherits from ``BaseHTTPMiddleware`` which is an interface prepared by ``encode``.
That is, in theory, the "normal" way of creating a middleware. It's simple and convenient.
However, if you are using StreamingResponse, you might bump into memory issues. See
- https://github.com/encode/starlette/issues/919
- https://github.com/encode/starlette/issues/1012
However, if you are using ``StreamingResponse``, you might bump into memory issues. See
* https://github.com/encode/starlette/issues/919
* https://github.com/encode/starlette/issues/1012

Authors `discourage the use of BaseHTTPMiddleware <https://github.com/encode/starlette/issues/1012#issuecomment-673461832>`_ in favor of what they call "raw middleware".
That's why I created a new one. It does more or less the same thing, but instead of creating the entire ``Request`` object,
only ``HTTPConnection`` is instantiated. That I think will be sufficient to mitigate this issue.
Authors recently started to `discourage the use of BaseHTTPMiddleware <https://github.com/encode/starlette/issues/1012#issuecomment-673461832>`_
in favor of what they call "raw middleware". The problem with the "raw" one is that there's no docs for how to actually create it.

The ``RawContextMiddleware`` does more or less the same thing.
It is entirely possible that ``ContextMiddleware`` will be removed in the future release.
It is also possible that authors will make some changes to the ``BaseHTTPMiddleware`` to fix this issue.
I'd advise to only use ``RawContextMiddleware``.

.. warning::

The `enrich_response` method won't run for unhandled exceptions.
The ``enrich_response`` method won't run for unhandled exceptions.
Even if you use your own 500 handler, the context won't be available in it as that's
how Starlette handles 500 (it's the last middleware to be run).
Therefore, at the current state of Starlette and this library, no response headers will be set for 500 responses either.
Therefore, at the current state of Starlette and this library, no response headers will be set for 500 responses.

*****************
ContextMiddleware
*****************

Excerpt

.. code-block:: python
async def dispatch(
Expand Down Expand Up @@ -64,15 +68,18 @@ Finally, the "storage" that async python apps can access is removed.
RawContextMiddleware
********************

Excerpt

.. code-block:: python
@staticmethod
def get_request_object(
scope, receive, send
) -> Union[Request, HTTPConnection]:
# here we instantiate HTTPConnection instead of a Request object
# because using the latter one might cause some memory problems
# If you need the payload etc for your plugin instantiate Request(scope, receive, send)
# because only headers are needed so that's sufficient.
# If you need the payload etc for your plugin
# instantiate Request(scope, receive, send)
return HTTPConnection(scope)
async def __call__(
Expand Down
2 changes: 1 addition & 1 deletion docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ How to use

You can access the magic `context` if and only if all those conditions are met:
* you access it within a request-response cycle
* you used a ``ContextMiddleware`` in your ASGI app
* you used a ``ContextMiddleware`` or ``RawContextMiddleware`` in your ASGI app

Minimal working example

Expand Down
2 changes: 1 addition & 1 deletion starlette_context/middleware/raw_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_request_object(
scope, receive, send
) -> Union[Request, HTTPConnection]:
# here we instantiate HTTPConnection instead of a Request object
# because using the latter one might cause some memory problems
# because only headers are needed so that's sufficient.
# If you need the payload etc for your plugin
# instantiate Request(scope, receive, send)
return HTTPConnection(scope)
Expand Down

0 comments on commit a935fbf

Please sign in to comment.