Skip to content

Commit

Permalink
Merge pull request #748 from tseaver/741-hoist_default_project
Browse files Browse the repository at this point in the history
#741: hoist project detection/setup into 'gcloud._helpers'.
  • Loading branch information
tseaver committed Mar 23, 2015
2 parents 9c09ced + c590c56 commit 4512eff
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 221 deletions.
80 changes: 80 additions & 0 deletions gcloud/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
This module is not part of the public API surface of `gcloud`.
"""
import os
import socket

try:
Expand Down Expand Up @@ -156,3 +157,82 @@ def _compute_engine_id():
pass
finally:
connection.close()


_PROJECT_ENV_VAR_NAME = 'GCLOUD_PROJECT'


def _get_production_project():
"""Gets the production project if it can be inferred."""
return os.getenv(_PROJECT_ENV_VAR_NAME)


def _determine_default_project(project=None):
"""Determine default project ID explicitly or implicitly as fall-back.
In implicit case, currently only supports enviroment variable but will
support App Engine, Compute Engine and other environments in the future.
Local environment variable used is:
- GCLOUD_PROJECT
:type project: string
:param project: Optional. The project name to use as default.
:rtype: string or ``NoneType``
:returns: Default project if it can be determined.
"""
if project is None:
project = _get_production_project()

return project


def set_default_project(project=None):
"""Set default project either explicitly or implicitly as fall-back.
:type project: string
:param project: Optional. The project name to use as default.
:raises: :class:`EnvironmentError` if no project was found.
"""
project = _determine_default_project(project=project)
if project is not None:
_DEFAULTS.project = project
else:
raise EnvironmentError('No project could be inferred.')


def get_default_project():
"""Get default project.
:rtype: string or ``NoneType``
:returns: The default project if one has been set.
"""
return _DEFAULTS.project


class _DefaultsContainer(object):
"""Container for defaults.
:type project: string
:param project: Persistent implied project from environment.
:type implicit: boolean
:param implicit: if False, assign the instance's ``project`` attribute
unconditionally; otherwise, assign it only if the
value is not None.
"""

@_lazy_property_deco
@staticmethod
def project():
"""Return the implicit default project."""
return _determine_default_project()

def __init__(self, project=None, implicit=False):
if project is not None or not implicit:
self.project = project


_DEFAULTS = _DefaultsContainer(implicit=True)
17 changes: 17 additions & 0 deletions gcloud/_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

"""Shared testing utilities."""

from gcloud import _helpers
from gcloud._helpers import _DefaultsContainer


class _Monkey(object):
# context-manager for replacing module names in the scope of a test.
Expand All @@ -30,3 +33,17 @@ def __enter__(self):
def __exit__(self, exc_type, exc_val, exc_tb):
for key, value in self.to_restore.items():
setattr(self.module, key, value)


def _monkey_defaults(*args, **kwargs):
mock_defaults = _DefaultsContainer(*args, **kwargs)
return _Monkey(_helpers, _DEFAULTS=mock_defaults)


def _setup_defaults(test_case, *args, **kwargs):
test_case._replaced_defaults = _helpers._DEFAULTS
_helpers._DEFAULTS = _DefaultsContainer(*args, **kwargs)


def _tear_down_defaults(test_case):
_helpers._DEFAULTS = test_case._replaced_defaults
4 changes: 2 additions & 2 deletions gcloud/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@
import os

from gcloud import credentials
from gcloud._helpers import get_default_project
from gcloud._helpers import set_default_project
from gcloud.storage import _implicit_environ
from gcloud.storage._implicit_environ import get_default_bucket
from gcloud.storage._implicit_environ import get_default_connection
from gcloud.storage._implicit_environ import get_default_project
from gcloud.storage._implicit_environ import set_default_project
from gcloud.storage.api import create_bucket
from gcloud.storage.api import get_all_buckets
from gcloud.storage.api import get_bucket
Expand Down
78 changes: 4 additions & 74 deletions gcloud/storage/_implicit_environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,96 +14,26 @@

"""Module to provide implicit behavior based on enviroment.
Allows the storage package to infer the current project, default bucket
and connection from the enviroment.
Allows the storage package to infer the default bucket and connection
from the enviroment.
"""


import os

from gcloud._helpers import _lazy_property_deco


_PROJECT_ENV_VAR_NAME = 'GCLOUD_PROJECT'


def _get_production_project():
"""Gets the production project if it can be inferred."""
return os.getenv(_PROJECT_ENV_VAR_NAME)


def _determine_default_project(project=None):
"""Determine default project ID explicitly or implicitly as fall-back.
In implicit case, currently only supports enviroment variable but will
support App Engine, Compute Engine and other environments in the future.
Local environment variable used is:
- GCLOUD_PROJECT
:type project: string
:param project: Optional. The project name to use as default.
:rtype: string or ``NoneType``
:returns: Default project if it can be determined.
"""
if project is None:
project = _get_production_project()

return project


def set_default_project(project=None):
"""Set default project either explicitly or implicitly as fall-back.
:type project: string
:param project: Optional. The project name to use as default.
:raises: :class:`EnvironmentError` if no project was found.
"""
project = _determine_default_project(project=project)
if project is not None:
_DEFAULTS.project = project
else:
raise EnvironmentError('No project could be inferred.')


class _DefaultsContainer(object):
"""Container for defaults.
:type project: string
:param project: Persistent implied project from environment.
:type bucket: :class:`gcloud.storage.bucket.Bucket`
:param bucket: Persistent implied default bucket from environment.
:type connection: :class:`gcloud.storage.connection.Connection`
:param connection: Persistent implied connection from environment.
"""

@_lazy_property_deco
@staticmethod
def project():
"""Return the implicit default project."""
return _determine_default_project()

def __init__(self, project=None, bucket=None, connection=None,
implicit=False):
if project is not None or not implicit:
self.project = project
def __init__(self, bucket=None, connection=None):
self.bucket = bucket
self.connection = connection


def get_default_project():
"""Get default project.
:rtype: string or ``NoneType``
:returns: The default project if one has been set.
"""
return _DEFAULTS.project


def get_default_bucket():
"""Get default bucket.
Expand All @@ -122,4 +52,4 @@ def get_default_connection():
return _DEFAULTS.connection


_DEFAULTS = _DefaultsContainer(implicit=True)
_DEFAULTS = _DefaultsContainer()
2 changes: 1 addition & 1 deletion gcloud/storage/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
"""

from gcloud.exceptions import NotFound
from gcloud._helpers import get_default_project
from gcloud.storage._implicit_environ import get_default_connection
from gcloud.storage._implicit_environ import get_default_project
from gcloud.storage.bucket import Bucket
from gcloud.storage.iterator import Iterator

Expand Down
Loading

0 comments on commit 4512eff

Please sign in to comment.