Vehicle-Anti-Theft-Face-Rec.../venv/Lib/site-packages/gcloud/pubsub/connection.py

539 lines
20 KiB
Python

# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Create / interact with gcloud pubsub connections."""
import os
from gcloud import connection as base_connection
from gcloud.environment_vars import PUBSUB_EMULATOR
class Connection(base_connection.JSONConnection):
"""A connection to Google Cloud Pubsub via the JSON REST API.
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
:param credentials: (Optional) The OAuth2 Credentials to use for this
connection.
:type http: :class:`httplib2.Http` or class that defines ``request()``.
:param http: (Optional) HTTP object to make requests.
:type api_base_url: string
:param api_base_url: The base of the API call URL. Defaults to the value
:attr:`Connection.API_BASE_URL`.
"""
API_BASE_URL = 'https://pubsub.googleapis.com'
"""The base of the API call URL."""
API_VERSION = 'v1'
"""The version of the API, used in building the API call's URL."""
API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}'
"""A template for the URL of a particular API call."""
SCOPE = ('https://www.googleapis.com/auth/pubsub',
'https://www.googleapis.com/auth/cloud-platform')
"""The scopes required for authenticating as a Cloud Pub/Sub consumer."""
def __init__(self, credentials=None, http=None, api_base_url=None):
super(Connection, self).__init__(credentials=credentials, http=http)
if api_base_url is None:
emulator_host = os.getenv(PUBSUB_EMULATOR)
if emulator_host is None:
api_base_url = self.__class__.API_BASE_URL
else:
api_base_url = 'http://' + emulator_host
self.api_base_url = api_base_url
def build_api_url(self, path, query_params=None,
api_base_url=None, api_version=None):
"""Construct an API url given a few components, some optional.
Typically, you shouldn't need to use this method.
:type path: string
:param path: The path to the resource.
:type query_params: dict or list
:param query_params: A dictionary of keys and values (or list of
key-value pairs) to insert into the query
string of the URL.
:type api_base_url: string
:param api_base_url: The base URL for the API endpoint.
Typically you won't have to provide this.
:type api_version: string
:param api_version: The version of the API to call.
Typically you shouldn't provide this and instead
use the default for the library.
:rtype: string
:returns: The URL assembled from the pieces provided.
"""
if api_base_url is None:
api_base_url = self.api_base_url
return super(Connection, self.__class__).build_api_url(
path, query_params=query_params,
api_base_url=api_base_url, api_version=api_version)
class _PublisherAPI(object):
"""Helper mapping publisher-related APIs.
:type connection: :class:`Connection`
:param connection: the connection used to make API requests.
"""
def __init__(self, connection):
self._connection = connection
def list_topics(self, project, page_size=None, page_token=None):
"""API call: list topics for a given project
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list
:type project: string
:param project: project ID
:type page_size: int
:param page_size: maximum number of topics to return, If not passed,
defaults to a value set by the API.
:type page_token: string
:param page_token: opaque marker for the next "page" of topics. If not
passed, the API will return the first page of
topics.
:rtype: tuple, (list, str)
:returns: list of ``Topic`` resource dicts, plus a
"next page token" string: if not None, indicates that
more topics can be retrieved with another call (pass that
value as ``page_token``).
"""
conn = self._connection
params = {}
if page_size is not None:
params['pageSize'] = page_size
if page_token is not None:
params['pageToken'] = page_token
path = '/projects/%s/topics' % (project,)
resp = conn.api_request(method='GET', path=path, query_params=params)
return resp.get('topics', ()), resp.get('nextPageToken')
def topic_create(self, topic_path):
"""API call: create a topic
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/create
:type topic_path: string
:param topic_path: the fully-qualified path of the new topic, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
:rtype: dict
:returns: ``Topic`` resource returned from the API.
"""
conn = self._connection
return conn.api_request(method='PUT', path='/%s' % (topic_path,))
def topic_get(self, topic_path):
"""API call: retrieve a topic
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/get
:type topic_path: string
:param topic_path: the fully-qualified path of the topic, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
:rtype: dict
:returns: ``Topic`` resource returned from the API.
"""
conn = self._connection
return conn.api_request(method='GET', path='/%s' % (topic_path,))
def topic_delete(self, topic_path):
"""API call: delete a topic
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/delete
:type topic_path: string
:param topic_path: the fully-qualified path of the topic, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
"""
conn = self._connection
conn.api_request(method='DELETE', path='/%s' % (topic_path,))
def topic_publish(self, topic_path, messages):
"""API call: publish one or more messages to a topic
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/publish
:type topic_path: string
:param topic_path: the fully-qualified path of the topic, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
:type messages: list of dict
:param messages: messages to be published.
:rtype: list of string
:returns: list of opaque IDs for published messages.
"""
conn = self._connection
data = {'messages': messages}
response = conn.api_request(
method='POST', path='/%s:publish' % (topic_path,), data=data)
return response['messageIds']
def topic_list_subscriptions(self, topic_path, page_size=None,
page_token=None):
"""API call: list subscriptions bound to a topic
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics.subscriptions/list
:type topic_path: string
:param topic_path: the fully-qualified path of the topic, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
:type page_size: int
:param page_size: maximum number of subscriptions to return, If not
passed, defaults to a value set by the API.
:type page_token: string
:param page_token: opaque marker for the next "page" of topics. If not
passed, the API will return the first page of
topics.
:rtype: list of strings
:returns: fully-qualified names of subscriptions for the supplied
topic.
"""
conn = self._connection
params = {}
if page_size is not None:
params['pageSize'] = page_size
if page_token is not None:
params['pageToken'] = page_token
path = '/%s/subscriptions' % (topic_path,)
resp = conn.api_request(method='GET', path=path, query_params=params)
return resp.get('subscriptions', ()), resp.get('nextPageToken')
class _SubscriberAPI(object):
"""Helper mapping subscriber-related APIs.
:type connection: :class:`Connection`
:param connection: the connection used to make API requests.
"""
def __init__(self, connection):
self._connection = connection
def list_subscriptions(self, project, page_size=None, page_token=None):
"""API call: list subscriptions for a given project
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/list
:type project: string
:param project: project ID
:type page_size: int
:param page_size: maximum number of subscriptions to return, If not
passed, defaults to a value set by the API.
:type page_token: string
:param page_token: opaque marker for the next "page" of subscriptions.
If not passed, the API will return the first page
of subscriptions.
:rtype: tuple, (list, str)
:returns: list of ``Subscription`` resource dicts, plus a
"next page token" string: if not None, indicates that
more subscriptions can be retrieved with another call (pass
that value as ``page_token``).
"""
conn = self._connection
params = {}
if page_size is not None:
params['pageSize'] = page_size
if page_token is not None:
params['pageToken'] = page_token
path = '/projects/%s/subscriptions' % (project,)
resp = conn.api_request(method='GET', path=path, query_params=params)
return resp.get('subscriptions', ()), resp.get('nextPageToken')
def subscription_create(self, subscription_path, topic_path,
ack_deadline=None, push_endpoint=None):
"""API call: create a subscription
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/create
:type subscription_path: string
:param subscription_path: the fully-qualified path of the new
subscription, in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:type topic_path: string
:param topic_path: the fully-qualified path of the topic being
subscribed, in format
``projects/<PROJECT>/topics/<TOPIC_NAME>``.
:type ack_deadline: int, or ``NoneType``
:param ack_deadline: the deadline (in seconds) by which messages pulled
from the back-end must be acknowledged.
:type push_endpoint: string, or ``NoneType``
:param push_endpoint: URL to which messages will be pushed by the
back-end. If not set, the application must pull
messages.
:rtype: dict
:returns: ``Subscription`` resource returned from the API.
"""
conn = self._connection
path = '/%s' % (subscription_path,)
resource = {'topic': topic_path}
if ack_deadline is not None:
resource['ackDeadlineSeconds'] = ack_deadline
if push_endpoint is not None:
resource['pushConfig'] = {'pushEndpoint': push_endpoint}
return conn.api_request(method='PUT', path=path, data=resource)
def subscription_get(self, subscription_path):
"""API call: retrieve a subscription
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/get
:type subscription_path: string
:param subscription_path: the fully-qualified path of the subscription,
in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:rtype: dict
:returns: ``Subscription`` resource returned from the API.
"""
conn = self._connection
path = '/%s' % (subscription_path,)
return conn.api_request(method='GET', path=path)
def subscription_delete(self, subscription_path):
"""API call: delete a subscription
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/delete
:type subscription_path: string
:param subscription_path: the fully-qualified path of the subscription,
in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
"""
conn = self._connection
path = '/%s' % (subscription_path,)
conn.api_request(method='DELETE', path=path)
def subscription_modify_push_config(self, subscription_path,
push_endpoint):
"""API call: update push config of a subscription
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/modifyPushConfig
:type subscription_path: string
:param subscription_path: the fully-qualified path of the new
subscription, in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:type push_endpoint: string, or ``NoneType``
:param push_endpoint: URL to which messages will be pushed by the
back-end. If not set, the application must pull
messages.
"""
conn = self._connection
path = '/%s:modifyPushConfig' % (subscription_path,)
resource = {'pushConfig': {'pushEndpoint': push_endpoint}}
conn.api_request(method='POST', path=path, data=resource)
def subscription_pull(self, subscription_path, return_immediately=False,
max_messages=1):
"""API call: retrieve messages for a subscription
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/modifyPushConfig
:type subscription_path: string
:param subscription_path: the fully-qualified path of the new
subscription, in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:type return_immediately: boolean
:param return_immediately: if True, the back-end returns even if no
messages are available; if False, the API
call blocks until one or more messages are
available.
:type max_messages: int
:param max_messages: the maximum number of messages to return.
:rtype: list of dict
:returns: the ``receivedMessages`` element of the response.
"""
conn = self._connection
path = '/%s:pull' % (subscription_path,)
data = {
'returnImmediately': return_immediately,
'maxMessages': max_messages,
}
response = conn.api_request(method='POST', path=path, data=data)
return response.get('receivedMessages', ())
def subscription_acknowledge(self, subscription_path, ack_ids):
"""API call: acknowledge retrieved messages
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/modifyPushConfig
:type subscription_path: string
:param subscription_path: the fully-qualified path of the new
subscription, in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:type ack_ids: list of string
:param ack_ids: ack IDs of messages being acknowledged
"""
conn = self._connection
path = '/%s:acknowledge' % (subscription_path,)
data = {
'ackIds': ack_ids,
}
conn.api_request(method='POST', path=path, data=data)
def subscription_modify_ack_deadline(self, subscription_path, ack_ids,
ack_deadline):
"""API call: update ack deadline for retrieved messages
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/modifyAckDeadline
:type subscription_path: string
:param subscription_path: the fully-qualified path of the new
subscription, in format
``projects/<PROJECT>/subscriptions/<SUB_NAME>``.
:type ack_ids: list of string
:param ack_ids: ack IDs of messages being acknowledged
:type ack_deadline: int
:param ack_deadline: the deadline (in seconds) by which messages pulled
from the back-end must be acknowledged.
"""
conn = self._connection
path = '/%s:modifyAckDeadline' % (subscription_path,)
data = {
'ackIds': ack_ids,
'ackDeadlineSeconds': ack_deadline,
}
conn.api_request(method='POST', path=path, data=data)
class _IAMPolicyAPI(object):
"""Helper mapping IAM policy-related APIs.
:type connection: :class:`Connection`
:param connection: the connection used to make API requests.
"""
def __init__(self, connection):
self._connection = connection
def get_iam_policy(self, target_path):
"""API call: fetch the IAM policy for the target
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/getIamPolicy
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/getIamPolicy
:type target_path: string
:param target_path: the path of the target object.
:rtype: dict
:returns: the resource returned by the ``getIamPolicy`` API request.
"""
conn = self._connection
path = '/%s:getIamPolicy' % (target_path,)
return conn.api_request(method='GET', path=path)
def set_iam_policy(self, target_path, policy):
"""API call: update the IAM policy for the target
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/setIamPolicy
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/setIamPolicy
:type target_path: string
:param target_path: the path of the target object.
:type policy: dict
:param policy: the new policy resource.
:rtype: dict
:returns: the resource returned by the ``setIamPolicy`` API request.
"""
conn = self._connection
wrapped = {'policy': policy}
path = '/%s:setIamPolicy' % (target_path,)
return conn.api_request(method='POST', path=path, data=wrapped)
def test_iam_permissions(self, target_path, permissions):
"""API call: test permissions
See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/testIamPermissions
https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/testIamPermissions
:type target_path: string
:param target_path: the path of the target object.
:type permissions: list of string
:param permissions: the permissions to check
:rtype: dict
:returns: the resource returned by the ``getIamPolicy`` API request.
"""
conn = self._connection
wrapped = {'permissions': permissions}
path = '/%s:testIamPermissions' % (target_path,)
resp = conn.api_request(method='POST', path=path, data=wrapped)
return resp.get('permissions', [])