I am trying to use the Python spellchecking library Pyenchant in a Lambda function on AWS. Pyenchant is a wrapper for the C libenchant library which in turn relies on word dictionaries from providers such as Aspell.

In my python code running on Lambda I am able to successfully import the enchant library having compiled it and the C libraries (libenchant.so) on an AWS linux EC2 instance and copying the outputs to my Lambda deployment package.

However, the pyenchant library cannot load any of the word dictionaries when run on Lambda that it needs to work. I then installed Aspell on the EC2 instance using:

yum install aspell-en enchant-aspell

I then copied the following additional .so files to my deployment package's /lib folder:

  • libaspell.so
  • libenchant_aspell.so
  • libenchant_ispell.so
  • libenchant_myspell.so
  • libenchant.so

I'm pretty sure libenchant_aspell.so is the actual dictionary but it's not picking it up and I cannot figure out where to go next.

Below is my lambda_handler python code:

from __future__ import print_function
import os
import sys
import re
import enchant

enchant.set_param("enchant.aspell.dictionary.path","/var/task/lib")

def lambda_handler(event, context):

    print("# List available enchant dictionary languages")
    print(enchant.list_languages())
    b = enchant.Broker()
    print("# List available enchant brokers")
    print(b.describe())
    d = enchant.Dict("en_GB")
    # print(d.provider.name)
    # print(d.provider.file)
    return "Done"

And here is the output from invoking the Lambda function:

START RequestId: 7539245b-d3d6-11e6-b7e6-edc1dc8cbdd4 Version: $LATEST
# List available enchant dictionary languages
[]
# List available enchant brokers
[]
Dictionary for language 'en_GB' could not be found: DictNotFoundError
Traceback (most recent call last):
  File "/var/task/package_test.py", line 16, in lambda_handler
    d = enchant.Dict("en_GB")
  File "/var/task/enchant/__init__.py", line 558, in __init__
    _EnchantObject.__init__(self)
  File "/var/task/enchant/__init__.py", line 168, in __init__
    self._init_this()
  File "/var/task/enchant/__init__.py", line 565, in _init_this
    this = self._broker._request_dict_data(self.tag)
  File "/var/task/enchant/__init__.py", line 310, in _request_dict_data
    self._raise_error(eStr % (tag,),DictNotFoundError)
  File "/var/task/enchant/__init__.py", line 258, in _raise_error
    raise eclass(default)
DictNotFoundError: Dictionary for language 'en_GB' could not be found

END RequestId: 7539245b-d3d6-11e6-b7e6-edc1dc8cbdd4
REPORT RequestId: 7539245b-d3d6-11e6-b7e6-edc1dc8cbdd4  Duration: 1.03 ms   Billed Duration: 100 ms     Memory Size: 256 MB Max Memory Used: 16 MB

As you can see import enchant works fine but it cannot find any of the dictionary files.

I'm really stuck on this, have spent best part of 6 hours trying to figure out how to get this working. Thanks in advance for your help.

1

There are 1 answers

1
dataHead On

Well, for anyone else who comes across this problem (which will probably be no-one...) it turned out that it was not possible to use this package on Lambda. Something to do with not having the right infrastructure to load shared object resources several levels deep. In the end I just used a flask web server on EC2 and it worked fine.