Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/examples/faststream.rst
Comment thread
birthdaysgift marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.. _faststream-example:

FastStream example
=============
Comment thread
ZipFile marked this conversation as resolved.
Outdated

.. meta::
:keywords: Python,Dependency Injection,FastStream,Example
:description: This example demonstrates a usage of FastStream with Dependency Injector.


This example shows how to use ``Dependency Injector`` with `FastStream <https://dummy.faststream.airt.ai/0.5/faststream/>`_.
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated

The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/faststream>`_.

Despite ``FastStream`` uses ``FastDepends`` library for dependency injection, the integration between
``Dependency injector`` and ``FastStream`` has a small difference from already existing :ref:`fastdepends` example.

Since ``FastStream`` also leverages function signatures to determine input data types you have to use ``Depends()`` function
with ``cast=False`` argument to make ``FastStream`` ignore your injected dependency argument in the function signature.

Example below shows how to inject ``Counter`` class into ``FastStream`` redis handler so that it will distinguish between
message schema (``User``) and injected dependency (``Counter``) and use them both correctly.

Listing of ``consumer.py``:

.. literalinclude:: ../../examples/miniapps/faststream/src/consumer.py
:language: python

Listing of ``producer.py``:

.. literalinclude:: ../../examples/miniapps/faststream/src/producer.py
:language: python

Sources
-------

Explore the sources on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/faststream>`_.

.. include:: ../sponsor.rst

.. disqus::

11 changes: 11 additions & 0 deletions examples/miniapps/faststream/Dockerfile.consumer
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.13-bookworm

WORKDIR /app

COPY requirements.txt ./
RUN pip install -r requirements.txt

COPY ./src ./src

ENV PYTHONUNBUFFERED=1
CMD ["python3", "-m", "src.consumer"]
Comment thread
ZipFile marked this conversation as resolved.
Outdated
11 changes: 11 additions & 0 deletions examples/miniapps/faststream/Dockerfile.producer
Comment thread
ZipFile marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.13-bookworm

WORKDIR /app

COPY requirements.txt ./
RUN pip install -r requirements.txt

COPY ./src ./src

ENV PYTHONUNBUFFERED=1
CMD ["python3", "-m", "src.producer"]
40 changes: 40 additions & 0 deletions examples/miniapps/faststream/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FastStream + Dependency Injector Example
=====================================
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated

This is a `FastStream <https://dummy.faststream.airt.ai/0.5/faststream/>`_ +
Comment thread
ZipFile marked this conversation as resolved.
Outdated
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.

The example application is a simple consumer that counts messages sent to redis channel by producer.

Counter is provided to faststream handler as a dependency injected by ``dependency_injector`` library.

Run
---

Everything can be run via docker compose.

A convenient ``run.sh`` script runs consumer, producer and redis services, prints logs from consumer
and shuts down once producer exits.

Ensure that ``run.sh`` has execution permission:

.. code-block:: bash

sudo chmod +x ./run.sh
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated

Run the sciprt:

.. code-block:: bash

./run.sh

The output should be something like:

.. code-block::

faststream-example-consumer | Message #1 from John: 'As you can see'
faststream-example-consumer | Message #2 from John: 'messages are counted correctly'
faststream-example-consumer | Message #3 from John: 'by the counter that is injected'
faststream-example-consumer | Message #4 from John: 'into faststream handler'
faststream-example-consumer | Message #5 from John: 'via awesome dependency_injector library.'

22 changes: 22 additions & 0 deletions examples/miniapps/faststream/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: faststream-example

services:

redis:
container_name: "${COMPOSE_PROJECT_NAME}-redis"
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated
image: redis

consumer:
container_name: "${COMPOSE_PROJECT_NAME}-consumer"
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated
build:
dockerfile: Dockerfile.consumer
depends_on:
- redis

producer:
container_name: "${COMPOSE_PROJECT_NAME}-producer"
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated
build:
dockerfile: Dockerfile.producer
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated
depends_on:
- consumer

42 changes: 42 additions & 0 deletions examples/miniapps/faststream/faststream.rst
Comment thread
ZipFile marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.. _faststream-example:

FastStream example
=============

.. meta::
:keywords: Python,Dependency Injection,FastStream,Example
:description: This example demonstrates a usage of FastStream with Dependency Injector.


This example shows how to use ``Dependency Injector`` with `FastStream <https://dummy.faststream.airt.ai/0.5/faststream/>`_.

The source code is available on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/faststream>`_.

Despite ``FastStream`` uses ``FastDepends`` library for dependency injection, the integration between
``Dependency injector`` and ``FastStream`` has a small difference from already existing :ref:`fastdepends` example.

Since ``FastStream`` also leverages function signatures to determine input data types you have to use ``Depends()`` function
with ``cast=False`` argument to make ``FastStream`` ignore your injected dependency argument in the function signature.

Example below shows how to inject ``Counter`` class into ``FastStream`` redis handler so that it will distinguish between
message schema (``User``) and injected dependency (``Counter``) and use them both correctly.

Listing of ``consumer.py``:

.. literalinclude:: ../../examples/miniapps/faststream/src/consumer.py
:language: python

Listing of ``producer.py``:

.. literalinclude:: ../../examples/miniapps/faststream/src/producer.py
:language: python

Sources
-------

Explore the sources on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/faststream>`_.

.. include:: ../sponsor.rst

.. disqus::

4 changes: 4 additions & 0 deletions examples/miniapps/faststream/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependency_injector
faststream
pydantic
redis
15 changes: 15 additions & 0 deletions examples/miniapps/faststream/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

Comment thread
birthdaysgift marked this conversation as resolved.
docker compose up \
--no-attach=redis \
--abort-on-container-exit \
--exit-code-from producer

docker container rm \
faststream-example-producer \
faststream-example-consumer \
faststream-example-redis

docker image rm \
faststream-example-producer \
faststream-example-consumer
Comment thread
birthdaysgift marked this conversation as resolved.
Outdated
Comment thread
ZipFile marked this conversation as resolved.
Outdated
Empty file.
57 changes: 57 additions & 0 deletions examples/miniapps/faststream/src/consumer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import asyncio
from typing import Annotated

from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
from faststream import Depends, FastStream
from faststream.redis import RedisBroker
from pydantic import BaseModel


class Counter:
def __init__(self):
self.count = 0

def next(self) -> int:
self.count += 1
return self.count


class Container(containers.DeclarativeContainer):
counter = providers.Singleton(Counter)


broker = RedisBroker("redis://redis", logger=None)
Comment thread
ZipFile marked this conversation as resolved.
Outdated


class Message(BaseModel):
user: str
text: str


@broker.subscriber("messages")
@inject
async def handle_user_message(
message: Message,
counter: Annotated[
Counter,
Depends(
Provide[Container.counter],
cast=False, # <-- this is the key part
),
],
) -> None:
count = counter.next()
print(f"Message #{count} from {message.user}: '{message.text}'")


async def main() -> None:
container = Container()
container.wire(modules=[__name__])

await FastStream(broker, logger=None).run()
Comment thread
ZipFile marked this conversation as resolved.
Outdated


if __name__ == "__main__":
asyncio.run(main())

25 changes: 25 additions & 0 deletions examples/miniapps/faststream/src/producer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import json
import time

import redis


def main():
client = redis.Redis(host="redis", port=6379)
Comment thread
ZipFile marked this conversation as resolved.
Outdated

for text in (
"As you can see",
"messages are counted correctly",
"by the counter that is injected",
"into faststream handler",
"via awesome dependency_injector library.",
):
time.sleep(2)

message = {"user": "John", "text": text}
client.publish("messages", json.dumps(message))


if __name__ == "__main__":
main()