Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds optional location_prefix kwarg in to_legacy_urlsafe #4635

Merged
merged 5 commits into from
Dec 20, 2017

Conversation

egalpin
Copy link
Contributor

@egalpin egalpin commented Dec 20, 2017

Fixes #3597

I encountered an issue with respect to urlsafe keys in a system that is using both google-cloud-datastore and ndb in different services. I was receiving incompatible urlsafe keys when using the output of to_legacy_urlsafe in things like ndb.Key(urlsafe=<output_from_legacy_urlsafe>) running under App Engine. I received the following error:

BadRequestError: app s~your-app-id cannot access app your-app-id's data

I then tried the suggestion as per #3597 of adding the location prefix to the project under cloud-datastore like so:

datastore.Client(project='s~your-app-id')

Unfortunately, I was met with this error (where your-app-id is a real project, with active datastore db which I can access via the Google Cloud Console):

The project s~your-app-id does not exist or it does not contain an active Cloud Datastore database.

I was able to produce compatible urlsafe keys by specifying the location prefix only when creating the urlsafe keys. This PR contains that small change.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address on your commit. Check your existing CLA data and verify that your email is set on your git commits.
  • If your company signed a CLA, they designated a Point of Contact who decides which employees are authorized to participate. You may need to contact the Point of Contact for your company and ask to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the project maintainer to go/cla#troubleshoot. The email used to register you as an authorized contributor must be the email used for the Git commit.
  • In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

@googlebot googlebot added the cla: no This human has *not* signed the Contributor License Agreement. label Dec 20, 2017
@egalpin
Copy link
Contributor Author

egalpin commented Dec 20, 2017

I've signed the CLA

@egalpin egalpin force-pushed the allow-location-identifier-urlsafe branch from a2beb53 to af85667 Compare December 20, 2017 14:38
@googlebot
Copy link

CLAs look good, thanks!

@googlebot googlebot added cla: yes This human has signed the Contributor License Agreement. and removed cla: no This human has *not* signed the Contributor License Agreement. labels Dec 20, 2017
@egalpin
Copy link
Contributor Author

egalpin commented Dec 20, 2017

If this isn't acceptable as a change in the repo, anyone wanting to do the same should be able to use this snippet in their code:

import base64

from google.cloud.datastore import _app_engine_key_pb2
from google.cloud.datastore.key import _to_legacy_path


def to_urlsafe(key, location_prefix=None):
    """Convert to a base64 encode urlsafe string for App Engine.

    This is intended to work with the "legacy" representation of a
    datastore "Key" used within Google App Engine (a so-called
    "Reference"). The returned string can be used as the ``urlsafe``
    argument to ``ndb.Key(urlsafe=...)``. The base64 encoded values
    will have padding removed.
    .. note::
            The string returned by ``to_legacy_urlsafe`` is equivalent, but
            not identical, to the string returned by ``ndb``. The location
            prefix may need to be specified to obtain idendentical urlsafe
            keys.

    :type key: google.cloud.datastore.key.Key
    :param key: The key that you wish to convert to urlsafe

    :type location_prefix: str
    :param location_prefix: The location prefix of ones project. Often
                            this value is 's~', but may be 'dev~', 'e~', or
                            other location prefixes currently unknown.
    :rtype: bytes
    :returns: A bytestring containing the key encoded as URL-safe base64.
    """
    if location_prefix:
        project_id = location_prefix + key._project
    else:
        project_id = key._project

    reference = _app_engine_key_pb2.Reference(
        app=project_id,
        path=_to_legacy_path(key._path),  # Avoid the copy.
        name_space=key.namespace,
    )
    raw_bytes = reference.SerializeToString()
    return base64.urlsafe_b64encode(raw_bytes)

Copy link
Contributor

@dhermes dhermes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for filing. I don't see this as controversial in any way, so should be easy to merge!

Do you mind adding a unit test for the newly added parameter? If not, let me know and I can lend a hand.

@@ -310,13 +310,25 @@ def to_legacy_urlsafe(self):
.. note::

The string returned by ``to_legacy_urlsafe`` is equivalent, but
not identical, to the string returned by ``ndb``.
not identical, to the string returned by ``ndb``. The location
prefix may need to be specified to obtain idendentical urlsafe

This comment was marked as spam.

keys.

:type location_prefix: str
:param location_prefix: The location prefix of ones project. Often

This comment was marked as spam.


:type location_prefix: str
:param location_prefix: The location prefix of ones project. Often
this value is 's~', but may be 'dev~', 'e~', or

This comment was marked as spam.


:rtype: bytes
:returns: A bytestring containing the key encoded as URL-safe base64.
"""
if location_prefix:

This comment was marked as spam.

@dhermes
Copy link
Contributor

dhermes commented Dec 20, 2017

@egalpin Thanks for the update, are you planning on sending unit test updates or shall I?

I had some strange GitHub refresh state and never saw them. My bad.

@@ -430,6 +435,15 @@ def test_from_legacy_urlsafe_needs_padding(self):
self.assertIsNone(key.namespace)
self.assertEqual(key.flat_path, self._URLSAFE_FLAT_PATH2)

def test_from_legacy_urlsafe_with_location_prefix(self):

This comment was marked as spam.

This comment was marked as spam.

@dhermes dhermes force-pushed the allow-location-identifier-urlsafe branch from c84c8d2 to 55808e6 Compare December 20, 2017 19:43
@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this State. It's up to you to confirm consent of the commit author(s) and merge this pull request when appropriate.

@googlebot googlebot added cla: no This human has *not* signed the Contributor License Agreement. and removed cla: yes This human has signed the Contributor License Agreement. labels Dec 20, 2017
Copy link
Contributor

@dhermes dhermes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dhermes dhermes merged commit 4e50bba into googleapis:master Dec 20, 2017
@egalpin
Copy link
Contributor Author

egalpin commented Dec 20, 2017

I need update author details on some commits (working with multiple GH accounts on this machine)

@dhermes
Copy link
Contributor

dhermes commented Dec 20, 2017

@egalpin The CLA issue was because I pushed a commit to the PR and the CLA-bot gets confused by multi-author PRs. No need to do anything. Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: no This human has *not* signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Datastore Key's reference is missing location identifier in app argument in to_legacy_urlsafe()
3 participants