Investigate the cause when an error is thrown when python3.8 is not found when using lambda-uploader with python3.8

The beginning of the matter

I decided to add a python function that will be complicated to some extent on AWS Lambda, but since pip cannot be used on lambda, when using a function that uses an external module, ** [Sanzugawara-like sneaking work of finding the external modules used one by one from \ Python〇〇 \ Lib \ site-packages ] and zipping them together occurs. ** ** Of course, human beings are unreliable creatures, so if you try to do this kind of work manually every time, an accident will occur like the runaway blue train of a certain Britain who slammed Panjandrum and marmite **

** Will an accident happen? Accidents are caused by humans! ** ** (* In addition, this work takes a lot of time)

Therefore, I planned to improve efficiency and reduce the accident rate as much as possible by using lambda-uploader and entrusting the extraction work of external modules.

Work environment

To use lambda-uploader

・ Lambda.json → Configuration file that summarizes the outline of the lambda function to be uploaded ・ Requirements.txt → If you define an external module to be used by the created lambda function, it will refer to this file and automatically pick it up and zip it. In other words, if you create a batch that automatically generates files from pip freeze, it will automate the most risky work. ** Do not cause an accident **

・ Event.json → The content of the POST request to be thrown during the test, which may be empty when testing the GET request So this time it is unnecessary. Other reference contents etc. When there is no description, so it seems that it is not a required file.

・ 〇〇.py → It is an entry point of aws lambda

python


def lambda_handler(event, context):~

A py file that describes the processing of functions.

The procedure of lambda-uploader is roughly divided into the following three points in order based on the configuration files described above.

  1. build
  2. zip
  3. upload (to aws lambda)

Set as follows in the json file (information related to security is hidden) ...

lambda.json


{
    "name": "testFunction",
    "description": "testFunction description.",
    "region": "ap-northeast-1",
    "handler": "lambda_function.lambda_handler",
    "role": "arn:aws:iam::XXXXXXXXXXXX:role/BlogenistBlogSample",
    "timeout": 30,
    "memory": 128,
    "runtime": "python3.8"← Default if not explicitly specified(Python2 which is being abandoned from the times.7)Upload with.
}

Exo Dedede Dedede

And an (unexpected) accident happened

Carn

PS C:\workspace(python)\testcode\lambda> lambda-uploader                                                                Building Package
⁉️ Unexpected error. Please report this traceback.
Uploader: 1.3.0
Botocore: 1.16.38
Boto3: 1.19.38

Traceback (most recent call last):
  File "c:\program files\python38\lib\site-packages\lambda_uploader\shell.py", line 194, in main
    _execute(args)
  File "c:\program files\python38\lib\site-packages\lambda_uploader\shell.py", line 83, in _execute
    pkg = package.build_package(pth, requirements,
  File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 51, in build_package
    pkg.build(ignore)
  File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 79, in build
    self.install_dependencies()
  File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 151, in install_dependencies
    self._build_new_virtualenv()
  File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 177, in _build_new_virtualenv
    python_exe = self._python_executable()
  File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 195, in _python_executable
    raise Exception('Unable to locate {} executable'
Exception: Unable to locate python3.8 executable

(´ ・ ω ・ `)

Exception: Unable to locate python3.8 executable

(´ ; ω ; `) Boo

In the last line, if python3.8 is not found at build time, an error will be thrown (Oh).

Try to find out the cause

That's why (I think that python.exe is there because the final execution environment python itself is on aws), and the cause investigation started.

  1. Isn't your PATH? → No problem. Check both [\ python38 ] and [\ Python38 \ Lib \ site-packages ] in the environment variable settings (or rather, since I have been using commands so far with the setting to pass PATH at the time of installation, PATH is the cause at this point That's strange)

  2. Do I have to specify a minor version as well? So I modified the json parameter to "runtime": "python 3.8.6"  →Exception: Unable to locate python3.8.6 executable (´ ・ ω ・ \ ) (´ ・ ω ・)

  3. Better yet, remove json's runtime parameter  →Exception: Unable to locate python2.7 executable (´ ・ ω ・ \ ) (´ ・ ω ・ \) (´ ・ ω ・ `) Solise Soda

  4. lambda-uploader It may be a bug of the module, so Go to git to see the latest version (** The module that is not reflected in pypi and is updated forever only on git Unexpectedly many **)  ↓ スクリーンショット 2021-01-07 112928.png  ↓ スクリーンショット 2021-01-07 113018222.png

(´ ; ω ; `) Boo

Even if I check the error contents in various ways, it does not get caught So, since there is Traceback, I go directly to the source code of lambda-uploader. If you haven't messed with the settings strangely, \ Python38 \ Lib \ site-packages \ lambda_uploader has the target code, so open the directory quickly and near the last processed part

File "c:\program files\python38\lib\site-packages\lambda_uploader\package.py", line 195, in _python_executable
    raise Exception('Unable to locate {} executable'

Investigate.

package.py


    def _python_executable(self):
        if self._pyexec is not None:
            python_exe = find_executable(self._pyexec)
            if not python_exe:
Line 195 → raise Exception('Unable to locate {} executable'
                                .format(self._pyexec))

If the processing of the find_executable function is suspicious, I will stare at it and investigate the caller.

spawn.py


def find_executable(executable, path=None):
    """Tries to find 'executable' in the directories listed in 'path'.

    A string listing directories separated by 'os.pathsep'; defaults to
    os.environ['PATH'].  Returns the complete filename or None if not found.
    """
    _, ext = os.path.splitext(executable)
    if (sys.platform == 'win32') and (ext != '.exe'):
        executable = executable + '.exe'

    if os.path.isfile(executable):
        return executable

    if path is None:
        path = os.environ.get('PATH', None)
        if path is None:
            try:
                path = os.confstr("CS_PATH")
            except (AttributeError, ValueError):
                # os.confstr() or CS_PATH is not available
                path = os.defpath
        # bpo-35755: Don't use os.defpath if the PATH environment variable is
        # set to an empty string

    # PATH='' doesn't match, whereas PATH=':' looks in the current directory
    if not path:
        return None

    paths = path.split(os.pathsep)
    for p in paths:
        f = os.path.join(p, executable)
        print(f)
        if os.path.isfile(f):
            print(f)
            # the file exists, we have a shot at spawn working
            return f
    return None

As far as I can see the above code in order, I got the environment variable, divided it (a single line string connected by a semicolon if it is as it is), attached something to the end and checked the file.

    for p in paths:
        f = os.path.join(p, executable)
        print(f)     #Print statement in case of trouble
        if os.path.isfile(f):
            # the file exists, we have a shot at spawn working
            return f

Run again.

PS C:\workspace(python)\testcode\lambda> lambda-uploader
Building Package
* ↓ is the content that was spit out by print
C:\Program Files\Python38\Scripts\python3.8.exe
C:\Program Files\Python38\python3.8.exe

・ ・ ・ Python3 at the end of other environment variables below.8.String with exe attached&Traceback

As far as I saw the above, I thought that it was not such a strange thing, but the error was that python3.8 could not be found, so when I went to the corresponding directory ... キャプチャ.PNG

(ω ・ \ ) (・ ω ・ \) (´ ・ ω ・ \ ) (´ ; ω ;) Boo

**why? ** **

Then rewrite json.

So it was because I was searching for an exe file that did not exist in the first place. for that reason,

    "runtime": "python"

If you write **, it will move. Until the build. ** ** It's obviously a strange movement, so I thought that if I moved it as it was, it would get stuck after that. As a matter of course, it failed in the upload process. The content of the exception

botocore.errorfactory.InvalidParameterValueException: An error occurred (InvalidParameterValueException) when calling the UpdateFunctionConfiguration operation: Value python at 'runtime' failed to satisfy constraint: Member must satisfy enum value set: [java8, java11, nodejs10.x, nodejs12.x, python2.7, python3.6, python3.7, python3.8, dotnetcore2.1, go1.x, ruby2.5] or be a valid ARN

Since botocore is a part that handles aws authentication, I checked Is there a package that operates aws services (it was misguided from the conclusion) botocore module In the first place, the source code of the lambda-uploader module issued a SyntaxWarning: "is" with a literal. Did you mean "=="? warning, and ** after all Can't it be used with python3.8? I tried the following that came up while thinking **.

スクリーンショット 2021-01-07 165221.png

PS C:\workspace(python)\testcode\lambda> lambda-uploader                                                                                                                                     Building Package
Uploading Package
Fin

Even if I checked on aws lambda, I was able to upload normally. I'm sorry that the solution wasn't very refreshing.

However, what kind of flow does python〇〇.exe come in? (I was wondering if vitalenv would refer to python〇〇.exe that was generated by interrupting earlier, but even if I looked at the contents, it was referenced before virtualenv.)

If anyone knows the cause, please point it out in the comments.

Conclusion

** The great thing about python is that you can directly rewrite the module that has been PIPed, debug it, and check its operation. (Don't forget to put it back when you're done) **

Also, lambda-uploader hasn't been updated for nearly 3 years, and existing code is starting to have trouble due to recent changes in python specifications, so it may be better to assume that it will not be usable in the future.

Recommended Posts

Investigate the cause when an error is thrown when python3.8 is not found when using lambda-uploader with python3.8
When the Linux command $ yum -y install gives an error (yum: command not found)
I want to improve efficiency with Python even in an experimental system (4) Use ser.close () when an error is thrown using try syntax
I got an error when using Tensorboard with Pytorch
[Python] Type Error:'WebElement' object is not iterable What to do when an error occurs
There is a pattern that the program did not stop when using Python threading
Error when playing with python
[Python] Error and solution memo when using venv with pyenv + anaconda
Build Python environment on Ubuntu (when pip is not the default)
When using MeCab with virtualenv python
Precautions when using six with Python 2.5
Solution when an error occurs when hiding the console screen with PyInstaller
Workaround for the problem that? Is displayed when checking the version when using non-standard perl | python with pkg version
Dealing with key not found error in pacstrap when installing Arch Linux
How to deal with OAuth2 error when using Google APIs from Python
[Python] What to do when an error related to SSL authentication is returned
Notify using Notification Center when the execution environment is macOS in Python
Bug that says'val_loss' is not found when using Early Stopping in pytorch-lightning (0.5.3.2)
python note: when easy_install is not available
[Python] Name Error: name'urlparse' is not defined
Behind the flyer: Using Docker with Python
Note when creating an environment with python
What is the cause of the following error?
When I get an error with PyInstaller
Working with OpenStack using the Python SDK
[Python] I want to know the variables in the function when an error occurs!
I got an error when I put opencv in python3 with Raspberry Pi [Remedy]
When using PyQtGraph with Python Pyside, pay attention to the order of import
When the log acquired by rsyslog is not updated after rotation with logrotate
What to do if you get an error when installing python with pyenv
Notify slack when the switch sales page is updated ~ slack bot development with python ③ ~
To automatically send an email with an attachment using the Gmail API in Python
Try to find the probability that it is a multiple of 3 and not a multiple of 5 when one is removed from a card with natural numbers 1 to 100 using Ruby and Python.
Error when installing a module with Python pip
I got an error when saving with OpenCV
Let's write FizzBuzz with an error: Python Version
Python log is not output with docker-compose up
Rollback processing when an error occurs with fabric
Spider not found appears when crawling with Scrapy
What are you using when testing with Python?
[Python Data Frame] When the value is empty, fill it with the value of another column.
What to do if you get an OpenSSL error when installing Python 2 with pyenv
How to deal with "Type Error: No matching signature found" error when using pandas fillna
[Introduction to Python] What is the important "if __name__ =='__main__':" when dealing with modules?
I get an error when I try to raise Python to 3 series using pyenv on Catalina
Record when generating an executable file from Python code using pyinstaller on Mac (OSError: Python library not found: avoiding libpython3.7m.dylib, .Python, libpython3.7.dylib)
Addresses an issue where an error does not occur even if the path does not pass when trying to read an image with cv2.imread ()
When the selected object in bpy.context.selected_objects is not returned
Initial settings when using the foursquare API in python
Today's python error: HTTPError: 404 Client Error: Not Found for url:
Error due to conflict between python when using gurobi
Troublesome story when using Python3 with VScode on ubuntu
Check when the version does not switch with pyenv
Error when executing Python commands without using Anaconda Prompt
A memorandum when an error occurs with pip install
Python memo using perl-Dictionary type (case is not valid)
When you get an error in python scraping (requests)
When "ERROR: HTTP is not supported." Is displayed in mpsyt
Memory is not allocated when ndarray is initialized with numpy.zeros ()
python (2) requires self because the method is an instance method
When it is troublesome to set up an SMTP server locally when sending mail with Python.