Repository: googleapis/python-spanner-django

Issue:
dbapi: conform user_agent to be passed into client as google.api_core.gapic_v1.client_info.ClientInfo
We currently pass in the user agent through 
https://github.com/orijtech/spanner-orm/blob/13dbb62c7c2774d40a3a8ce56fe2d50e2fe7b6ab/spanner/dbapi/__init__.py#L75-L78
and
https://github.com/orijtech/spanner-orm/blob/13dbb62c7c2774d40a3a8ce56fe2d50e2fe7b6ab/spanner/dbapi/__init__.py#L91-L94

but the advisory says that `user_agent` is deprecated and used so we should pass it in as google.api_core.gapic_v1.client_info.ClientInfo  e.g.
```python
from google.api_core.gapic_v1.client_info import ClientInfo
ci = ClientInfo(user_agent='spanner-django/0.0.1')
```


Discussion:

Resolving patch:
diff --git a/spanner/dbapi/__init__.py b/spanner/dbapi/__init__.py
--- a/spanner/dbapi/__init__.py
+++ b/spanner/dbapi/__init__.py
@@ -29,7 +29,7 @@
     BINARY, DATETIME, NUMBER, ROWID, STRING, Date, DateFromTicks, Time,
     TimeFromTicks, Timestamp, TimestampFromTicks,
 )
-from .version import USER_AGENT
+from .version import google_client_info
 
 # Globals that MUST be defined ###
 apilevel = "2.0"  # Implements the Python Database API specification 2.0 version.
@@ -74,7 +74,7 @@ def connect(spanner_url, credentials_uri=None):
 
     kwargs = dict(
         project=conn_params.get('project_id'),
-        user_agent=USER_AGENT,
+        client_info=google_client_info(),
     )
 
     # Pre-requisite are the database and instance names.
diff --git a/spanner/dbapi/version.py b/spanner/dbapi/version.py
--- a/spanner/dbapi/version.py
+++ b/spanner/dbapi/version.py
@@ -12,6 +12,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import sys
 
-VERSION = 'v0.0.1'
+from google.api_core.gapic_v1.client_info import ClientInfo
+
+VERSION = '0.0.1'
 USER_AGENT = 'spanner-django/' + VERSION
+
+vers = sys.version_info
+
+
+def google_client_info():
+    """
+    Return a google.api_core.gapic_v1.client_info.ClientInfo
+    containg the user_agent and python_version for this library
+    """
+
+    return ClientInfo(
+        user_agent=USER_AGENT,
+        python_version='%d.%d.%d' % (vers.major, vers.minor, vers.micro or 0),
+    )


Test patch:
diff --git a/tests/spanner/dbapi/test_version.py b/tests/spanner/dbapi/test_version.py
new file mode 100644
--- /dev/null
+++ b/tests/spanner/dbapi/test_version.py
@@ -0,0 +1,30 @@
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+from unittest import TestCase
+
+from google.api_core.gapic_v1.client_info import ClientInfo
+from spanner.dbapi.version import USER_AGENT, google_client_info
+
+
+class VersionUtils(TestCase):
+    def test_google_client_info(self):
+        vers = sys.version_info
+        got = google_client_info().to_grpc_metadata()
+        want = ClientInfo(
+            user_agent=USER_AGENT,
+            python_version='%d.%d.%d' % (vers.major, vers.minor, vers.micro or 0),
+        ).to_grpc_metadata()
+        self.assertEqual(got, want)