23

My Docker Command is:

docker run --rm wappalyzer/cli https://wappalyzer.com

When I run my python script:

#!/usr/bin/python
from subprocess import call
import json
import os
import docker

docker run --rm wappalyzer/cli "MYURL"

it says

File "t.py", line 7
    docker run --rm wappalyzer/cli "MYURL"
             ^
SyntaxError: invalid syntax

My os is ubuntu 14.04 and I am using ubuntu terminal.

1
  • 5
    Maybe you should look at os.system() or subprocess.checkoutput(), just pasting your commandline into a program, whithout even quoting it is not going to work. Commented Jul 1, 2017 at 14:36

5 Answers 5

30

As @AndyShinn says, Python is not a shell language, but you can call to docker as if you were running a shell command:

#!/usr/bin/python
import subprocess

with open("/tmp/output.log", "a") as output:
    subprocess.call("docker run --rm wappalyzer/cli https://wappalyzer.com", shell=True, stdout=output, stderr=output)

With this approach you don't need to import docker.

Sign up to request clarification or add additional context in comments.

3 Comments

Instead displaying in the terminal i need to redirect above command out put to a text file.Please can you help me to solve that.I'm new to both Ubuntu and python.
I've added the file output.
You're welcome: link
14

This isn't valid Python code. If you are just looking to run a container and passing a command as an argument, you could do something like this:

#!/usr/bin/env python
import sys
import docker

image = "wappalyzer/cli"

client = docker.from_env()
client.containers.run(image,  sys.argv[1], True)

But you should read up more about Python and running processes from Python if that is what you are after. Python is not a shell language and you can't just use shell commands inline.

Comments

11

UPDATE : 2021-03-22

We now have python-on-whales A Docker client for Python. Works on Linux, macOS, and Windows, for Python 3.7 and above.

>>> from python_on_whales import docker
>>> output = docker.run("hello-world")
>>> print(output)
Hello from Docker! This message shows that your installation appears to be 
working correctly.
>>> from python_on_whales import DockerClient
>>> docker = DockerClient(compose_files=["./my-compose-file.yml"])
>>> docker.compose.build()
>>> docker.compose.up()
...
>>> docker.compose.down()

2 Comments

The post shows "UPDATE : 2022-03-22", so it's from the future?
5

You can use a pip package named docker and use it to connect to the Docker. The difference between running a command in subProcess and this solution is the format. You can manage your images, containers, and everything a CLI is capable of.

Check it out here: https://docker-py.readthedocs.io/en/stable/

Sample:

import docker
client = docker.from_env()

client.containers.run("ubuntu", "echo hello world")

# or

client.containers.run("bfirsh/reticulate-splines", detach=True)

# you can even stream your output like this:
for line in container.logs(stream=True):
   print(line.strip())

All code samples are available at the source URL I mentioned.

Comments

3

Edge cases and parameterization of this answer follow.

It is also better to use subprocess.run over subprocess.call

import docker
import subprocess
import os
import time


def main():
    client, log_path = _set_up_environment()
    _run_docker_compose("docker-compose-with-rabbit.yaml", log_path)


def _run_docker_compose(docker_compose_name, log_path):
    bash_command = f"docker-compose -f {docker_compose_name}} up -d"
    _execute_shell_command(bash_command, log_path)


def _execute_shell_command(bash_command, log_path):
    with open(log_path, "w") as output:
        subprocess.run(
            bash_command,
            shell=True,  # pass single string to shell, let it handle.
            stdout=output,
            stderr=output
        )
    while not output.closed:
        time.sleep(0.1)
    print(f"{os.linesep} COMMAND {bash_command} LOG OUTPUT:")
    with open(log_path, "r") as output:
        for line in output:
            print(line)


def _create_docker_log_file():
    log_location, log_name = "logs", "output.log"
    log_path = os.path.join(os.getcwd(), log_location, log_name)
    os.makedirs(os.path.dirname(log_path), exist_ok=True)
    assert os.path.isdir(os.path.dirname(log_path))
    if not os.path.isfile(log_path):
        os.mknod(log_path)

    return log_location, log_name, log_path


def _set_up_environment():
    log_location, log_name, log_path = _create_docker_log_file()
    client = docker.from_env()
    return client, log_path

if __name__ == "__main__":
    main()


1 Comment

Not sure of the tradeoffs but here is one using subprocess.Popen gist.github.com/VietThan/99218291dd64ff835872b0d971acac32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.