{"id":736,"library":"google-cloud-pubsub","title":"Google Cloud Pub/Sub Client Library","description":"The `google-cloud-pubsub` Python client library provides a fully-managed, real-time messaging service for Google Cloud Pub/Sub. It facilitates asynchronous communication, decoupling services that produce messages from those that consume them, offering 'at least once' delivery, low latency, and on-demand scalability. The library is actively maintained with frequent, often weekly, releases for bug fixes and minor features within the broader `google-cloud-python` monorepo.","status":"active","version":"2.36.0","language":"python","source_language":"en","source_url":"https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-pubsub","tags":["google-cloud","pubsub","messaging","asynchronous","event-driven"],"install":[{"cmd":"pip install google-cloud-pubsub","lang":"bash","label":"Install latest stable version"}],"dependencies":[],"imports":[{"note":"Older versions or incorrect top-level imports might not expose the v1 API clients directly. Always use `pubsub_v1` for current stable client access.","wrong":"from google.cloud import pubsub\npublisher = pubsub.PublisherClient()","symbol":"PublisherClient","correct":"from google.cloud import pubsub_v1\npublisher = pubsub_v1.PublisherClient()"},{"note":"Older versions or incorrect top-level imports might not expose the v1 API clients directly. Always use `pubsub_v1` for current stable client access.","wrong":"from google.cloud import pubsub\nsubscriber = pubsub.SubscriberClient()","symbol":"SubscriberClient","correct":"from google.cloud import pubsub_v1\nsubscriber = pubsub_v1.SubscriberClient()"}],"quickstart":{"code":"import os\nimport time\nfrom concurrent.futures import TimeoutError\nfrom google.cloud import pubsub_v1\n\nproject_id = os.environ.get('GOOGLE_CLOUD_PROJECT') or os.environ.get('GCP_PROJECT') or 'your-gcp-project-id'\ntopic_id = 'my-topic-id'\nsubscription_id = 'my-subscription-id'\n\nif not project_id or project_id == 'your-gcp-project-id':\n    raise ValueError(\"Please set the GOOGLE_CLOUD_PROJECT environment variable or replace 'your-gcp-project-id'.\")\n\npublisher = pubsub_v1.PublisherClient()\nsubscriber = pubsub_v1.SubscriberClient()\n\ntopic_path = publisher.topic_path(project_id, topic_id)\nsubscription_path = subscriber.subscription_path(project_id, subscription_id)\n\n# Create topic if it doesn't exist\ntry:\n    publisher.get_topic(request={\"topic\": topic_path})\n    print(f\"Topic {topic_path} already exists.\")\nexcept Exception:\n    print(f\"Creating topic {topic_path}...\")\n    publisher.create_topic(request={\"name\": topic_path})\n    print(f\"Topic {topic_path} created.\")\n\n# Create subscription if it doesn't exist\ntry:\n    subscriber.get_subscription(request={\"subscription\": subscription_path})\n    print(f\"Subscription {subscription_path} already exists.\")\nexcept Exception:\n    print(f\"Creating subscription {subscription_path}...\")\n    subscriber.create_subscription(request={\"name\": subscription_path, \"topic\": topic_path})\n    print(f\"Subscription {subscription_path} created.\")\n\n\n# --- Publisher --- \nmessage_data = \"Hello, Pub/Sub!\"\nprint(f\"Publishing message: '{message_data}' to {topic_path}\")\nfuture = publisher.publish(topic_path, message_data.encode('utf-8'))\nmessage_id = future.result()\nprint(f\"Published message with ID: {message_id}\")\n\n# --- Subscriber --- \ndef callback(message: pubsub_v1.subscriber.message.Message):\n    print(f\"Received message: {message.data.decode('utf-8')}\")\n    print(f\"Acknowledging message: {message.message_id}\")\n    message.ack()\n\nprint(f\"Listening for messages on {subscription_path}...\")\nstreaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)\n\n# Wrap subscriber in a 'with' block to automatically call close() when done.\nwith subscriber:\n    try:\n        # `subscribe` is non-blocking, so we must keep the main thread from exiting to allow it to run.\n        streaming_pull_future.result(timeout=30) # Wait 30 seconds for messages\n    except TimeoutError:\n        streaming_pull_future.cancel()  # Trigger the shutdown.\n        streaming_pull_future.result()  # Block until the shutdown is complete.\n    except KeyboardInterrupt:\n        streaming_pull_future.cancel()  # Trigger the shutdown.\n        streaming_pull_future.result()  # Block until the shutdown is complete.\n\nprint(\"Finished listening for messages.\")\n\n# Clean up resources (optional)\n# publisher.delete_topic(request={\"topic\": topic_path})\n# subscriber.delete_subscription(request={\"subscription\": subscription_path})\n# print(f\"Topic {topic_id} and subscription {subscription_id} deleted.\")\n","lang":"python","description":"This quickstart demonstrates how to publish a message to a Google Cloud Pub/Sub topic and then subscribe to and consume that message from a subscription. It handles topic and subscription creation if they don't exist and uses environment variables for project configuration."},"warnings":[{"fix":"Upgrade your Python environment to 3.9+ or pin the library version: `pip install google-cloud-pubsub==2.34.0`.","message":"Versions of `google-cloud-pubsub` from `2.35.0` and higher require Python 3.9 or newer. If you are using Python 3.7 or 3.8, you must pin the library version to `google-cloud-pubsub==2.34.0` or earlier.","severity":"breaking","affected_versions":">=2.35.0"},{"fix":"For most applications, create a single `PublisherClient` and a single `SubscriberClient` instance per process and reuse them across operations to optimize resource utilization.","message":"Instantiating multiple `PublisherClient` or `SubscriberClient` instances unnecessarily can lead to resource inefficiencies. These clients handle connection pooling and caching internally.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Carefully tune your subscription's acknowledgment deadline to allow sufficient time for message processing. Implement appropriate flow control settings (`max_messages`, `max_bytes`) to prevent your application from being overwhelmed by messages. Always call `message.ack()` or `message.nack()` after processing.","message":"Incorrectly configuring subscriber acknowledgment deadlines or flow control (prefetch settings) can cause 'stuck subscribers', messages being redelivered repeatedly (poison pill effect), or excessive resource consumption.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Design your subscriber logic to be *idempotent*. Your message processing should produce the same result whether it's executed once or multiple times for the same message. Utilize unique business keys (like a transaction ID) and check against a fast-access store to prevent duplicate processing.","message":"Pub/Sub guarantees at-least-once delivery, meaning a message might be delivered more than once in certain scenarios (e.g., subscriber restarts, ack deadline issues).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always store or log the `message_id` returned by the publish operation. This ID is the primary way to correlate a published message with its ingestion in Google Cloud Logs Explorer and track its lifecycle.","message":"Failing to capture and log the `message_id` returned by `publisher.publish().result()` can severely hinder debugging and traceability in production.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure the `GOOGLE_CLOUD_PROJECT` environment variable is set to your actual Google Cloud Project ID (e.g., `my-project-123`) before initializing clients, or explicitly pass the project ID to the client constructor, for example: `PublisherClient(project='my-project-123')`.","message":"The Google Cloud Project ID must be provided to the Pub/Sub client libraries to identify the project where resources reside. This can be done by setting the `GOOGLE_CLOUD_PROJECT` environment variable or by explicitly passing the `project` argument to client constructors. Failing to provide a valid project ID (or leaving it as a placeholder like 'your-gcp-project-id') will prevent client initialization.","severity":"breaking","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T18:27:09.532Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Ensure the service account key is valid and correctly configured, the OAuth token is not expired, and the service account or user has the required Pub/Sub IAM roles (e.g., `roles/pubsub.publisher`, `roles/pubsub.subscriber`) for the specific topic or subscription in the correct project.","cause":"The client application lacks valid authentication credentials or the necessary IAM permissions to access Pub/Sub resources.","error":"UNAUTHENTICATED / 403 (Forbidden) / PERMISSION_DENIED"},{"fix":"Ensure `google-cloud-pubsub` is listed in your `requirements.txt` file and installed (e.g., `pip install google-cloud-pubsub`). For deployment environments, verify that the `pip install -r requirements.txt` step is executed and packages are correctly bundled.","cause":"The `google-cloud-pubsub` library or its dependencies are not correctly installed or accessible in the Python environment, often seen in deployed environments like App Engine or Docker.","error":"ModuleNotFoundError: No module named 'google'"},{"fix":"Increase the timeout duration for publish operations in the publisher client's retry settings (e.g., `total_timeout` to 600 seconds). For subscribers, ensure adequate client resources (memory, CPU) and stable network connectivity, and let the client library handle deadline extensions automatically.","cause":"A publish or subscribe operation failed to complete within the allocated timeout duration, often due to client-side bottlenecks, network issues, or insufficient retry settings.","error":"DEADLINE_EXCEEDED"},{"fix":"Update your code to use the `SubscriberClient` for pull operations, which was introduced in newer versions of the library (typically after 0.27.0). Example: `from google.cloud.pubsub_v1 import SubscriberClient` and then `subscriber = SubscriberClient()`.","cause":"This error occurs when using an outdated `google-cloud-pubsub` client API, specifically attempting to call `pull` directly on a generic `Client` object, instead of the dedicated `SubscriberClient`.","error":"AttributeError: 'Client' object has no attribute 'pull'"}],"ecosystem":"pypi","meta_description":null,"install_score":95,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":"2.38.0","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":2.27,"mem_mb":29.5,"disk_size":"75.6M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.06,"mem_mb":29.1,"disk_size":"74.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":6.8,"import_time_s":1.23,"mem_mb":24.3,"disk_size":"73M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.17,"mem_mb":23.9,"disk_size":"72M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":2.62,"mem_mb":31.6,"disk_size":"81.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.07,"mem_mb":31.3,"disk_size":"79.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":6.6,"import_time_s":1.76,"mem_mb":26.7,"disk_size":"79M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.75,"mem_mb":26.5,"disk_size":"78M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":2.69,"mem_mb":31.3,"disk_size":"72.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":3.17,"mem_mb":31,"disk_size":"71.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":5.3,"import_time_s":2.07,"mem_mb":26.5,"disk_size":"70M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.41,"mem_mb":26.2,"disk_size":"69M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":2.56,"mem_mb":31.7,"disk_size":"71.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":4.04,"mem_mb":31.6,"disk_size":"70.7M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":5.1,"import_time_s":1.98,"mem_mb":26.9,"disk_size":"70M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.59,"mem_mb":26.7,"disk_size":"68M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":2.06,"mem_mb":29.5,"disk_size":"75.7M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.86,"mem_mb":29.3,"disk_size":"74.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":7.8,"import_time_s":1.49,"mem_mb":24.3,"disk_size":"73M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.32,"mem_mb":24.1,"disk_size":"72M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}