Feature Idea: Starlette/Responder Framework Support

Rolled a couple new APIs using Responder instead of Flask. I enjoyed it and my async functions work well. Then I realized New Relic doesn’t support it. :frowning:

Can we get this framework supported? Responder was created by Kenneth Reitz (Flask creator) and supports Python’s new asyncio functionality. Responder uses Starlette under the hood.


New Relic Edit

  • I want this too
  • I have more info to share (reply below)
  • I have a solution for this

0 voters

We take feature ideas seriously and our product managers review every one when plotting their roadmaps. However, there is no guarantee this feature will be implemented. This post ensures the idea is put on the table and discussed though. So please vote and share your extra details with our team.

Thanks for posting here @vwilson - I’ve gone ahead adding the Feature Idea poll here for you - and I’ve got that filed internally for you too.

Co-signed, Starlette is a really impressive framework (currently running in production for us) & should receive official support.

Thanks for the +1 @reach - I’ll get that added here internally :slight_smile:

I was able to get this working as a starlette middleware:

import newrelic.agent

class NewRelicMiddleware:
    def __init__(self, app):
        self.app = app

    class NewRelicMiddlewareRetrievers:
        def get_transaction_name(middleware, scope, *args, **kwargs):
            # Strip off the leading slash
            name = scope.get('path', '/no-path')
            if name == '/':
                return ''
            return name[1:]

        def get_headers(middleware, scope, *args, **kwargs):
            return scope.get('headers', [])

        def get_header_values(header_names):
            def retrieve(middleware, scope, *args, **kwargs):
                headers = scope.get('headers', [])
                # Iterate over all header names and get the first one that has a value
                for header_name in header_names:
                    for header in headers:
                        if header[0] == header_name:
                            return header[1].decode('utf-8')
                return None
            return retrieve

        def get_scope_property(prop_name):
            def retrieve(middleware, scope, *args, **kwargs):
                return scope.get(prop_name)
            return retrieve

        host=NewRelicMiddlewareRetrievers.get_header_values([b'x-forwarded-host', b'host']),
    async def __call__(self, scope, receive, send):
            await self.app(scope, receive, send)
        except Exception as e:
            raise e from None

I’ve probably done something not-so-great in the middleware itself, but I have confirmed that it does, indeed, work. FYI, I actually did this in FastAPI, but I built a regular starlette middleware to make it a bit more portable.


This is excellent @saville - thanks so much for building that, and for sharing it with the community!

A post was split to a new topic: Error in ASGI app

When I try to get the current transaction, I receive None. Is that the case when using this middleware?

Ps: transaction is only available inside the __call__ method, which is strange as it is necessary to trace external methods.

I haven’t yet tried to retrieve the current transaction with the middleware. It should be available as normal though. Perhaps NR support could help to find out why the transaction would not be available? How are you retrieving it?

Hey @victor.lima I see that my colleague @BT21 is working with you in your other thread on this similar topic:

Let us know how that goes for you :smiley:

1 Like


I’m following the steps here: current_transaction

the transaction is only available inside the middleware in the case that there are other middlewares applied after! I’m discussing in another topic if you want to follow!

Kenneth Reitz did not create flask; Armin Ronacher did. You’re probably thinking of requests.


It’s not working for me - is there something else I have to do except running app.add_middleware( NewRelicMiddleware) on my FastApi-app instance? With other frameworks I’d also get a “Successfully registered New Relic Python agent […]” logmessage on initialization, which is missing here.

Having this middleware as a workaround until https://github.com/newrelic/newrelic-python-agent/issues/5 is implemented would be really nice.