Skip to content

Commit 4e50bba

Browse files
egalpindhermes
authored andcommitted
Adds optional location_prefix kwarg in to_legacy_urlsafe (#4635)
1 parent 465a888 commit 4e50bba

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

datastore/google/cloud/datastore/key.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def to_protobuf(self):
298298

299299
return key
300300

301-
def to_legacy_urlsafe(self):
301+
def to_legacy_urlsafe(self, location_prefix=None):
302302
"""Convert to a base64 encode urlsafe string for App Engine.
303303
304304
This is intended to work with the "legacy" representation of a
@@ -310,13 +310,26 @@ def to_legacy_urlsafe(self):
310310
.. note::
311311
312312
The string returned by ``to_legacy_urlsafe`` is equivalent, but
313-
not identical, to the string returned by ``ndb``.
313+
not identical, to the string returned by ``ndb``. The location
314+
prefix may need to be specified to obtain identical urlsafe
315+
keys.
316+
317+
:type location_prefix: str
318+
:param location_prefix: The location prefix of an App Engine project
319+
ID. Often this value is 's~', but may also be
320+
'e~', or other location prefixes currently
321+
unknown.
314322
315323
:rtype: bytes
316324
:returns: A bytestring containing the key encoded as URL-safe base64.
317325
"""
326+
if location_prefix is None:
327+
project_id = self.project
328+
else:
329+
project_id = location_prefix + self.project
330+
318331
reference = _app_engine_key_pb2.Reference(
319-
app=self.project,
332+
app=project_id,
320333
path=_to_legacy_path(self._path), # Avoid the copy.
321334
name_space=self.namespace,
322335
)

datastore/tests/unit/test_key.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class TestKey(unittest.TestCase):
3535
_URLSAFE_EXAMPLE2 = b'agZzfmZpcmVyDwsSBEtpbmQiBVRoaW5nDA'
3636
_URLSAFE_APP2 = 's~fire'
3737
_URLSAFE_FLAT_PATH2 = ('Kind', 'Thing')
38+
_URLSAFE_EXAMPLE3 = b'ahhzfnNhbXBsZS1hcHAtbm8tbG9jYXRpb25yCgsSBFpvcnAYWAw'
39+
_URLSAFE_APP3 = 'sample-app-no-location'
40+
_URLSAFE_FLAT_PATH3 = ('Zorp', 88)
3841

3942
@staticmethod
4043
def _get_target_class():
@@ -408,6 +411,13 @@ def test_to_legacy_urlsafe_strip_padding(self):
408411
# Make sure it started with base64 padding.
409412
self.assertNotEqual(len(self._URLSAFE_EXAMPLE2) % 4, 0)
410413

414+
def test_to_legacy_urlsafe_with_location_prefix(self):
415+
key = self._make_one(
416+
*self._URLSAFE_FLAT_PATH3,
417+
project=self._URLSAFE_APP3)
418+
urlsafe = key.to_legacy_urlsafe(location_prefix='s~')
419+
self.assertEqual(urlsafe, self._URLSAFE_EXAMPLE3)
420+
411421
def test_from_legacy_urlsafe(self):
412422
klass = self._get_target_class()
413423
key = klass.from_legacy_urlsafe(self._URLSAFE_EXAMPLE1)
@@ -430,6 +440,15 @@ def test_from_legacy_urlsafe_needs_padding(self):
430440
self.assertIsNone(key.namespace)
431441
self.assertEqual(key.flat_path, self._URLSAFE_FLAT_PATH2)
432442

443+
def test_from_legacy_urlsafe_with_location_prefix(self):
444+
klass = self._get_target_class()
445+
# Make sure it will have base64 padding added.
446+
key = klass.from_legacy_urlsafe(self._URLSAFE_EXAMPLE3)
447+
448+
self.assertEqual(key.project, self._URLSAFE_APP3)
449+
self.assertIsNone(key.namespace)
450+
self.assertEqual(key.flat_path, self._URLSAFE_FLAT_PATH3)
451+
433452
def test_is_partial_no_name_or_id(self):
434453
key = self._make_one('KIND', project=self._DEFAULT_PROJECT)
435454
self.assertTrue(key.is_partial)

0 commit comments

Comments
 (0)