Integrate Python with Podman REST API

Integrate Python with Podman REST API

Test Environment

Fedora 32 installed
Podman installed
Python 3.8 installed
Python request library installed
Python json library installed

In this article we will see how we can use a basic Python application to trigger REST API calls using the Podman REST API service url. We will see how we can trigger either a GET or POST request with the required parameters passed along with the request to retrieve information or manage the resource from the standalone Podman system.

You can use the below API referene to get more details on the resource which we want to get details and what are the required and optional parameters that can be passed as a part of the API request.

API Reference URL – https://docs.podman.io/en/latest/_static/api.html

Github Source code – https://github.com/novicejava1/python/blob/master/simplepython/podmanPython.py

If you are interested in watching the video. Here is the youtube video on the same step by step procedure outline below in this article.

Procedure –

Step1: Start the Podman service on TCP channel

First we need to start the Podman REST API service on TCP channel port in order to consume it using the Python application. Here is the below command to start the tomcat service on a TCP channel port 8080.

Start Podman REST API service
[root@fed32 ~]# podman system service tcp:localhost:8080 --time=0 &

Step2: Import Python requests and json library to query Podman REST API url for Podman system information

Once the service is up and running we can build a python application with ‘requests’ library to communicate with the API service and ‘json’ library to convert, format and filter the response from the API service. Here in the below definition ‘podmanInfo’ we are trying to fetch the Podman standalone system information and try to convert the response to JSON format and filter particular JSON fields of interest.

Retrieve Podman standalone system information using API call
[root@fed32 Python]# cat podmanPython.py 
#!/usr/bin/env python3

import requests
import json
import sys

def podmanInfo(podService, apiContext):
    url = service + "/" + context
    print(url)
    response = requests.get(url)
    print(type(response.text))
    jsonresponse = json.loads(response.text)
    #print(jsonresponse["host"])
    print(jsonresponse["host"]["hostname"])
    print(jsonresponse["host"]["arch"])
    print(jsonresponse["store"]["configFile"])

service = "http://localhost:8080/v1.40.0/libpod"
print(service)
#context="info"
context=sys.argv[1]
print(context)
print("Retrieve Podman System information")
podmanInfo(service, context)

[root@fed32 Python]# ./podmanPython.py info
http://localhost:8080/v1.40.0/libpod
info
Retrieve Podman System information
http://localhost:8080/v1.40.0/libpod/info
<class 'str'="">
fed32.stack.com
amd64
/etc/containers/storage.conf

Step3: Query Podman API to fetch the list of all the containers available

In this step we are trying to trigger an API call with a GET request to fetch all the available containers on our standalone podman system whether they are running or in stopped state. As you can see from the definition of ‘podmanContainers’ we are trying to iterate through the jsonresponse to retrieve the top level nodes ‘Names’ field from the JSON response data.

Retrieve Podman containers list using GET API request
[root@fed32 Python]# cat podmanPython.py
...
def podmanContainers(podmanService, apiContext):
    url = service + "/" + context
    response = requests.get(url)
    print(type(response.text))
    jsonresponse = json.loads(response.text)
    #print(jsonresponse[0]["Names"])
    #print(jsonresponse[1]["Names"])
    for eachItem in jsonresponse:
        print(eachItem["Names"])
...

[root@fed32 Python]# ./podmanPython.py containers/json?all=true
http://localhost:8080/v1.40.0/libpod
containers/json?all=true
Retrieve List of all containers
<class 'str'="">
['nginxTest']
['busyman2']
['sweet_dirac']

Step4: Query Podman API to fetch the list of all the Images available on the system

In this step we are trying to trigger an API call with a GET request to fetch all the images available on our standalone podman system. As you can see from the definition of ‘podmanImages’ we are trying to iterate through the jsonresponse to retrieve the top level nodes ‘Names’ field from the JSON response data.

Also please note the first output with two image names comma separate. The reason for that is i have one local image with name ‘localhost/hello:1.0’ from which i created another image with tag name ‘docker.io/novicejava1/hello:1.0’ to push to the remote repository. Both these image tags are from the same image id.

Retrieve Podman images list using GET API request
[root@fed32 Python]# cat podmanPython.py
...
def podmanImages(podmanService, apiContext):
    url = service + "/" + context
    response = requests.get(url)
    print(type(response.text))
    jsonresponse = json.loads(response.text)
    #print(jsonresponse[0]["Names"])
    #print(jsonresponse[1]["Names"])
    for eachItem in jsonresponse:
        print(eachItem["Names"])
...

[root@fed32 Python]# ./podmanPython.py images/json
http://localhost:8080/v1.40.0/libpod
images/json
Retrieve List of all images
<class 'str'="">
['localhost/hello:1.0', 'docker.io/novicejava1/hello:1.0']
['docker.io/library/busybox:latest']
['docker.io/library/nginx:latest']

Step5: Query Podman API to Pull the image from registry

Until now we have see how we can trigger a GET request. In this step we will try to pull an image from the docker.io registry but for this request we need to post data related to the image name which we want to pull along with the request. Hence we are going to use the POST request to send our reference parameter with image name that we want to pull as shown in the below ‘podmanPullImage’ definition.

Pull image from docker.io registry using POST API request
[root@fed32 Python]# cat podmanPython.py 
...
def podmanPullImage(podmanService, apiContext):
    url = service + "/" + context
    print(url)
    headers = {'Content-type': 'application/json'}
    payload = {'reference':'docker.io/library/mongo'}
    #response = requests.post(url, data = jsonpayload)
    #response = requests.post(url, headers=headers, json={'reference': 'mongo'})
    response = requests.request("POST", url, headers=headers, params=payload)
    print(response)
    print(response.text)
...

[root@fed32 Python]# ./podmanPython.py images/pull
http://localhost:8080/v1.40.0/libpod
images/pull
Retrieve images from registry
http://localhost:8080/v1.40.0/libpod/images/pull

{"stream":"Trying to pull docker.io/library/mongo...n"}
{"stream":"Getting image source signaturesn"}
{"stream":"Copying blob sha256:3cf8fb62ba5ffb221a2edb2208741346eb4d2d99a174138e4afbb69ce1fd9966n"}
{"stream":"Copying blob sha256:e80c964ece6a3edf0db1cfc72ae0e6f0699fb776bbfcc92b708fbb945b0b9547n"}
...
{"stream":"Copying blob sha256:f623ce2ba1e101df1c925b3c0230e28cd30b4e1940064a79a6816cb568754214n"}
{"stream":"Copying config sha256:ef5c2207766e4cfa7d009b7372f315fa67a47ea5dd5b71a15b2f829c7f7d024fn"}
{"stream":"Writing manifest to image destinationn"}
{"stream":"Storing signaturesn"}
{"images":["ef5c2207766e4cfa7d009b7372f315fa67a47ea5dd5b71a15b2f829c7f7d024f"]}
{"id":"ef5c2207766e4cfa7d009b7372f315fa67a47ea5dd5b71a15b2f829c7f7d024f"}

I have tried to show you how we can leverage the Podman API service and use it from our Python application using basic examples. You can further try to explore more on this and come up with different function for API service call to manage various resources within the Podman standalone system using the API Reference URL – https://docs.podman.io/en/latest/_static/api.html.

Hope you enjoyed reading this article. Thank you.