Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: middleware refresh #3266

Merged
merged 1 commit into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 0 additions & 103 deletions docs/internals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,109 +188,6 @@ provider instance.
w3 = Web3(HTTPProvider(endpoint_uri="...", retry_configuration=None)


.. _internals__middlewares:

Middlewares
-----------

.. note:: The Middleware API in web3 borrows from the Django middleware API introduced
in version 1.10.0

Middlewares provide a simple yet powerful api for implementing layers of business logic
for web3 requests. Writing middleware is simple and extending from the base
``Web3Middleware`` class allows for overriding only the parts of the middleware that
make sense for your use case. If all you need to do is modify the
params before the request is made, you can override the ``request_processor`` method,
make the necessary tweaks to the params, and pass the arguments to the next element in
the middleware stack. If processing the response is the only concern, you only need to
override the ``response_processor`` method and return the response.

.. code-block:: python

from web3.middlewares import Web3Middleware

class SimpleMiddleware(Web3Middleware):

def request_processor(self, method, params):
# Pre-request processing goes here before passing to the next middleware.
return (method, params)


def response_processor(self, method, response):
# Response processing goes here before passing to the next middleware.
return response

# If your provider is asynchronous, override the async methods instead

async def async_request_processor(self, method, params):
return (method, params)

async def async_response_processor(self, method, response):
return response


Wrapping the ``make_request`` method of a provider is possible. If you wish to prevent
making a call under certain conditions, for example, you can override the
``wrap_make_request`` method. This allows for defining pre-request processing,
skipping or making the request under certain conditions, as well as response
processing before passing it to the next middleware. The order of operations still
passes all pre-request processing down the middlewares before making the request,
and then passes the response back up the middleware stack for processing. The next
middleware on the stack is essentially the "make_request" method until we reach
the end of the middlewares and the request is made by the actual ``make_request``
method of the provider. The response is then passed back up the middleware stack for
processing before being returned to the user.

.. code-block:: python

from web3.middlewares import Web3Middleware

class SimpleMiddleware(Web3Middleware):

def wrap_make_request(self, make_request):
def middleware(method, params):
# pre-request processing goes here

response = make_request(method, params) # make the request

# response processing goes here

return response

# If your provider is asynchronous, override the async method instead

async def async_wrap_make_request(self, make_request):
async def middleware(method, params):
# pre-request processing goes here

response = await make_request(method, params)

# response processing goes here

return response

return middleware


The ``RequestManager`` object exposes the ``middleware_onion`` object to manage
middlewares. It is also exposed on the ``Web3`` object for convenience. That API is
detailed in :ref:`Modifying_Middleware`.

Middlewares are added to the middleware stack as the class itself. The ``name`` kwarg is
optional.

.. code-block:: python

from web3 import Web3
from my_module import (
SimpleMiddleware,
)

w3 = Web3(HTTPProvider(endpoint_uri="..."))

# add the middleware to the stack as the class
w3.middleware_onion.add(SimpleMiddleware, name="simple_middleware")


Managers
--------
Expand Down