Skip to content

Commit 96489a1

Browse files
committed
Merge branch 'master' of github.com:GoogleCloudPlatform/google-cloud-python into arrays
2 parents 909cf52 + 455eaf6 commit 96489a1

File tree

80 files changed

+1079
-4386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1079
-4386
lines changed

Makefile.datastore

Lines changed: 0 additions & 53 deletions
This file was deleted.

README.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ Cloud Platform services:
3737
- `Google Cloud DNS`_ (`DNS README`_)
3838
- `Stackdriver Error Reporting`_ (`Error Reporting README`_)
3939
- `Google Cloud Natural Language`_ (`Natural Language README`_)
40-
- `Google Translate`_ (`Translate README`_)
40+
- `Google Cloud Translation`_ (`Translation README`_)
41+
- `Google Cloud Speech`_ (`Speech README`_)
4142
- `Google Cloud Vision`_ (`Vision README`_)
4243
- `Google Cloud Bigtable - HappyBase`_ (`HappyBase README`_)
4344
- `Google Cloud Runtime Configuration`_ (`Runtime Config README`_)
@@ -68,8 +69,10 @@ updates. See `versioning`_ for more details.
6869
.. _Error Reporting README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/error_reporting
6970
.. _Google Cloud Natural Language: https://pypi.python.org/pypi/google-cloud-language
7071
.. _Natural Language README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/language
71-
.. _Google Translate: https://pypi.python.org/pypi/google-cloud-translate
72-
.. _Translate README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/translate
72+
.. _Google Cloud Translation: https://pypi.python.org/pypi/google-cloud-translate
73+
.. _Translation README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/translate
74+
.. _Google Cloud Speech: https://pypi.python.org/pypi/google-cloud-speech
75+
.. _Speech README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/speech
7376
.. _Google Cloud Vision: https://pypi.python.org/pypi/google-cloud-vision
7477
.. _Vision README: https://github.com/GoogleCloudPlatform/google-cloud-python/tree/master/vision
7578
.. _Google Cloud Bigtable - HappyBase: https://pypi.python.org/pypi/google-cloud-happybase/

bigquery/google/cloud/bigquery/_helpers.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
from collections import OrderedDict
1919
import datetime
2020

21+
from google.cloud._helpers import UTC
2122
from google.cloud._helpers import _date_from_iso8601_date
2223
from google.cloud._helpers import _datetime_from_microseconds
2324
from google.cloud._helpers import _datetime_to_rfc3339
24-
from google.cloud._helpers import _microseconds_from_datetime
2525
from google.cloud._helpers import _RFC3339_NO_FRACTION
2626
from google.cloud._helpers import _time_from_iso8601_time_naive
2727
from google.cloud._helpers import _to_bytes
@@ -150,7 +150,11 @@ def _bytes_to_json(value):
150150
def _timestamp_to_json(value):
151151
"""Coerce 'value' to an JSON-compatible representation."""
152152
if isinstance(value, datetime.datetime):
153-
value = _microseconds_from_datetime(value) / 1.0e6
153+
if value.tzinfo not in (None, UTC):
154+
# Convert to UTC and remove the time zone info.
155+
value = value.replace(tzinfo=None) - value.utcoffset()
156+
value = '%s %s+00:00' % (
157+
value.date().isoformat(), value.time().isoformat())
154158
return value
155159

156160

@@ -553,10 +557,12 @@ def from_api_repr(cls, resource):
553557
instance = cls(name)
554558
types = instance.struct_types
555559
for item in resource['parameterType']['structTypes']:
556-
types[item['name']] = item['type']
560+
types[item['name']] = item['type']['type']
557561
struct_values = resource['parameterValue']['structValues']
558562
for key, value in struct_values.items():
559-
converted = _CELLDATA_FROM_JSON[types[key]](value, None)
563+
type_ = types[key]
564+
value = value['value']
565+
converted = _CELLDATA_FROM_JSON[type_](value, None)
560566
instance.struct_values[key] = converted
561567
return instance
562568

@@ -567,18 +573,19 @@ def to_api_repr(self):
567573
:returns: JSON mapping
568574
"""
569575
types = [
570-
{'name': key, 'type': value}
576+
{'name': key, 'type': {'type': value}}
571577
for key, value in self.struct_types.items()
572578
]
573579
values = {}
574580
for name, value in self.struct_values.items():
575581
converter = _SCALAR_VALUE_TO_JSON.get(self.struct_types[name])
576582
if converter is not None:
577583
value = converter(value)
578-
values[name] = value
584+
values[name] = {'value': value}
579585

580586
resource = {
581587
'parameterType': {
588+
'type': 'STRUCT',
582589
'structTypes': types,
583590
},
584591
'parameterValue': {

bigquery/google/cloud/bigquery/client.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,25 @@ class Client(JSONClient):
5858
passed when creating a dataset / job. If not passed,
5959
falls back to the default inferred from the environment.
6060
61-
:type credentials: :class:`oauth2client.client.OAuth2Credentials` or
62-
:class:`NoneType`
63-
:param credentials: The OAuth2 Credentials to use for the connection
64-
owned by this client. If not passed (and if no ``http``
65-
object is passed), falls back to the default inferred
66-
from the environment.
67-
68-
:type http: :class:`httplib2.Http` or class that defines ``request()``.
69-
:param http: An optional HTTP object to make requests. If not passed, an
61+
:type credentials: :class:`~google.auth.credentials.Credentials`
62+
:param credentials: (Optional) The OAuth2 Credentials to use for this
63+
client. If not passed (and if no ``http`` object is
64+
passed), falls back to the default inferred from the
65+
environment.
66+
67+
:type http: :class:`~httplib2.Http`
68+
:param http: (Optional) HTTP object to make requests. Can be any object
69+
that defines ``request()`` with the same interface as
70+
:meth:`~httplib2.Http.request`. If not passed, an
7071
``http`` object is created that is bound to the
7172
``credentials`` for the current object.
7273
"""
7374

74-
_connection_class = Connection
75+
def __init__(self, project=None, credentials=None, http=None):
76+
super(Client, self).__init__(
77+
project=project, credentials=credentials, http=http)
78+
self._connection = Connection(
79+
credentials=self._credentials, http=self._http)
7580

7681
def list_projects(self, max_results=None, page_token=None):
7782
"""List projects for the project associated with this client.

bigquery/unit_tests/test__helpers.py

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,35 @@ def _call_fut(self, value):
546546
def test_w_float(self):
547547
self.assertEqual(self._call_fut(1.234567), 1.234567)
548548

549-
def test_w_datetime(self):
549+
def test_w_string(self):
550+
ZULU = '2016-12-20 15:58:27.339328+00:00'
551+
self.assertEqual(self._call_fut(ZULU), ZULU)
552+
553+
def test_w_datetime_wo_zone(self):
554+
import datetime
555+
ZULU = '2016-12-20 15:58:27.339328+00:00'
556+
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328)
557+
self.assertEqual(self._call_fut(when), ZULU)
558+
559+
def test_w_datetime_w_non_utc_zone(self):
560+
import datetime
561+
562+
class _Zone(datetime.tzinfo):
563+
564+
def utcoffset(self, _):
565+
return datetime.timedelta(minutes=-240)
566+
567+
ZULU = '2016-12-20 19:58:27.339328+00:00'
568+
when = datetime.datetime(
569+
2016, 12, 20, 15, 58, 27, 339328, tzinfo=_Zone())
570+
self.assertEqual(self._call_fut(when), ZULU)
571+
572+
def test_w_datetime_w_utc_zone(self):
550573
import datetime
551574
from google.cloud._helpers import UTC
552-
from google.cloud._helpers import _microseconds_from_datetime
553-
when = datetime.datetime(2016, 12, 3, 14, 11, 27, tzinfo=UTC)
554-
self.assertEqual(self._call_fut(when),
555-
_microseconds_from_datetime(when) / 1e6)
575+
ZULU = '2016-12-20 15:58:27.339328+00:00'
576+
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328, tzinfo=UTC)
577+
self.assertEqual(self._call_fut(when), ZULU)
556578

557579

558580
class Test_datetime_to_json(unittest.TestCase):
@@ -907,20 +929,20 @@ def test_to_api_repr_w_bool(self):
907929
self.assertEqual(param.to_api_repr(), EXPECTED)
908930

909931
def test_to_api_repr_w_timestamp_datetime(self):
932+
from google.cloud._helpers import UTC
910933
import datetime
911-
from google.cloud._helpers import _microseconds_from_datetime
912-
now = datetime.datetime.utcnow()
913-
seconds = _microseconds_from_datetime(now) / 1.0e6
934+
STAMP = '2016-12-20 15:58:27.339328+00:00'
935+
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328, tzinfo=UTC)
914936
EXPECTED = {
915937
'parameterType': {
916938
'type': 'TIMESTAMP',
917939
},
918940
'parameterValue': {
919-
'value': seconds,
941+
'value': STAMP,
920942
},
921943
}
922944
klass = self._get_target_class()
923-
param = klass.positional(type_='TIMESTAMP', value=now)
945+
param = klass.positional(type_='TIMESTAMP', value=when)
924946
self.assertEqual(param.to_api_repr(), EXPECTED)
925947

926948
def test_to_api_repr_w_timestamp_micros(self):
@@ -1060,6 +1082,7 @@ def test_from_api_repr_w_name(self):
10601082
def test_from_api_repr_wo_name(self):
10611083
RESOURCE = {
10621084
'parameterType': {
1085+
'type': 'ARRAY',
10631086
'arrayType': 'INT64',
10641087
},
10651088
'parameterValue': {
@@ -1076,6 +1099,7 @@ def test_to_api_repr_w_name(self):
10761099
EXPECTED = {
10771100
'name': 'foo',
10781101
'parameterType': {
1102+
'type': 'ARRAY',
10791103
'arrayType': 'INT64',
10801104
},
10811105
'parameterValue': {
@@ -1088,6 +1112,7 @@ def test_to_api_repr_w_name(self):
10881112
def test_to_api_repr_wo_name(self):
10891113
EXPECTED = {
10901114
'parameterType': {
1115+
'type': 'ARRAY',
10911116
'arrayType': 'INT64',
10921117
},
10931118
'parameterValue': {
@@ -1101,6 +1126,7 @@ def test_to_api_repr_wo_name(self):
11011126
def test_to_api_repr_w_unknown_type(self):
11021127
EXPECTED = {
11031128
'parameterType': {
1129+
'type': 'ARRAY',
11041130
'arrayType': 'UNKNOWN',
11051131
},
11061132
'parameterValue': {
@@ -1148,13 +1174,17 @@ def test_from_api_repr_w_name(self):
11481174
RESOURCE = {
11491175
'name': 'foo',
11501176
'parameterType': {
1177+
'type': 'STRUCT',
11511178
'structTypes': [
1152-
{'name': 'bar', 'type': 'INT64'},
1153-
{'name': 'baz', 'type': 'STRING'},
1179+
{'name': 'bar', 'type': {'type': 'INT64'}},
1180+
{'name': 'baz', 'type': {'type': 'STRING'}},
11541181
],
11551182
},
11561183
'parameterValue': {
1157-
'structValues': {'bar': 123, 'baz': 'abc'},
1184+
'structValues': {
1185+
'bar': {'value': 123},
1186+
'baz': {'value': 'abc'},
1187+
},
11581188
},
11591189
}
11601190
klass = self._get_target_class()
@@ -1166,13 +1196,17 @@ def test_from_api_repr_w_name(self):
11661196
def test_from_api_repr_wo_name(self):
11671197
RESOURCE = {
11681198
'parameterType': {
1199+
'type': 'STRUCT',
11691200
'structTypes': [
1170-
{'name': 'bar', 'type': 'INT64'},
1171-
{'name': 'baz', 'type': 'STRING'},
1201+
{'name': 'bar', 'type': {'type': 'INT64'}},
1202+
{'name': 'baz', 'type': {'type': 'STRING'}},
11721203
],
11731204
},
11741205
'parameterValue': {
1175-
'structValues': {'bar': 123, 'baz': 'abc'},
1206+
'structValues': {
1207+
'bar': {'value': 123},
1208+
'baz': {'value': 'abc'},
1209+
},
11761210
},
11771211
}
11781212
klass = self._get_target_class()
@@ -1185,13 +1219,17 @@ def test_to_api_repr_w_name(self):
11851219
EXPECTED = {
11861220
'name': 'foo',
11871221
'parameterType': {
1222+
'type': 'STRUCT',
11881223
'structTypes': [
1189-
{'name': 'bar', 'type': 'INT64'},
1190-
{'name': 'baz', 'type': 'STRING'},
1224+
{'name': 'bar', 'type': {'type': 'INT64'}},
1225+
{'name': 'baz', 'type': {'type': 'STRING'}},
11911226
],
11921227
},
11931228
'parameterValue': {
1194-
'structValues': {'bar': '123', 'baz': 'abc'},
1229+
'structValues': {
1230+
'bar': {'value': '123'},
1231+
'baz': {'value': 'abc'},
1232+
},
11951233
},
11961234
}
11971235
sub_1 = self._make_subparam('bar', 'INT64', 123)
@@ -1202,13 +1240,17 @@ def test_to_api_repr_w_name(self):
12021240
def test_to_api_repr_wo_name(self):
12031241
EXPECTED = {
12041242
'parameterType': {
1243+
'type': 'STRUCT',
12051244
'structTypes': [
1206-
{'name': 'bar', 'type': 'INT64'},
1207-
{'name': 'baz', 'type': 'STRING'},
1245+
{'name': 'bar', 'type': {'type': 'INT64'}},
1246+
{'name': 'baz', 'type': {'type': 'STRING'}},
12081247
],
12091248
},
12101249
'parameterValue': {
1211-
'structValues': {'bar': '123', 'baz': 'abc'},
1250+
'structValues': {
1251+
'bar': {'value': '123'},
1252+
'baz': {'value': 'abc'},
1253+
},
12121254
},
12131255
}
12141256
sub_1 = self._make_subparam('bar', 'INT64', 123)

circle.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ general:
2424

2525
deployment:
2626
release:
27-
tag: /(([a-z]+)-)?([0-9]+)\.([0-9]+)\.([0-9]+)/
27+
# See "scripts/circleci_tagged_pkg.py" for info on REGEX
28+
tag: /(([a-z]+)-)*([0-9]+)\.([0-9]+)\.([0-9]+)/
2829
owner: GoogleCloudPlatform
2930
commands:
3031
- pip install --upgrade twine

0 commit comments

Comments
 (0)