Skip to content

Create client from service account stored in string #8

@frankyn

Description

@frankyn

Hi,

This was raised in python-storage: googleapis/python-storage#93

python-cloud-core library has support for from_service_account_json, which accepts a file path to a service account.

Feature request is to add support to accept a json string of the service account. User stores the service account file contents in an environment variable instead of in a file.

Open question: I'm not sure if this is a path that should be supported so I'm leaving that as an open question in this issue. If this feature is not supported then the workaround is to construct a credentials object and explicitly set a project id:

# Storage example but is a general issue AFAIU

import os
import json

from google.cloud import storage
from google.oauth2 import service_account

credentials_json_string = "{...service account....}"

credentials_json = json.loads(credentials_json_string)
credentials = service_account.Credentials.from_service_account_info(credentials_json)

# Credentials has project_id already so project should be optional but it's not.
client = storage.Client(project=credentials['project_id'], credentials=credentials)

print(list(client.list_buckets()))

Proposal:

    @classmethod
    def from_service_account_json_string(cls, json_credentials, *args, **kwargs):
        """Factory to create credentials with provided json_credentials.
        :type json_credentials: str
        :param json_credentials: The contents of a private key file. This string must contain
                                      a JSON object with a private key and
                                      other credentials information (downloaded
                                      from the Google APIs console).
        :type args: tuple
        :param args: Remaining positional arguments to pass to constructor.
        :param kwargs: Remaining keyword arguments to pass to constructor.
        :rtype: :class:`_ClientFactoryMixin`
        :returns: The client created with the provided JSON credentials.
        :raises TypeError: if there is a conflict with the kwargs
                 and the credentials created by the factory.
        """
        if "credentials" in kwargs:
            raise TypeError("credentials must not be in keyword arguments")
        credentials_info = json.load(json_credentials)
        credentials = service_account.Credentials.from_service_account_info(
            credentials_info
        )
        if cls._SET_PROJECT:
            if "project" not in kwargs:
                kwargs["project"] = credentials_info.get("project_id")

        kwargs["credentials"] = credentials
        return cls(*args, **kwargs)

Metadata

Metadata

Assignees

Labels

type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions