If a payload with fruits/apples
comes in, we would receive it. If a payload with just fruits
come in, we would not receive it, because we are specifically asking for apples
to be present as a topic. Neither would fruit/oranges
match our subscription, while fruits/apples/macintosh
would, as it contains our topics (and a bit more).
The below matrix shows how subscription paths match topics:
Topics | /fruits | /fruits/apples | /fruits/apples/red | /fruits/oranges | /apples |
---|---|---|---|---|---|
fruits | ✓ | ✗ | ✗ | ✗ | ✗ |
fruits + apples | ✓ | ✓ | ✗ | ✗ | ✓ |
fruits + apples + red | ✓ | ✓ | ✓ | ✗ | ✓ |
fruits + oranges | ✓ | ✗ | ✗ | ✓ | ✗ |
Event payloads requires that the IP or IP range (Ipv4 or IPv6) is listed in pypubsub.yaml
under payloaders
first. Once whitelisted, clients can do a POST or PUT to the pubsub service on port 2069, passing a JSON object as the request body, for instance:
curl -XPUT -d '{"text": "Apples are delicious"}' http://localhost:2069/fruits/apples
Event payloads MUST be in dictionary (hash) format, or they will be rejected.
On the subscription side, any client listening to http://localhost:2069/fruits
or http://localhost:2069/fruits/apples
will receive the following event in their stream:
{ "text": "Apples are delicious", "pubsub_topics": ["fruits", "apples"], "pubsub_path": "/fruits/apples" }
To push an event to PyPubSub via Python, you can make use of the requests library in Python:
import requests requests.put('http://localhost:2069/fruits/apples', json = {"cultivar": "macintosh"})
You can subscribe to topics via cURL like so: curl http://localhost:2069/topics/here
where topics/here
are the topics you are subscribing to, with /
as a delimiter between topics. To subscribe to all events, you can omit the topics.
For Python, you can import the asfpy
package via pip and utilize its pubsub plugin:
import asfpy.pubsub def process_event(payload): print("we got an event from pubsub") ... def main(): pubsub = asfpy.pubsub.Listener('http://localhost:2069') pubsub.attach(process_event) # poll forever
PyPubSub supports private events that only authenticated clients can receive.
To mark an event as private, simply prepend private
as the first topic when you push the event:
curl -XPUT -d '{"private_text": "Squeamish Ossifrage"}' http://localhost/private/topics/here
Events broadcast with a /private
prefix will only allude to its privacy via the pubsub_path
element in the JSON blob. The topics list does not include ‘private’ (as it's technically not a topic for the broadcast). Thus the above example would output the following event to all authed subscribers with access:
{ "private_text": "Squeamish Ossifrage", "pubsub_topics": ["topics", "here"], "pubsub_path": "/private/topics/here" }
Clients ACL is defined in pypubsub_acl.yaml
(and is entirely optional, you can omit the file). See the example ACL configuration for an example. Access is, as with public events, defined with “highest common denominator” in mind, meaning access to topics is granted to the specific topic group specified in the yaml and its sub-groups. Thus, if you grant access to internal
and foo
in one ACL segment, events pushed to private/internal/foo
would be seen by that client, whereas pushes to private/internal/bar
would not.
To authenticate and receive private events, use Basic authentication, such as:
curl -u 'user:pass' http://localhost:2069/internal/topics/here
PyPubSub supports ACL via asynchronous LDAP, either through group memberships or single users via their dn.
See pypubsub.yaml
for an LDAP example.
PyPubSub is licensed under the Apache License v/2.