Python - Practical Handbook, Quick reference guide

Logo

A Python quick reference guide, to be completed over time : json data, program arguments (argparse), ini files (configparser), yaml files (PyYAML), HTTP requests (packages requests and httplib2)…

JSON

import json

loads : loading JSON data from a string variable

response_json='{"a":1, "b":2}'
json_data = json.loads(response_json)

for key in json_data:
	print("key : %s, value: %s" % (key,json_data[key]))

load : loading JSON data from a file

with open('json-data.json', 'r') as f:
    json_data = json.load(f)

Handling malformed data

with open('json-data.json') as f:
	try:
		json_data = json.load(f)
	except Exception as e:
		print("Exception raised | %s " % str(e))
		exit()

dumps : returning a JSON string from a dictionary

response = {}
response["url"] = "sqlpac.com"
response["ostypes"] = ["mac","win"]
response["isactive"] = True

json_string = json.dumps(response)
{"url": "sqlpac.com", "ostypes": ["mac", "win"], "isactive": true}

dump : writing JSON data to a file from a dictionary

with open('response.json', 'w') as f:
 json.dump(response,f,indent=4, ensure_ascii=False, sort_keys=False )
{
    "url": "sqlpac.com",
    "ostypes": [
        "mac",
        "win"
    ],
    "isactive": true
}

Options indent, ensure_ascii, sort_keys are also available in the method dumps.

argparse (parsing arguments)

import argparse
p = argparse.ArgumentParser()
              
p.add_argument('-a','--address', help='URL', required=True)
p.add_argument("-j","--jsonauth",
					help="JSON Authentication file path",
					default="/home/sqlpac/auth.json",
					dest="jfile")
p.add_argument("-y","--year",
                      type=int,
                      default=2020,
                      help="Year")
p.add_argument("-v","--verbosity",
                      help="Verbosity",
                      action="store_true")

args = p.parse_args()
              
print(args.year)
print(args.jfile)
…

Multiple values : nargs n | *

p.add_argument('-a','--address',nargs='*',help='URLs',required=True)

Values are then stored in a list object :

print(args.address)['url1.html', 'url2.html']

Inheriting from existing parsers to avoid code redundancy :

    p1 = argparse.ArgumentParser(add_help=False)
    p1.add_argument("-a", "--address", nargs='*',
                    help="URLs to be checked")
 
    p2 = argparse.ArgumentParser(add_help=False)
    p2.add_argument("-j", "--jsonauth",
                    default="/home/sqlpac/auth.json",
                    help="JSON Authentication file path")
   
    child = argparse.ArgumentParser(parents=[p1,p2],add_help=True)
    child.add_argument("-y","--year",
                      type=int,
                      default=2020,
                      help="Year")

In parent parsers, add_help is set to False to avoid conflicts on option -h, --help.

Getting program name :

print(p.prog)demoarg.py

INI files (configparser)

sqlpac.ini :

[general]
dir=/home/sqlpac
logdir = ${dir}/logs
debug=false
              
[debug]
logdir = ${general:logdir}/debug
log=debug.log

read : reading an ini file

import configparser

cfg = configparser.ConfigParser()
cfg.read('sqlpac.ini')

sections : getting sections

sec = cfg.sections()
print(sec)
['general', 'debug']

Config object does not guess data types, string datatype is applied. Conversion must be performed :

vdebug = cfg['general'].getboolean('debug', False)

In the example above, extended interpolation is needed for variables evaluations (cross sections) :

import configparser
from configparser import ExtendedInterpolation

cfg = configparser.ConfigParser(interpolation=ExtendedInterpolation())
cfg.read('sqlpac.ini')

print(cfg['debug']['logdir'])
/home/sqlpac/logs/debug

Modifying delimiters and prefix comments :

cfg = configparser.ConfigParser( delimiters=('=', ':', '~'),
                                 comment_prefixes=('#', ';', '@') )

write : writing an ini file

import configparser
config = configparser.ConfigParser()

config.add_section('general');
config.set('general','dir','/home/sqlpac')

with open('sqlpac.ini', 'w') as cfgfile:
  config.write(cfgfile)

YAML files

sqlpac.yaml :

general:
  dir: /home/sqlpac
  logdir: /home/sqlpac/logs
  debug: false

Package PyYAML must be installed.

load : reading a YAML file

import yaml

with open("sqlpac.yaml", "r") as ymlfile:
    cfg = yaml.load(ymlfile, Loader=yaml.FullLoader)

The appropriate data types are applied compared to configparser

print(type(cfg['general']['debug']))
<class 'bool'>

The data type is forced in the YAML file :

general:
  version: !!str 5.8

dump : writing a YAML file

import yaml
cfgyaml = {}

cfgyaml["general"] = {}
cfgyaml["general"]["dir"] = "/home/sqlpac"

with open("sqlpac.yaml", "w") as f:
	yaml.dump(cfgyaml, f, sort_keys=False)

sort_keys is available starting PyYAML v 5.1, by default keys are ordered.

Variables are not possible with YAML files compared to configparser, however sub sections are allowed.

requests

get : a simple GET request

import requests

r = requests.get('https://www.sqlpac.com/rpc.php')
  • Status : r.status_code
  • Headers : r.headers
  • Results : r.text

json : a JSON decoder is integrated in the package requests

json_data = r.json()

Sending GET parameters

q = { 'name': 'Doe', 'year': 2006 }
r = requests.get('https://www.sqlpac.com/rpc.php', params=q)

post : sending POST parameters :

d = { 'name': 'Doe', 'year': 2006 }
r = requests.post('https://www.sqlpac.com/rpc.php', data=d)

Uploading files using POST method :

d = { 'name': 'Doe', 'year': 2006 }
f = {'file': open('1.txt', 'rb'), 'file': open('2.txt', 'rb')}
r = requests.post('https://www.sqlpac.com/rpc.php', data=d, files=f)

Use verify=False to disable SSL certificate validation :

r = requests.get('https://www.sqlpac.com/rpc.php', params=q,
                  verify=False)

Basic authentication :

import requests
from requests.auth import HTTPBasicAuth

r = requests.get('https://www.sqlpac.com/rpc.php',
                 auth=HTTPBasicAuth('<user>', '<password>'))

httplib2

request : a simple GET request

import httplib2

http = httplib2.Http()
(headers,content) = http.request("https://www.sqlpac.com/rpc.php",
                                 method="GET")
  • Status : headers.status
  • Headers : headers
  • Results : content

A JSON decoder is not integrated, package json is used :

import httplib2
import json

http = httplib2.Http()
(headers,content)= http.request("https://www.sqlpac.com/rpc.php",
                                 method="GET")

if (headers.status==200):
  json_data = json.loads(content)

Sending GET parameters (package urllib)

import httplib2
from urllib.parse import urlencode

q = { "name": "Doe", "year": 2006 }
p = urlencode(q)

http = httplib2.Http()
(headers,content)= http.request("https://www.sqlpac.com/rpc.php?" + p,
                                    method="GET")

Sending POST parameters :

import httplib2
from urllib.parse import urlencode

d = { 'name': 'Doe', 'year': 2006 }

http = httplib2.Http()
(headers,content)= http.request("https://www.sqlpac.com/rpc.php",
						method="POST",
						headers={'Content-type': 'application/x-www-form-urlencoded'},
						body=urlencode(d)
								  )

To disable SSL certificate validation :

http = httplib2.Http()
http.disable_ssl_certificate_validation=True

Basic authentication :

http = httplib2.Http()
http.add_credentials('<user>','<password>')