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

#741: hoist project detection/setup into 'gcloud._helpers'. #748

Merged
merged 1 commit into from
Mar 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

This comment was marked as spam.

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):

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

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