1414
1515"""GAX wrapper for Pubsub API requests."""
1616
17+ import functools
18+
1719from google .cloud .gapic .pubsub .v1 .publisher_api import PublisherApi
1820from google .cloud .gapic .pubsub .v1 .subscriber_api import SubscriberApi
1921from google .gax import CallOptions
2931from google .cloud ._helpers import _pb_timestamp_to_rfc3339
3032from google .cloud .exceptions import Conflict
3133from google .cloud .exceptions import NotFound
34+ from google .cloud .iterator import Iterator
35+ from google .cloud .iterator import Page
36+ from google .cloud .pubsub .topic import Topic
37+
38+
39+ _FAKE_ITEMS_KEY = 'not-a-key'
3240
3341
3442class _PublisherAPI (object ):
3543 """Helper mapping publisher-related APIs.
3644
3745 :type gax_api: :class:`google.pubsub.v1.publisher_api.PublisherApi`
3846 :param gax_api: API object used to make GAX requests.
47+
48+ :type client: :class:`~google.cloud.pubsub.client.Client`
49+ :param client: The client that owns this API object.
3950 """
40- def __init__ (self , gax_api ):
51+
52+ def __init__ (self , gax_api , client ):
4153 self ._gax_api = gax_api
54+ self ._client = client
4255
4356 def list_topics (self , project , page_size = 0 , page_token = None ):
4457 """List topics for the project associated with this API.
@@ -58,21 +71,21 @@ def list_topics(self, project, page_size=0, page_token=None):
5871 passed, the API will return the first page of
5972 topics.
6073
61- :rtype: tuple, (list, str)
62- :returns: list of ``Topic`` resource dicts, plus a
63- "next page token" string: if not None, indicates that
64- more topics can be retrieved with another call (pass that
65- value as ``page_token``).
74+ :rtype: :class:`~google.cloud.iterator.Iterator`
75+ :returns: Iterator of :class:`~google.cloud.pubsub.topic.Topic`
76+ accessible to the current API.
6677 """
6778 if page_token is None :
6879 page_token = INITIAL_PAGE
6980 options = CallOptions (page_token = page_token )
7081 path = 'projects/%s' % (project ,)
7182 page_iter = self ._gax_api .list_topics (
7283 path , page_size = page_size , options = options )
73- topics = [{'name' : topic_pb .name } for topic_pb in page_iter .next ()]
74- token = page_iter .page_token or None
75- return topics , token
84+ page_iter = functools .partial (_recast_page_iterator , page_iter )
85+
86+ return Iterator (client = self ._client , path = path ,
87+ item_to_value = _item_to_topic ,
88+ page_iter = page_iter )
7689
7790 def topic_create (self , topic_path ):
7891 """API call: create a topic
@@ -543,3 +556,42 @@ def make_gax_subscriber_api(connection):
543556 if connection .in_emulator :
544557 channel = insecure_channel (connection .host )
545558 return SubscriberApi (channel = channel )
559+
560+
561+ def _item_to_topic (iterator , resource ):
562+ """Convert a JSON job to the native object.
563+
564+ :type iterator: :class:`~google.cloud.iterator.Iterator`
565+ :param iterator: The iterator that is currently in use.
566+
567+ :type resource: :class:`google.pubsub.v1.pubsub_pb2.Topic`
568+ :param resource: A topic returned from the API.
569+
570+ :rtype: :class:`~google.cloud.pubsub.topic.Topic`
571+ :returns: The next topic in the page.
572+ """
573+ return Topic .from_api_repr (
574+ {'name' : resource .name }, iterator .client )
575+
576+
577+ def _recast_page_iterator (page_iter , iterator ):
578+ """Wrap GAX pages generator.
579+
580+ In particular, wrap each page and capture some state from the
581+ GAX iterator.
582+
583+ Yields :class:`~google.cloud.iterator.Page` instances
584+
585+ :type page_iter: :class:`~google.gax.PageIterator`
586+ :param page_iter: The iterator to wrap.
587+
588+ :type iterator: :class:`~google.cloud.iterator.Iterator`
589+ :param iterator: The iterator that owns each page.
590+ """
591+ for items in page_iter :
592+ fake_response = {_FAKE_ITEMS_KEY : items }
593+ page = Page (
594+ iterator , fake_response , _FAKE_ITEMS_KEY , _item_to_topic )
595+ iterator .next_page_token = page_iter .page_token or None
596+ iterator .num_results += page .num_items
597+ yield page
0 commit comments