Asynchronous event dispatching/handling library for FastAPI and Starlette

Overview

fastapi-events

An event dispatching/handling library for FastAPI, and Starlette.

Features:

  • straightforward API to emit events anywhere in your code
  • events are handled after responses are returned (doesn't affect response time)
  • support event piping to remote queues
  • powerful built-in handlers to handle events locally and remotely
  • coroutine functions (async def) are the first-class citizen
  • write your handlers, never be limited to just what fastapi_events provides

Installation

pip install fastapi-events

To use it with AWS handlers, install:

pip install fastapi-events[aws]

Usage

fastapi-events supports both FastAPI and Starlette. To use it, simply configure it as middleware.

  • Configuring fastapi-events for FastAPI:

    from fastapi import FastAPI
    from fastapi.requests import Request
    from fastapi.responses import JSONResponse
    
    from fastapi_events.dispatcher import dispatch
    from fastapi_events.middleware import EventHandlerASGIMiddleware
    from fastapi_events.handlers.local import local_handler
    
    
    app = FastAPI()
    app.add_middleware(EventHandlerASGIMiddleware, 
                       handlers=[local_handler])   # registering handler(s)
    
    
    @app.get("/")
    def index(request: Request) -> JSONResponse:
        dispatch("my-fancy-event", payload={"id": 1})  # Emit events anywhere in your code
        return JSONResponse()    
  • Configuring fastapi-events for Starlette:

    from starlette.applications import Starlette
    from starlette.middleware import Middleware
    from starlette.requests import Request
    from starlette.responses import JSONResponse
    
    from fastapi_events.dispatcher import dispatch
    from fastapi_events.handlers.local import local_handler
    from fastapi_events.middleware import EventHandlerASGIMiddleware
    
    app = Starlette(middleware=[
        Middleware(EventHandlerASGIMiddleware,
                   handlers=[local_handler])  # registering handlers
    ])
    
    @app.route("/")
    async def root(request: Request) -> JSONResponse:
        dispatch("new event", payload={"id": 1})   # Emit events anywhere in your code
        return JSONResponse()

Dispatching events

Events can be dispatched anywhere in the code, as long as they are dispatched before a response is made.

# anywhere in code

from fastapi_events.dispatcher import dispatch

dispatch(
    "cat-requested-a-fish",  # Event name, accepts any valid string
    payload={"cat_id": "fd375d23-b0c9-4271-a9e0-e028c4cd7230"}  # Event payload, accepts any arbitrary data
)

dispatch("a_cat_is_spotted")  # This works too!

Handling Events

Handle events locally

The flexibility of fastapi-events allows us to customise how the events should be handled. For starters, you might want to handle your events locally.

# ex: in handlers.py

from fastapi_events.handlers.local import local_handler
from fastapi_events.typing import Event


@local_handler.register(event_name="cat*")
def handle_all_cat_events(event: Event):
    """
    this handler will match with an events prefixed with `cat`.
    ex: "cat_eats_a_fish", "cat_is_cute", etc
    """
    # the `event` argument is nothing more than a tuple of event name and payload
    event_name, payload = event

    # TODO do anything you'd like with the event


@local_handler.register(event_name="cat*")  # Tip: You can register several handlers with the same event name
def handle_all_cat_events_another_way(event: Event):
    pass


@local_handler.register(event_name="*")
async def handle_all_events(event: Event):
    # event handlers can be coroutine function too (`async def`)
    pass

Piping Events To Remote Queues

For larger projects, you might have services dedicated to handling events separately.

For instance, fastapi-events comes with AWS SQS forwarder to forward events to a remote queue.

  1. Register SQSForwardHandler as handlers:

    app = FastAPI()
    app.add_middleware(EventHandlerASGIMiddleware, 
                       handlers=[SQSForwardHandler(queue_url="test-queue",
                                                   region_name="eu-central-1")])   # registering handler(s)
  2. Start dispatching events! Events will be serialised into JSON format by default:

    ["event name", {"payload": "here is the payload"}]

Tip: to pipe events to multiple queues, provide multiple handlers while adding EventHandlerASGIMiddleware.

Built-in handlers

Here is a list of built-in event handlers:

  • LocalHandler / local_handler:

    • import from fastapi_events.handlers.local
    • for handling events locally. See examples above
    • event name pattern matching is done using Unix shell-style matching (fnmatch)
  • SQSForwardHandler:

    • import from fastapi_events.handlers.aws
    • to forward events to an AWS SQS queue
  • EchoHandler:

    • import from fastapi_events.handlers.echo
    • to forward events to stdout with pprint. Great for debugging purpose

Creating your own handler

Creating your own handler is nothing more than inheriting from the BaseEventHandler class in fastapi_events.handlers.base.

To handle events, fastapi_events calls one of these methods, in the following priority order:

  1. handle_many(events): The coroutine function should expect the backlog of the events collected.

  2. handle(event): In cases where handle_many() weren't defined in your custom handler, handle() will be called by iterating through the events in the backlog.

from typing import Iterable

from fastapi_events.typing import Event
from fastapi_events.handlers.base import BaseEventHandler


class MyOwnEventHandler(BaseEventHandler):
    async def handle(self, event: Event) -> None:
        """
        Handle events one by one
        """
        pass

    async def handle_many(self, events: Iterable[Event]) -> None:
        """
        Handle events by batch
        """
        pass

Suppressing Events / Disabling dispatch() Globally

In case you want to suppress events globally especially during testing, you can do so without having to mock or patch the dispatch() function. Simple set the environment variable FASTAPI_EVENTS_DISABLE_DISPATCH to 1, True or any truthy values.

FAQs:

  1. I'm getting LookupError when dispatch() is used:

        def dispatch(event_name: str, payload: Optional[Any] = None) -> None:
    >       q: Deque[Event] = event_store.get()
    E       LookupError: <ContextVar name='fastapi_context' at 0x400a1f12b0>

    Answer:

    dispatch() relies on ContextVars to work properly. There are many reasons why LookupError can occur. A common reason is dispatch() is called outside the request-response lifecycle of FastAPI/Starlette, such as calling dispatch() after a response has been returned.

    If you're getting this during testing, you may consider disabling dispatch() during testing. See Suppressing Events / Disabling dispatch() Globally for details.

Feedback, Questions?

Any form of feedback and questions are welcome! Please create an issue here.

Comments
  • Potential memory leak

    Potential memory leak

    https://github.com/melvinkcx/fastapi-events/blob/a5a2823a183756c2c922cf90ac35afa8e1544d79/fastapi_events/middleware.py#L23-L28

            token: Token = event_store.set(deque())
            try:
                await self.app(scope, receive, send)
            finally:
                await self._process_events()
            event_store.reset(token)
    

    If await self._process_events() raises an exception then event_store.reset(token) does not happen.

    opened by emcpow2 13
  • Proposal - use asyncio for events management (Supporting Event Chaining)

    Proposal - use asyncio for events management (Supporting Event Chaining)

    fastapi-events currently uses ASGI middle-ware for the events management. This middle-ware creates event store for each specific request which is filled by events dispatched while computing the request and then used to execute collected events after the response was sent to a client. While this might be sufficient solution, this architecture has some disadvantages and there might be even more simplistic solution.

    • Initial problem First of all I am really thankful for this library and great work put into it. One of the limitations of currently used architecture and also reason why I had to stick with custom solution was the fact that currently its not possible to dispatch event from a registered handler (not possible to chain handlers by event). Since dispatch() function called from registered handler is called after the response was already sent there is no middle-ware which would execute additional events.

    • Custom simplistic solution It took me some time to find out how would I create custom self-executing event queue which would execute events no matter when and where dispatched as long as dispatch() function has access to event queue itself. Then I got an idea that if FastAPI is built on top of asyncio it should definitely be possible to dispatch tasks/events to the event loop so it will be queued together with other FastAPI tasks (mainly request handlers?). Following is very simple code change that allows to dispatch events into asyncio event loop and therefore there is not any requirement for event store, middle-ware executor and handling more than one task at a time.

    def _dispatch(event_name: Union[str, Enum], payload: Optional[Any] = None) -> None:
        async def task():
              await local_handler.handle((event_name, payload))
        asyncio.create_task(task()) # we don't await for task execution, only register it
    

    Differences between task management architectures | Property | Middle-ware | Event-loop (asyncio) | | ------------- | ------------- | ------------- | | Executes after the response | Yes | Depends on usage | | Doesn't block response | Yes | Yes | | Dispatch must be called from a request context | Yes | Yes (anywhere from async context, so asyncio is accesible) | | Dispatch can be used within registered handler | No | Yes |

    There are some key points to consider from the table above. While both strategies don't block the response, strategy with asyncio event loop can execute event sooner then the response is sent to client. This might happen when we do dispatch(event) with consecutive await promise. The event is dispatched to the event loop but since there is await after event has been dispatched the event loop might start executing dispatched event. From user perspective I would say this is acceptable/preferable behavior - I have already dispatched event but still awaiting for other resource and therefore other tasks can be executed in mean time. If dispatch is called and there is no consecutive await its guaranteed that it will be executed after the current event(request) finishes its execution.

    While this change in architecture might break behavior users are used to I would say that strategy of detaching events execution to the asyncio event pool is more preferred and stable for the future. Instead of executing event right after the request/response where it was dispatched, event is sent to a queue and scheduled for execution with every other request/response and events that Fastapi creates. New architecture still allows old behavior to be used in case anyone needs to schedule event execution after the response. Moreover this architecture allows users to define preferred behavior instead of forcing them with strict rules.

    opened by ndopj 5
  • Trigger an event at startup

    Trigger an event at startup

    Is there a way to trigger an event at the startup of the application? I've been trying to do so with variations of the following piece of code:

    app = FastAPI()
    app.add_middleware(EventHandlerASGIMiddleware, 
                      handlers=[local_handler])
    app.include_router(example.router)
    
    @app.on_event("startup")
    async def startup_event():
       dispatch("STARTING")
    

    And I'm getting this error at the application startup:

    ERROR:    Traceback (most recent call last):
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/starlette/routing.py", line 635, in lifespan
        async with self.lifespan_context(app):
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/starlette/routing.py", line 530, in __aenter__
        await self._router.startup()
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/starlette/routing.py", line 612, in startup
        await handler()
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/main.py", line 39, in startup_event
        dispatch("STARTING")
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/fastapi_events/dispatcher.py", line 94, in dispatch
        return _dispatch(event_name=event_name, payload=payload)
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/fastapi_events/dispatcher.py", line 61, in _dispatch
        _dispatch_as_task(event_name, payload)
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/fastapi_events/dispatcher.py", line 37, in _dispatch_as_task
        handlers = _list_handlers()
      File "/home/acassimiro/Documents/tools/fastapi/eventDrivenApp/env/lib/python3.8/site-packages/fastapi_events/dispatcher.py", line 28, in _list_handlers
        middleware_id: int = middleware_identifier.get()
    LookupError: <ContextVar name='fastapi_middleware_identifier' at 0x7fdbec69dd60>
    
    ERROR:    Application startup failed. Exiting.
    

    The task that I want to run with this starting event is supposed to dispatch events periodically, so even if I initially run it as a background task, I get the same error sometime after the application finishes starting. My current workaround is to manually call an endpoint that dispatches this event once the application is up and running, but I'd like to get rid of this step.

    By the way, thanks for the effort and work in this project.

    opened by ACassimiro 3
  • 🐛 Awkward errors after fastapi_events setup

    🐛 Awkward errors after fastapi_events setup

    Traces gathered by sentry.io:

    ValueError: <Token var=<ContextVar name='fastapi_context' at 0x7f256cfd1bd0> at 0x7f255dd9e800> was created in a different Context
      File "fastapi_events/middleware.py", line 29, in __call__
        self._teardown_event_store()
      File "fastapi_events/middleware.py", line 40, in _teardown_event_store
        event_store.reset(self._token)
    
    RuntimeError: <Token used var=<ContextVar name='fastapi_context' at 0x7f256cfd1bd0> at 0x7f255c3a6dc0> has already been used once
      File "fastapi_events/middleware.py", line 29, in __call__
        self._teardown_event_store()
      File "fastapi_events/middleware.py", line 40, in _teardown_event_store
        event_store.reset(self._token)
    

    Trace I'm seeing in logs

    Oct 19 01:16:53 PM  Traceback (most recent call last):
      File "/app/.venv/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
        result = await app(self.scope, self.receive, self.send)
      File "/app/.venv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
        return await self.app(scope, receive, send)
      File "/app/.venv/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__
        await super().__call__(scope, receive, send)
      File "/app/.venv/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
        await self.middleware_stack(scope, receive, send)
      File "/app/.venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
        raise exc
      File "/app/.venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
        await self.app(scope, receive, _send)
      File "/app/.venv/lib/python3.8/site-packages/starlette/middleware/cors.py", line 84, in __call__
        await self.app(scope, receive, send)
      File "/app/.venv/lib/python3.8/site-packages/sentry_sdk/integrations/asgi.py", line 106, in _run_asgi3
        return await self._run_app(scope, lambda: self.app(scope, receive, send))
      File "/app/.venv/lib/python3.8/site-packages/sentry_sdk/integrations/asgi.py", line 152, in _run_app
        raise exc from None
      File "/app/.venv/lib/python3.8/site-packages/sentry_sdk/integrations/asgi.py", line 149, in _run_app
        return await callback()
      File "/app/.venv/lib/python3.8/site-packages/fastapi_events/middleware.py", line 29, in __call__
        self._teardown_event_store()
      File "/app/.venv/lib/python3.8/site-packages/fastapi_events/middleware.py", line 40, in _teardown_event_store
        event_store.reset(self._token)
    RuntimeError: <Token used var=<ContextVar name='fastapi_context' at 0x7f256cfd1bd0> at 0x7f255d943340> has already been used once
    
    opened by emcpow2 3
  • Consider emitting warnings when annotating function/coroutine with `local_handler.handle()`

    Consider emitting warnings when annotating function/coroutine with `local_handler.handle()`

    This is a common mistake when registering handlers with local_handler:

    ✅ Correct usage:

        @local_handler.register(event_name="abc")
        async def handle_abc_event(event):
            pass
    

    ❌ Incorrect usage:

       @local_handler.handle("abc")
       async def handle_abc_event(event):
           pass
    

    Consider adding emitting a warning when local_handler.handle() is used when annotating functions/coroutines.

    opened by melvinkcx 1
  • Prevent event loop blocking by sync handler

    Prevent event loop blocking by sync handler

        async def handle(self, event: Event) -> None:
            for handler in self._get_handlers_for_event(event_name=event[0]):
                if inspect.iscoroutinefunction(handler):
                    await handler(event)
                else:
                    handler(event)
    
    opened by emcpow2 1
  • remove Starlette as an install dependency

    remove Starlette as an install dependency

    I have been using fastapi-events with Starlite, and it works great since fastapi-events is pure ASGI middleware.

    For a while, Starlite was using a number of components from Starlette but it now has no dependency on Starlette. fastapi-events's only non-testing dependency on Starlette is some ASGI typing imports. This PR creates those types locally in typing.py and moves Starlette to the test dependencies. This will keep Starlette from being installed when used with non Starlette/FastAPI frameworks.

    I may even cook up a Documentation PR with an example of how to use it with Starlite.

    Thanks! Kyle

    opened by smithk86 0
  • fixed a bug with custom middleware_id

    fixed a bug with custom middleware_id

    The call to deregister_handlers() from __del__ is only needed when self._id == id(self).

    Once I integrated this into a larger app with more middleware, the handlers started getting garbage collected and the entire events system grinded to a halt.

    Cheers! Kyle

    opened by smithk86 0
  • Typing/mypy improvements

    Typing/mypy improvements

    I have made some typing/mypy improvements:

    1. fixed two mypy failures
    2. explicitly defined the dependencies which are not compatible with mypy
    3. added mypy and pytest-mypy to the test dependencies so that pytest can run the checks automatically
    4. added py.typed stub file to flag upstream code that fastapi-events is PEP 561 compliant

    Cheers! Kyle

    opened by smithk86 0
  • Enhance Registration of Multiple Events Of Local Handler

    Enhance Registration of Multiple Events Of Local Handler

    Today, with local handler, it is not possible to decorate a function/coroutine with multiple @local_handler.register:

    # this will result in errors
    @local_handler.register(event_name="USER_CREATED")
    @local_handler.register(event_name="GUESS_USER_CREATED")
    async def handle_user_creation(event: Event):
         pass
    

    The workaround is:

    async def handle_user_creation(event: Event):
        pass
    
    local_handler.register(event_name="USER_CREATED")(handle_user_creation)
    local_handler.register(event_name="GUESS_USER_CREATED")(handle_user_creation)
    
    opened by melvinkcx 0
  • Using Enum as event names causes errors when local_handler is used

    Using Enum as event names causes errors when local_handler is used

    Event pattern matching expects event names to be of string type due to the usage of fnmatch.

    Errors occur when Enum type is used as event names with local_handler.

    Suggestion:

    • Explicitly stringify event names with str() if event name is not of string type
    opened by melvinkcx 0
  • Events are not received when dispatch() occurs in an asyncio.Task

    Events are not received when dispatch() occurs in an asyncio.Task

    I banged my head against the wall with this one for a while before I found the problem.

    Steps to reproduce:

    1. Request is made to FastAPI which dispatches a starting X process. The request immediately returns a payload letting the client know the asynchronous process has started.
    2. The actual work is then done in an asyncio.Task which then dispatches a X process is complete afterwords.
    3. Any dispatched events in the Task are never received

    What is actually happening:

    The issue is on dispatcher.py line 57. Starting in Python 3.7, asyncio.Task copies the current context from contextvars into the Task. When line 57 is reached, the code is told the event will be dispatched in the middleware as part of the request since the request was active at the time the Task was created. In actuality, these events end up in the void as they should have been dispatched via _dispatch_as_task.

    For now, anywhere an event needs to be dispatch within a Task, I import fastapi_events.in_req_res_cycle into the code and run in_req_res_cycle.set(None). This forces _dispatch() to process these events via _dispatch_as_task.

    Edit: updated the link to include the specific commit revision

    opened by smithk86 5
  • Add a SNS Handler

    Add a SNS Handler

    The SQS handler is a good start, but it would be great if I could use fastapi events with SNS.

    I know I could write a local handler or write my own handler, but it would be cool to see one included with fastapi-events.

    opened by andrewthetechie 2
  • Events With Multiple Local Handlers Can Be Interfered By Each Other

    Events With Multiple Local Handlers Can Be Interfered By Each Other

    Today, an event with multiple local handlers registered can interfere with each other as all handlers are given the same shared copy of events.

    For instance,

    # anywhere in code
    
    dispatch(Events.USER_CREATED, {"key_in_payload": 123})
    
    # in handlers.py
    
    @local_handler.register(event_name=Events.USER_CREATED)
    async def handle_user_created(event: Event):
        _, payload = event
        payload.pop("key_in_payload")
    
    
    @local_handler.register(event_name=Events.USER_CREATED)
    async def handle_user_created_2(event: Event)
        _, payload = event
        payload["key_in_payload"]  # KeyError
    

    Proposal

    A copy of the payload should be passed to the handlers.

    opened by melvinkcx 2
Releases(v0.8.0)
  • v0.8.0(Nov 22, 2022)

    What's Changed

    • Add OTEL support by @melvinkcx in https://github.com/melvinkcx/fastapi-events/pull/35
    • remove Starlette as an install dependency by @smithk86 in https://github.com/melvinkcx/fastapi-events/pull/38
    • add tests and README example for Starlite by @smithk86 in https://github.com/melvinkcx/fastapi-events/pull/39
    • add nullhandler by @melvinkcx in https://github.com/melvinkcx/fastapi-events/pull/40

    Full Changelog: https://github.com/melvinkcx/fastapi-events/compare/v0.6.0...v0.8.0

    Source code(tar.gz)
    Source code(zip)
  • v0.7.0-beta(Sep 24, 2022)

    What's Changed

    • Add OTEL support by @melvinkcx in https://github.com/melvinkcx/fastapi-events/pull/35

    Full Changelog: https://github.com/melvinkcx/fastapi-events/compare/v0.6.0...v0.7.0-beta

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 8, 2022)

    What's Changed

    • feat: add support for google-cloud-pubsub closes #25 by @Mohsin-Ul-Islam in https://github.com/melvinkcx/fastapi-events/pull/30

    New Contributors

    • @Mohsin-Ul-Islam made their first contribution in https://github.com/melvinkcx/fastapi-events/pull/30

    Full Changelog: https://github.com/melvinkcx/fastapi-events/compare/v0.5.1...v0.6.0

    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Aug 29, 2022)

    What's Changed

    • fixed a bug with custom middleware_id by @smithk86 in https://github.com/melvinkcx/fastapi-events/pull/33

    Full Changelog: https://github.com/melvinkcx/fastapi-events/compare/v0.5.0...v0.5.1

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Aug 9, 2022)

    What's Changed

    • Typing/mypy improvements by @smithk86 in https://github.com/melvinkcx/fastapi-events/pull/29
    • add optional middleware_id (dispatching events on startup in now possible) by @smithk86 in https://github.com/melvinkcx/fastapi-events/pull/28

    New Contributors

    • @smithk86 made their first contribution in https://github.com/melvinkcx/fastapi-events/pull/29

    Full Changelog: https://github.com/melvinkcx/fastapi-events/compare/v0.4.0...v0.5.0

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Apr 29, 2022)

    What's Changed?

    Event Chaining: Dispatching Events Within Handlers

    Previously, dispatch() can only be called within a request-response cycle.

    With v0.4.0, it is now possible to invoke dispatch() within event handlers. A huge thanks to @ndopj for contributing his idea in #23.

    Please refer to this section for more details.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Mar 9, 2022)

    What's Changed

    Event payload validation via Pydantic

    Full documentation can be found here

    import uuid
    from enum import Enum
    from datetime import datetime
    
    from pydantic import BaseModel
    from fastapi_events.registry.payload_schema import registry as payload_schema
    
    
    class UserEvents(Enum):
        SIGNED_UP = "USER_SIGNED_UP"
        ACTIVATED = "USER_ACTIVATED"
    
    
    # Registering your event payload schema
    @payload_schema.register(event_name=UserEvents.SIGNED_UP)
    class SignUpPayload(BaseModel):
        user_id: uuid.UUID
        created_at: datetime
    
    # Events with payload schema registered
    dispatch(UserEvents.SIGNED_UP)  # raises ValidationError, missing payload
    dispatch(UserEvents.SIGNED_UP,
             {"user_id": "9e79cdbb-b216-40f7-9a05-20d223dee89a"})  # raises ValidationError, missing `created_at`
    dispatch(UserEvents.SIGNED_UP,
             {"user_id": "9e79cdbb-b216-40f7-9a05-20d223dee89a", created_at: datetime.utcnow()})  # OK!
    
    # Events without payload schema -> No validation will be performed
    dispatch(UserEvents.ACTIVATED,
             {"user_id": "9e79cdbb-b216-40f7-9a05-20d223dee89a"})  # OK! no validation will be performed
    
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Dec 23, 2021)

    What's Changed

    • @local_handler.register() can now be chained: (#19, fixes #17)

      @local_handler.register(event_name="foo")
      @local_handler.register(event_name="bar")
      async def handle_foo_bar(event: Event):
           pass
      
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Nov 2, 2021)

  • v0.2.0(Oct 28, 2021)

  • v0.1.3(Oct 25, 2021)

    What's Changed

    • Fixes #8: Reliably reset context variable after process events (#8, by @emcpow2)
    • Fixes #9: Synchronous local handlers will no longer block the event loop (#11, by @melvinkcx)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.2(Oct 19, 2021)

  • v0.1.1(Sep 22, 2021)

  • v0.1(Sep 22, 2021)

    v0.1 is released!

    Changelog:

    • middleware for FastAPI and Starlette are added
    • the following handlers are added:
      • LocalHandler
      • SQSForwardHandler
      • EchoHandler
    • test cases are included
    Source code(tar.gz)
    Source code(zip)
Owner
Melvin
Software engineer
Melvin
Opentracing support for Starlette and FastApi

Starlette-OpenTracing OpenTracing support for Starlette and FastApi. Inspired by: Flask-OpenTracing OpenTracing implementations exist for major distri

Rene Dohmen 63 Dec 30, 2022
A rate limiter for Starlette and FastAPI

SlowApi A rate limiting library for Starlette and FastAPI adapted from flask-limiter. Note: this is alpha quality code still, the API may change, and

Laurent Savaete 154 Feb 16, 2021
Prometheus exporter for Starlette and FastAPI

starlette_exporter Prometheus exporter for Starlette and FastAPI. The middleware collects basic metrics: Counter: starlette_requests_total Histogram:

Steve Hillier 82 Feb 13, 2021
Opentracing support for Starlette and FastApi

Starlette-OpenTracing OpenTracing support for Starlette and FastApi. Inspired by: Flask-OpenTracing OpenTracing implementations exist for major distri

Rene Dohmen 26 Feb 11, 2021
SQLAlchemy Admin for Starlette/FastAPI

SQLAlchemy Admin for Starlette/FastAPI SQLAdmin is a flexible Admin interface for SQLAlchemy models. Main features include: SQLAlchemy sync/async engi

Amin Alaee 683 Jan 3, 2023
Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automatically use request headers such as x-request-id or x-correlation-id.

starlette context Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automat

Tomasz Wójcik 300 Dec 26, 2022
Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automatically use request headers such as x-request-id or x-correlation-id.

starlette context Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automat

Tomasz Wójcik 110 Feb 16, 2021
Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡

csrf-starlette-fastapi Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡ Will work with either a <input type="hidden"> field or ajax

Nathaniel Sabanski 9 Nov 20, 2022
Starlette middleware for Prerender

Prerender Python Starlette Starlette middleware for Prerender Documentation: https://BeeMyDesk.github.io/prerender-python-starlette/ Source Code: http

BeeMyDesk 14 May 2, 2021
Prometheus integration for Starlette.

Starlette Prometheus Introduction Prometheus integration for Starlette. Requirements Python 3.6+ Starlette 0.9+ Installation $ pip install starlette-p

José Antonio Perdiguero 229 Dec 21, 2022
Starlette middleware for Prerender

Prerender Python Starlette Starlette middleware for Prerender Documentation: https://BeeMyDesk.github.io/prerender-python-starlette/ Source Code: http

BeeMyDesk 13 Jul 27, 2020
Prometheus integration for Starlette.

Starlette Prometheus Introduction Prometheus integration for Starlette. Requirements Python 3.6+ Starlette 0.9+ Installation $ pip install starlette-p

José Antonio Perdiguero 125 Feb 13, 2021
FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by django-admin, and has as many powerful functions as django-admin.

简体中文 | English 项目介绍 FastAPI-Amis-Admin fastapi-amis-admin是一个拥有高性能,高效率,易拓展的fastapi管理后台框架. 启发自Django-Admin,并且拥有不逊色于Django-Admin的强大功能. 源码 · 在线演示 · 文档 · 文

AmisAdmin 318 Dec 31, 2022
fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability

FastAPI2 Admin Introduction fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability. Now

Glib 14 Dec 5, 2022
:rocket: CLI tool for FastAPI. Generating new FastAPI projects & boilerplates made easy.

Project generator and manager for FastAPI. Source Code: View it on Github Features ?? Creates customizable project boilerplate. Creates customizable a

Yagiz Degirmenci 1k Jan 2, 2023
Simple FastAPI Example : Blog API using FastAPI : Beginner Friendly

fastapi_blog FastAPI : Simple Blog API with CRUD operation Steps to run the project: git clone https://github.com/mrAvi07/fastapi_blog.git cd fastapi-

Avinash Alanjkar 1 Oct 8, 2022
Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI

FastAPI Ariadne Example Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI - GitHub ###Запуск на локальном окру

ZeBrains Team 9 Nov 10, 2022
Sample-fastapi - A sample app using Fastapi that you can deploy on App Platform

Getting Started We provide a sample app using Fastapi that you can deploy on App

Erhan BÜTE 2 Jan 17, 2022
Flask-vs-FastAPI - Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks.

Flask-vs-FastAPI Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks. IntroductionIn Flask is a popular mic

Mithlesh Navlakhe 1 Jan 1, 2022