REGION_ID is an abbreviated code that Google assigns
based on the region you select when you create your app. The code does not
correspond to a country or province, even though some region IDs may appear
similar to commonly used country and province codes. For apps created after
REGION_ID.r is included in
App Engine URLs. For existing apps created before this date, the
region ID is optional in the URL.
Learn more about region IDs.
Pub/Sub provides reliable, many-to-many, asynchronous messaging between applications. Publisher applications can send messages to a topic, and other applications can subscribe to that topic to receive the messages.
This document describes how to use the Cloud Client Library to send and receive Pub/Sub messages in a Python app.
- Follow the instructions in "Hello, World!" for Python on App Engine to set up your environment and project, and to understand how App Engine Python apps are structured.
- Write down and save your project ID, because you will need it to run the
sample application described in this document.
Cloning the sample app
Copy the sample apps to your local machine, and navigate to the
git clone https://github.com/GoogleCloudPlatform/python-docs-samples cd python-docs-samples/appengine/flexible/pubsub
Creating a topic and subscription
Create a topic and subscription, which includes specifying the endpoint to which the Pub/Sub server should send requests:
gcloud pubsub topics create YOUR_TOPIC_NAME gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \ --topic YOUR_TOPIC_NAME \ --push-endpoint \ https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/pubsub/push?token=YOUR_TOKEN \ --ack-deadline 10
YOUR_TOKENwith a secret random token. The push endpoint uses this to verify requests.
Setting environment variables
app.yamlfile to set the environment variables for your project ID, topic, and verification token:
env_variables: PUBSUB_TOPIC: your-topic # This token is used to verify that requests originate from your # application. It can be any sufficiently random string. PUBSUB_VERIFICATION_TOKEN: 1234abc
The sample app uses the Cloud Client Libraries.
The sample app uses the values you set in the
app.yamlfile to configure environment variables. The push request handler uses these values to confirm that the request came from Pub/Sub and originated from a trusted source:
app.config['PUBSUB_VERIFICATION_TOKEN'] = \ os.environ['PUBSUB_VERIFICATION_TOKEN'] app.config['PUBSUB_TOPIC'] = os.environ['PUBSUB_TOPIC']
The sample app maintains a global list to store messages received by this instance:
MESSAGES = 
pubsub_push()method receives pushed messages and adds them to the
@app.route('/pubsub/push', methods=['POST']) def pubsub_push(): if (request.args.get('token', '') != current_app.config['PUBSUB_VERIFICATION_TOKEN']): return 'Invalid request', 400 envelope = json.loads(request.data.decode('utf-8')) payload = base64.b64decode(envelope['message']['data']) MESSAGES.append(payload) # Returning any 2xx status indicates successful receipt of the message. return 'OK', 200
index()method interacts with the App Engine web app to publish new messages and display received messages:
@app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'GET': return render_template('index.html', messages=MESSAGES) data = request.form.get('payload', 'Example payload').encode('utf-8') # publisher = pubsub_v1.PublisherClient() topic_path = publisher.topic_path( current_app.config['PROJECT'], current_app.config['PUBSUB_TOPIC']) publisher.publish(topic_path, data=data) return 'OK', 200
Running the sample locally
When running locally, you can use the Cloud SDK to provide authentication to use Google Cloud APIs. Assuming you set up your environment as described in Prerequisites, you have already run the
gcloud initcommand, which provides this authentication.
Install dependencies, preferably in a virtual environment.
Mac OS / Linux
- Create an
isolated Python environment:
python3 -m venv env
- If you're not in the directory that contains the sample code, navigate
to the directory that contains the
hello_worldsample code. Then install dependencies:
pip install -r requirements.txt
Use PowerShell to run your Python packages.
- Locate your installation of PowerShell.
- Right-click on the shortcut to PowerShell and start it as an administrator.
- Create an
isolated Python environment.
python -m venv env
- Navigate to your project directory and install dependencies. If you're not in the directory
that contains the sample code, navigate to the directory that contains the
hello_worldsample code. Then, install dependencies:
pip install -r requirements.txt
Then set environment variables before starting your application:
export GOOGLE_CLOUD_PROJECT=[your-project-id] export PUBSUB_VERIFICATION_TOKEN=[your-verification-token] export PUBSUB_TOPIC=[your-topic] python main.py
Simulating push notifications
The application can send messages locally, but it is not able to receive push messages locally. You can, however, simulate a push message by making an HTTP request to the local push notification endpoint. The sample includes the file
You can use
httpieclient to send an HTTP
curl -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"
http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json
HTTP/1.0 200 OK Content-Length: 2 Content-Type: text/html; charset=utf-8 Date: Mon, 10 Aug 2015 17:52:03 GMT Server: Werkzeug/0.10.4 Python/2.7.10 OK
After the request completes, you can refresh
localhost:8080and see the message in the list of received messages.
Running on App Engine
To deploy the demo app to App Engine by using the
gcloudcommand-line tool, you run the following command from the directory where your
app.yamlfile is located:
gcloud app deploy
You can now access the application at
https://PROJECT_ID.REGION_ID.r.appspot.com. You can use the form to submit messages, but there's no guarantee of which instance of your application will receive the notification. You can send multiple messages and refresh the page to see the received message.
- Create an isolated Python environment: