Skip to content

Commit

Permalink
Merge pull request #1460 from kwmsmith/from-yaml-source-relative-to-yaml
Browse files Browse the repository at this point in the history
Allow option to load yaml resources relative to yaml file
  • Loading branch information
kwmsmith committed Mar 24, 2016
2 parents 640fe88 + 2047022 commit 1f7702e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 32 deletions.
90 changes: 58 additions & 32 deletions blaze/server/spider.py
Expand Up @@ -7,7 +7,8 @@
import argparse
import importlib

import toolz
from contextlib import contextmanager

import yaml

from blaze.interactive import data as bz_data
Expand Down Expand Up @@ -72,28 +73,46 @@ def data_spider(path,
"""
# NOTE: this is named `data_spider` rather than just `spider` to
# disambiguate this function from the `blaze.server.spider` module.
return {
os.path.basename(path): _spider(path, ignore=ignore,
followlinks=followlinks,
hidden=hidden,
extra_kwargs=extra_kwargs)
}
return {os.path.basename(path): _spider(path,
ignore=ignore,
followlinks=followlinks,
hidden=hidden,
extra_kwargs=extra_kwargs)}


def from_yaml(path, ignore=(ValueError, NotImplementedError), followlinks=True,
hidden=False):
@contextmanager
def pushd(path):
"""Context manager that changes to ``path`` directory on enter and
changes back to ``os.getcwd()`` on exit.
"""
cwd = os.getcwd()
os.chdir(os.path.abspath(path))
try:
yield
finally:
os.chdir(cwd)


def from_yaml(fh,
ignore=(ValueError, NotImplementedError),
followlinks=True,
hidden=False,
relative_to_yaml_dir=False):
"""Construct a dictionary of resources from a YAML specification.
Parameters
----------
path : str
Path to a YAML specification of resources to load
fh : file
File object referring to the YAML specification of resources to load.
ignore : tuple of Exception, optional
Ignore these exceptions when calling ``blaze.data``
Ignore these exceptions when calling ``blaze.data``.
followlinks : bool, optional
Follow symbolic links
Follow symbolic links.
hidden : bool, optional
Load hidden files
Load hidden files.
relative_to_yaml_dir: bool, optional, default False
Load paths relative to yaml file's directory. Default is to load
relative to process' CWD.
Returns
-------
Expand All @@ -105,22 +124,24 @@ def from_yaml(path, ignore=(ValueError, NotImplementedError), followlinks=True,
data_spider : Traverse a directory tree for resources
"""
resources = {}
for name, info in yaml.load(path.read()).items():
try:
source = info.pop('source')
except KeyError:
raise ValueError('source key not found for data source named %r' %
name)
for mod in info.pop('imports', []):
importlib.import_module(mod)
if os.path.isdir(source):
resources[name] = data_spider(os.path.expanduser(source),
ignore=ignore,
followlinks=followlinks,
hidden=hidden,
extra_kwargs=info)
else:
resources[name] = bz_data(source, **info)
yaml_dir = os.path.dirname(os.path.abspath(fh.name))
for name, info in yaml.load(fh.read()).items():
with pushd(yaml_dir if relative_to_yaml_dir else os.getcwd()):
try:
source = info.pop('source')
except KeyError:
raise ValueError('source key not found for data source named %r' %
name)
for mod in info.pop('imports', []):
importlib.import_module(mod)
if os.path.isdir(source):
resources[name] = data_spider(os.path.expanduser(source),
ignore=ignore,
followlinks=followlinks,
hidden=hidden,
extra_kwargs=info)
else:
resources[name] = bz_data(source, **info)
return resources


Expand All @@ -141,6 +162,8 @@ def _parse_args():
help='Exceptions to ignore when calling ``blaze.data`` on a file')
p.add_argument('-d', '--hidden', action='store_true',
help='Call ``blaze.data`` on hidden files')
p.add_argument('--yaml-dir', action='store_true',
help='Load path-based resources relative to yaml file directory.')
p.add_argument('-D', '--debug', action='store_true',
help='Start the Flask server in debug mode')
return p.parse_args()
Expand All @@ -152,8 +175,11 @@ def _main():
resources = from_yaml(args.path,
ignore=ignore,
followlinks=args.follow_links,
hidden=args.hidden)
Server(resources).run(host=args.host, port=args.port, debug=args.debug)
hidden=args.hidden,
relative_to_yaml_dir=args.yaml_dir)
Server(resources).run(host=args.host,
port=args.port,
debug=args.debug)


if __name__ == '__main__':
Expand Down
3 changes: 3 additions & 0 deletions docs/source/whatsnew/0.10.0.txt
Expand Up @@ -109,3 +109,6 @@ Miscellaneous
* Merged the ``core`` and ``all`` conda recipes (:issue:`1451`). This
simplifies the build process and makes it consistent with the single
``blaze`` package provided by the Anaconda distribution.
* Adds a ``--yaml-dir`` option to ``blaze-server`` to indicate the server
should load path-based ``yaml`` resources relative to the yaml file's
directory, not the CWD of the process (:issue:`1460`).

0 comments on commit 1f7702e

Please sign in to comment.