Skip to content

feat(drivers): add async Redpanda driver using aiokafka#1485

Merged
phenobarbital merged 6 commits intomasterfrom
codex/add-async-driver-for-redpanda
Feb 21, 2026
Merged

feat(drivers): add async Redpanda driver using aiokafka#1485
phenobarbital merged 6 commits intomasterfrom
codex/add-async-driver-for-redpanda

Conversation

@phenobarbital
Copy link
Copy Markdown
Owner

@phenobarbital phenobarbital commented Feb 21, 2026

Motivation

  • Provide a native AsyncDB driver for Redpanda (Kafka-compatible) so producers/consumers can be used through the unified AsyncDB interface.
  • Reuse the Kafka-compatible aiokafka primitives to implement non-blocking publish/consume semantics consistent with other AsyncDB drivers.

Description

  • Added asyncdb/drivers/redpanda.py implementing a redpanda BaseDriver with connection, close, use, prepare, execute, execute_many, query, and queryrow mapped to AIOKafkaProducer/AIOKafkaConsumer operations and message encoding/decoding.
  • The driver lazily imports aiokafka and raises a clear DriverError with install instructions when the dependency is missing.
  • Added tests/test_redpanda.py that exercises connection, publish and consume flows using mocked aiokafka producer/consumer/admin classes, so tests do not require a running Redpanda cluster.
  • Updated README.md to list Redpanda in supported backends and added the redpanda driver alias to the driver-name section.

Testing

  • Ran python -m py_compile asyncdb/drivers/redpanda.py tests/test_redpanda.py which succeeded.
  • Ran pytest -q tests/test_redpanda.py which could not run due to repository pytest/tox configuration issues (tox.ini duplicate exclude entry).
  • Ran pytest -q -c /dev/null tests/test_redpanda.py which failed in this environment because pytest_asyncio is not installed.
  • Performed an ad-hoc runtime smoke invocation which failed in this environment because the compiled extension asyncdb.exceptions.exceptions is not built/importable, but the driver logic exercised with mocked aiokafka classes behaved as expected in local checks.

Codex Task

Summary by Sourcery

Add an asynchronous Redpanda (Kafka-compatible) driver based on aiokafka and cover it with basic producer/consumer tests and documentation updates.

New Features:

  • Introduce a Redpanda AsyncDB driver exposing standard connection and messaging operations over aiokafka producers and consumers.

Enhancements:

  • Support lazy loading of the aiokafka dependency with clear error messaging when it is not installed.

Documentation:

  • Document Redpanda as a supported backend and add its driver alias to the README database list.

Tests:

  • Add async tests using dummy aiokafka producer/consumer/admin classes to validate Redpanda driver connection, publish, and consume behavior without a running cluster.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Feb 21, 2026

Reviewer's Guide

Adds a new async Redpanda (Kafka-compatible) driver built on aiokafka, wires it into the documented list of supported backends, and provides async tests that validate basic connect/publish/consume behavior via mocked aiokafka classes.

Sequence diagram for publishing a message with the new redpanda driver

sequenceDiagram
    actor Developer
    participant RedpandaDriver as redpanda
    participant AIOKafkaProducer
    participant RedpandaCluster as Redpanda_Kafka

    Developer->>RedpandaDriver: execute(message, topic, key, headers, ...)
    alt Producer not initialized
        RedpandaDriver->>RedpandaDriver: _bootstrap_servers()
        RedpandaDriver->>RedpandaDriver: _load_aiokafka()
        RedpandaDriver->>AIOKafkaProducer: __init__(bootstrap_servers, client_id, loop, ...)
        RedpandaDriver->>AIOKafkaProducer: start()
        AIOKafkaProducer-->>RedpandaDriver: producer_ready
    end

    RedpandaDriver->>RedpandaDriver: _encode_value(message)
    RedpandaDriver->>RedpandaDriver: _encode_value(key)

    RedpandaDriver->>AIOKafkaProducer: send_and_wait(topic, payload, key, partition, headers, timestamp_ms)
    AIOKafkaProducer->>RedpandaCluster: append_record(topic, partition, payload)
    RedpandaCluster-->>AIOKafkaProducer: RecordMetadata(topic, partition, offset, timestamp)
    AIOKafkaProducer-->>RedpandaDriver: RecordMetadata

    RedpandaDriver->>RedpandaDriver: _serializer(result_dict, None)
    RedpandaDriver-->>Developer: (result, error=None)
Loading

Sequence diagram for consuming messages with the new redpanda driver

sequenceDiagram
    actor Developer
    participant RedpandaDriver as redpanda
    participant AIOKafkaConsumer
    participant RedpandaCluster as Redpanda_Kafka

    Developer->>RedpandaDriver: query(topic_or_sentence, timeout_ms, max_records, ...)
    RedpandaDriver->>RedpandaDriver: _load_aiokafka()
    RedpandaDriver->>AIOKafkaConsumer: __init__(topic, bootstrap_servers, group_id, client_id, ...)

    RedpandaDriver->>AIOKafkaConsumer: start()
    AIOKafkaConsumer-->>RedpandaDriver: consumer_ready

    RedpandaDriver->>AIOKafkaConsumer: getmany(timeout_ms, max_records)
    AIOKafkaConsumer->>RedpandaCluster: fetch_batches(topic, partitions)
    RedpandaCluster-->>AIOKafkaConsumer: records_by_partition
    AIOKafkaConsumer-->>RedpandaDriver: records dict

    RedpandaDriver->>RedpandaDriver: iterate records, decode key/value
    RedpandaDriver->>RedpandaDriver: _serializer(messages_list, None)
    RedpandaDriver-->>Developer: (messages, error=None)

    RedpandaDriver->>AIOKafkaConsumer: stop()
    AIOKafkaConsumer-->>RedpandaDriver: stopped
Loading

Class diagram for the new async redpanda driver

classDiagram
    class BaseDriver {
        <<abstract>>
        string _provider
        string _syntax
        string _dsn_template
        string _dsn
        dict _params
        any _connection
        bool _connected
        any _loop
        any _prepared
        +__init__(dsn, loop, params, kwargs)
        +_serializer(data, error)
    }

    class redpanda {
        <<driver>>
        string _provider
        string _syntax
        string _dsn_template
        string _topic
        string _group_id
        string _client_id
        AIOKafkaProducer _producer
        AIOKafkaAdminClient _admin
        +__init__(dsn, loop, params, topic, group_id, client_id, kwargs)
        +connection(kwargs) async
        +close() async
        +use(database) async
        +prepare(sentence) async
        +execute(sentence, args, kwargs) async
        +execute_many(sentence, args) async
        +query(sentence, kwargs) async
        +queryrow(sentence) async
        +fetch_all(sentence, kwargs) async
        +fetch_one(sentence) async
        -_load_aiokafka()
        -_bootstrap_servers()
        -_encode_value(value)
    }

    class AIOKafkaProducer {
        +__init__(loop, bootstrap_servers, client_id, kwargs)
        +start() async
        +stop() async
        +send_and_wait(topic, value, key, partition, headers, timestamp_ms) async
    }

    class AIOKafkaConsumer {
        +__init__(topic, loop, bootstrap_servers, group_id, client_id, auto_offset_reset, enable_auto_commit, kwargs)
        +start() async
        +stop() async
        +getmany(timeout_ms, max_records) async
    }

    class AIOKafkaAdminClient {
        +__init__(bootstrap_servers, client_id, loop, kwargs)
        +close() async
    }

    BaseDriver <|-- redpanda
    redpanda --> AIOKafkaProducer : uses
    redpanda --> AIOKafkaConsumer : uses
    redpanda --> AIOKafkaAdminClient : uses
Loading

File-Level Changes

Change Details Files
Introduce async Redpanda driver that exposes AsyncDB-compatible producer/consumer operations via aiokafka.
  • Define redpanda BaseDriver subclass with provider metadata, DSN template, and topic/group/client configuration derived from params/kwargs.
  • Implement lazy aiokafka loading helper that raises a DriverError with install instructions when the dependency is missing.
  • Implement connection lifecycle: create and start AIOKafkaProducer on connection, track connection state, and cleanly stop producer/admin in close().
  • Implement execute/execute_many to publish messages to a topic using send_and_wait, with JSON/bytes/string encoding and structured metadata results passed through the existing serializer.
  • Implement query/queryrow (and fetch_all/fetch_one aliases) that create a short-lived AIOKafkaConsumer to read messages, decode key/value as UTF-8 strings, and serialize them into AsyncDB’s standard (result, error) format.
asyncdb/drivers/redpanda.py
Document Redpanda as a supported backend and define its driver alias.
  • Add Redpanda (Kafka-compatible, requires aiokafka) to the supported databases list.
  • Add redpanda: Redpanda/Kafka (aiokafka) to the driver-name mapping section.
README.md
Add async tests for the Redpanda driver using dummy aiokafka classes.
  • Define dummy producer, consumer, and admin classes plus message/metadata helpers to simulate aiokafka behavior without a live cluster.
  • Monkeypatch the driver’s _load_aiokafka to return dummy classes for tests.
  • Add async tests that verify connection establishment, execute() publish behavior and metadata shape, and query()/queryrow() consumption behavior and decoding of key/value fields.
tests/test_redpanda.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The _bootstrap_servers method uses self._dsn directly, which will include the scheme when instantiated via a standard DSN (e.g. redpanda://host:port); consider parsing the DSN and/or consistently using _dsn_template so the bootstrap servers string is always in <host>:<port> form.
  • In query, keys and values are always decoded as UTF-8 strings, which will fail or corrupt data for non-text/binary payloads; consider returning raw bytes (or making decoding configurable) to avoid unexpected UnicodeDecodeError and preserve arbitrary message contents.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `_bootstrap_servers` method uses `self._dsn` directly, which will include the scheme when instantiated via a standard DSN (e.g. `redpanda://host:port`); consider parsing the DSN and/or consistently using `_dsn_template` so the bootstrap servers string is always in `<host>:<port>` form.
- In `query`, keys and values are always decoded as UTF-8 strings, which will fail or corrupt data for non-text/binary payloads; consider returning raw bytes (or making decoding configurable) to avoid unexpected `UnicodeDecodeError` and preserve arbitrary message contents.

## Individual Comments

### Comment 1
<location> `asyncdb/drivers/redpanda.py:161-168` </location>
<code_context>
+            messages = []
+            for _, batch in records.items():
+                for msg in batch:
+                    messages.append(
+                        {
+                            "topic": msg.topic,
+                            "partition": msg.partition,
+                            "offset": msg.offset,
+                            "timestamp": msg.timestamp,
+                            "key": msg.key.decode("utf-8") if msg.key else None,
+                            "value": msg.value.decode("utf-8") if msg.value else None,
+                        }
+                    )
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Unconditional UTF-8 decoding of keys/values may fail for arbitrary binary messages.

Decoding `msg.key` and `msg.value` as UTF-8 will raise `UnicodeDecodeError` for non-text or differently encoded payloads, which are valid in Kafka/Redpanda. If arbitrary or binary data is possible, consider returning bytes or making decoding configurable to avoid these runtime failures.

Suggested implementation:

```python
            records = await consumer.getmany(timeout_ms=timeout_ms, max_records=max_records)
            messages = []
            for _, batch in records.items():
                for msg in batch:
                    messages.append(
                        {
                            "topic": msg.topic,
                            "partition": msg.partition,
                            "offset": msg.offset,
                            "timestamp": msg.timestamp,
                            "key": msg.key,
                            "value": msg.value,
                        }
                    )

```

If callers expect text instead of bytes, consider:
1) Documenting that `key` and `value` are returned as `bytes` and should be decoded by the caller using the appropriate encoding, or
2) Adding an optional parameter (e.g. `decode: bool = False` and `encoding: str = "utf-8"`) to this method and, when enabled, decoding with `errors="replace"` to avoid runtime failures for arbitrary binary payloads.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +161 to +168
messages.append(
{
"topic": msg.topic,
"partition": msg.partition,
"offset": msg.offset,
"timestamp": msg.timestamp,
"key": msg.key.decode("utf-8") if msg.key else None,
"value": msg.value.decode("utf-8") if msg.value else None,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Unconditional UTF-8 decoding of keys/values may fail for arbitrary binary messages.

Decoding msg.key and msg.value as UTF-8 will raise UnicodeDecodeError for non-text or differently encoded payloads, which are valid in Kafka/Redpanda. If arbitrary or binary data is possible, consider returning bytes or making decoding configurable to avoid these runtime failures.

Suggested implementation:

            records = await consumer.getmany(timeout_ms=timeout_ms, max_records=max_records)
            messages = []
            for _, batch in records.items():
                for msg in batch:
                    messages.append(
                        {
                            "topic": msg.topic,
                            "partition": msg.partition,
                            "offset": msg.offset,
                            "timestamp": msg.timestamp,
                            "key": msg.key,
                            "value": msg.value,
                        }
                    )

If callers expect text instead of bytes, consider:

  1. Documenting that key and value are returned as bytes and should be decoded by the caller using the appropriate encoding, or
  2. Adding an optional parameter (e.g. decode: bool = False and encoding: str = "utf-8") to this method and, when enabled, decoding with errors="replace" to avoid runtime failures for arbitrary binary payloads.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new asynchronous driver for Redpanda (Kafka-compatible messaging) to AsyncDB, using aiokafka as the underlying client library. The driver implements the standard AsyncDB interface with producer/consumer operations mapped to execute/query methods, and includes basic test coverage using mocked aiokafka components.

Changes:

  • Added redpanda driver (asyncdb/drivers/redpanda.py) with support for publishing and consuming messages through the AsyncDB interface
  • Added unit tests (tests/test_redpanda.py) with mocked aiokafka classes to test connection, publish, and consume operations
  • Updated README.md to list Redpanda as a supported backend with its driver alias

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 11 comments.

File Description
asyncdb/drivers/redpanda.py New driver implementation mapping AsyncDB methods to AIOKafkaProducer/Consumer operations with lazy dependency loading
tests/test_redpanda.py Unit tests using mock aiokafka classes to verify connection, execute (publish), query (consume), and queryrow operations
README.md Documentation updates adding Redpanda to supported databases list and driver aliases section

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

servers = kwargs.pop("bootstrap_servers", self._bootstrap_servers())
try:
self._producer = AIOKafkaProducer(
loop=self._loop,
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop parameter is deprecated in aiokafka version 0.8.0+ (released in 2022). Modern versions of aiokafka automatically use the current event loop. Passing the loop parameter explicitly may cause deprecation warnings or errors in recent versions. Consider removing the loop parameter or making it conditional based on the aiokafka version.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +107
def _encode_value(self, value: Any) -> bytes:
if value is None:
raise DriverError("Cannot publish an empty message")
if isinstance(value, bytes):
return value
if isinstance(value, str):
return value.encode("utf-8")
return json.dumps(value).encode("utf-8")

async def execute(self, sentence: Any, *args, **kwargs) -> Optional[Any]:
if not self._producer:
await self.connection()
topic = kwargs.pop("topic", self._topic)
if not topic:
raise DriverError("No topic selected. Use use(<topic>) or pass topic=<topic>.")

key = kwargs.pop("key", None)
partition = kwargs.pop("partition", None)
headers = kwargs.pop("headers", None)
timestamp_ms = kwargs.pop("timestamp_ms", None)

payload = self._encode_value(sentence)
encoded_key = self._encode_value(key) if key is not None else None
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _encode_value method raises a DriverError when value is None, but on line 107 it's called with key which can be None. This will cause the error "Cannot publish an empty message" even though having a None key is valid in Kafka/Redpanda (only the value is required). The condition on line 107 correctly checks if key is not None before encoding, but if someone mistakenly passes key=None to _encode_value, the error message would be misleading. Consider either allowing None in _encode_value with a clearer error message, or adding a separate _encode_key method.

Copilot uses AI. Check for mistakes.
Comment on lines +167 to +168
"key": msg.key.decode("utf-8") if msg.key else None,
"value": msg.value.decode("utf-8") if msg.value else None,
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decode calls on lines 167-168 will raise a UnicodeDecodeError if msg.key or msg.value contain binary data that's not valid UTF-8. Consider adding error handling for decode errors, or providing a configurable decoder. This is especially important for Kafka/Redpanda which can contain arbitrary binary data. For example, Avro or Protobuf serialized messages would fail here.

Copilot uses AI. Check for mistakes.
Comment thread tests/test_redpanda.py
Comment on lines +86 to +96
async def test_redpanda_query_and_queryrow(patch_aiokafka):
db = AsyncDB("redpanda", params={"host": "127.0.0.1", "port": 9092, "topic": "events"})

records, error = await db.query("events")
assert error is None
assert len(records) == 1
assert records[0]["key"] == "user-1"

row, error = await db.queryrow("events")
assert error is None
assert row["value"] == '{"event":"created"}'
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test doesn't establish a connection before calling query and queryrow operations. While the query method creates its own consumer and doesn't require a prior connection, it would be more consistent with other test patterns (e.g., test_redis.py, test_mongo.py) to explicitly call await db.connection() at the start of the test, even though it's not strictly necessary for consume operations. This also tests that the connection and close methods work correctly.

Copilot uses AI. Check for mistakes.
except Exception as err:
raise DriverError(f"Error closing Redpanda connection: {err}") from err

async def use(self, database: str):
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use method on line 79 sets self._topic but is not async, while it's defined as async. If use() needs to perform any validation or initialization of the topic (e.g., checking if it exists, creating it, etc.), those operations cannot be performed in the current implementation. Consider either making use() perform actual async operations (like checking topic existence using the admin client), or remove the async keyword if it's truly a synchronous operation. Most other drivers' use() methods in the codebase are async and perform actual operations.

Suggested change
async def use(self, database: str):
async def use(self, database: str):
await self.connection()

Copilot uses AI. Check for mistakes.
Comment thread tests/test_redpanda.py
Comment on lines +130 to +135
response, error = await self.execute(message, *args)
if error:
return await self._serializer(results, error)
results.append(response)
return await self._serializer(results, None)

Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling on line 131 is unreachable. The execute method only returns [result, None] on success or raises DriverError on failure - it never returns a non-None error in the tuple. The if error check will always be False. Either remove this dead code, or modify execute to catch exceptions and return them via _serializer as [None, error] instead of raising them.

Suggested change
response, error = await self.execute(message, *args)
if error:
return await self._serializer(results, error)
results.append(response)
return await self._serializer(results, None)
response = await self.execute(message, *args)
results.append(response)
return await self._serializer(results, None)

Copilot uses AI. Check for mistakes.
max_records = kwargs.pop("max_records", 100)
consumer = AIOKafkaConsumer(
topic,
loop=self._loop,
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop parameter is deprecated in aiokafka version 0.8.0+ (released in 2022). Modern versions of aiokafka automatically use the current event loop. Passing the loop parameter explicitly may cause deprecation warnings or errors in recent versions. Consider removing the loop parameter or making it conditional based on the aiokafka version.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +180 to +186
messages, error = await self.query(sentence, max_records=1)
if error:
return await self._serializer(None, error)
row = messages[0] if messages else None
return await self._serializer(row, None)

fetch_one = queryrow
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling on lines 181-182 is unreachable. The query method only returns [messages, None] on success or raises DriverError on failure - it never returns a non-None error in the tuple. The if error check will always be False. Either remove this dead code, or modify query to catch exceptions and return them via _serializer as [None, error] instead of raising them.

Suggested change
messages, error = await self.query(sentence, max_records=1)
if error:
return await self._serializer(None, error)
row = messages[0] if messages else None
return await self._serializer(row, None)
fetch_one = queryrow
messages, _ = await self.query(sentence, max_records=1)
row = messages[0] if messages else None
return await self._serializer(row, None)
fetch_one = queryrow
fetch_one = queryrow

Copilot uses AI. Check for mistakes.
Comment on lines +180 to +182
messages, error = await self.query(sentence, max_records=1)
if error:
return await self._serializer(None, error)
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The queryrow method assumes query returns a (messages, error) tuple and checks for error on line 181. However, the query method raises DriverError on failure (line 173) rather than returning it in a tuple. This means if query fails, an uncaught exception will be raised instead of being handled. The error handling on lines 181-182 is unreachable. Either query should catch exceptions and return them via _serializer, or queryrow should remove the error check (since exceptions will propagate anyway).

Suggested change
messages, error = await self.query(sentence, max_records=1)
if error:
return await self._serializer(None, error)
messages, _ = await self.query(sentence, max_records=1)

Copilot uses AI. Check for mistakes.
@phenobarbital
Copy link
Copy Markdown
Owner Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 21, 2026

@phenobarbital I've opened a new pull request, #1486, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 21, 2026

@phenobarbital I've opened a new pull request, #1487, to work on those changes. Once the pull request is ready, I'll request review from you.

phenobarbital and others added 3 commits February 21, 2026 21:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
[WIP] WIP Address feedback on async Redpanda driver using aiokafka
[WIP] Add async Redpanda driver using aiokafka
@phenobarbital phenobarbital merged commit 69d60bb into master Feb 21, 2026
3 checks passed
@phenobarbital phenobarbital deleted the codex/add-async-driver-for-redpanda branch February 21, 2026 22:00
phenobarbital added a commit that referenced this pull request Mar 20, 2026
…r-redpanda

feat(drivers): add async Redpanda driver using aiokafka
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants