pgtoolkit.service

This module supports reading, validating, editing and rendering pg_service file. See The Connection Service File in PostgreSQL documentation.

API Reference

The main entrypoint of the API is the parse() function. find() function may be useful if you need to search for pg_service.conf files in regular locations.

pgtoolkit.service.find(environ: MutableMapping[str, str] | None = None) str[source]

Find service file.

Parameters:

environ (dict) – Dict of environment variables.

find() searches for the first candidate of pg_service.conf file from either environment and regular locations. find() raises an Exception if it fails to find a Connection service file.

from pgtoolkit.service import find

try:
    servicefile = find()
except Exception as e:
    "Deal with exception."
else:
    "Manage servicefile."
pgtoolkit.service.parse(file: str | Iterable[str], source: str | None = None) ServiceFile[source]

Parse a service file.

Parameters:
  • file – a file-object as returned by open or a string corresponding to the path to a file to open and parse.

  • source – Name of the source.

Return type:

A ServiceFile object.

Actually it only requires as fo an iterable object yielding each lines of the file. You can provide source to have more precise error message.

Warning

pgtoolkit is less strict than libpq. libpq does not accepts spaces around equals. pgtoolkit accepts spaces but do not write them.

class pgtoolkit.service.Service(name: str, parameters: dict[str, str | int] | None = None, **extra: str | int)[source]

Service definition.

The Service class represents a single service definition in a Service file. It’s actually a dictionnary of its own parameters.

The name attributes is mapped to the section name of the service in the Service file.

Each parameters can be accessed either as a dictionnary entry or as an attributes.

>>> myservice = Service('myservice', {'dbname': 'mydb'}, host='myhost')
>>> myservice.name
'myservice'
>>> myservice.dbname
'mydb'
>>> myservice['dbname']
'mydb'
>>> myservice.user = 'myuser'
>>> list(sorted(myservice.items()))
[('dbname', 'mydb'), ('host', 'myhost'), ('user', 'myuser')]
class pgtoolkit.service.ServiceFile[source]

Service file representation, parsing and rendering.

ServiceFile is subscriptable. You can access service using servicefile['servicename'] syntax.

add(service: Service) None[source]

Adds a Service object to the service file.

parse(fo: Iterable[str], source: str | None = None) None[source]

Add service from a service file.

This method is strictly the same as parse(). It’s the method counterpart.

save(fo: IO[str] | None = None) None[source]

Writes services in fo file-like object.

Parameters:

fo – a file-like object. Is not required if path is set.

Note

Comments are not preserved.

path

Path to a file. Is automatically set when calling parse() with a path to a file. save() will write to this file if set.

Edit a service file

from pgtoolkit.service import parse, Service

servicefilename = 'my_service.conf'
with open(servicefile) as fo:
    servicefile = parse(fo, source=servicefilename)

myservice = servicefile['myservice']
myservice.host = 'newhost'
# Update service file
servicefile.add(myservice)

newservice = Service(name='newservice', host='otherhost')
servicefile.add(newservice)

with open(servicefile, 'w') as fo:
    servicefile.save(fo)

Shorter version using the file directly in parse:

servicefile = parse('my_service.conf')
[...]
servicefile.save()

Load a service file to connect with psycopg2

Actually, psycopg2 already support pgservice file. This is just a showcase.

from pgtoolkit.service import find, parse
from psycopg2 import connect

servicefilename = find()
with open(servicefile) as fo:
    servicefile = parse(fo, source=servicefilename)
connection = connect(**servicefile['myservice'])

Using as a script

pgtoolkit.service is usable as a CLI script. It accepts a service file path as first argument, read it, validate it and re-render it, loosing comments.

ServiceFile is less strict than libpq. Spaces are accepted around =. The output conform strictly to libpq parser.

$ python -m pgtoolkit.service data/pg_service.conf
[mydb]
host=somehost
port=5433
user=admin

[my ini-style]
host=otherhost