diff --git a/README.rst b/README.rst index dc2d9ace2f91..b2fcb47df468 100644 --- a/README.rst +++ b/README.rst @@ -123,7 +123,7 @@ Check out the `Authentication section`_ in our documentation to learn more. You may also find the `authentication document`_ shared by all the ``google-cloud-*`` libraries to be helpful. -.. _Authentication section: https://google-cloud-python.readthedocs.io/en/latest/google-cloud-auth.html +.. _Authentication section: https://google-cloud-python.readthedocs.io/en/latest/core/auth.html .. _authentication document: https://github.com/GoogleCloudPlatform/gcloud-common/tree/master/authentication Contributing diff --git a/bigquery/google/cloud/bigquery/query.py b/bigquery/google/cloud/bigquery/query.py index 6b764f3c664d..ee24d8397b73 100644 --- a/bigquery/google/cloud/bigquery/query.py +++ b/bigquery/google/cloud/bigquery/query.py @@ -226,6 +226,20 @@ def total_bytes_processed(self): if total_bytes_processed is not None: return int(total_bytes_processed) + @property + def num_dml_affected_rows(self): + """Total number of rows affected by a DML query. + + See: + https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query#numDmlAffectedRows + + :rtype: int, or ``NoneType`` + :returns: Count generated on the server (None until set by the server). + """ + num_dml_affected_rows = self._properties.get('numDmlAffectedRows') + if num_dml_affected_rows is not None: + return int(num_dml_affected_rows) + @property def rows(self): """Query results. diff --git a/bigquery/tests/unit/test_query.py b/bigquery/tests/unit/test_query.py index a15833af347d..c2b3ce5496e1 100644 --- a/bigquery/tests/unit/test_query.py +++ b/bigquery/tests/unit/test_query.py @@ -70,6 +70,7 @@ def _makeResource(self, complete=False): ] resource['pageToken'] = self.TOKEN resource['totalBytesProcessed'] = 100000 + resource['numDmlAffectedRows'] = 123 resource['cacheHit'] = False return resource @@ -124,10 +125,12 @@ def _verifyResourceProperties(self, query, resource): self.assertEqual(query.complete, resource.get('jobComplete')) self.assertEqual(query.errors, resource.get('errors')) self.assertEqual(query.page_token, resource.get('pageToken')) + if 'totalRows' in resource: self.assertEqual(query.total_rows, int(resource['totalRows'])) else: self.assertIsNone(query.total_rows) + if 'totalBytesProcessed' in resource: self.assertEqual(query.total_bytes_processed, int(resource['totalBytesProcessed'])) @@ -139,6 +142,12 @@ def _verifyResourceProperties(self, query, resource): else: self.assertIsNone(query.name) + if 'numDmlAffectedRows' in resource: + self.assertEqual(query.num_dml_affected_rows, + int(resource['numDmlAffectedRows'])) + else: + self.assertIsNone(query.num_dml_affected_rows) + self._verify_udf_resources(query, resource) self._verifyQueryParameters(query, resource) self._verifySchema(query, resource) @@ -371,6 +380,27 @@ def test_total_bytes_processed_present_string(self): query._set_properties(resource) self.assertEqual(query.total_bytes_processed, TOTAL_BYTES_PROCESSED) + def test_num_dml_affected_rows_missing(self): + client = _Client(self.PROJECT) + query = self._make_one(self.QUERY, client) + self.assertIsNone(query.num_dml_affected_rows) + + def test_num_dml_affected_rows_present_integer(self): + DML_AFFECTED_ROWS = 123456 + client = _Client(self.PROJECT) + query = self._make_one(self.QUERY, client) + resource = {'numDmlAffectedRows': DML_AFFECTED_ROWS} + query._set_properties(resource) + self.assertEqual(query.num_dml_affected_rows, DML_AFFECTED_ROWS) + + def test_num_dml_affected_rows_present_string(self): + DML_AFFECTED_ROWS = 123456 + client = _Client(self.PROJECT) + query = self._make_one(self.QUERY, client) + resource = {'numDmlAffectedRows': str(DML_AFFECTED_ROWS)} + query._set_properties(resource) + self.assertEqual(query.num_dml_affected_rows, DML_AFFECTED_ROWS) + def test_schema(self): client = _Client(self.PROJECT) query = self._make_one(self.QUERY, client) diff --git a/docs/bigquery-client.rst b/docs/bigquery/client.rst similarity index 71% rename from docs/bigquery-client.rst rename to docs/bigquery/client.rst index 2c7b2c8d21ff..42d4ed8e082a 100644 --- a/docs/bigquery-client.rst +++ b/docs/bigquery/client.rst @@ -1,5 +1,5 @@ -BigQuery Client -=============== +Client +====== .. automodule:: google.cloud.bigquery.client :members: diff --git a/docs/bigquery-dataset.rst b/docs/bigquery/dataset.rst similarity index 100% rename from docs/bigquery-dataset.rst rename to docs/bigquery/dataset.rst diff --git a/docs/bigquery-job.rst b/docs/bigquery/job.rst similarity index 100% rename from docs/bigquery-job.rst rename to docs/bigquery/job.rst diff --git a/docs/bigquery-query.rst b/docs/bigquery/query.rst similarity index 100% rename from docs/bigquery-query.rst rename to docs/bigquery/query.rst diff --git a/docs/bigquery-schema.rst b/docs/bigquery/schema.rst similarity index 100% rename from docs/bigquery-schema.rst rename to docs/bigquery/schema.rst diff --git a/docs/bigquery_snippets.py b/docs/bigquery/snippets.py similarity index 100% rename from docs/bigquery_snippets.py rename to docs/bigquery/snippets.py diff --git a/docs/bigquery-table.rst b/docs/bigquery/table.rst similarity index 100% rename from docs/bigquery-table.rst rename to docs/bigquery/table.rst diff --git a/docs/bigquery-usage.rst b/docs/bigquery/usage.rst similarity index 93% rename from docs/bigquery-usage.rst rename to docs/bigquery/usage.rst index 27fadafbe14a..aaa63e91b679 100644 --- a/docs/bigquery-usage.rst +++ b/docs/bigquery/usage.rst @@ -1,5 +1,16 @@ -Using the API -============= +BigQuery +======== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + dataset + job + query + schema + table Authentication / Configuration ------------------------------ @@ -71,31 +82,31 @@ Dataset operations List datasets for the client's project: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_datasets] :end-before: [END client_list_datasets] Create a new dataset for the client's project: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_create] :end-before: [END dataset_create] Check for the existence of a dataset: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_exists] :end-before: [END dataset_exists] Refresh metadata for a dataset (to pick up changes made by another client): -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_reload] :end-before: [END dataset_reload] Patch metadata for a dataset: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_patch] :end-before: [END dataset_patch] @@ -114,7 +125,7 @@ Replace the ACL for a dataset, and update all writeable fields: Delete a dataset: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_delete] :end-before: [END dataset_delete] @@ -124,61 +135,61 @@ Tables Tables exist within datasets. List tables for the dataset: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START dataset_list_tables] :end-before: [END dataset_list_tables] Create a table: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_create] :end-before: [END table_create] Check for the existence of a table: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_exists] :end-before: [END table_exists] Refresh metadata for a table (to pick up changes made by another client): -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_reload] :end-before: [END table_reload] Patch specific properties for a table: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_patch] :end-before: [END table_patch] Update all writable metadata for a table -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_update] :end-before: [END table_update] Get rows from a table's data: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_fetch_data] :end-before: [END table_fetch_data] Insert rows into a table's data: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_insert_data] :end-before: [END table_insert_data] Upload table data from a file: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_upload_from_file] :end-before: [END table_upload_from_file] Delete a table: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START table_delete] :end-before: [END table_delete] @@ -195,7 +206,7 @@ Jobs describe actions peformed on data in BigQuery tables: List jobs for a project: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_jobs] :end-before: [END client_list_jobs] @@ -205,13 +216,13 @@ Querying data (synchronous) Run a query which can be expected to complete within bounded time: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_run_sync_query] :end-before: [END client_run_sync_query] Run a query using a named query parameter: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_run_sync_query_w_param] :end-before: [END client_run_sync_query_w_param] @@ -219,7 +230,7 @@ If the rows returned by the query do not fit into the initial response, then we need to fetch the remaining rows via :meth:`~google.cloud.bigquery.query.QueryResults.fetch_data`: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_run_sync_query_paged] :end-before: [END client_run_sync_query_paged] @@ -227,7 +238,7 @@ If the query takes longer than the timeout allowed, ``query.complete`` will be ``False``. In that case, we need to poll the associated job until it is done, and then fetch the results: -.. literalinclude:: bigquery_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_run_sync_query_timeout] :end-before: [END client_run_sync_query_timeout] diff --git a/docs/bigtable-client-intro.rst b/docs/bigtable/client-intro.rst similarity index 96% rename from docs/bigtable-client-intro.rst rename to docs/bigtable/client-intro.rst index d53fd3246136..cb31767f3c26 100644 --- a/docs/bigtable-client-intro.rst +++ b/docs/bigtable/client-intro.rst @@ -23,7 +23,7 @@ Configuration ------------- - For an overview of authentication in ``google-cloud-python``, - see :doc:`google-cloud-auth`. + see :doc:`/core/auth`. - In addition to any authentication configuration, you can also set the :envvar:`GOOGLE_CLOUD_PROJECT` environment variable for the Google Cloud Console @@ -84,7 +84,7 @@ After a :class:`Client `, the next highest- object is an :class:`Instance `. You'll need one before you can interact with tables or data. -Head next to learn about the :doc:`bigtable-instance-api`. +Head next to learn about the :doc:`instance-api`. .. _Instance Admin: https://github.com/GoogleCloudPlatform/cloud-bigtable-client/tree/master/bigtable-protos/src/main/proto/google/bigtable/admin/instance/v1 .. _Table Admin: https://github.com/GoogleCloudPlatform/cloud-bigtable-client/tree/master/bigtable-protos/src/main/proto/google/bigtable/admin/table/v1 diff --git a/docs/bigtable-client.rst b/docs/bigtable/client.rst similarity index 100% rename from docs/bigtable-client.rst rename to docs/bigtable/client.rst diff --git a/docs/bigtable-cluster.rst b/docs/bigtable/cluster.rst similarity index 100% rename from docs/bigtable-cluster.rst rename to docs/bigtable/cluster.rst diff --git a/docs/bigtable-column-family.rst b/docs/bigtable/column-family.rst similarity index 100% rename from docs/bigtable-column-family.rst rename to docs/bigtable/column-family.rst diff --git a/docs/bigtable-data-api.rst b/docs/bigtable/data-api.rst similarity index 99% rename from docs/bigtable-data-api.rst rename to docs/bigtable/data-api.rst index 028e137aa2dc..57b179d93b64 100644 --- a/docs/bigtable-data-api.rst +++ b/docs/bigtable/data-api.rst @@ -7,7 +7,7 @@ column families, you are ready to store and retrieve data. Cells vs. Columns vs. Column Families +++++++++++++++++++++++++++++++++++++ -* As explained in the :doc:`table overview `, tables can +* As explained in the :doc:`table overview `, tables can have many column families. * As described below, a table can also have many rows which are specified by row keys. diff --git a/docs/bigtable-instance-api.rst b/docs/bigtable/instance-api.rst similarity index 98% rename from docs/bigtable-instance-api.rst rename to docs/bigtable/instance-api.rst index da53d6fbf2ba..119ca15c88a5 100644 --- a/docs/bigtable-instance-api.rst +++ b/docs/bigtable/instance-api.rst @@ -123,7 +123,7 @@ Now we go down the hierarchy from :class:`Instance ` to a :class:`Table `. -Head next to learn about the :doc:`bigtable-table-api`. +Head next to learn about the :doc:`table-api`. .. _Instance Admin API: https://cloud.google.com/bigtable/docs/creating-instance .. _CreateInstance: https://github.com/GoogleCloudPlatform/cloud-bigtable-client/blob/2aae624081f652427052fb652d3ae43d8ac5bf5a/bigtable-protos/src/main/proto/google/bigtable/admin/instance/v1/bigtable_instance_service.proto#L66-L68 diff --git a/docs/bigtable-instance.rst b/docs/bigtable/instance.rst similarity index 100% rename from docs/bigtable-instance.rst rename to docs/bigtable/instance.rst diff --git a/docs/bigtable-row-data.rst b/docs/bigtable/row-data.rst similarity index 100% rename from docs/bigtable-row-data.rst rename to docs/bigtable/row-data.rst diff --git a/docs/bigtable-row-filters.rst b/docs/bigtable/row-filters.rst similarity index 100% rename from docs/bigtable-row-filters.rst rename to docs/bigtable/row-filters.rst diff --git a/docs/bigtable-row.rst b/docs/bigtable/row.rst similarity index 100% rename from docs/bigtable-row.rst rename to docs/bigtable/row.rst diff --git a/docs/bigtable-table-api.rst b/docs/bigtable/table-api.rst similarity index 98% rename from docs/bigtable-table-api.rst rename to docs/bigtable/table-api.rst index 61f22257e2bc..5168aad49ff7 100644 --- a/docs/bigtable-table-api.rst +++ b/docs/bigtable/table-api.rst @@ -98,7 +98,7 @@ or similar): This rule helps the backend determine when and how to clean up old cells in the column family. -See :doc:`bigtable-column-family` for more information about +See :doc:`column-family` for more information about :class:`GarbageCollectionRule ` and related classes. @@ -141,7 +141,7 @@ Now we go down the final step of the hierarchy from :class:`Row ` as well as streaming data directly via a :class:`Table `. -Head next to learn about the :doc:`bigtable-data-api`. +Head next to learn about the :doc:`data-api`. .. _ListTables: https://github.com/GoogleCloudPlatform/cloud-bigtable-client/blob/2aae624081f652427052fb652d3ae43d8ac5bf5a/bigtable-protos/src/main/proto/google/bigtable/admin/table/v1/bigtable_table_service.proto#L40-L42 .. _CreateTable: https://github.com/GoogleCloudPlatform/cloud-bigtable-client/blob/2aae624081f652427052fb652d3ae43d8ac5bf5a/bigtable-protos/src/main/proto/google/bigtable/admin/table/v1/bigtable_table_service.proto#L35-L37 diff --git a/docs/bigtable-table.rst b/docs/bigtable/table.rst similarity index 100% rename from docs/bigtable-table.rst rename to docs/bigtable/table.rst diff --git a/docs/bigtable-usage.rst b/docs/bigtable/usage.rst similarity index 82% rename from docs/bigtable-usage.rst rename to docs/bigtable/usage.rst index 9d5b931b97ff..421b2426f8cf 100644 --- a/docs/bigtable-usage.rst +++ b/docs/bigtable/usage.rst @@ -1,5 +1,22 @@ -Using the API -============= +Bigtable +======== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client-intro + client + cluster + instance + instance-api + table + table-api + column-family + row + row-data + row-filters + data-api API requests are sent to the `Google Cloud Bigtable`_ API via RPC over HTTP/2. In order to support this, we'll rely on `gRPC`_. We are working with the gRPC @@ -7,7 +24,7 @@ team to rapidly make the install story more user-friendly. Get started by learning about the :class:`Client ` on the -:doc:`bigtable-client-intro` page. +:doc:`client-intro` page. In the hierarchy of API concepts diff --git a/docs/google-cloud-auth.rst b/docs/core/auth.rst similarity index 97% rename from docs/google-cloud-auth.rst rename to docs/core/auth.rst index e7f9c6780283..ac3c4b29528a 100644 --- a/docs/google-cloud-auth.rst +++ b/docs/core/auth.rst @@ -87,14 +87,19 @@ However, you may want to be explicit because from different projects In these situations, you can create an explicit -:class:`~google.auth.credentials.Credentials` object suited to your -environment. After creation, you can pass it directly to a -:class:`Client `: +:class:`~google.auth.credentials.Credentials` object suited to your environment. +After creation, you can pass it directly to a :class:`Client `: .. code:: python client = Client(credentials=credentials) +.. tip:: + To create a credentials object, follow the `google-auth-guide`_. + +.. _google-auth-guide: https://google-auth.readthedocs.io/en/latest/user-guide.html#service-account-private-key-files + + Google App Engine Environment ----------------------------- diff --git a/docs/google-cloud-config.rst b/docs/core/config.rst similarity index 96% rename from docs/google-cloud-config.rst rename to docs/core/config.rst index b30822522f76..7328f685f606 100644 --- a/docs/google-cloud-config.rst +++ b/docs/core/config.rst @@ -43,7 +43,7 @@ Authentication ============== The authentication credentials can be implicitly determined from the -environment or directly. See :doc:`google-cloud-auth`. +environment or directly. See :doc:`/core/auth`. Logging in via ``gcloud beta auth application-default login`` will automatically configure a JSON key file with your default project ID and diff --git a/docs/core/index.rst b/docs/core/index.rst new file mode 100644 index 000000000000..58985beec8f1 --- /dev/null +++ b/docs/core/index.rst @@ -0,0 +1,10 @@ +Core +==== + +.. toctree:: + config + auth + iterators + operation-api + modules + diff --git a/docs/iterators.rst b/docs/core/iterators.rst similarity index 100% rename from docs/iterators.rst rename to docs/core/iterators.rst diff --git a/docs/google-cloud-api.rst b/docs/core/modules.rst similarity index 100% rename from docs/google-cloud-api.rst rename to docs/core/modules.rst diff --git a/docs/operation-api.rst b/docs/core/operation-api.rst similarity index 100% rename from docs/operation-api.rst rename to docs/core/operation-api.rst diff --git a/docs/datastore-usage.rst b/docs/datastore-usage.rst deleted file mode 100644 index 041c5a755c0e..000000000000 --- a/docs/datastore-usage.rst +++ /dev/null @@ -1,6 +0,0 @@ -Using the API -============= - -.. automodule:: google.cloud.datastore - :members: - :show-inheritance: diff --git a/docs/datastore-batches.rst b/docs/datastore/batches.rst similarity index 100% rename from docs/datastore-batches.rst rename to docs/datastore/batches.rst diff --git a/docs/datastore-client.rst b/docs/datastore/client.rst similarity index 100% rename from docs/datastore-client.rst rename to docs/datastore/client.rst diff --git a/docs/datastore-entities.rst b/docs/datastore/entities.rst similarity index 100% rename from docs/datastore-entities.rst rename to docs/datastore/entities.rst diff --git a/docs/datastore-helpers.rst b/docs/datastore/helpers.rst similarity index 100% rename from docs/datastore-helpers.rst rename to docs/datastore/helpers.rst diff --git a/docs/datastore-keys.rst b/docs/datastore/keys.rst similarity index 100% rename from docs/datastore-keys.rst rename to docs/datastore/keys.rst diff --git a/docs/datastore-queries.rst b/docs/datastore/queries.rst similarity index 100% rename from docs/datastore-queries.rst rename to docs/datastore/queries.rst diff --git a/docs/datastore-transactions.rst b/docs/datastore/transactions.rst similarity index 100% rename from docs/datastore-transactions.rst rename to docs/datastore/transactions.rst diff --git a/docs/datastore/usage.rst b/docs/datastore/usage.rst new file mode 100644 index 000000000000..6e22780f5a21 --- /dev/null +++ b/docs/datastore/usage.rst @@ -0,0 +1,21 @@ +Datastore +========= + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + entities + keys + queries + transactions + batches + helpers + +Modules +------- + +.. automodule:: google.cloud.datastore + :members: + :show-inheritance: diff --git a/docs/dns-changes.rst b/docs/dns/changes.rst similarity index 100% rename from docs/dns-changes.rst rename to docs/dns/changes.rst diff --git a/docs/dns-client.rst b/docs/dns/client.rst similarity index 100% rename from docs/dns-client.rst rename to docs/dns/client.rst diff --git a/docs/dns-resource-record-set.rst b/docs/dns/resource-record-set.rst similarity index 100% rename from docs/dns-resource-record-set.rst rename to docs/dns/resource-record-set.rst diff --git a/docs/dns-usage.rst b/docs/dns/usage.rst similarity index 97% rename from docs/dns-usage.rst rename to docs/dns/usage.rst index ab7bdac08a59..7ba5e77c0208 100644 --- a/docs/dns-usage.rst +++ b/docs/dns/usage.rst @@ -1,5 +1,14 @@ -Using the API -============= +DNS +=== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + zone + resource-record-set + changes Client ------ @@ -8,7 +17,7 @@ Client configure your DNS applications. Each instance holds both a ``project`` and an authenticated connection to the DNS service. -For an overview of authentication in ``google-cloud-python``, see :doc:`google-cloud-auth`. +For an overview of authentication in ``google-cloud-python``, see :doc:`/core/auth`. Assuming your environment is set up as described in that document, create an instance of :class:`Client `. diff --git a/docs/dns-zone.rst b/docs/dns/zone.rst similarity index 100% rename from docs/dns-zone.rst rename to docs/dns/zone.rst diff --git a/docs/error-reporting-client.rst b/docs/error-reporting/client.rst similarity index 100% rename from docs/error-reporting-client.rst rename to docs/error-reporting/client.rst diff --git a/docs/error-reporting-usage.rst b/docs/error-reporting/usage.rst similarity index 96% rename from docs/error-reporting-usage.rst rename to docs/error-reporting/usage.rst index 47ed2fce977d..7fd89c04b936 100644 --- a/docs/error-reporting-usage.rst +++ b/docs/error-reporting/usage.rst @@ -1,12 +1,18 @@ -Using the API -============= +Stackdriver Error Reporting +=========================== +.. toctree:: + :maxdepth: 2 + :hidden: + + client + util Authentication and Configuration -------------------------------- - For an overview of authentication in ``google-cloud-python``, - see :doc:`google-cloud-auth`. + see :doc:`/core/auth`. - In addition to any authentication configuration, you should also set the :envvar:`GOOGLE_CLOUD_PROJECT` environment variable for the project you'd like diff --git a/docs/error-reporting-util.rst b/docs/error-reporting/util.rst similarity index 100% rename from docs/error-reporting-util.rst rename to docs/error-reporting/util.rst diff --git a/docs/index.rst b/docs/index.rst index 2467260f9745..88a39b4c9a94 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,240 +1,27 @@ .. toctree:: - :maxdepth: 0 - :hidden: - :caption: google-cloud - - google-cloud-api - google-cloud-config - google-cloud-auth - iterators - operation-api - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: BigQuery - - bigquery-usage - Client - bigquery-dataset - bigquery-job - bigquery-table - bigquery-query - bigquery-schema - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: BigTable - - bigtable-usage - bigtable-client-intro - bigtable-instance-api - bigtable-table-api - bigtable-data-api - Client - bigtable-instance - bigtable-cluster - bigtable-table - bigtable-column-family - bigtable-row - bigtable-row-filters - bigtable-row-data - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Datastore - - datastore-usage - Client - datastore-entities - datastore-keys - datastore-queries - datastore-transactions - datastore-batches - datastore-helpers - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: DNS - - dns-usage - Client - dns-zone - dns-resource-record-set - dns-changes - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Natural Language - - language-usage - Client - language-document - language-responses - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Pub/Sub - - pubsub-usage - Client - pubsub-topic - pubsub-subscription - pubsub-message - pubsub-iam - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Resource Manager - - Overview - resource-manager-client - resource-manager-project - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Runtime Configuration - - runtimeconfig-usage - Client - runtimeconfig-config - runtimeconfig-variable - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Spanner - - spanner-usage - spanner-client-usage - spanner-instance-usage - spanner-database-usage - spanner-session-crud-usage - spanner-session-implicit-txn-usage - spanner-session-pool-usage - spanner-batch-usage - spanner-snapshot-usage - spanner-transaction-usage - - spanner-client-api - spanner-instance-api - spanner-database-api - spanner-session-api - spanner-keyset-api - spanner-snapshot-api - spanner-batch-api - spanner-transaction-api - spanner-streamed-api - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Speech - - speech-usage - Client - speech-encoding - speech-operation - speech-result - speech-sample - speech-alternative - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Stackdriver Error Reporting - - error-reporting-usage - Client - error-reporting-util - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Stackdriver Logging - - logging-usage - Client - logging-logger - logging-entries - logging-metric - logging-sink - logging-stdlib-usage - logging-handlers - logging-handlers-app-engine - logging-handlers-container-engine - logging-transports-sync - logging-transports-thread - logging-transports-base - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Stackdriver Monitoring - - monitoring-usage - Client - monitoring-metric - monitoring-resource - monitoring-group - monitoring-query - monitoring-timeseries - monitoring-label - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Storage - - Client - storage-blobs - storage-buckets - storage-acl - storage-batch - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Translate - - translate-usage - Client - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: Vision - - vision-usage - vision-annotations - vision-batch - vision-client - vision-color - vision-crop-hint - vision-entity - vision-feature - vision-face - vision-image - vision-safe-search - vision-text - vision-web - -.. toctree:: - :maxdepth: 0 - :hidden: - :caption: External Links - - GitHub - Issues - Stack Overflow - PyPI + :maxdepth: 2 + :hidden: + + core/index + bigquery/usage + bigtable/usage + datastore/usage + dns/usage + language/usage + pubsub/usage + resource-manager/api + runtimeconfig/usage + spanner/usage + speech/usage + error-reporting/usage + monitoring/usage + logging/usage + storage/client + translate/usage + vision/usage + +Google Cloud Client Library for Python +====================================== Getting started --------------- @@ -245,8 +32,6 @@ The ``google-cloud`` library is ``pip`` install-able: $ pip install google-cloud ----- - Cloud Datastore ~~~~~~~~~~~~~~~ @@ -281,3 +66,11 @@ Cloud Storage bucket = client.get_bucket('') blob = bucket.blob('my-test-file.txt') blob.upload_from_string('this is test content!') + +Resources +~~~~~~~~~ + +* `GitHub `__ +* `Issues `__ +* `Stack Overflow `__ +* `PyPI `__ diff --git a/docs/language-client.rst b/docs/language/client.rst similarity index 100% rename from docs/language-client.rst rename to docs/language/client.rst diff --git a/docs/language-document.rst b/docs/language/document.rst similarity index 100% rename from docs/language-document.rst rename to docs/language/document.rst diff --git a/docs/language-responses.rst b/docs/language/responses.rst similarity index 100% rename from docs/language-responses.rst rename to docs/language/responses.rst diff --git a/docs/language-usage.rst b/docs/language/usage.rst similarity index 98% rename from docs/language-usage.rst rename to docs/language/usage.rst index bb443f89054c..9b9cfb9cde6a 100644 --- a/docs/language-usage.rst +++ b/docs/language/usage.rst @@ -1,5 +1,13 @@ -Using the API -============= +Natural Language +================ + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + document + responses The `Google Natural Language`_ API can be used to reveal the structure and meaning of text via powerful machine @@ -26,7 +34,7 @@ means to configure your application. Each instance holds an authenticated connection to the Natural Language service. For an overview of authentication in ``google-cloud-python``, see -:doc:`google-cloud-auth`. +:doc:`/core/auth`. Assuming your environment is set up as described in that document, create an instance of :class:`~google.cloud.language.client.Client`. diff --git a/docs/logging-client.rst b/docs/logging/client.rst similarity index 100% rename from docs/logging-client.rst rename to docs/logging/client.rst diff --git a/docs/logging-entries.rst b/docs/logging/entries.rst similarity index 100% rename from docs/logging-entries.rst rename to docs/logging/entries.rst diff --git a/docs/logging-handlers-app-engine.rst b/docs/logging/handlers-app-engine.rst similarity index 100% rename from docs/logging-handlers-app-engine.rst rename to docs/logging/handlers-app-engine.rst diff --git a/docs/logging-handlers-container-engine.rst b/docs/logging/handlers-container-engine.rst similarity index 100% rename from docs/logging-handlers-container-engine.rst rename to docs/logging/handlers-container-engine.rst diff --git a/docs/logging-handlers.rst b/docs/logging/handlers.rst similarity index 100% rename from docs/logging-handlers.rst rename to docs/logging/handlers.rst diff --git a/docs/logging-logger.rst b/docs/logging/logger.rst similarity index 100% rename from docs/logging-logger.rst rename to docs/logging/logger.rst diff --git a/docs/logging-metric.rst b/docs/logging/metric.rst similarity index 100% rename from docs/logging-metric.rst rename to docs/logging/metric.rst diff --git a/docs/logging-sink.rst b/docs/logging/sink.rst similarity index 100% rename from docs/logging-sink.rst rename to docs/logging/sink.rst diff --git a/docs/logging_snippets.py b/docs/logging/snippets.py similarity index 100% rename from docs/logging_snippets.py rename to docs/logging/snippets.py diff --git a/docs/logging-stdlib-usage.rst b/docs/logging/stdlib-usage.rst similarity index 100% rename from docs/logging-stdlib-usage.rst rename to docs/logging/stdlib-usage.rst diff --git a/docs/logging-transports-base.rst b/docs/logging/transports-base.rst similarity index 100% rename from docs/logging-transports-base.rst rename to docs/logging/transports-base.rst diff --git a/docs/logging-transports-sync.rst b/docs/logging/transports-sync.rst similarity index 100% rename from docs/logging-transports-sync.rst rename to docs/logging/transports-sync.rst diff --git a/docs/logging-transports-thread.rst b/docs/logging/transports-thread.rst similarity index 100% rename from docs/logging-transports-thread.rst rename to docs/logging/transports-thread.rst diff --git a/docs/logging-usage.rst b/docs/logging/usage.rst similarity index 87% rename from docs/logging-usage.rst rename to docs/logging/usage.rst index 5c8490c72635..5ec64aa90598 100644 --- a/docs/logging-usage.rst +++ b/docs/logging/usage.rst @@ -1,12 +1,28 @@ -Using the API -============= - +Stackdriver Logging +=================== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + logger + entries + metric + sink + stdlib-usage + handlers + handlers-app-engine + handlers-container-engine + transports-sync + transports-thread + transports-base Authentication and Configuration -------------------------------- - For an overview of authentication in ``google-cloud-python``, - see :doc:`google-cloud-auth`. + see :doc:`/core/auth`. - In addition to any authentication configuration, you should also set the :envvar:`GOOGLE_CLOUD_PROJECT` environment variable for the project you'd like @@ -22,13 +38,13 @@ Authentication and Configuration - After configuring your environment, create a :class:`~google.cloud.logging.client.Client` - .. literalinclude:: logging_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_create_default] :end-before: [END client_create_default] or pass in ``credentials`` and ``project`` explicitly - .. literalinclude:: logging_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_create_explicit] :end-before: [END client_create_explicit] @@ -40,19 +56,19 @@ To write log entries, first create a :class:`~google.cloud.logging.logger.Logger`, passing the "log name" with which to associate the entries: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START logger_create] :end-before: [END logger_create] Write a simple text entry to the logger. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START logger_log_text] :end-before: [END logger_log_text] Write a dictionary entry to the logger. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START logger_log_struct] :end-before: [END logger_log_struct] @@ -62,13 +78,13 @@ Retrieving log entries Fetch entries for the default project. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_entries_default] :end-before: [END client_list_entries_default] Fetch entries across multiple projects. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_entries_multi_project] :end-before: [END client_list_entries_multi_project] @@ -78,25 +94,25 @@ Filter entries retrieved using the `Advanced Logs Filters`_ syntax Fetch entries for the default project. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_entries_filter] :end-before: [END client_list_entries_filter] Sort entries in descending timestamp order. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_entries_order_by] :end-before: [END client_list_entries_order_by] Retrieve entries in batches of 10, iterating until done. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_entries_paged] :end-before: [END client_list_entries_paged] Retrieve entries for a single logger, sorting in descending timestamp order: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START logger_list_entries] :end-before: [END logger_list_entries] @@ -104,7 +120,7 @@ Retrieve entries for a single logger, sorting in descending timestamp order: Delete all entries for a logger ------------------------------- -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START logger_delete] :end-before: [END logger_delete] @@ -117,31 +133,31 @@ used within Stackdriver Monitoring to create charts and alerts. List all metrics for a project: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_metrics] :end-before: [END client_list_metrics] Create a metric: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START metric_create] :end-before: [END metric_create] Refresh local information about a metric: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START metric_reload] :end-before: [END metric_reload] Update a metric: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START metric_update] :end-before: [END metric_update] Delete a metric: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START metric_delete] :end-before: [END metric_delete] @@ -162,13 +178,13 @@ Make sure that the storage bucket you want to export logs too has Add ``cloud-logs@google.com`` as the owner of the bucket: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_bucket_permissions] :end-before: [END sink_bucket_permissions] Create a Cloud Storage sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_storage_create] :end-before: [END sink_storage_create] @@ -183,13 +199,13 @@ See: `Setting permissions for BigQuery`_ .. _Setting permissions for BigQuery: https://cloud.google.com/logging/docs/export/configure_export_v2#errors_exporting_to_bigquery -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_dataset_permissions] :end-before: [END sink_dataset_permissions] Create a BigQuery sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_bigquery_create] :end-before: [END sink_bigquery_create] @@ -204,13 +220,13 @@ See: `Setting permissions for Pub/Sub`_ .. _Setting permissions for Pub/Sub: https://cloud.google.com/logging/docs/export/configure_export_v2#errors_exporting_logs_to_cloud_pubsub -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_topic_permissions] :end-before: [END sink_topic_permissions] Create a Cloud Pub/Sub sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_pubsub_create] :end-before: [END sink_pubsub_create] @@ -219,25 +235,25 @@ Manage Sinks List all sinks for a project: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_sinks] :end-before: [END client_list_sinks] Refresh local information about a sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_reload] :end-before: [END sink_reload] Update a sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_update] :end-before: [END sink_update] Delete a sink: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START sink_delete] :end-before: [END sink_delete] @@ -249,7 +265,7 @@ Stackdriver Logging. There are different handler options to accomplish this. To automatically pick the default for your current environment, use :meth:`~google.cloud.logging.client.Client.get_default_handler`. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START create_default_handler] :end-before: [END create_default_handler] @@ -259,7 +275,7 @@ as well as any other loggers created. A helper method :meth:`~google.cloud.logging.client.Client.setup_logging` is provided to configure this automatically. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START setup_logging] :end-before: [END setup_logging] @@ -270,12 +286,12 @@ to configure this automatically. You can also exclude certain loggers: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START setup_logging_excludes] :end-before: [END setup_logging_excludes] Cloud Logging Handler -===================== +~~~~~~~~~~~~~~~~~~~~~ If you prefer not to use :meth:`~google.cloud.logging.client.Client.get_default_handler`, you can @@ -283,7 +299,7 @@ directly create a :class:`~google.cloud.logging.handlers.handlers.CloudLoggingHandler` instance which will write directly to the API. -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START create_cloud_handler] :end-before: [END create_cloud_handler] @@ -298,12 +314,29 @@ All logs will go to a single custom log, which defaults to "python". The name of the Python logger will be included in the structured log entry under the "python_logger" field. You can change it by providing a name to the handler: -.. literalinclude:: logging_snippets.py +.. literalinclude:: snippets.py :start-after: [START create_named_handler] :end-before: [END create_named_handler] +Cloud Logging Handler transports +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :class:`~google.cloud.logging.handlers.handlers.CloudLoggingHandler` +logging handler can use different transports. The default is +:class:`~google.cloud.logging.handlers.BackgroundThreadTransport`. + + 1. :class:`~google.cloud.logging.handlers.BackgroundThreadTransport` this is + the default. It writes entries on a background + :class:`python.threading.Thread`. + + 1. :class:`~google.cloud.logging.handlers.SyncTransport` this handler does a + direct API call on each logging statement to write the entry. + + +.. _Google Container Engine: https://cloud.google.com/container-engine/ + fluentd logging handlers -======================== +~~~~~~~~~~~~~~~~~~~~~~~~ Besides :class:`~google.cloud.logging.handlers.handlers.CloudLoggingHandler`, which writes directly to the API, two other handlers are provided. @@ -323,20 +356,3 @@ In both cases, the fluentd agent is configured to automatically parse log files in an expected format and forward them to Stackdriver logging. The handlers provided help set the correct metadata such as log level so that logs can be filtered accordingly. - -Cloud Logging Handler transports -================================= - -The :class:`~google.cloud.logging.handlers.handlers.CloudLoggingHandler` -logging handler can use different transports. The default is -:class:`~google.cloud.logging.handlers.BackgroundThreadTransport`. - - 1. :class:`~google.cloud.logging.handlers.BackgroundThreadTransport` this is - the default. It writes entries on a background - :class:`python.threading.Thread`. - - 1. :class:`~google.cloud.logging.handlers.SyncTransport` this handler does a - direct API call on each logging statement to write the entry. - - -.. _Google Container Engine: https://cloud.google.com/container-engine/ diff --git a/docs/monitoring-client.rst b/docs/monitoring/client.rst similarity index 100% rename from docs/monitoring-client.rst rename to docs/monitoring/client.rst diff --git a/docs/monitoring-group.rst b/docs/monitoring/group.rst similarity index 100% rename from docs/monitoring-group.rst rename to docs/monitoring/group.rst diff --git a/docs/monitoring-label.rst b/docs/monitoring/label.rst similarity index 100% rename from docs/monitoring-label.rst rename to docs/monitoring/label.rst diff --git a/docs/monitoring-metric.rst b/docs/monitoring/metric.rst similarity index 100% rename from docs/monitoring-metric.rst rename to docs/monitoring/metric.rst diff --git a/docs/monitoring-query.rst b/docs/monitoring/query.rst similarity index 100% rename from docs/monitoring-query.rst rename to docs/monitoring/query.rst diff --git a/docs/monitoring-resource.rst b/docs/monitoring/resource.rst similarity index 100% rename from docs/monitoring-resource.rst rename to docs/monitoring/resource.rst diff --git a/docs/monitoring-timeseries.rst b/docs/monitoring/timeseries.rst similarity index 100% rename from docs/monitoring-timeseries.rst rename to docs/monitoring/timeseries.rst diff --git a/docs/monitoring-usage.rst b/docs/monitoring/usage.rst similarity index 98% rename from docs/monitoring-usage.rst rename to docs/monitoring/usage.rst index 2f0408264ea8..558425c5cab0 100644 --- a/docs/monitoring-usage.rst +++ b/docs/monitoring/usage.rst @@ -1,6 +1,17 @@ -Using the API -============= +Stackdriver Monitoring +====================== +.. toctree:: + :maxdepth: 2 + :hidden: + + client + metric + resource + group + query + timeseries + label Introduction ------------ @@ -49,7 +60,7 @@ GCP projects and AWS accounts. It can also simply be the ID of a monitored project. Most often the authentication credentials will be determined -implicitly from your environment. See :doc:`google-cloud-auth` for +implicitly from your environment. See :doc:`/core/auth` for more information. It is thus typical to create a client object as follows: diff --git a/docs/pubsub-client.rst b/docs/pubsub/client.rst similarity index 100% rename from docs/pubsub-client.rst rename to docs/pubsub/client.rst diff --git a/docs/pubsub-iam.rst b/docs/pubsub/iam.rst similarity index 100% rename from docs/pubsub-iam.rst rename to docs/pubsub/iam.rst diff --git a/docs/pubsub-message.rst b/docs/pubsub/message.rst similarity index 100% rename from docs/pubsub-message.rst rename to docs/pubsub/message.rst diff --git a/docs/pubsub_snippets.py b/docs/pubsub/snippets.py similarity index 100% rename from docs/pubsub_snippets.py rename to docs/pubsub/snippets.py diff --git a/docs/pubsub-subscription.rst b/docs/pubsub/subscription.rst similarity index 100% rename from docs/pubsub-subscription.rst rename to docs/pubsub/subscription.rst diff --git a/docs/pubsub-topic.rst b/docs/pubsub/topic.rst similarity index 100% rename from docs/pubsub-topic.rst rename to docs/pubsub/topic.rst diff --git a/docs/pubsub-usage.rst b/docs/pubsub/usage.rst similarity index 84% rename from docs/pubsub-usage.rst rename to docs/pubsub/usage.rst index e385fe6eba5e..96727e654835 100644 --- a/docs/pubsub-usage.rst +++ b/docs/pubsub/usage.rst @@ -1,5 +1,16 @@ -Using the API -============= +Pub / Sub +========= + + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + topic + subscription + message + iam Authentication / Configuration ------------------------------ @@ -41,43 +52,43 @@ Manage topics for a project List topics for the default project: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_topics] :end-before: [END client_list_topics] Create a new topic for the default project: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_create] :end-before: [END topic_create] Check for the existence of a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_exists] :end-before: [END topic_exists] Delete a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_delete] :end-before: [END topic_delete] Fetch the IAM policy for a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_get_iam_policy] :end-before: [END topic_get_iam_policy] Update the IAM policy for a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_set_iam_policy] :end-before: [END topic_set_iam_policy] Test permissions allowed by the current IAM policy on a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_check_iam_permissions] :end-before: [END topic_check_iam_permissions] @@ -87,19 +98,19 @@ Publish messages to a topic Publish a single message to a topic, without attributes: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_publish_simple_message] :end-before: [END topic_publish_simple_message] Publish a single message to a topic, with attributes: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_publish_message_with_attrs] :end-before: [END topic_publish_message_with_attrs] Publish a set of messages to a topic (as a single request): -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_batch] :end-before: [END topic_batch] @@ -115,79 +126,79 @@ Manage subscriptions to topics List all subscriptions for the default project: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_list_subscriptions] :end-before: [END client_list_subscriptions] List subscriptions for a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_list_subscriptions] :end-before: [END topic_list_subscriptions] Create a new pull subscription for a topic, with defaults: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_subscription_defaults] :end-before: [END topic_subscription_defaults] Create a new pull subscription for a topic with a non-default ACK deadline: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_subscription_ack90] :end-before: [END topic_subscription_ack90] Create a new push subscription for a topic: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START topic_subscription_push] :end-before: [END topic_subscription_push] Check for the existence of a subscription: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_exists] :end-before: [END subscription_exists] Convert a pull subscription to push: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_pull_push] :end-before: [END subscription_pull_push] Convert a push subscription to pull: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_push_pull] :end-before: [END subscription_push_pull] Re-synchronize a subscription with the back-end: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_reload] :end-before: [END subscription_reload] Fetch the IAM policy for a subscription -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_get_iam_policy] :end-before: [END subscription_get_iam_policy] Update the IAM policy for a subscription: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_set_iam_policy] :end-before: [END subscription_set_iam_policy] Test permissions allowed by the current IAM policy on a subscription: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_check_iam_permissions] :end-before: [END subscription_check_iam_permissions] Delete a subscription: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_delete] :end-before: [END subscription_delete] @@ -197,33 +208,33 @@ Pull messages from a subscription Fetch pending messages for a pull subscription: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_pull] :end-before: [END subscription_pull] Note that received messages must be acknowledged, or else the back-end will re-send them later: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_acknowledge] :end-before: [END subscription_acknowledge] Fetch messages for a pull subscription without blocking (none pending): -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_pull_return_immediately] :end-before: [END subscription_pull_return_immediately] Update the acknowlegement deadline for pulled messages: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_modify_ack_deadline] :end-before: [END subscription_modify_ack_deadline] Fetch pending messages, acknowledging those whose processing doesn't raise an error: -.. literalinclude:: pubsub_snippets.py +.. literalinclude:: snippets.py :start-after: [START subscription_pull_autoack] :end-before: [END subscription_pull_autoack] diff --git a/docs/resource-manager-api.rst b/docs/resource-manager/api.rst similarity index 97% rename from docs/resource-manager-api.rst rename to docs/resource-manager/api.rst index f74439763a10..006e1c20171c 100644 --- a/docs/resource-manager-api.rst +++ b/docs/resource-manager/api.rst @@ -1,5 +1,12 @@ -Resource Manager Overview -------------------------- +Resource Manager +---------------- + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + project The Cloud Resource Manager API provides methods that you can use to programmatically manage your projects in the Google Cloud Platform. diff --git a/docs/resource-manager-client.rst b/docs/resource-manager/client.rst similarity index 100% rename from docs/resource-manager-client.rst rename to docs/resource-manager/client.rst diff --git a/docs/resource-manager-project.rst b/docs/resource-manager/project.rst similarity index 100% rename from docs/resource-manager-project.rst rename to docs/resource-manager/project.rst diff --git a/docs/runtimeconfig-usage.rst b/docs/runtimeconfig-usage.rst deleted file mode 100644 index 9f9e77252a6a..000000000000 --- a/docs/runtimeconfig-usage.rst +++ /dev/null @@ -1,6 +0,0 @@ -Using the API -============= - -.. automodule:: google.cloud.runtimeconfig - :members: - :show-inheritance: diff --git a/docs/runtimeconfig-client.rst b/docs/runtimeconfig/client.rst similarity index 100% rename from docs/runtimeconfig-client.rst rename to docs/runtimeconfig/client.rst diff --git a/docs/runtimeconfig-config.rst b/docs/runtimeconfig/config.rst similarity index 100% rename from docs/runtimeconfig-config.rst rename to docs/runtimeconfig/config.rst diff --git a/docs/runtimeconfig/usage.rst b/docs/runtimeconfig/usage.rst new file mode 100644 index 000000000000..3278d5aff9c5 --- /dev/null +++ b/docs/runtimeconfig/usage.rst @@ -0,0 +1,17 @@ +Runtimeconfig +============= + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + config + variable + +Modules +------- + +.. automodule:: google.cloud.runtimeconfig + :members: + :show-inheritance: diff --git a/docs/runtimeconfig-variable.rst b/docs/runtimeconfig/variable.rst similarity index 100% rename from docs/runtimeconfig-variable.rst rename to docs/runtimeconfig/variable.rst diff --git a/docs/spanner-batch-api.rst b/docs/spanner/batch-api.rst similarity index 100% rename from docs/spanner-batch-api.rst rename to docs/spanner/batch-api.rst diff --git a/docs/spanner-batch-usage.rst b/docs/spanner/batch-usage.rst similarity index 99% rename from docs/spanner-batch-usage.rst rename to docs/spanner/batch-usage.rst index 3bf4917958d2..1bdce70e5342 100644 --- a/docs/spanner-batch-usage.rst +++ b/docs/spanner/batch-usage.rst @@ -176,4 +176,4 @@ if the ``with`` block exits without raising an exception. Next Step --------- -Next, learn about :doc:`spanner-snapshot-usage`. +Next, learn about :doc:`snapshot-usage`. diff --git a/docs/spanner-client-api.rst b/docs/spanner/client-api.rst similarity index 100% rename from docs/spanner-client-api.rst rename to docs/spanner/client-api.rst diff --git a/docs/spanner-client-usage.rst b/docs/spanner/client-usage.rst similarity index 96% rename from docs/spanner-client-usage.rst rename to docs/spanner/client-usage.rst index 6c044e5ba5b5..a40c064f86da 100644 --- a/docs/spanner-client-usage.rst +++ b/docs/spanner/client-usage.rst @@ -25,7 +25,7 @@ Configuration ------------- - For an overview of authentication in ``google.cloud-python``, - see :doc:`google-cloud-auth`. + see :doc:`/core/auth`. - In addition to any authentication configuration, you can also set the :envvar:`GCLOUD_PROJECT` environment variable for the Google Cloud Console @@ -62,7 +62,7 @@ After a :class:`~google.cloud.spanner.client.Client`, the next highest-level object is an :class:`~google.cloud.spanner.instance.Instance`. You'll need one before you can interact with databases. -Next, learn about the :doc:`spanner-instance-usage`. +Next, learn about the :doc:`instance-usage`. .. _Instance Admin: https://cloud.google.com/spanner/reference/rpc/google.spanner.admin.instance.v1 .. _Database Admin: https://cloud.google.com/spanner/reference/rpc/google.spanner.admin.database.v1 diff --git a/docs/spanner-database-api.rst b/docs/spanner/database-api.rst similarity index 100% rename from docs/spanner-database-api.rst rename to docs/spanner/database-api.rst diff --git a/docs/spanner-database-usage.rst b/docs/spanner/database-usage.rst similarity index 98% rename from docs/spanner-database-usage.rst rename to docs/spanner/database-usage.rst index 3d1a51c6ed9a..aecd1ab12ccc 100644 --- a/docs/spanner-database-usage.rst +++ b/docs/spanner/database-usage.rst @@ -121,4 +121,4 @@ method: Next Step --------- -Next, learn about :doc:`spanner-session-crud-usage`. +Next, learn about :doc:`session-crud-usage`. diff --git a/docs/spanner-instance-api.rst b/docs/spanner/instance-api.rst similarity index 100% rename from docs/spanner-instance-api.rst rename to docs/spanner/instance-api.rst diff --git a/docs/spanner-instance-usage.rst b/docs/spanner/instance-usage.rst similarity index 98% rename from docs/spanner-instance-usage.rst rename to docs/spanner/instance-usage.rst index e05910bc59fd..f3b254e4f808 100644 --- a/docs/spanner-instance-usage.rst +++ b/docs/spanner/instance-usage.rst @@ -175,7 +175,7 @@ Now we go down the hierarchy from :class:`~google.cloud.spanner.instance.Instance` to a :class:`~google.cloud.spanner.database.Database`. -Next, learn about the :doc:`spanner-database-usage`. +Next, learn about the :doc:`database-usage`. .. _Instance Admin API: https://cloud.google.com/spanner/reference/rpc/google.spanner.admin.instance.v1 diff --git a/docs/spanner-keyset-api.rst b/docs/spanner/keyset-api.rst similarity index 100% rename from docs/spanner-keyset-api.rst rename to docs/spanner/keyset-api.rst diff --git a/docs/spanner-session-api.rst b/docs/spanner/session-api.rst similarity index 100% rename from docs/spanner-session-api.rst rename to docs/spanner/session-api.rst diff --git a/docs/spanner-session-crud-usage.rst b/docs/spanner/session-crud-usage.rst similarity index 96% rename from docs/spanner-session-crud-usage.rst rename to docs/spanner/session-crud-usage.rst index 43e983f787d8..e0734bee1066 100644 --- a/docs/spanner-session-crud-usage.rst +++ b/docs/spanner/session-crud-usage.rst @@ -77,4 +77,4 @@ you can use the session as a Python context manager: Next Step --------- -Next, learn about :doc:`spanner-session-implicit-txn-usage`. +Next, learn about :doc:`session-implicit-txn-usage`. diff --git a/docs/spanner-session-implicit-txn-usage.rst b/docs/spanner/session-implicit-txn-usage.rst similarity index 96% rename from docs/spanner-session-implicit-txn-usage.rst rename to docs/spanner/session-implicit-txn-usage.rst index cf0c06672917..5c7d3025f566 100644 --- a/docs/spanner-session-implicit-txn-usage.rst +++ b/docs/spanner/session-implicit-txn-usage.rst @@ -51,4 +51,4 @@ fails if the result set is too large, Next Step --------- -Next, learn about :doc:`spanner-batch-usage`. +Next, learn about :doc:`batch-usage`. diff --git a/docs/spanner-session-pool-usage.rst b/docs/spanner/session-pool-usage.rst similarity index 100% rename from docs/spanner-session-pool-usage.rst rename to docs/spanner/session-pool-usage.rst diff --git a/docs/spanner-snapshot-api.rst b/docs/spanner/snapshot-api.rst similarity index 100% rename from docs/spanner-snapshot-api.rst rename to docs/spanner/snapshot-api.rst diff --git a/docs/spanner-snapshot-usage.rst b/docs/spanner/snapshot-usage.rst similarity index 97% rename from docs/spanner-snapshot-usage.rst rename to docs/spanner/snapshot-usage.rst index 272612c00e75..d67533edb8f7 100644 --- a/docs/spanner-snapshot-usage.rst +++ b/docs/spanner/snapshot-usage.rst @@ -81,4 +81,4 @@ fails if the result set is too large, Next Step --------- -Next, learn about :doc:`spanner-transaction-usage`. +Next, learn about :doc:`transaction-usage`. diff --git a/docs/spanner-streamed-api.rst b/docs/spanner/streamed-api.rst similarity index 100% rename from docs/spanner-streamed-api.rst rename to docs/spanner/streamed-api.rst diff --git a/docs/spanner-transaction-api.rst b/docs/spanner/transaction-api.rst similarity index 100% rename from docs/spanner-transaction-api.rst rename to docs/spanner/transaction-api.rst diff --git a/docs/spanner-transaction-usage.rst b/docs/spanner/transaction-usage.rst similarity index 100% rename from docs/spanner-transaction-usage.rst rename to docs/spanner/transaction-usage.rst diff --git a/docs/spanner-usage.rst b/docs/spanner/usage.rst similarity index 60% rename from docs/spanner-usage.rst rename to docs/spanner/usage.rst index f308201b674f..0d9142041523 100644 --- a/docs/spanner-usage.rst +++ b/docs/spanner/usage.rst @@ -1,11 +1,35 @@ -Using the API -============= +Spanner +======= + +.. toctree:: + :maxdepth: 2 + :hidden: + + client-usage + instance-usage + database-usage + session-crud-usage + session-implicit-txn-usage + session-pool-usage + batch-usage + snapshot-usage + transaction-usage + + client-api + instance-api + database-api + session-api + keyset-api + snapshot-api + batch-api + transaction-api + streamed-api API requests are sent to the `Cloud Spanner`_ API via RPC over HTTP/2. In order to support this, we'll rely on `gRPC`_. Get started by learning about the :class:`~google.cloud.spanner.client.Client` -on the :doc:`spanner-client-usage` page. +on the :doc:`client-usage` page. In the hierarchy of API concepts diff --git a/docs/speech-alternative.rst b/docs/speech/alternative.rst similarity index 100% rename from docs/speech-alternative.rst rename to docs/speech/alternative.rst diff --git a/docs/speech-client.rst b/docs/speech/client.rst similarity index 100% rename from docs/speech-client.rst rename to docs/speech/client.rst diff --git a/docs/speech-encoding.rst b/docs/speech/encoding.rst similarity index 100% rename from docs/speech-encoding.rst rename to docs/speech/encoding.rst diff --git a/docs/speech-operation.rst b/docs/speech/operation.rst similarity index 100% rename from docs/speech-operation.rst rename to docs/speech/operation.rst diff --git a/docs/speech-result.rst b/docs/speech/result.rst similarity index 100% rename from docs/speech-result.rst rename to docs/speech/result.rst diff --git a/docs/speech-sample.rst b/docs/speech/sample.rst similarity index 100% rename from docs/speech-sample.rst rename to docs/speech/sample.rst diff --git a/docs/speech-usage.rst b/docs/speech/usage.rst similarity index 98% rename from docs/speech-usage.rst rename to docs/speech/usage.rst index 81f5cdd0cb0c..a651965e9e18 100644 --- a/docs/speech-usage.rst +++ b/docs/speech/usage.rst @@ -1,5 +1,16 @@ -Using the API -============= +Speech +====== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client + encoding + operation + result + sample + alternative The `Google Speech`_ API enables developers to convert audio to text. The API recognizes over 80 languages and variants, to support your global user @@ -15,7 +26,7 @@ means to configure your application. Each instance holds an authenticated connection to the Cloud Speech Service. For an overview of authentication in ``google-cloud-python``, see -:doc:`google-cloud-auth`. +:doc:`/core/auth`. Assuming your environment is set up as described in that document, create an instance of :class:`~google.cloud.speech.client.Client`. diff --git a/docs/storage-client.rst b/docs/storage-client.rst deleted file mode 100644 index 1358bbfe664c..000000000000 --- a/docs/storage-client.rst +++ /dev/null @@ -1,6 +0,0 @@ -Storage Client -============== - -.. automodule:: google.cloud.storage.client - :members: - :show-inheritance: diff --git a/docs/storage-acl.rst b/docs/storage/acl.rst similarity index 100% rename from docs/storage-acl.rst rename to docs/storage/acl.rst diff --git a/docs/storage-batch.rst b/docs/storage/batch.rst similarity index 100% rename from docs/storage-batch.rst rename to docs/storage/batch.rst diff --git a/docs/storage-blobs.rst b/docs/storage/blobs.rst similarity index 100% rename from docs/storage-blobs.rst rename to docs/storage/blobs.rst diff --git a/docs/storage-buckets.rst b/docs/storage/buckets.rst similarity index 100% rename from docs/storage-buckets.rst rename to docs/storage/buckets.rst diff --git a/docs/storage/client.rst b/docs/storage/client.rst new file mode 100644 index 000000000000..a72de7af9f8e --- /dev/null +++ b/docs/storage/client.rst @@ -0,0 +1,16 @@ +Storage +======= + +.. toctree:: + :maxdepth: 2 + :hidden: + + blobs + buckets + acl + batch + + +.. automodule:: google.cloud.storage.client + :members: + :show-inheritance: diff --git a/docs/storage_snippets.py b/docs/storage/snippets.py similarity index 100% rename from docs/storage_snippets.py rename to docs/storage/snippets.py diff --git a/docs/translate-client.rst b/docs/translate/client.rst similarity index 100% rename from docs/translate-client.rst rename to docs/translate/client.rst diff --git a/docs/translate-usage.rst b/docs/translate/usage.rst similarity index 97% rename from docs/translate-usage.rst rename to docs/translate/usage.rst index 91d0d4a8bfc1..21723a93d6db 100644 --- a/docs/translate-usage.rst +++ b/docs/translate/usage.rst @@ -1,5 +1,11 @@ -Using the API -============= +Translation +=========== + +.. toctree:: + :maxdepth: 2 + :hidden: + + client With `Google Cloud Translation`_, you can dynamically translate text between thousands of language pairs. The Google Cloud Translation API diff --git a/docs/vision-annotations.rst b/docs/vision/annotations.rst similarity index 100% rename from docs/vision-annotations.rst rename to docs/vision/annotations.rst diff --git a/docs/vision-batch.rst b/docs/vision/batch.rst similarity index 100% rename from docs/vision-batch.rst rename to docs/vision/batch.rst diff --git a/docs/vision-client.rst b/docs/vision/client.rst similarity index 100% rename from docs/vision-client.rst rename to docs/vision/client.rst diff --git a/docs/vision-color.rst b/docs/vision/color.rst similarity index 100% rename from docs/vision-color.rst rename to docs/vision/color.rst diff --git a/docs/vision-crop-hint.rst b/docs/vision/crop-hint.rst similarity index 100% rename from docs/vision-crop-hint.rst rename to docs/vision/crop-hint.rst diff --git a/docs/vision-entity.rst b/docs/vision/entity.rst similarity index 100% rename from docs/vision-entity.rst rename to docs/vision/entity.rst diff --git a/docs/vision-face.rst b/docs/vision/face.rst similarity index 100% rename from docs/vision-face.rst rename to docs/vision/face.rst diff --git a/docs/vision-feature.rst b/docs/vision/feature.rst similarity index 100% rename from docs/vision-feature.rst rename to docs/vision/feature.rst diff --git a/docs/vision-image.rst b/docs/vision/image.rst similarity index 100% rename from docs/vision-image.rst rename to docs/vision/image.rst diff --git a/docs/vision-safe-search.rst b/docs/vision/safe-search.rst similarity index 100% rename from docs/vision-safe-search.rst rename to docs/vision/safe-search.rst diff --git a/docs/vision-text.rst b/docs/vision/text.rst similarity index 100% rename from docs/vision-text.rst rename to docs/vision/text.rst diff --git a/docs/vision-usage.rst b/docs/vision/usage.rst similarity index 98% rename from docs/vision-usage.rst rename to docs/vision/usage.rst index ffa31fb94562..07775aaef9a9 100644 --- a/docs/vision-usage.rst +++ b/docs/vision/usage.rst @@ -1,14 +1,30 @@ -#################### -Using the Vision API -#################### - +###### +Vision +###### + +.. toctree:: + :maxdepth: 2 + :hidden: + + annotations + batch + client + color + crop-hint + entity + feature + face + image + safe-search + text + web ******************************** Authentication and Configuration ******************************** - For an overview of authentication in ``google-cloud-python``, - see :doc:`google-cloud-auth`. + see :doc:`/core/auth`. - In addition to any authentication configuration, you should also set the :envvar:`GOOGLE_CLOUD_PROJECT` environment variable for the project you'd diff --git a/docs/vision-web.rst b/docs/vision/web.rst similarity index 100% rename from docs/vision-web.rst rename to docs/vision/web.rst diff --git a/logging/google/cloud/logging/handlers/_helpers.py b/logging/google/cloud/logging/handlers/_helpers.py index e5bdabe2e388..1ebb064ed228 100644 --- a/logging/google/cloud/logging/handlers/_helpers.py +++ b/logging/google/cloud/logging/handlers/_helpers.py @@ -19,10 +19,11 @@ try: import flask -except ImportError: +except ImportError: # pragma: NO COVER flask = None -from google.cloud.logging.handlers.middleware.request import _get_django_request +from google.cloud.logging.handlers.middleware.request import ( + _get_django_request) _FLASK_TRACE_HEADER = 'X_CLOUD_TRACE_CONTEXT' _DJANGO_TRACE_HEADER = 'HTTP_X_CLOUD_TRACE_CONTEXT' @@ -63,7 +64,7 @@ def get_trace_id_from_flask(): if header is None: return None - trace_id = header.split('/')[0] + trace_id = header.split('/', 1)[0] return trace_id @@ -79,14 +80,11 @@ def get_trace_id_from_django(): if request is None: return None - try: - header = request.META.get(_DJANGO_TRACE_HEADER) - except KeyError: - return None - + header = request.META.get(_DJANGO_TRACE_HEADER) if header is None: return None - trace_id = header.split('/')[0] + + trace_id = header.split('/', 1)[0] return trace_id diff --git a/logging/google/cloud/logging/handlers/app_engine.py b/logging/google/cloud/logging/handlers/app_engine.py index f8b12c44a42e..f1998a9ee13e 100644 --- a/logging/google/cloud/logging/handlers/app_engine.py +++ b/logging/google/cloud/logging/handlers/app_engine.py @@ -73,7 +73,10 @@ def get_gae_resource(self): return gae_resource def get_gae_labels(self): - """Return the labels for GAE app which includes trace_id. + """Return the labels for GAE app. + + If the trace ID can be detected, it will be included as a label. + Currently, no other labels are included. :rtype: dict :returns: Labels for GAE app. diff --git a/logging/google/cloud/logging/handlers/middleware/request.py b/logging/google/cloud/logging/handlers/middleware/request.py index 1acf7ffd9961..4c0b22a8e96b 100644 --- a/logging/google/cloud/logging/handlers/middleware/request.py +++ b/logging/google/cloud/logging/handlers/middleware/request.py @@ -12,6 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +"""Django middleware helper to capture a request. + +The request is stored on a thread-local so that it can be +inspected by other helpers. +""" + import threading diff --git a/logging/tests/unit/handlers/middleware/test_request.py b/logging/tests/unit/handlers/middleware/test_request.py index ab8c18d1aa0e..983d67129647 100644 --- a/logging/tests/unit/handlers/middleware/test_request.py +++ b/logging/tests/unit/handlers/middleware/test_request.py @@ -14,16 +14,10 @@ import unittest +import mock -class TestRequestMiddleware(unittest.TestCase): - def _get_target_class(self): - from google.cloud.logging.handlers.middleware.request import RequestMiddleware - - return RequestMiddleware - - def _make_one(self, *args, **kw): - return self._get_target_class()(*args, **kw) +class DjangoBase(unittest.TestCase): @classmethod def setUpClass(cls): @@ -40,11 +34,53 @@ def tearDownClass(cls): teardown_test_environment() - def test_get_django_request(self): + +class TestRequestMiddleware(DjangoBase): + + def _get_target_class(self): + from google.cloud.logging.handlers.middleware import request + + return request.RequestMiddleware + + def _make_one(self, *args, **kw): + return self._get_target_class()(*args, **kw) + + def test_process_request(self): from django.test import RequestFactory - from google.cloud.logging.handlers.middleware.request import _get_django_request + from google.cloud.logging.handlers.middleware import request middleware = self._make_one() - request = RequestFactory().get('/') - middleware.process_request(request) - self.assertEqual(_get_django_request(), request) + mock_request = RequestFactory().get('/') + middleware.process_request(mock_request) + + django_request = request._get_django_request() + self.assertEqual(django_request, mock_request) + + +class Test__get_django_request(DjangoBase): + + @staticmethod + def _call_fut(): + from google.cloud.logging.handlers.middleware import request + + return request._get_django_request() + + @staticmethod + def _make_patch(new_locals): + return mock.patch( + 'google.cloud.logging.handlers.middleware.request._thread_locals', + new=new_locals) + + def test_with_request(self): + thread_locals = mock.Mock(spec=['request']) + with self._make_patch(thread_locals): + django_request = self._call_fut() + + self.assertIs(django_request, thread_locals.request) + + def test_without_request(self): + thread_locals = mock.Mock(spec=[]) + with self._make_patch(thread_locals): + django_request = self._call_fut() + + self.assertIsNone(django_request) diff --git a/logging/tests/unit/handlers/test__helpers.py b/logging/tests/unit/handlers/test__helpers.py index c50ce0044e85..0731c825d32c 100644 --- a/logging/tests/unit/handlers/test__helpers.py +++ b/logging/tests/unit/handlers/test__helpers.py @@ -14,9 +14,17 @@ import unittest +import mock + class Test_get_trace_id_from_flask(unittest.TestCase): + @staticmethod + def _call_fut(): + from google.cloud.logging.handlers import _helpers + + return _helpers.get_trace_id_from_flask() + @staticmethod def create_app(): import flask @@ -25,29 +33,22 @@ def create_app(): @app.route('/') def index(): - return 'test flask trace' + return 'test flask trace' # pragma: NO COVER return app def setUp(self): - self.app = Test_get_trace_id_from_flask.create_app() - - def test_trace_id_no_context_header(self): - from google.cloud.logging.handlers import _helpers + self.app = self.create_app() + def test_no_context_header(self): with self.app.test_request_context( path='/', headers={}): - trace_id = _helpers.get_trace_id_from_flask() - trace_id_returned = _helpers.get_trace_id() + trace_id = self._call_fut() self.assertIsNone(trace_id) - self.assertIsNone(trace_id_returned) - - def test_trace_id_valid_context_header(self): - from google.cloud.logging.handlers._helpers import get_trace_id_from_flask - from google.cloud.logging.handlers._helpers import get_trace_id + def test_valid_context_header(self): flask_trace_header = 'X_CLOUD_TRACE_CONTEXT' expected_trace_id = 'testtraceidflask' flask_trace_id = expected_trace_id + '/testspanid' @@ -57,15 +58,19 @@ def test_trace_id_valid_context_header(self): headers={flask_trace_header: flask_trace_id}) with context: - trace_id = get_trace_id_from_flask() - trace_id_returned = get_trace_id() + trace_id = self._call_fut() self.assertEqual(trace_id, expected_trace_id) - self.assertEqual(trace_id, trace_id_returned) class Test_get_trace_id_from_django(unittest.TestCase): + @staticmethod + def _call_fut(): + from google.cloud.logging.handlers import _helpers + + return _helpers.get_trace_id_from_django() + def setUp(self): from django.conf import settings from django.test.utils import setup_test_environment @@ -76,47 +81,91 @@ def setUp(self): def tearDown(self): from django.test.utils import teardown_test_environment + from google.cloud.logging.handlers.middleware import request teardown_test_environment() + request._thread_locals.__dict__.clear() - def test_trace_id_no_context_header(self): + def test_no_context_header(self): from django.test import RequestFactory - from google.cloud.logging.handlers import _helpers from google.cloud.logging.handlers.middleware import request django_request = RequestFactory().get('/') middleware = request.RequestMiddleware() middleware.process_request(django_request) - trace_id = _helpers.get_trace_id_from_django() - trace_id_returned = _helpers.get_trace_id() - + trace_id = self._call_fut() self.assertIsNone(trace_id) - self.assertIsNone(trace_id_returned) - - request._thread_locals.__dict__.clear() - def test_trace_id_valid_context_header(self): + def test_valid_context_header(self): from django.test import RequestFactory - from google.cloud.logging.handlers._helpers import get_trace_id_from_django - from google.cloud.logging.handlers._helpers import get_trace_id - from google.cloud.logging.handlers.middleware.request import RequestMiddleware - from google.cloud.logging.handlers.middleware.request import _thread_locals + from google.cloud.logging.handlers.middleware import request django_trace_header = 'HTTP_X_CLOUD_TRACE_CONTEXT' expected_trace_id = 'testtraceiddjango' django_trace_id = expected_trace_id + '/testspanid' - request = RequestFactory().get( + django_request = RequestFactory().get( '/', **{django_trace_header: django_trace_id}) - middleware = RequestMiddleware() - middleware.process_request(request) - trace_id = get_trace_id_from_django() - trace_id_returned = get_trace_id() + middleware = request.RequestMiddleware() + middleware.process_request(django_request) + trace_id = self._call_fut() self.assertEqual(trace_id, expected_trace_id) - self.assertEqual(trace_id, trace_id_returned) - _thread_locals.__dict__.clear() + +class Test_get_trace_id(unittest.TestCase): + + @staticmethod + def _call_fut(): + from google.cloud.logging.handlers import _helpers + + return _helpers.get_trace_id() + + def _helper(self, django_return, flask_return): + django_patch = mock.patch( + 'google.cloud.logging.handlers._helpers.get_trace_id_from_django', + return_value=django_return) + flask_patch = mock.patch( + 'google.cloud.logging.handlers._helpers.get_trace_id_from_flask', + return_value=flask_return) + + with django_patch as django_mock: + with flask_patch as flask_mock: + trace_id = self._call_fut() + + return django_mock, flask_mock, trace_id + + def test_from_django(self): + django_mock, flask_mock, trace_id = self._helper( + 'test-django-trace-id', None) + self.assertEqual(trace_id, django_mock.return_value) + + django_mock.assert_called_once_with() + flask_mock.assert_not_called() + + def test_from_flask(self): + django_mock, flask_mock, trace_id = self._helper( + None, 'test-flask-trace-id') + self.assertEqual(trace_id, flask_mock.return_value) + + django_mock.assert_called_once_with() + flask_mock.assert_called_once_with() + + def test_from_django_and_flask(self): + django_mock, flask_mock, trace_id = self._helper( + 'test-django-trace-id', 'test-flask-trace-id') + # Django wins. + self.assertEqual(trace_id, django_mock.return_value) + + django_mock.assert_called_once_with() + flask_mock.assert_not_called() + + def test_missing(self): + django_mock, flask_mock, trace_id = self._helper(None, None) + self.assertIsNone(trace_id) + + django_mock.assert_called_once_with() + flask_mock.assert_called_once_with() diff --git a/logging/tests/unit/handlers/test_app_engine.py b/logging/tests/unit/handlers/test_app_engine.py index ccdaf2992335..6438c4abb8a0 100644 --- a/logging/tests/unit/handlers/test_app_engine.py +++ b/logging/tests/unit/handlers/test_app_engine.py @@ -15,8 +15,10 @@ import logging import unittest +import mock -class TestAppEngineHandlerHandler(unittest.TestCase): + +class TestAppEngineHandler(unittest.TestCase): PROJECT = 'PROJECT' def _get_target_class(self): @@ -28,7 +30,6 @@ def _make_one(self, *args, **kw): return self._get_target_class()(*args, **kw) def test_constructor(self): - import mock from google.cloud.logging.handlers.app_engine import _GAE_PROJECT_ENV from google.cloud.logging.handlers.app_engine import _GAE_SERVICE_ENV from google.cloud.logging.handlers.app_engine import _GAE_VERSION_ENV @@ -48,8 +49,6 @@ def test_constructor(self): self.assertEqual(handler.labels, {}) def test_emit(self): - import mock - client = mock.Mock(project=self.PROJECT, spec=['project']) handler = self._make_one(client, transport=_Transport) gae_resource = handler.get_gae_resource() @@ -66,6 +65,35 @@ def test_emit(self): handler.transport.send_called_with, (record, message, gae_resource, gae_labels)) + def _get_gae_labels_helper(self, trace_id): + get_trace_patch = mock.patch( + 'google.cloud.logging.handlers.app_engine.get_trace_id', + return_value=trace_id) + + client = mock.Mock(project=self.PROJECT, spec=['project']) + # The handler actually calls ``get_gae_labels()``. + with get_trace_patch as mock_get_trace: + handler = self._make_one(client, transport=_Transport) + mock_get_trace.assert_called_once_with() + + gae_labels = handler.get_gae_labels() + self.assertEqual(mock_get_trace.mock_calls, + [mock.call(), mock.call()]) + + return gae_labels + + def test_get_gae_labels_with_label(self): + from google.cloud.logging.handlers import app_engine + + trace_id = 'test-gae-trace-id' + gae_labels = self._get_gae_labels_helper(trace_id) + expected_labels = {app_engine._TRACE_ID_LABEL: trace_id} + self.assertEqual(gae_labels, expected_labels) + + def test_get_gae_labels_without_label(self): + gae_labels = self._get_gae_labels_helper(None) + self.assertEqual(gae_labels, {}) + class _Transport(object): diff --git a/pubsub/google/cloud/pubsub/client.py b/pubsub/google/cloud/pubsub/client.py index 1df95a2400de..17bb67cb66e2 100644 --- a/pubsub/google/cloud/pubsub/client.py +++ b/pubsub/google/cloud/pubsub/client.py @@ -141,7 +141,7 @@ def list_topics(self, page_size=None, page_token=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_list_topics] :end-before: [END client_list_topics] @@ -170,7 +170,7 @@ def list_subscriptions(self, page_size=None, page_token=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_list_subscriptions] :end-before: [END client_list_subscriptions] @@ -223,7 +223,7 @@ def topic(self, name, timestamp_messages=False): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_topic] :end-before: [END client_topic] @@ -245,7 +245,7 @@ def subscription(self, name, ack_deadline=None, push_endpoint=None, Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START client_subscription] :end-before: [END client_subscription] diff --git a/pubsub/google/cloud/pubsub/subscription.py b/pubsub/google/cloud/pubsub/subscription.py index 538913cca33e..22f93246924c 100644 --- a/pubsub/google/cloud/pubsub/subscription.py +++ b/pubsub/google/cloud/pubsub/subscription.py @@ -200,7 +200,7 @@ def create(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_create] :end-before: [END subscription_create] @@ -225,7 +225,7 @@ def exists(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_exists] :end-before: [END subscription_exists] @@ -258,7 +258,7 @@ def reload(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_reload] :end-before: [END subscription_reload] @@ -285,7 +285,7 @@ def delete(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_delete] :end-before: [END subscription_delete] @@ -306,11 +306,11 @@ def modify_push_configuration(self, push_endpoint, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_push_pull] :end-before: [END subscription_push_pull] - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_pull_push] :end-before: [END subscription_pull_push] @@ -337,7 +337,7 @@ def pull(self, return_immediately=False, max_messages=1, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_pull] :end-before: [END subscription_pull] @@ -376,7 +376,7 @@ def acknowledge(self, ack_ids, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_acknowledge] :end-before: [END subscription_acknowledge] @@ -460,7 +460,7 @@ def get_iam_policy(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_get_iam_policy] :end-before: [END subscription_get_iam_policy] @@ -486,7 +486,7 @@ def set_iam_policy(self, policy, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_set_iam_policy] :end-before: [END subscription_set_iam_policy] @@ -517,7 +517,7 @@ def check_iam_permissions(self, permissions, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START subscription_check_iam_permissions] :end-before: [END subscription_check_iam_permissions] diff --git a/pubsub/google/cloud/pubsub/topic.py b/pubsub/google/cloud/pubsub/topic.py index f16c9d99baed..f9a8c28a3a09 100644 --- a/pubsub/google/cloud/pubsub/topic.py +++ b/pubsub/google/cloud/pubsub/topic.py @@ -59,19 +59,19 @@ def subscription(self, name, ack_deadline=None, push_endpoint=None, Example: pull-mode subcription, default parameter values - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_subscription_defaults] :end-before: [END topic_subscription_defaults] Example: pull-mode subcription, override ``ack_deadline`` default - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_subscription_ack90] :end-before: [END topic_subscription_ack90] Example: push-mode subcription - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_subscription_push] :end-before: [END topic_subscription_push] @@ -160,7 +160,7 @@ def create(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_create] :end-before: [END topic_create] @@ -181,7 +181,7 @@ def exists(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_exists] :end-before: [END topic_exists] @@ -211,7 +211,7 @@ def delete(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_delete] :end-before: [END topic_delete] @@ -242,13 +242,13 @@ def publish(self, message, client=None, **attrs): Example without message attributes: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_publish_simple_message] :end-before: [END topic_publish_simple_message] With message attributes: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_publish_message_with_attrs] :end-before: [END topic_publish_message_with_attrs] @@ -279,7 +279,7 @@ def batch(self, client=None, **kwargs): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_batch] :end-before: [END topic_batch] @@ -312,7 +312,7 @@ def list_subscriptions(self, page_size=None, page_token=None, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_list_subscriptions] :end-before: [END topic_list_subscriptions] @@ -347,7 +347,7 @@ def get_iam_policy(self, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_get_iam_policy] :end-before: [END topic_get_iam_policy] @@ -373,7 +373,7 @@ def set_iam_policy(self, policy, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_set_iam_policy] :end-before: [END topic_set_iam_policy] @@ -404,7 +404,7 @@ def check_iam_permissions(self, permissions, client=None): Example: - .. literalinclude:: pubsub_snippets.py + .. literalinclude:: snippets.py :start-after: [START topic_check_iam_permissions] :end-before: [END topic_check_iam_permissions] diff --git a/storage/google/cloud/storage/__init__.py b/storage/google/cloud/storage/__init__.py index 433f711025f6..bc6fccc971c2 100644 --- a/storage/google/cloud/storage/__init__.py +++ b/storage/google/cloud/storage/__init__.py @@ -16,7 +16,7 @@ You'll typically use these to get started with the API: -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START storage_get_started] :end-before: [END storage_get_started] diff --git a/storage/google/cloud/storage/acl.py b/storage/google/cloud/storage/acl.py index 3424f24c66ef..389a312fb219 100644 --- a/storage/google/cloud/storage/acl.py +++ b/storage/google/cloud/storage/acl.py @@ -18,7 +18,7 @@ an ACL object under the hood, and you can interact with that using :func:`google.cloud.storage.bucket.Bucket.acl`: -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START client_bucket_acl] :end-before: [END client_bucket_acl] @@ -49,14 +49,14 @@ You can use any of these like any other factory method (these happen to be :class:`_ACLEntity` factories): -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START acl_user_settings] :end-before: [END acl_user_settings] After that, you can save any changes you make with the :func:`google.cloud.storage.acl.ACL.save` method: -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START acl_save] :end-before: [END acl_save] @@ -64,14 +64,14 @@ object (whether it was created by a factory method or not) from a :class:`google.cloud.storage.bucket.Bucket`: -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START acl_save_bucket] :end-before: [END acl_save_bucket] To get the list of ``entity`` and ``role`` for each unique pair, the :class:`ACL` class is iterable: -.. literalinclude:: storage_snippets.py +.. literalinclude:: snippets.py :start-after: [START acl_print] :end-before: [END acl_print] diff --git a/storage/google/cloud/storage/blob.py b/storage/google/cloud/storage/blob.py index 7163b7d0d3b5..671cda3052a1 100644 --- a/storage/google/cloud/storage/blob.py +++ b/storage/google/cloud/storage/blob.py @@ -439,7 +439,7 @@ def download_to_file(self, file_obj, client=None): Downloading a file that has been encrypted with a `customer-supplied`_ encryption key: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START download_to_file] :end-before: [END download_to_file] @@ -840,7 +840,7 @@ def upload_from_file(self, file_obj, rewind=False, size=None, Uploading a file with a `customer-supplied`_ encryption key: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START upload_from_file] :end-before: [END upload_from_file] diff --git a/storage/google/cloud/storage/bucket.py b/storage/google/cloud/storage/bucket.py index efb45934f548..f0f040e0627e 100644 --- a/storage/google/cloud/storage/bucket.py +++ b/storage/google/cloud/storage/bucket.py @@ -233,7 +233,7 @@ def get_blob(self, blob_name, client=None): This will return None if the blob doesn't exist: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START get_blob] :end-before: [END get_blob] @@ -392,7 +392,7 @@ def delete_blob(self, blob_name, client=None): For example: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START delete_blob] :end-before: [END delete_blob] @@ -408,7 +408,7 @@ def delete_blob(self, blob_name, client=None): the exception, call ``delete_blobs``, passing a no-op ``on_error`` callback, e.g.: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START delete_blobs] :end-before: [END delete_blobs] @@ -768,13 +768,13 @@ def configure_website(self, main_page_suffix=None, not_found_page=None): If you want this bucket to host a website, just provide the name of an index page and a page to use when a blob isn't found: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START configure_website] :end-before: [END configure_website] You probably should also make the whole bucket public: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START make_public] :end-before: [END make_public] @@ -939,7 +939,7 @@ def generate_upload_policy( For example: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START policy_document] :end-before: [END policy_document] diff --git a/storage/google/cloud/storage/client.py b/storage/google/cloud/storage/client.py index 24e073bc72dd..93785e05269f 100644 --- a/storage/google/cloud/storage/client.py +++ b/storage/google/cloud/storage/client.py @@ -156,7 +156,7 @@ def get_bucket(self, bucket_name): For example: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START get_bucket] :end-before: [END get_bucket] @@ -179,7 +179,7 @@ def lookup_bucket(self, bucket_name): You can use this if you would rather check for a None value than catching an exception: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START lookup_bucket] :end-before: [END lookup_bucket] @@ -199,7 +199,7 @@ def create_bucket(self, bucket_name): For example: - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START create_bucket] :end-before: [END create_bucket] @@ -225,7 +225,7 @@ def list_buckets(self, max_results=None, page_token=None, prefix=None, This will not populate the list of blobs available in each bucket. - .. literalinclude:: storage_snippets.py + .. literalinclude:: snippets.py :start-after: [START list_buckets] :end-before: [END list_buckets] diff --git a/videointelligence/README.rst b/videointelligence/README.rst index 1790007d95b4..d3741cd88fc1 100644 --- a/videointelligence/README.rst +++ b/videointelligence/README.rst @@ -16,7 +16,7 @@ Quick Start .. code-block:: console - $ pip install --upgrade google-cloud-video-intelligence + $ pip install --upgrade google-cloud-videointelligence Authentication -------------- diff --git a/videointelligence/google/cloud/videointelligence_v1beta1/__init__.py b/videointelligence/google/cloud/videointelligence_v1beta1/__init__.py index 60b42da4de3f..9e732b5800bd 100644 --- a/videointelligence/google/cloud/videointelligence_v1beta1/__init__.py +++ b/videointelligence/google/cloud/videointelligence_v1beta1/__init__.py @@ -17,7 +17,7 @@ from google.cloud.gapic.videointelligence.v1beta1.video_intelligence_service_client import VideoIntelligenceServiceClient from google.cloud.gapic.videointelligence.v1beta1 import enums -from google.cloud.gapic.videointelligence_v1beta1 import types +from google.cloud.videointelligence_v1beta1 import types diff --git a/videointelligence/google/cloud/videointelligence_v1beta1/types.py b/videointelligence/google/cloud/videointelligence_v1beta1/types.py index 482b4adad57d..9ac3b8a6b2a5 100644 --- a/videointelligence/google/cloud/videointelligence_v1beta1/types.py +++ b/videointelligence/google/cloud/videointelligence_v1beta1/types.py @@ -20,7 +20,7 @@ names = [] -for name, message in get_messages(video_intelligence_pb2): +for name, message in get_messages(video_intelligence_pb2).items(): setattr(sys.modules[__name__], name, message) names.append(name)