NoBS Python

Guides

Pub/Sub

NoBS supports a publish/subscribe (PubSub) pattern for event-driven workflows. PubSub allows one component of your system to publish an event and multiple subscribers to react to that event independently. This is useful for systems where an action should trigger one or more asynchronous side effects, such as sending notifications, recording analytics, or triggering downstream processing.

Defining an Event

An event must be represented as a typed request model. This ensures structured and validated messages.

python
from pydantic import BaseModel

class CreatedUser(BaseModel):
    id: int
    name: str
    email: str

Next, define the PubSub topic:

python
from nobs.pubsub import PubSub

on_user_created = PubSub(CreatedUser, subject="on_user_created")

The subject is the channel or topic name. All subscribers connected to this subject will receive every event published to it.

Creating Subscribers

Subscribers are functions that accept the event model as an argument. These functions run when a message is published to the PubSub subject.

python
def send_verify_email(user: CreatedUser) -> None:
    ...

def predict_cluster(user: CreatedUser) -> None:
    ...

Each subscriber is registered on the project:

python
from nobs.models import Project, Compute
from nobs.secrets import BaseSettings, SecretStr

class SendGridConfig(BaseSettings):
    api_token: SecretStr

project = Project(
    name="my-project",

    verify_email=on_user_created.subscriber(
        send_verify_email,
        secrets=[SendGridConfig]
    ),

    predict_cluster=on_user_created.subscriber(
        predict_cluster,
        compute=Compute(
            mvcpu_limit=1000,
            mb_memory_limit=1024
        )
    )
)

Key points

  • send_verify_email requires a SendGrid API token, so it declares a secrets list.
  • predict_cluster requests additional CPU and memory resources, so it configures compute.

Publishing Events

To trigger the subscribers, publish an event:

python
await on_user_created.publish(
    CreatedUser(
        id=1,
        name="Ash Ketchum",
        email="ash@example.com",
    )
)

All subscribers will receive and process this event independently. The caller does not wait for subscriber functions to complete.

When to Use PubSub

Use PubSub when:

  • Multiple workflows should trigger from a single action
  • You want to decouple producers from consumers
  • Tasks should run asynchronously and independently of request/response cycles

Examples include:

  • Sending welcome or verification emails
  • Running analytics processing
  • Kicking off model predictions or data enrichment pipelines

When to Use PubSub Instead of a Queue Worker

A queue worker is designed for one-to-one task execution. A message is produced, added to a queue, and one worker consumes it. This works well when each task is independent and produces a single result or side effect.

PubSub is designed for one-to-many event distribution. A published event can trigger several subscribers, each performing different actions. The producer does not need to know who will receive the event or what they will do with it.

Choose PubSub when:

  • The action should trigger multiple workflows. For example, creating a user may send a welcome email, record analytics, and schedule background enrichment.
  • You want strong decoupling between systems. The producer only emits a well-defined event and does not depend on downstream logic or services.
  • New behavior may be added later without changing existing code. New subscribers can be added to the event subject without modifying the event producer.

Choose a queue worker when:

  • The work is single-purpose and results in one job to be processed.
  • You need strict ordering or single-task guarantees.
  • The task should be retried or tracked as a single job rather than as part of a fan-out pattern.

In short, use PubSub when an event represents something that happened and other parts of the system should react independently. Use a queue worker when you need to schedule or manage a discrete background job with a single responsibility.

Previous
Queues and Workers