Skip to content

Commit

Permalink
release/1.0.0: Add subcommand show to list the supportes estimators…
Browse files Browse the repository at this point in the history
…, languages and templates in a compact table
  • Loading branch information
nok committed Dec 18, 2019
1 parent 7c5f807 commit 3fcf218
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 18 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def main():
'scikit-learn>=0.17,<=0.22a0',
'Jinja2>=2.10.1',
'loguru>=0.3.2',
'tabulate>=0.8.6',
'joblib',
],
extras_require={
Expand Down
63 changes: 59 additions & 4 deletions sklearn_porter/Estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

import urllib.request
from abc import ABCMeta
from json import loads, JSONDecodeError
from collections import OrderedDict
from functools import partial
from json import JSONDecodeError, loads
from multiprocessing import Pool, cpu_count
from os import environ, remove
from pathlib import Path
from shutil import which
from subprocess import STDOUT, CalledProcessError, check_output
from sys import platform, stdout, version_info
from shutil import which
from tempfile import mktemp
from textwrap import dedent
from time import sleep
from typing import Callable, Dict, List, Optional, Tuple, Union
from functools import partial

# Additional installed modules:
import numpy as np
from loguru import logger as L
from tabulate import tabulate

# scikit-learn
from sklearn import __version__ as sklearn_version
Expand All @@ -26,8 +28,8 @@
from sklearn.metrics import accuracy_score

# sklearn-porter
from sklearn_porter import enums as enum
from sklearn_porter import decorators as decorator
from sklearn_porter import enums as enum
from sklearn_porter import exceptions as exception
from sklearn_porter import meta
from sklearn_porter.utils import options
Expand Down Expand Up @@ -969,6 +971,59 @@ def _system_call(cmd: str, executable='/bin/bash'):
return [out.get('predict')]


def show(language: Optional[Union[str, enum.Language]] = None):
"""
Show the supported estimators, programming languages
and templates in a compact table.
Parameters
----------
language : Language
The requested programming language.
Returns
-------
Show the table.
"""
languages = enum.LANGUAGES
if language:
language = enum.Language.convert(language)
languages = {language.value.KEY: language.value}
headers = ['Estimator'] + [l.LABEL for l in languages.values()]
clazzes = Estimator.classifiers() + Estimator.regressors()
clazzes = {_get_qualname(c()): c() for c in clazzes}
clazzes = OrderedDict(sorted(clazzes.items()))
table = []
templates = dict(attached='ᴀ', combined='ᴄ', exported='ᴇ')
for name, est in clazzes.items():
tr = [name]
for lang in languages.keys():
td = []
for tpl in templates.keys():
if can(
estimator=est,
language=lang,
template=tpl,
method='predict_proba'
):
out = '✓{}ᴾ'.format(templates.get(tpl))
elif can(estimator=est, language=lang, template=tpl):
out = '✓{} '.format(templates.get(tpl))
else:
out = '···'
td.append(out)
td = ' | '.join(td)
tr.append(td)
table.append(tr)
return tabulate(
table,
headers=headers,
tablefmt='presto',
disable_numparse=True,
colalign=['left'] + ['center'] * len(languages)
)


def can(
estimator: Union[BaseEstimator, ABCMeta],
language: Optional[Union[str, enum.Language]] = None,
Expand Down
2 changes: 1 addition & 1 deletion sklearn_porter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

from sklearn_porter.Estimator import Estimator, make, port, save, test
from sklearn_porter.Estimator import Estimator, make, port, save, show, test
from sklearn_porter import meta
from sklearn_porter.utils import options

Expand Down
22 changes: 11 additions & 11 deletions sklearn_porter/cli/command/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from typing import Dict

# sklearn-porter
from sklearn_porter import Estimator, options
from sklearn_porter import options, show
from sklearn_porter.cli.common import arg_debug, arg_help
from sklearn_porter.language import LANGUAGES


def config(sub_parser: _SubParsersAction):
Expand All @@ -28,22 +29,21 @@ def config(sub_parser: _SubParsersAction):
)
for group in parser._action_groups:
group.title = str(group.title).capitalize()

parser.add_argument(
'-l',
'--language',
type=str,
required=False,
choices=LANGUAGES.keys(),
help='The name of the programming language.'
)
for fn in (arg_debug, arg_help):
fn(parser)

parser.set_defaults(func=main)


def _get_qualname(obj: object):
return obj.__class__.__module__ + '.' + obj.__class__.__qualname__


def main(args: Dict):
if args.get('debug'):
options['logging.level'] = DEBUG

estimators = Estimator.classifiers() + Estimator.regressors()

for e in estimators:
print(e.__name__)
print(show(args.get('language')))
5 changes: 3 additions & 2 deletions tests/EstimatorTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,11 @@ def test_regressions_of_classifiers(

@pytest.mark.parametrize(
'args', [
['show'], ['port', str(SERIALIZED_MODEL), '--skip-warnings'],
['show'], ['show', '-l', 'java'], ['show', '-l', 'js'],
['port', str(SERIALIZED_MODEL), '--skip-warnings'],
['save', str(SERIALIZED_MODEL), '--skip-warnings']
],
ids=['show', 'port', 'save']
ids=['show', 'show_java', 'show_js', 'port', 'save']
)
def test_cli_subcommand(args: List):
parsed = parse_args(args)
Expand Down

0 comments on commit 3fcf218

Please sign in to comment.