How to Integrate Python with Podman REST API

How to Integrate Python with Podman REST API

podman_restapi_python_integration

Here 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.

Test Environment

Fedora 32
Podman
Python3.8
request library
json library

You can use the below API reference 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.

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

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.

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

Step2: Query Podman REST API

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.

[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 List of Containers

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.

[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 List of Images

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.

[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: 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.

[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.

Hope you enjoyed reading this article. Thank you..