Skip to content
Closed
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
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
History
-------

4.6.0 (2016-04-10)
~~~~~~~~~~~~~~~~~~

- Adding REST methods to manage new types of whizzml resources: scripts,
executions and libraries.

4.5.2 (2016-03-24)
~~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion bigml/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '4.5.2'
__version__ = '4.6.0'
17 changes: 13 additions & 4 deletions bigml/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
from bigml.logistichandler import LogisticRegressionHandler
from bigml.associationhandler import AssociationHandler
from bigml.associationsethandler import AssociationSetHandler
from bigml.scripthandler import ScriptHandler
from bigml.executionhandler import ExecutionHandler
from bigml.libraryhandler import LibraryHandler


# Repeating constants and functions for backwards compatibility
Expand All @@ -83,8 +86,9 @@
SAMPLE_PATH, SAMPLE_RE, CORRELATION_PATH, CORRELATION_RE,
STATISTICAL_TEST_PATH, STATISTICAL_TEST_RE,
LOGISTIC_REGRESSION_PATH, LOGISTIC_REGRESSION_RE, ASSOCIATION_PATH,
ASSOCIATION_RE, ASSOCIATION_SET_PATH, ASSOCIATION_SET_RE)

ASSOCIATION_RE, ASSOCIATION_SET_PATH, ASSOCIATION_SET_RE,
SCRIPT_PATH, SCRIPT_RE,
EXECUTION_PATH, EXECUTION_RE, LIBRARY_PATH, LIBRARY_RE)

from bigml.resourcehandler import (
get_resource, get_resource_type, check_resource_type, get_source_id,
Expand All @@ -94,7 +98,8 @@
get_batch_anomaly_score_id, get_resource_id, resource_is_ready,
get_status, check_resource, http_ok, get_project_id, get_sample_id,
get_correlation_id, get_statistical_test_id, get_logistic_regression_id,
get_association_id, get_association_set_id)
get_association_id, get_association_set_id, get_script_id,
get_execution_id, get_library_id)


# Map status codes to labels
Expand All @@ -120,7 +125,8 @@ def count(listing):
return listing['meta']['query_total']


class BigML(AssociationSetHandler, AssociationHandler,
class BigML(LibraryHandler, ExecutionHandler, ScriptHandler,
AssociationSetHandler, AssociationHandler,
LogisticRegressionHandler,
StatisticalTestHandler, CorrelationHandler,
SampleHandler, ProjectHandler,
Expand Down Expand Up @@ -190,6 +196,9 @@ def __init__(self, username=None, api_key=None, dev_mode=False,
LogisticRegressionHandler.__init__(self)
AssociationHandler.__init__(self)
AssociationSetHandler.__init__(self)
ScriptHandler.__init__(self)
ExecutionHandler.__init__(self)
LibraryHandler.__init__(self)

self.getters = {}
for resource_type in RESOURCE_RE:
Expand Down
14 changes: 13 additions & 1 deletion bigml/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
LOGISTIC_REGRESSION_PATH = 'logisticregression'
ASSOCIATION_PATH = 'association'
ASSOCIATION_SET_PATH = 'associationset'
SCRIPT_PATH = 'script'
EXECUTION_PATH = 'execution'
LIBRARY_PATH = 'library'


# Resource Ids patterns
Expand Down Expand Up @@ -81,6 +84,12 @@
(ASSOCIATION_PATH, ID_PATTERN, ASSOCIATION_PATH, SHARED_PATTERN))
ASSOCIATION_SET_RE = re.compile(r'^%s/%s$' % \
(ASSOCIATION_SET_PATH, ID_PATTERN))
SCRIPT_RE = re.compile(r'^%s/%s|^shared/%s/%s$' % \
(SCRIPT_PATH, ID_PATTERN, SCRIPT_PATH, SHARED_PATTERN))
EXECUTION_RE = re.compile(r'^%s/%s|^shared/%s/%s$' % \
(EXECUTION_PATH, ID_PATTERN, EXECUTION_PATH, SHARED_PATTERN))
LIBRARY_RE = re.compile(r'^%s/%s|^shared/%s/%s$' % \
(LIBRARY_PATH, ID_PATTERN, LIBRARY_PATH, SHARED_PATTERN))

RESOURCE_RE = {
SOURCE_PATH: SOURCE_RE,
Expand All @@ -102,7 +111,10 @@
STATISTICAL_TEST_PATH: STATISTICAL_TEST_RE,
LOGISTIC_REGRESSION_PATH: LOGISTIC_REGRESSION_RE,
ASSOCIATION_PATH: ASSOCIATION_RE,
ASSOCIATION_SET_PATH: ASSOCIATION_SET_RE}
ASSOCIATION_SET_PATH: ASSOCIATION_SET_RE,
SCRIPT_PATH: SCRIPT_RE,
EXECUTION_PATH: EXECUTION_RE,
LIBRARY_PATH: LIBRARY_RE}


RENAMED_RESOURCES = {
Expand Down
134 changes: 134 additions & 0 deletions bigml/executionhandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# Copyright 2015 BigML
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Base class for whizzml script executions' REST calls

https://bigml.com/developers/executions

"""

try:
import simplejson as json
except ImportError:
import json


from bigml.resourcehandler import ResourceHandler
from bigml.resourcehandler import (check_resource_type,
get_execution_id, get_resource_type,
get_script_id, check_resource)
from bigml.constants import (EXECUTION_PATH, SCRIPT_PATH,
TINY_RESOURCE)


class ExecutionHandler(ResourceHandler):
"""This class is used by the BigML class as
a mixin that provides the executions' REST calls. It should not
be instantiated independently.

"""
def __init__(self):
"""Initializes the ExecutionHandler. This class is intended to be
used as a mixin on ResourceHandler, that inherits its
attributes and basic method from BigMLConnection, and must not be
instantiated independently.

"""
self.execution_url = self.url + EXECUTION_PATH

def create_execution(self, origin_resource, args=None,
wait_time=3, retries=10):
"""Creates an execution from a `script` or a list of `scripts`.

"""

create_args = {}
if args is not None:
create_args.update(args)

if isinstance(origin_resource, basestring):
# single script
scripts = [origin_resource]
else:
scripts = origin_resource

script_ids = [get_script_id(script) for script in scripts]
if all([get_resource_type(script_id) == SCRIPT_PATH for
script_id in script_ids]):
for script in scripts:
check_resource(script,
query_string=TINY_RESOURCE,
wait_time=wait_time, retries=retries,
raise_on_error=True, api=self)
else:
raise Exception("A script id or a list of them is needed to create"
" a script execution. %s found." %
get_resource_type(origin_resource))

if len(scripts) > 1:
create_args.update({
"scripts": script_ids})
else:
create_args.update({
"script": script_ids[0]})

body = json.dumps(create_args)
return self._create(self.execution_url, body)

def get_execution(self, execution, query_string=''):
"""Retrieves an execution.

The execution parameter should be a string containing the
execution id or the dict returned by create_execution.
As execution is an evolving object that is processed
until it reaches the FINISHED or FAULTY state, the function will
return a dict that encloses the execution contents and state info
available at the time it is called.
"""
check_resource_type(execution, EXECUTION_PATH,
message="An execution id is needed.")
execution_id = get_execution_id(execution)
if execution_id:
return self._get("%s%s" % (self.url, execution_id),
query_string=query_string)

def list_executions(self, query_string=''):
"""Lists all your executions.

"""
return self._list(self.execution_url, query_string)

def update_execution(self, execution, changes):
"""Updates an execution.

"""
check_resource_type(execution, EXECUTION_PATH,
message="An execution id is needed.")
execution_id = get_execution_id(execution)
if execution_id:
body = json.dumps(changes)
return self._update("%s%s" % (self.url, execution_id), body)

def delete_execution(self, execution):
"""Deletes an execution.

"""
check_resource_type(execution, EXECUTION_PATH,
message="An execution id is needed.")
execution_id = get_execution_id(execution)
if execution_id:
return self._delete("%s%s" % (self.url, execution_id))
2 changes: 1 addition & 1 deletion bigml/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import sys
import json


from bigml.util import invert_dictionary, python_map_type, find_locale
from bigml.util import DEFAULT_LOCALE
from bigml.api import get_resource_type
Expand Down Expand Up @@ -588,7 +589,6 @@ def new_fields_structure(self, csv_attributes_file=None,
self.field_id(int(field_attributes[0]))
new_fields_structure[field_id] = \
dict(zip(headers, field_attributes[1: 6]))

except ValueError:
raise ValueError("The first column should contain either the"
" column or ID of the fields. Failed to find"
Expand Down
139 changes: 139 additions & 0 deletions bigml/libraryhandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# Copyright 2015 BigML
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""Base class for whizzml libraries' REST calls

https://bigml.com/developers/libraries

"""

try:
import simplejson as json
except ImportError:
import json
import os

from bigml.resourcehandler import ResourceHandler
from bigml.resourcehandler import (check_resource_type,
get_library_id, get_resource_type,
check_resource)
from bigml.constants import LIBRARY_PATH, TINY_RESOURCE


class LibraryHandler(ResourceHandler):
"""This class is used by the BigML class as
a mixin that provides the whizzml libraries' REST calls. It should not
be instantiated independently.

"""
def __init__(self):
"""Initializes the LibraryHandler. This class is intended to be
used as a mixin on ResourceHandler, that inherits its
attributes and basic method from BigMLConnection, and must not be
instantiated independently.

"""
self.library_url = self.url + LIBRARY_PATH

def create_library(self, source_code=None, args=None,
wait_time=3, retries=10):
"""Creates a whizzml library from its source code. The `source_code`
parameter can be a:
{library ID}: the ID for an existing whizzml library
{path}: the path to a file containing the source code
{string} : the string containing the source code for the library

"""
create_args = {}
if args is not None:
create_args.update(args)

if source_code is None:
raise Exception('A valid code string'
' or a library id must be provided.')
resource_type = get_resource_type(source_code)
if resource_type == LIBRARY_PATH:
library_id = get_library_id(source_code)
if library_id:
check_resource(library_id,
query_string=TINY_RESOURCE,
wait_time=wait_time, retries=retries,
raise_on_error=True, api=self)
create_args.update({
"origin": library_id})
elif isinstance(source_code, basestring):
try:
if os.path.exists(source_code):
with open(source_code) as code_file:
source_code = code_file.read()
except IOError:
raise IOError("Could not open the source code file %s." %
source_code)
create_args.update({
"source_code": source_code})
else:
raise Exception("A library id or a valid source code"
" is needed to create a"
" library. %s found." % resource_type)


body = json.dumps(create_args)
return self._create(self.library_url, body)

def get_library(self, library, query_string=''):
"""Retrieves a library.

The library parameter should be a string containing the
library id or the dict returned by create_script.
As library is an evolving object that is processed
until it reaches the FINISHED or FAULTY state, the function will
return a dict that encloses the library content and state info
available at the time it is called.
"""
check_resource_type(library, LIBRARY_PATH,
message="A library id is needed.")
library_id = get_library_id(library)
if library_id:
return self._get("%s%s" % (self.url, library_id),
query_string=query_string)

def list_libraries(self, query_string=''):
"""Lists all your libraries.

"""
return self._list(self.library_url, query_string)

def update_library(self, library, changes):
"""Updates a library.

"""
check_resource_type(library, LIBRARY_PATH,
message="A library id is needed.")
library_id = get_library_id(library)
if library_id:
body = json.dumps(changes)
return self._update("%s%s" % (self.url, library_id), body)

def delete_library(self, library):
"""Deletes a library.

"""
check_resource_type(library, LIBRARY_PATH,
message="A library id is needed.")
library_id = get_library_id(library)
if library_id:
return self._delete("%s%s" % (self.url, library_id))
Loading