|
14 | 14 |
|
15 | 15 | """GAX wrapper for Pubsub API requests.""" |
16 | 16 |
|
| 17 | +import functools |
| 18 | + |
17 | 19 | from google.cloud.gapic.pubsub.v1.publisher_api import PublisherApi |
18 | 20 | from google.cloud.gapic.pubsub.v1.subscriber_api import SubscriberApi |
19 | 21 | from google.gax import CallOptions |
|
29 | 31 | from google.cloud._helpers import _pb_timestamp_to_rfc3339 |
30 | 32 | from google.cloud.exceptions import Conflict |
31 | 33 | from 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' |
32 | 40 |
|
33 | 41 |
|
34 | 42 | class _PublisherAPI(object): |
@@ -58,21 +66,24 @@ def list_topics(self, project, page_size=0, page_token=None): |
58 | 66 | passed, the API will return the first page of |
59 | 67 | topics. |
60 | 68 |
|
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``). |
| 69 | + :rtype: :class:`~google.cloud.iterator.Iterator` |
| 70 | + :returns: Iterator of :class:`~google.cloud.pubsub.topic.Topic` |
| 71 | + accessible to the current API. |
66 | 72 | """ |
67 | 73 | if page_token is None: |
68 | 74 | page_token = INITIAL_PAGE |
69 | 75 | options = CallOptions(page_token=page_token) |
70 | 76 | path = 'projects/%s' % (project,) |
71 | 77 | page_iter = self._gax_api.list_topics( |
72 | 78 | 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 |
| 79 | + page_iter = functools.partial(_recast_page_iterator, page_iter) |
| 80 | + |
| 81 | + # NOTE: We don't currently have access to the client, so callers |
| 82 | + # that want the client, must manually bind the client to the |
| 83 | + # iterator instance returned. |
| 84 | + return Iterator(client=None, path=path, |
| 85 | + item_to_value=_item_to_topic, |
| 86 | + page_iter=page_iter) |
76 | 87 |
|
77 | 88 | def topic_create(self, topic_path): |
78 | 89 | """API call: create a topic |
@@ -543,3 +554,42 @@ def make_gax_subscriber_api(connection): |
543 | 554 | if connection.in_emulator: |
544 | 555 | channel = insecure_channel(connection.host) |
545 | 556 | return SubscriberApi(channel=channel) |
| 557 | + |
| 558 | + |
| 559 | +def _item_to_topic(iterator, resource): |
| 560 | + """Convert a JSON job to the native object. |
| 561 | +
|
| 562 | + :type iterator: :class:`~google.cloud.iterator.Iterator` |
| 563 | + :param iterator: The iterator that is currently in use. |
| 564 | +
|
| 565 | + :type resource: :class:`google.pubsub.v1.pubsub_pb2.Topic` |
| 566 | + :param resource: A topic returned from the API. |
| 567 | +
|
| 568 | + :rtype: :class:`~google.cloud.pubsub.topic.Topic` |
| 569 | + :returns: The next topic in the page. |
| 570 | + """ |
| 571 | + return Topic.from_api_repr( |
| 572 | + {'name': resource.name}, iterator.client) |
| 573 | + |
| 574 | + |
| 575 | +def _recast_page_iterator(page_iter, iterator): |
| 576 | + """Wrap GAX pages generator. |
| 577 | +
|
| 578 | + In particular, wrap each page and capture some state from the |
| 579 | + GAX iterator. |
| 580 | +
|
| 581 | + Yields :class:`~google.cloud.iterator.Page` instances |
| 582 | +
|
| 583 | + :type page_iter: :class:`~google.gax.PageIterator` |
| 584 | + :param page_iter: The iterator to wrap. |
| 585 | +
|
| 586 | + :type iterator: :class:`~google.cloud.iterator.Iterator` |
| 587 | + :param iterator: The iterator that owns each page. |
| 588 | + """ |
| 589 | + for items in page_iter: |
| 590 | + fake_response = {_FAKE_ITEMS_KEY: items} |
| 591 | + page = Page( |
| 592 | + iterator, fake_response, _FAKE_ITEMS_KEY, _item_to_topic) |
| 593 | + iterator.next_page_token = page_iter.page_token or None |
| 594 | + iterator.num_results += page.num_items |
| 595 | + yield page |
0 commit comments