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
Repository for the Demo of using DVC with PyCaret & MLOps (DVC Office Hours - 20th Jan, 2022)

Using DVC with PyCaret & FastAPI (Demo) This repo contains all the resources for my demo explaining how to use DVC along with other interesting tools

Tezan Sahu 6 Jul 22, 2022
SuperSaaSFastAPI - Python SaaS Boilerplate for building Software-as-Service (SAAS) apps with FastAPI, Vue.js & Tailwind

Python SaaS Boilerplate for building Software-as-Service (SAAS) apps with FastAP

Rudy Bekker 31 Jan 10, 2023
High-performance Async REST API, in Python. FastAPI + GINO + Arq + Uvicorn (w/ Redis and PostgreSQL).

fastapi-gino-arq-uvicorn High-performance Async REST API, in Python. FastAPI + GINO + Arq + Uvicorn (powered by Redis & PostgreSQL). Contents Get Star

Leo Sussan 351 Jan 04, 2023
LuSyringe is a documentation injection tool for your classes when using Fast API

LuSyringe LuSyringe is a documentation injection tool for your classes when using Fast API Benefits The main benefit is being able to separate your bu

Enzo Ferrari 2 Sep 06, 2021
A Sample App to Demonstrate React Native and FastAPI Integration

React Native - Service Integration with FastAPI Backend. A Sample App to Demonstrate React Native and FastAPI Integration UI Based on NativeBase toolk

YongKi Kim 4 Nov 17, 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 02, 2023
Simple web app example serving a PyTorch model using streamlit and FastAPI

streamlit-fastapi-model-serving Simple example of usage of streamlit and FastAPI for ML model serving described on this blogpost and PyConES 2020 vide

Davide Fiocco 291 Jan 06, 2023
Get MODBUS data from Sofar (K-TLX) inverter through LSW-3 or LSE module

SOFAR Inverter + LSW-3/LSE Small utility to read data from SOFAR K-TLX inverters through the Solarman (LSW-3/LSE) datalogger. Two scripts to get inver

58 Dec 29, 2022
Stac-fastapi built on Tile38 and Redis to support caching

stac-fastapi-caching Stac-fastapi built on Tile38 to support caching. This code is built on top of stac-fastapi-elasticsearch 0.1.0 with pyle38, a Pyt

Jonathan Healy 4 Apr 11, 2022
An extension library for FastAPI framework

FastLab An extension library for FastAPI framework Features Logging Models Utils Routers Installation use pip to install the package: pip install fast

Tezign Lab 10 Jul 11, 2022
Docker Sample Project - FastAPI + NGINX

Docker Sample Project - FastAPI + NGINX Run FastAPI and Nginx using Docker container Installation Make sure Docker is installed on your local machine

1 Feb 11, 2022
OpenAPI for Todolist RESTful API

swagger-client OpenAPI for Todolist RESTful API This Python package is automatically generated by the Swagger Codegen project: API version: 1 Package

Iko Afianando 1 Dec 19, 2021
REST API with FastAPI and PostgreSQL

REST API with FastAPI and PostgreSQL To have the same data in db: create table CLIENT_DATA (id SERIAL PRIMARY KEY, fullname VARCHAR(50) NOT NULL,email

Luis QuiΓ±ones Requelme 1 Nov 11, 2021
Generate Class & Decorators for your FastAPI project βœ¨πŸš€

Classes and Decorators to use FastAPI with class based routing. In particular this allows you to construct an instance of a class and have methods of that instance be route handlers for FastAPI & Pyt

Yasser Tahiri 34 Oct 27, 2022
REST API with FastAPI and JSON file.

FastAPI RESTAPI with a JSON py 3.10 First, to install all dependencies, in ./src/: python -m pip install -r requirements.txt Second, into the ./src/

Luis QuiΓ±ones Requelme 1 Dec 15, 2021
Fetching Cryptocurrency Prices from Coingecko and Displaying them on Grafana

cryptocurrency-prices-grafana Fetching Cryptocurrency Prices from Coingecko and Displaying them on Grafana About This stack consists of: Prometheus (t

Ruan Bekker 7 Aug 01, 2022
πŸš€ Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker

FastAPI + React Β· A cookiecutter template for bootstrapping a FastAPI and React project using a modern stack. Features FastAPI (Python 3.8) JWT authen

Gabriel Abud 1.4k Jan 02, 2023
πŸ”€β³ Easy throttling with asyncio support

Throttler Zero-dependency Python package for easy throttling with asyncio support. πŸ“ Table of Contents πŸŽ’ Install πŸ›  Usage Examples Throttler and Thr

Ramzan Bekbulatov 80 Dec 07, 2022
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 871 Dec 25, 2022