The Linux Page

localstack error: ImportError: cannot import name requests

Localstack — services simulating the Amazon S3 environment

Today I had a need to run the localstack services to emulate Amazon S3 and get some work done.


Note that below I talk about how to get localstack run on your own. The latest, though, offers a Docker which I highly recommend (see section about the Docker install below). You have nothing to do. Download and run with docker instead of trying to get the correct version of python on a system which does not offer that exact version...

Also, since Sep 15, 2020, the library took a sharp turn in regard to all the ports it manages, Instead of opening one port per feature, it will only open 4566 now. All the features can be access through that one single port. Making things simpler for new comers, but also lots of tweaks to your existing tests for old timers...


Install from Source (not recommended)

This is a gigantic project with a ton of services. Really difficult to go through the maze if you want/have to fix something in there... (my take without having looked too deeply.)

The README.md says that you should first install:

pip install localstack

That worked, but who knows which version got installed (ah! yes, no idea, it could be a really old one?)

Then to start the services do:

localstack start

It did not sound too complicated, so I went ahead and go this error on the start command:

alexis $ localstack start
Traceback (most recent call last):
  File "/usr/local/bin/localstack", line 35, in <module>
    from localstack.utils import cli, bootstrap
  File "/home/alexis/.local/lib/python2.7/site-packages/localstack/utils/cli.py", line 4, in <module>
    from localstack.utils.bootstrap import (
  File "/home/alexis/.local/lib/python2.7/site-packages/localstack/utils/bootstrap.py", line 12, in <module>
    import pip as pip_mod
  File "/usr/lib/python2.7/dist-packages/pip/__init__.py", line 16, in <module>
    from pip.vcs import git, mercurial, subversion, bazaar  # noqa
  File "/usr/lib/python2.7/dist-packages/pip/vcs/mercurial.py", line 9, in <module>
    from pip.download import path_to_url
  File "/usr/lib/python2.7/dist-packages/pip/download.py", line 39, in <module>
    from pip._vendor import requests, six
ImportError: cannot import name requests

The fact is that for requests, we do not need the "_vendor" anymore. Oh I fixed that one and then many more complained. I was not feeling too good in digging such problems out and replacing the import commands.

So I searched on the error and finally found an issue on their github project with the answer: run localstack with docker. That will hide your own version of Python and use the version used at the time development started on localstack (so probably much older than 2.7)

Install with Docker

What's sad is that they did not change anything on their home page. The README.md is still providing the wrong info. Oh well...

The solution is to run with Docker. Something like this:

Get the source like this:

git clone git@github.com:localstack/localstack.git

Just in case you do not have it yet, install docker:

sudo apt-get install docker.io

Yeah, funny that this is ".io" in a package name. Unconventional for Debian packages.

Docker is going to run as "docker:docker" and that means the /var/run/docker.sock will not be accessible to you unless you are root or part of the "docker" group. If you are not yet part of the group, add yourself. You can edit the /etc/groups file and search for docker and add your name after the last colon. Or use the usermod command like so:

sudo usermod -a -G docker <user-name>

To make sure that you are now part of that group do this:

alexis $ groups
alexis adm docker sudo

Usually, it does not automatically add you to the group. What you have to do is log out and back in. Then docker will appear in your list of groups and now you are ready!

Now run the docker command such as:

docker run -d \
    -p "10080:80"                                        \
    -p "10443:443"                                       \
    -v /var/run/docker.sock:/var/run/docker.sock         \
    -e SERVICES=$LOCALSTACK_SERVICES                     \
    -e DEBUG=$LOCALSTACK_DEBUG                           \
    -e DATA_DIR=$LOCALSTACK_DATA_DIR                     \
    -e PORT_WEB_UI=$LOCALSTACK_PORT_WEB_UI               \
    -e LAMBDA_EXECUTOR=$LOCALSTACK_LAMBDA_EXECUTOR       \
    -e KINESIS_ERROR_PROBABILITY=$LOCALSTACK_KINESIS_ERROR_PROBABILITY   \
    -e DYNAMODB_ERROR_PROBABILITY=$LOCALSTACK_DYNAMODB_ERROR_PROBABILITY \
    -e DOCKER_HOST=unix:///var/run/docker.sock           \
    --name my_localstack                                 \
    localstack/localstack

The last parameter is the location of the localstack code. Here is assumes you run the command from the outside of the source folder.

The -p options specify the ports. Now you want to use 8080:8080 for the HTTP controller (although I was not able to connect in the Sept. 15, 2020 version). And the actualy AWS services are setup using port 4566:4566.

If you have doubts about the available ports, try the following command:

docker ps -a

and you'll see the list of ports available in your dockers like in this message:

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                                           NAMES
f96bb8d0c447        localstack/localstack:latest   "docker-entrypoint.sh"   6 hours ago         Up 2 hours          0.0.0.0:4566->4566/tcp, 4567-4597/tcp, 0.0.0.0:8055->8080/tcp   megaphone_localstack

(Sorry, you'll have to scroll horizontally quite a bit to find the list of ports.)

As we can see, the newer version (9/15/20) offers the old ports (4567 to 4597), but in reality, those do not connect to anything. The 4566 works. I tried the 8080 and could not connect even from within my VM or from my host machine.

The first time it will download the latest version of localstack (in my case it was 422Mb) before starting. It had absolutely no problem to start once downloaded.

I do not show the content of the variables because at this point I did not tweak them. I'm sure you can find documentation for them if you need more.