And more!
This commit is contained in:
Sean C. Gillies 2018-05-11 11:44:41 -06:00
parent 78b372697b
commit 58b95de29b
4 changed files with 100 additions and 43 deletions

View File

@ -51,12 +51,6 @@ local = ThreadEnv()
log = logging.getLogger(__name__)
# Rasterio defaults
default_options = {
'CHECK_WITH_INVERT_PROJ': True,
'GTIFF_IMPLICIT_JPEG_OVR': False,
"RASTERIO_ENV": True
}
class Env(object):
"""Abstraction for GDAL and AWS configuration
@ -91,6 +85,24 @@ class Env(object):
for GDAL as needed.
"""
@classmethod
def default_options(cls):
"""Default configuration options
Parameters
----------
None
Returns
-------
dict
"""
return {
'CHECK_WITH_INVERT_PROJ': True,
'GTIFF_IMPLICIT_JPEG_OVR': False,
"RASTERIO_ENV": True
}
def __init__(self, session=None, aws_access_key_id=None,
aws_secret_access_key=None, aws_session_token=None,
region_name=None, profile_name=None, **options):
@ -101,27 +113,29 @@ class Env(object):
Parameters
----------
session: object, optional
A boto3 session.
aws_access_key_id: string, optional
session : optional
A boto3 session object.
aws_access_key_id : str, optional
An access key id, as per boto3.
aws_secret_access_key: string, optional
aws_secret_access_key : str, optional
A secret access key, as per boto3.
aws_session_token: string, optional
aws_session_token : str, optional
A session token, as per boto3.
region_name: string, optional
region_name : str, optional
A region name, as per boto3.
profile_name: string, optional
profile_name : str, optional
A shared credentials profile name, as per boto3.
**options: optional
**options : optional
A mapping of GDAL configuration options, e.g.,
`CPL_DEBUG=True, CHECK_WITH_INVERT_PROJ=False`.
Returns
-------
A new instance of Env.
Env
Note: We raise EnvError if the GDAL config options
Notes
-----
We raise EnvError if the GDAL config options
AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY are given. AWS
credentials are handled exclusively by boto3.
"""
@ -142,8 +156,37 @@ class Env(object):
self._creds = None
@classmethod
def from_defaults(cls, *args, **kwargs):
"""Create an environment with default config options
Parameters
----------
args : optional
Positional arguments for Env()
kwargs : optional
Keyword arguments for Env()
Returns
-------
Env
Notes
-----
The items in kwargs will be overlaid on the default values.
"""
options = Env.default_options()
options.update(**kwargs)
return Env(*args, **options)
@property
def is_credentialized(self):
"""Test for existence of cloud credentials
Returns
-------
bool
"""
return bool(self._creds)
def credentialize(self):
@ -151,6 +194,10 @@ class Env(object):
Note well: this method is a no-op if the GDAL environment
already has credentials, unless session is not None.
Returns
-------
None
"""
if not hascreds():
import boto3
@ -199,8 +246,8 @@ class Env(object):
# defined. This MUST happen before calling 'defenv()'.
local._discovered_options = {}
# Don't want to reinstate the "RASTERIO_ENV" option.
probe_env = {k for k in default_options if k != "RASTERIO_ENV"}
probe_env |= set(self.options.keys())
probe_env = {k for k in self.options.keys() if k != "RASTERIO_ENV"}
# probe_env |= set(self.options.keys())
for key in probe_env:
val = get_gdal_config(key, normalize=False)
if val is not None:
@ -247,11 +294,11 @@ def defenv(**options):
log.debug("No GDAL environment exists")
local._env = GDALEnv()
# first set default options, then add user options
set_options = {}
for d in (default_options, options):
for (k, v) in d.items():
set_options[k] = v
local._env.update_config_options(**set_options)
# set_options = {}
# for d in (default_options, options):
# for (k, v) in d.items():
# set_options[k] = v
local._env.update_config_options(**options)
log.debug(
"New GDAL environment %r created", local._env)
local._env.start()
@ -299,14 +346,14 @@ def delenv():
def ensure_env(f):
"""A decorator that ensures an env exists before a function
calls any GDAL C functions."""
if local._env:
return f
else:
@wraps(f)
def wrapper(*args, **kwds):
with Env():
@wraps(f)
def wrapper(*args, **kwds):
if local._env:
return f(*args, **kwds)
else:
with Env.from_defaults():
return f(*args, **kwds)
return wrapper
return wrapper
@attr.s(slots=True)
@ -476,8 +523,8 @@ def require_gdal_version(version, param=None, values=None, is_max_version=False,
elif full_kwds[param] in values:
raise GDALVersionError(
'parameter "{0}={1}" requires '
'GDAL {2} {3}{4}'.format(param, full_kwds[param],
inequality, version, reason))
'GDAL {2} {3}{4}'.format(
param, full_kwds[param], inequality, version, reason))
return f(*args, **kwds)

View File

@ -176,7 +176,7 @@ def transform_bounds(
@ensure_env
@require_gdal_version('2.0', param='resampling', values=GDAL2_RESAMPLING)
#@require_gdal_version('2.0', param='resampling', values=GDAL2_RESAMPLING)
def reproject(source, destination, src_transform=None, gcps=None,
src_crs=None, src_nodata=None, dst_transform=None, dst_crs=None,
dst_nodata=None, resampling=Resampling.nearest,

View File

@ -9,8 +9,9 @@ import pytest
import rasterio
from rasterio._env import del_gdal_config, get_gdal_config, set_gdal_config
from rasterio.env import defenv, delenv, getenv, setenv, ensure_env
from rasterio.env import default_options, GDALVersion, require_gdal_version
from rasterio.env import Env, defenv, delenv, getenv, setenv, ensure_env
# from rasterio.env import default_options, GDALVersion, require_gdal_version
from rasterio.env import GDALVersion, require_gdal_version
from rasterio.errors import EnvError, RasterioIOError, GDALVersionError
from rasterio.rio.main import main_group
@ -81,8 +82,7 @@ def test_env_accessors(gdalenv):
"""High level GDAL env access."""
defenv()
setenv(foo='1', bar='2')
expected = default_options.copy()
expected.update({'foo': '1', 'bar': '2'})
expected = {'foo': '1', 'bar': '2'}
items = getenv()
assert items == rasterio.env.local._env.options
# Comparison below requires removal of GDAL_DATA.
@ -122,9 +122,20 @@ def test_no_aws_gdal_config(gdalenv):
rasterio.Env(AWS_SECRET_ACCESS_KEY='y')
def test_env_empty(gdalenv):
"""Empty env has no defaults"""
env = rasterio.Env(foo='x')
assert env.options['foo'] == 'x'
assert not env.context_options
with env:
assert get_gdal_config('CHECK_WITH_INVERT_PROJ') is None
assert get_gdal_config('GTIFF_IMPLICIT_JPEG_OVR') is None
assert get_gdal_config("RASTERIO_ENV") is None
def test_env_defaults(gdalenv):
"""Test env defaults."""
env = rasterio.Env(foo='x')
env = rasterio.Env.from_defaults(foo='x')
assert env.options['foo'] == 'x'
assert not env.context_options
with env:
@ -163,11 +174,10 @@ def test_with_aws_session_credentials(gdalenv):
env = rasterio.Env(
aws_access_key_id='id', aws_secret_access_key='key',
aws_session_token='token', region_name='null-island-1')
expected = default_options.copy()
with env:
expected.update({
expected = {
'AWS_ACCESS_KEY_ID': 'id', 'AWS_REGION': 'null-island-1',
'AWS_SECRET_ACCESS_KEY': 'key', 'AWS_SESSION_TOKEN': 'token'})
'AWS_SECRET_ACCESS_KEY': 'key', 'AWS_SESSION_TOKEN': 'token'}
items = getenv()
# Comparison below requires removal of GDAL_DATA.
items.pop('GDAL_DATA', None)
@ -323,7 +333,7 @@ def test_ensure_defaults_teardown(gdalenv):
"""
def _check_defaults():
for key in default_options.keys():
for key in Env.default_options().keys():
assert get_gdal_config(key) is None
_check_defaults()

View File

@ -21,7 +21,7 @@ from .conftest import requires_gdal22
gdal_version = GDALVersion.runtime()
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
DST_TRANSFORM = Affine(300.0, 0.0, -8789636.708,