[config/dx] bundle a default fs (and http?) service if none is provided (#179)

This commit is contained in:
Romain Dorgueil
2017-10-05 07:17:16 +02:00
parent f7cf7ca482
commit b2f93b2416
13 changed files with 69 additions and 16 deletions

View File

@ -1,10 +1,10 @@
import logging
from bonobo.structs import Bag, ErrorBag, Graph, Token
from bonobo.nodes import CsvReader, CsvWriter, FileReader, FileWriter, Filter, JsonReader, JsonWriter, Limit, \
PickleReader, PickleWriter, PrettyPrinter, RateLimited, Tee, arg0_to_kwargs, count, identity, kwargs_to_arg0, noop
from bonobo.strategies import create_strategy
from bonobo.util.objects import get_name
from bonobo.structs import Bag, ErrorBag, Graph, Token
from bonobo.util import get_name
__all__ = []

View File

@ -1,7 +1,7 @@
from bonobo.config.configurables import Configurable
from bonobo.config.options import Method, Option
from bonobo.config.processors import ContextProcessor
from bonobo.config.services import Container, Exclusive, Service, requires
from bonobo.config.services import Container, Exclusive, Service, requires, create_container
use = requires
@ -14,6 +14,7 @@ __all__ = [
'Method',
'Option',
'Service',
'create_container',
'requires',
'use',
]

View File

@ -1,6 +1,5 @@
from bonobo.util.inspect import isoption, iscontextprocessor
from bonobo.util import isoption, iscontextprocessor, sortedlist
from bonobo.errors import AbstractError
from bonobo.util.collections import sortedlist
__all__ = [
'Configurable',

View File

@ -95,6 +95,30 @@ class Container(dict):
return value
def create_container(services=None, factory=Container):
"""
Create a container with reasonable default service implementations for commonly use, standard-named, services.
Services:
- `fs` defaults to a fs2 instance based on current working directory
- `http`defaults to requests
:param services:
:return:
"""
container = factory(services) if services else factory()
if not 'fs' in container:
import bonobo
container.setdefault('fs', bonobo.open_fs())
if not 'http' in container:
import requests
container.setdefault('http', requests)
return container
class Exclusive(ContextDecorator):
"""
Decorator and context manager used to require exclusive usage of an object, most probably a service. It's usefull

View File

@ -6,4 +6,4 @@ INHERIT_INPUT = Token('InheritInput')
LOOPBACK = Token('Loopback')
NOT_MODIFIED = Token('NotModified')
DEFAULT_SERVICES_FILENAME = '_services.py'
DEFAULT_SERVICES_ATTR = 'get_services'
DEFAULT_SERVICES_ATTR = 'get_services'

View File

@ -2,7 +2,7 @@ import traceback
from contextlib import contextmanager
from time import sleep
from bonobo.config import Container
from bonobo.config import create_container
from bonobo.config.processors import ContextCurrifier
from bonobo.plugins import get_enhancers
from bonobo.util.errors import print_error
@ -48,7 +48,7 @@ class LoopingExecutionContext(Wrapper):
raise RuntimeError(
'Having services defined both in GraphExecutionContext and child NodeExecutionContext is not supported, for now.'
)
self.services = Container(services) if services else Container()
self.services = create_container(services)
else:
self.services = None

View File

@ -1,6 +1,6 @@
from functools import partial
from bonobo.config.services import Container
from bonobo.config import create_container
from bonobo.constants import BEGIN, END
from bonobo.execution.node import NodeExecutionContext
from bonobo.execution.plugin import PluginExecutionContext
@ -23,7 +23,7 @@ class GraphExecutionContext:
self.graph = graph
self.nodes = [NodeExecutionContext(node, parent=self) for node in self.graph]
self.plugins = [PluginExecutionContext(plugin, parent=self) for plugin in plugins or ()]
self.services = Container(services) if services else Container()
self.services = create_container(services)
# Probably not a good idea to use it unless you really know what you're doing. But you can access the context.
self.services['__graph_context'] = self

View File

@ -4,11 +4,12 @@ import itertools
from bonobo import settings
from bonobo.config import Configurable, Option
from bonobo.config.processors import ContextProcessor
from bonobo.constants import NOT_MODIFIED
from bonobo.structs.bags import Bag
from bonobo.util.objects import ValueHolder
from bonobo.util.term import CLEAR_EOL
from bonobo.constants import NOT_MODIFIED
__all__ = [
'Limit',
'PrettyPrinter',

View File

@ -1,3 +1,4 @@
from bonobo.util.collections import sortedlist
from bonobo.util.inspect import (
inspect_node,
isbag,
@ -10,11 +11,18 @@ from bonobo.util.inspect import (
isoption,
istype,
)
from bonobo.util.objects import (
get_name,
get_attribute_or_create,
ValueHolder
)
from bonobo.util.python import require
# Bonobo's util API
__all__ = [
'require',
'ValueHolder',
'get_attribute_or_create',
'get_name',
'inspect_node',
'isbag',
'isconfigurable',
@ -25,4 +33,5 @@ __all__ = [
'ismethod',
'isoption',
'istype',
'require',
]

View File

@ -1,6 +1,5 @@
from collections import namedtuple
from bonobo.constants import LOOPBACK
def isconfigurable(mixed):
@ -99,6 +98,7 @@ def isloopbackbag(mixed):
:param mixed:
:return: bool
"""
from bonobo.constants import LOOPBACK
return isbag(mixed) and LOOPBACK in mixed.flags

View File

@ -3,8 +3,9 @@ import time
import pytest
from bonobo.util import get_name
from bonobo.config import Configurable, Container, Exclusive, Service, requires
from bonobo.config.services import validate_service_name
from bonobo.config.services import validate_service_name, create_container
class PrinterInterface():
@ -108,3 +109,23 @@ def test_requires():
svcargs = services.args_for(append)
assert len(svcargs) == 1
assert svcargs[0] == vcr.append
@pytest.mark.parametrize('services', [None, {}])
def test_create_container_empty_values(services):
c = create_container(services)
assert len(c) == 2
assert 'fs' in c and get_name(c['fs']) == 'OSFS'
assert 'http' in c and get_name(c['http']) == 'requests'
def test_create_container_override():
c = create_container({
'http': 'http',
'fs': 'fs',
})
assert len(c) == 2
assert 'fs' in c and c['fs'] == 'fs'
assert 'http' in c and c['http'] == 'http'

View File

@ -5,7 +5,6 @@ import pytest
import bonobo
from bonobo.config.processors import ContextCurrifier
from bonobo.constants import NOT_MODIFIED
from bonobo.util.inspect import inspect_node
def test_count():

View File

@ -3,7 +3,6 @@ import runpy
import sys
from unittest.mock import patch
import pathlib
import pkg_resources
import pytest