Hello community, here is the log from the commit of package python-padatious for openSUSE:Factory checked in at 2018-07-10 16:16:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-padatious (Old) and /work/SRC/openSUSE:Factory/.python-padatious.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-padatious" Tue Jul 10 16:16:41 2018 rev:2 rq:621747 version:0.4.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-padatious/python-padatious.changes 2018-03-16 10:39:38.680476460 +0100 +++ /work/SRC/openSUSE:Factory/.python-padatious.new/python-padatious.changes 2018-07-10 16:17:03.409385044 +0200 @@ -1,0 +2,13 @@ +Sun Jul 1 19:14:30 UTC 2018 - [email protected] + +- Update to python-padatious 0.4.3 + * Fix missing argument to padaos.add_entity() + +- Update to python-padatious 0.4.2 + * Add rule matching layer and support training timeout + +- Update to python-padatious 0.4.1 + * Formalize the bracket expansion language in EBNF and add support for + nested expansions. + +------------------------------------------------------------------- Old: ---- padatious-0.4.0.tar.gz New: ---- padatious-0.4.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-padatious.spec ++++++ --- /var/tmp/diff_new_pack.Zp43Fl/_old 2018-07-10 16:17:04.121383942 +0200 +++ /var/tmp/diff_new_pack.Zp43Fl/_new 2018-07-10 16:17:04.121383942 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-padatious # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -13,22 +13,25 @@ # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +%define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-padatious -Version: 0.4.0 +Version: 0.4.3 Release: 0 -License: Apache-2.0 Summary: A neural network intent parser -Url: http://github.com/MycroftAI/padatious +License: Apache-2.0 Group: Development/Languages/Python +Url: http://github.com/MycroftAI/padatious Source: https://files.pythonhosted.org/packages/source/p/padatious/padatious-%{version}.tar.gz Source99: https://raw.githubusercontent.com/MycroftAI/padatious/dev/LICENSE -BuildRequires: python-rpm-macros BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes +BuildRequires: python-rpm-macros Requires: python-fann2 Requires: python-xxhash BuildArch: noarch @@ -51,7 +54,6 @@ %files %{python_files} %defattr(-,root,root,-) -%doc README.md %license LICENSE %{python_sitelib}/* ++++++ padatious-0.4.0.tar.gz -> padatious-0.4.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/PKG-INFO new/padatious-0.4.3/PKG-INFO --- old/padatious-0.4.0/PKG-INFO 2018-02-16 07:52:58.000000000 +0100 +++ new/padatious-0.4.3/PKG-INFO 2018-06-19 18:16:57.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: padatious -Version: 0.4.0 +Version: 0.4.3 Summary: A neural network intent parser Home-page: http://github.com/MycroftAI/padatious Author: Matthew Scholefield Author-email: [email protected] License: Apache-2.0 -Description-Content-Type: UNKNOWN Description: UNKNOWN Keywords: intent-parser parser text text-processing Platform: UNKNOWN diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/README.md new/padatious-0.4.3/README.md --- old/padatious-0.4.0/README.md 2018-01-22 22:19:43.000000000 +0100 +++ new/padatious-0.4.3/README.md 1970-01-01 01:00:00.000000000 +0100 @@ -1,60 +0,0 @@ -# Padatious # - -An efficient and agile neural network intent parser - -### Features ### - - - Intents are easy to create - - Requires a relatively small amount of data - - Intents run independent of each other - - Easily extract entities (ie. Find the nearest *gas station* -> `place: gas station`) - - Fast training with a modular approach to neural networks - -### API Example ### - -Here's a simple example of how to use Padatious: - -**program.py**: -```Python -from padatious import IntentContainer - -container = IntentContainer('intent_cache') -container.add_intent('hello', ['Hi there!', 'Hello.']) -container.add_intent('goodbye', ['See you!', 'Goodbye!']) -container.add_intent('search', ['Search for {query} (using|on) {engine}.']) -container.train() - -print(container.calc_intent('Hello there!')) -print(container.calc_intent('Search for cats on CatTube.')) -``` - -Run with: - -```bash -python3 program.py -``` - -### Installing ### - -Padatious requires the following native packages to be installed: - - - [`FANN`][fann] (with dev headers) - - Python development headers - - `pip3` - - `swig` - -Ubuntu: - -``` -sudo apt-get install libfann-dev python3-dev python3-pip swig -``` - -Next, install Padatious via `pip3`: - -``` -pip3 install padatious -``` -Padatious also works in Python 2 if you are unable to upgrade. - - -[fann]:https://github.com/libfann/fann diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/__init__.py new/padatious-0.4.3/padatious/__init__.py --- old/padatious-0.4.0/padatious/__init__.py 2018-02-16 07:51:46.000000000 +0100 +++ new/padatious-0.4.3/padatious/__init__.py 2018-06-19 18:16:31.000000000 +0200 @@ -15,4 +15,4 @@ from .intent_container import IntentContainer from .match_data import MatchData -__version__ = '0.4.0' # Also change in setup.py +__version__ = '0.4.3' # Also change in setup.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/bracket_expansion.py new/padatious-0.4.3/padatious/bracket_expansion.py --- old/padatious-0.4.0/padatious/bracket_expansion.py 1970-01-01 01:00:00.000000000 +0100 +++ new/padatious-0.4.3/padatious/bracket_expansion.py 2018-06-19 18:12:33.000000000 +0200 @@ -0,0 +1,183 @@ +# Copyright 2017 Mycroft AI, Inc. +# +# 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. + + +class Fragment(object): + """(Abstract) empty sentence fragment""" + + def __init__(self, tree): + """ + Construct a sentence tree fragment which is merely a wrapper for + a list of Strings + + Args: + tree (?): Base tree for the sentence fragment, type depends on + subclass, refer to those subclasses + """ + self._tree = tree + + def tree(self): + """Return the represented sentence tree as raw data.""" + return self._tree + + def expand(self): + """ + Expanded version of the fragment. In this case an empty sentence. + + Returns: + List<List<str>>: A list with an empty sentence (= token/string list) + """ + return [[]] + + def __str__(self): + return self._tree.__str__() + + def __repr__(self): + return self._tree.__repr__() + + +class Word(Fragment): + """ + Single word in the sentence tree. + + Construct with a string as argument. + """ + + def expand(self): + """ + Creates one sentence that contains exactly that word. + + Returns: + List<List<str>>: A list with the given string as sentence + (= token/string list) + """ + return [[self._tree]] + + +class Sentence(Fragment): + """ + A Sentence made of several concatenations/words. + + Construct with a List<Fragment> as argument. + """ + + def expand(self): + """ + Creates a combination of all sub-sentences. + + Returns: + List<List<str>>: A list with all subsentence expansions combined in + every possible way + """ + old_expanded = [[]] + for sub in self._tree: + sub_expanded = sub.expand() + new_expanded = [] + while len(old_expanded) > 0: + sentence = old_expanded.pop() + for new in sub_expanded: + new_expanded.append(sentence + new) + old_expanded = new_expanded + return old_expanded + + +class Options(Fragment): + """ + A Combination of possible sub-sentences. + + Construct with List<Fragment> as argument. + """ + + def expand(self): + """ + Returns all of its options as seperated sub-sentences. + + Returns: + List<List<str>>: A list containing the sentences created by all + expansions of its sub-sentences + """ + options = [] + for option in self._tree: + options.extend(option.expand()) + return options + + +class SentenceTreeParser(object): + """ + Generate sentence token trees from a list of tokens + ['1', '(', '2', '|', '3, ')'] -> [['1', '2'], ['1', '3']] + """ + + def __init__(self, tokens): + self.tokens = tokens + + def _parse(self): + """ + Generate sentence token trees + ['1', '(', '2', '|', '3, ')'] -> ['1', ['2', '3']] + """ + self._current_position = 0 + return self._parse_expr() + + def _parse_expr(self): + """ + Generate sentence token trees from the current position to + the next closing parentheses / end of the list and return it + ['1', '(', '2', '|', '3, ')'] -> ['1', [['2'], ['3']]] + ['2', '|', '3'] -> [['2'], ['3']] + """ + # List of all generated sentences + sentence_list = [] + # Currently active sentence + cur_sentence = [] + sentence_list.append(Sentence(cur_sentence)) + # Determine which form the current expression has + while self._current_position < len(self.tokens): + cur = self.tokens[self._current_position] + self._current_position += 1 + if cur == '(': + # Parse the subexpression + subexpr = self._parse_expr() + # Check if the subexpression only has one branch + # -> If so, append "(" and ")" and add it as is + normal_brackets = False + if len(subexpr.tree()) == 1: + normal_brackets = True + cur_sentence.append(Word('(')) + # add it to the sentence + cur_sentence.append(subexpr) + if normal_brackets: + cur_sentence.append(Word(')')) + elif cur == '|': + # Begin parsing a new sentence + cur_sentence = [] + sentence_list.append(Sentence(cur_sentence)) + elif cur == ')': + # End parsing the current subexpression + break + # TODO anything special about {sth}? + else: + cur_sentence.append(Word(cur)) + return Options(sentence_list) + + def _expand_tree(self, tree): + """ + Expand a list of sub sentences to all combinated sentences. + ['1', ['2', '3']] -> [['1', '2'], ['1', '3']] + """ + return tree.expand() + + def expand_parentheses(self): + tree = self._parse() + return self._expand_tree(tree) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/entity_edge.py new/padatious-0.4.3/padatious/entity_edge.py --- old/padatious-0.4.0/padatious/entity_edge.py 2018-01-02 03:51:45.000000000 +0100 +++ new/padatious-0.4.3/padatious/entity_edge.py 2018-06-19 18:12:33.000000000 +0200 @@ -74,7 +74,8 @@ def load(self, prefix): prefix += '.' + {-1: 'l', +1: 'r'}[self.dir] self.net = fann.neural_net() - self.net.create_from_file(str(prefix + '.net')) # Must have str() + if not self.net.create_from_file(str(prefix + '.net')): # Must have str() + raise FileNotFoundError(str(prefix + '.net')) self.ids.load(prefix) def train(self, train_data): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/intent_container.py new/padatious-0.4.3/padatious/intent_container.py --- old/padatious-0.4.0/padatious/intent_container.py 2018-02-16 07:32:53.000000000 +0100 +++ new/padatious-0.4.3/padatious/intent_container.py 2018-06-19 18:12:33.000000000 +0200 @@ -11,6 +11,8 @@ # 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. +import padaos + from padatious.entity import Entity from padatious.entity_manager import EntityManager from padatious.intent_manager import IntentManager @@ -26,8 +28,9 @@ def __init__(self, cache_dir): self.intents = IntentManager(cache_dir) self.entities = EntityManager(cache_dir) + self.padaos = padaos.IntentContainer() - def add_intent(self, *args, **kwargs): + def add_intent(self, name, lines, reload_cache=False): """ Creates a new intent, optionally checking the cache first @@ -36,9 +39,10 @@ lines (list<str>): All the sentences that should activate the intent reload_cache: Whether to ignore cached intent if exists """ - self.intents.add(*args, **kwargs) + self.intents.add(name, lines, reload_cache) + self.padaos.add_intent(name, lines) - def add_entity(self, name, *args, **kwargs): + def add_entity(self, name, lines, reload_cache=False): """ Adds an entity that matches the given lines. @@ -52,9 +56,10 @@ reload_cache (bool): Whether to refresh all of cache """ Entity.verify_name(name) - self.entities.add(Entity.wrap_name(name), *args, **kwargs) + self.entities.add(Entity.wrap_name(name), lines, reload_cache) + self.padaos.add_entity(name, lines) - def load_entity(self, name, *args, **kwargs): + def load_entity(self, name, file_name, reload_cache=False): """ Loads an entity, optionally checking the cache first @@ -64,13 +69,15 @@ reload_cache (bool): Whether to refresh all of cache """ Entity.verify_name(name) - self.entities.load(Entity.wrap_name(name), *args, **kwargs) + self.entities.load(Entity.wrap_name(name), file_name, reload_cache) + with open(file_name) as f: + self.padaos.add_entity(name, f.read().split('\n')) def load_file(self, *args, **kwargs): """Legacy. Use load_intent instead""" self.load_intent(*args, **kwargs) - def load_intent(self, *args, **kwargs): + def load_intent(self, name, file_name, reload_cache=False): """ Loads an intent, optionally checking the cache first @@ -79,15 +86,19 @@ file_name (str): The location of the intent file reload_cache (bool): Whether to refresh all of cache """ - self.intents.load(*args, **kwargs) + self.intents.load(name, file_name, reload_cache) + with open(file_name) as f: + self.padaos.add_intent(name, f.read().split('\n')) def remove_intent(self, name): """Unload an intent""" self.intents.remove(name) + self.padaos.remove_intent(name) def remove_entity(self, name): """Unload an entity""" self.entities.remove(name) + self.padaos.remove_entity(name) def train(self, *args, **kwargs): """ @@ -103,6 +114,7 @@ self.intents.train(*args, **kwargs) self.entities.train(*args, **kwargs) self.entities.calc_ent_dict() + self.padaos.compile() def calc_intents(self, query): """ @@ -115,7 +127,15 @@ list<MatchData>: List of intent matches See calc_intent() for a description of the returned MatchData """ - return self.intents.calc_intents(query, self.entities) + intents = { + i.name: i for i in self.intents.calc_intents(query, self.entities) + } + for perfect_match in self.padaos.calc_intents(query): + intent = intents.get(perfect_match['name']) + if intent: + intent.conf = 1.0 + intent.matches = perfect_match['entities'] + return list(intents.values()) def calc_intent(self, query): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/simple_intent.py new/padatious-0.4.3/padatious/simple_intent.py --- old/padatious-0.4.0/padatious/simple_intent.py 2018-01-22 22:19:43.000000000 +0100 +++ new/padatious-0.4.3/padatious/simple_intent.py 2018-06-19 18:12:33.000000000 +0200 @@ -95,7 +95,6 @@ pollute(sent, 0) pollute(sent, len(sent)) - for sent in train_data.other_sents(self.name): add(sent, 0.0) add([], 0.0) @@ -122,6 +121,7 @@ prefix += '.intent' self = cls(name) self.net = fann.neural_net() - self.net.create_from_file(str(prefix + '.net')) # Must have str() + if not self.net.create_from_file(str(prefix + '.net')): # Must have str() + raise FileNotFoundError(str(prefix + '.net')) self.ids.load(prefix) return self diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/training_manager.py new/padatious-0.4.3/padatious/training_manager.py --- old/padatious-0.4.0/padatious/training_manager.py 2018-02-16 07:30:50.000000000 +0100 +++ new/padatious-0.4.3/padatious/training_manager.py 2018-06-19 18:12:33.000000000 +0200 @@ -11,8 +11,9 @@ # 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. - import multiprocessing as mp +from functools import partial +from multiprocessing.context import TimeoutError from os import mkdir from os.path import join, isfile, isdir, splitext @@ -68,31 +69,33 @@ self.objects_to_train = [i for i in self.objects_to_train if i.name != name] self.train_data.remove_lines(name) - def train(self, debug=True, single_thread=False): + def train(self, debug=True, single_thread=False, timeout=20): if not isdir(self.cache): mkdir(self.cache) - def args(i): - return i, self.cache, self.train_data, debug + train = partial( + _train_and_save, cache=self.cache, data=self.train_data, print_updates=debug + ) if single_thread: for i in self.objects_to_train: - _train_and_save(*args(i)) + train(i) else: # Train in multiple processes to disk pool = mp.Pool() try: - results = [ - pool.apply_async(_train_and_save, args(i)) - for i in self.objects_to_train - ] - - for i in results: - i.get() + pool.map_async(train, self.objects_to_train).get(timeout) + except TimeoutError: + if debug: + print('Some objects timed out while training') finally: pool.close() # Load saved objects from disk for obj in self.objects_to_train: - self.objects.append(self.cls.from_file(name=obj.name, folder=self.cache)) + try: + self.objects.append(self.cls.from_file(name=obj.name, folder=self.cache)) + except IOError: + if debug: + print('Took too long to train', obj.name) self.objects_to_train = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious/util.py new/padatious-0.4.3/padatious/util.py --- old/padatious-0.4.0/padatious/util.py 2018-01-02 03:51:45.000000000 +0100 +++ new/padatious-0.4.3/padatious/util.py 2018-06-19 18:12:33.000000000 +0200 @@ -13,6 +13,7 @@ # limitations under the License. from xxhash import xxh32 +from padatious.bracket_expansion import SentenceTreeParser def lines_hash(lines): @@ -88,49 +89,7 @@ Returns: list<list<str>>: Multiple possible sentences from original """ - if '(' not in sent or '|' not in sent: - return [sent] - else: - class State: # Parentheses state - IN = 0 - OUT = 1 - state = State.OUT - all_pars = {} - par_groups = [] - cur_group = [] - - remaining = [] - - for token in sent: - if state == State.IN: - if token in ')|': - par_groups.append(cur_group) - cur_group = [] - else: - cur_group.append(token) - if token == ')': - state = State.OUT - all_pars[len(remaining)] = par_groups - remaining.append('()') - par_groups = [] - elif state == State.OUT: - if token == '(': - state = State.IN - else: - remaining.append(token) - - sents = [[]] - for i, token in enumerate(remaining): - if token == '()': - for j in list(range(len(sents))): - pairs = all_pars[i] - for p in pairs[1:]: - sents.append(sents[j] + p) - sents[j] += pairs[0] - else: - for sent in sents: - sent.append(token) - return sents + return SentenceTreeParser(sent).expand_parentheses() def remove_comments(lines): @@ -169,4 +128,5 @@ """Enum with strings as keys. Implements items method""" @classmethod def values(cls): - return [getattr(cls, i) for i in dir(cls) if not i.startswith("__") and i != 'values'] + return [getattr(cls, i) for i in dir(cls) + if not i.startswith("__") and i != 'values'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious.egg-info/PKG-INFO new/padatious-0.4.3/padatious.egg-info/PKG-INFO --- old/padatious-0.4.0/padatious.egg-info/PKG-INFO 2018-02-16 07:52:58.000000000 +0100 +++ new/padatious-0.4.3/padatious.egg-info/PKG-INFO 2018-06-19 18:16:57.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: padatious -Version: 0.4.0 +Version: 0.4.3 Summary: A neural network intent parser Home-page: http://github.com/MycroftAI/padatious Author: Matthew Scholefield Author-email: [email protected] License: Apache-2.0 -Description-Content-Type: UNKNOWN Description: UNKNOWN Keywords: intent-parser parser text text-processing Platform: UNKNOWN diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious.egg-info/SOURCES.txt new/padatious-0.4.3/padatious.egg-info/SOURCES.txt --- old/padatious-0.4.0/padatious.egg-info/SOURCES.txt 2018-02-16 07:52:58.000000000 +0100 +++ new/padatious-0.4.3/padatious.egg-info/SOURCES.txt 2018-06-19 18:16:57.000000000 +0200 @@ -1,9 +1,9 @@ MANIFEST.in -README.md requirements.txt setup.cfg setup.py padatious/__init__.py +padatious/bracket_expansion.py padatious/entity.py padatious/entity_edge.py padatious/entity_manager.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/padatious.egg-info/requires.txt new/padatious-0.4.3/padatious.egg-info/requires.txt --- old/padatious-0.4.0/padatious.egg-info/requires.txt 2018-02-16 07:52:58.000000000 +0100 +++ new/padatious-0.4.3/padatious.egg-info/requires.txt 2018-06-19 18:16:57.000000000 +0200 @@ -1,2 +1,3 @@ fann2 xxhash +padaos diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/requirements.txt new/padatious-0.4.3/requirements.txt --- old/padatious-0.4.0/requirements.txt 2018-01-02 03:51:45.000000000 +0100 +++ new/padatious-0.4.3/requirements.txt 2018-06-19 18:12:33.000000000 +0200 @@ -1,2 +1,3 @@ fann2 xxhash +padaos diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/setup.cfg new/padatious-0.4.3/setup.cfg --- old/padatious-0.4.0/setup.cfg 2018-02-16 07:52:58.000000000 +0100 +++ new/padatious-0.4.3/setup.cfg 2018-06-19 18:16:57.000000000 +0200 @@ -4,4 +4,5 @@ [egg_info] tag_build = tag_date = 0 +tag_svn_revision = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/padatious-0.4.0/setup.py new/padatious-0.4.3/setup.py --- old/padatious-0.4.0/setup.py 2018-02-16 07:51:29.000000000 +0100 +++ new/padatious-0.4.3/setup.py 2018-06-19 18:15:53.000000000 +0200 @@ -7,7 +7,7 @@ setup( name='padatious', - version='0.4.0', # Also change in padatious/__init__.py + version='0.4.3', # Also change in padatious/__init__.py description='A neural network intent parser', url='http://github.com/MycroftAI/padatious', author='Matthew Scholefield',
