-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: pushing ingestion tasks to kafka
- Loading branch information
1 parent
717f5bb
commit 5f243d1
Showing
6 changed files
with
203 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from pydantic import BaseModel | ||
from typing import Optional | ||
|
||
|
||
class ApiError(BaseModel): | ||
message: Optional[str] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from decouple import config | ||
|
||
|
||
ingest_topic = config("KAFKA_TOPIC_INGEST", default="ingestion") | ||
|
||
|
||
kafka_bootstrap_servers: str = config( | ||
"KAFKA_BOOTSTRAP_SERVERS", default="localhost:9092" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import asyncio | ||
from api.ingest import ingest as _ingest, IngestPayload | ||
|
||
|
||
from service.redis.client import redis_client | ||
from service.redis.ingest_task_manager import IngestTaskManager | ||
from service.kafka.config import ingest_topic | ||
from service.kafka.consumer import get_kafka_consumer | ||
|
||
from kafka.consumer.fetcher import ConsumerRecord | ||
|
||
|
||
async def ingest(msg: ConsumerRecord): | ||
payload = IngestPayload(**msg.value) | ||
task_manager = IngestTaskManager(redis_client) | ||
await _ingest(payload, task_manager) | ||
|
||
|
||
kafka_actions = { | ||
ingest_topic: ingest, | ||
} | ||
|
||
|
||
async def process_msg(msg: ConsumerRecord, topic: str, consumer): | ||
await kafka_actions[topic](msg) | ||
consumer.commit() | ||
|
||
|
||
async def consume(): | ||
consumer = get_kafka_consumer(ingest_topic) | ||
|
||
while True: | ||
# Response format is {TopicPartiton('topic1', 1): [msg1, msg2]} | ||
msg_pack = consumer.poll(timeout_ms=3000) | ||
|
||
for tp, messages in msg_pack.items(): | ||
for message in messages: | ||
await process_msg(message, tp.topic, consumer) | ||
|
||
|
||
asyncio.run(consume()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from redis import Redis | ||
import json | ||
from models.ingest import IngestTaskResponse | ||
|
||
|
||
class CreateTaskDto(IngestTaskResponse): | ||
pass | ||
|
||
|
||
class UpdateTaskDto(IngestTaskResponse): | ||
pass | ||
|
||
|
||
class IngestTaskManager: | ||
def __init__(self, redis_client: Redis): | ||
self.redis_client = redis_client | ||
|
||
def create(self, task: CreateTaskDto): | ||
task_id = self.redis_client.incr("task_id") | ||
self.redis_client.set(task_id, task.model_dump_json()) | ||
return task_id | ||
|
||
def get(self, task_id): | ||
return IngestTaskResponse(**json.loads(self.redis_client.get(task_id))) | ||
|
||
def update(self, task_id, task: UpdateTaskDto): | ||
self.redis_client.set(task_id, task.model_dump_json()) | ||
|
||
def delete(self, task_id): | ||
self.redis_client.delete(task_id) |