Table of Contents
CPS Impress
This Python publishing module incorporates CPS Wikibase to Jupyter Notebook (WB2JN).
It performs a user defined SPARQL query with a result set filter and then generates output utilising Jinja2 templating.
This project depends on CPS Wikibase and is used by CPS Coffeebook.
CPS
CPS tools have been written for and provided by the CPS (Computational Publishing Service) as part of NFDI4Culture hosted at Wikibase4Research at TIB.
Setup
Debian
sudo apt install build-essential python3-full python3-pip mercurial hg clone https://hg.kewl.org/pub/cps_impress cd cps_impress make venv
TCSH
source ~/.venvs/cps_impress/bin/activate.csh make install rehash
BASH
source ~/.venvs/cps_impress/bin/activate make install
PyPi
This project is also packaged at PyPi
Use cps-impress as a dependency to include it.
NB The package doesn't include the CPS demos shown below.
Environment
An environment file .env is used to contain configuration data. See “dotenv” for details.
Within the root directory of the project the sub-directory configuration is as follows:
PROJECT_DIR="./Impress"
Command line interface
Two command line program exist at present and both have similar parameters.
project name
This defines the project directory within the PROJECT_DIR
template
This is the name of Jinja template to use (minus the j2 extension).
The template name can be anything preferred.
noescape
By default Jinja generates HTML and when using MARKDOWN this flag should be used to disable HTML entities in the output.
file
This is where output will be stored unless it's not given and then output will be to STDOUT.
args
Args are are list of values passed into the query method of the project.
These are to affect the purpose of the query and must be supported by the method.
Eg. CASTLE=Q68,ROOM=Q69
SPARQL
sparql --help
usage: sparql [-h] [-t TEMPLATE] [-n] [-f FILE] [-a ARGS] project
SPARQL project
positional arguments:
project project name
options:
-h, --help show this help message and exit
-t, --template TEMPLATE
template name
-n, --noescape no HTML escapes
-f, --file FILE output file else STDOUT
-a, --args ARGS arg=value,...
example: sparql project
WIKIBASE
wb --help
usage: wb [-h] [-t TEMPLATE] [-n] [-f FILE] [-a ARGS] project
Wikibase project
positional arguments:
project project name
options:
-h, --help show this help message and exit
-t, --template TEMPLATE
template name
-n, --noescape no HTML escapes
-f, --file FILE output file else STDOUT
-a, --args ARGS arg=value,...
example: wb project
Demos
The demos found in the Impress directory require a Wikibase server populated by CPS Deckenmalerei.
The demo server can be found here.
1.item 2.structures 3.schloss_solitude 4.schloss_solitude_paintings 5.qualifier DM_artworks_by_room DM_artworks_on_map DM_artworks_with_lightbox DM_section1 wikibase_item
SPARQL
Output bindings
sparql 1.item
bindings = [{'p': 'https://wikibase.kewl.org/prop/direct/P1', 'o': 'https://wikibase.kewl.org/entity/Q8'}, {'p': 'https://wikibase.kewl.org/prop/direct/P3', 'o': 'https://wikibase.kewl.org/entity/Q139'}, {'p': 'https://wikibase.kewl.org/prop/direct/P4', 'o': 'https://wikibase.kewl.org/entity/Q142'}, {'p': 'https://wikibase.kewl.org/prop/direct/P7', 'o': 'https://www.deckenmalerei.eu/fe9592b9-a451-44ff-9f4b-eabe23c8a979'}, {'p': 'https://wikibase.kewl.org/prop/P1', 'o': 'https://wikibase.kewl.org/entity/statement/Q140-A892FB78-A479-47D7-85A1-8FFD28EFB637'}, {'p': 'https://wikibase.kewl.org/prop/P3', 'o': 'https://wikibase.kewl.org/entity/statement/Q140-B2B5E01D-DAA6-45BA-B793-BA427C930B51'}, {'p': 'https://wikibase.kewl.org/prop/P4', 'o': 'https://wikibase.kewl.org/entity/statement/Q140-C05EDADD-439A-4414-9CAE-C109FE9B8656'}, {'p': 'https://wikibase.kewl.org/prop/P7', 'o': 'https://wikibase.kewl.org/entity/statement/Q140-3C848A31-9E9F-44C2-B8DC-EF8BB19CB6E1'}, {'p': 'http://schema.org/version', 'o': '363'}, {'p': 'http://schema.org/dateModified', 'o': '2025-07-11T19:21:22Z'}, {'p': 'http://schema.org/description', 'o': 'cps_deckenmalerei.db, 180'}, {'p': 'http://www.w3.org/2000/01/rdf-schema#label', 'o': 'Das Eckzimmer'}, {'p': 'http://wikiba.se/ontology#statements', 'o': '4'}, {'p': 'http://wikiba.se/ontology#sitelinks', 'o': '0'}, {'p': 'http://wikiba.se/ontology#identifiers', 'o': '0'}, {'p': 'http://wikiba.se/ontology#timestamp', 'o': '2025-07-11T19:40:11Z'}]
title = 1.item
Output HTML
sparql 1.item -t html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>1.item</title>
<link href="style.css" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
<p>p=https://wikibase.kewl.org/prop/direct/P1 o=https://wikibase.kewl.org/entity/Q8</p>
<p>p=https://wikibase.kewl.org/prop/direct/P3 o=https://wikibase.kewl.org/entity/Q139</p>
<p>p=https://wikibase.kewl.org/prop/direct/P4 o=https://wikibase.kewl.org/entity/Q142</p>
<p>p=https://wikibase.kewl.org/prop/direct/P7 o=https://www.deckenmalerei.eu/fe9592b9-a451-44ff-9f4b-eabe23c8a979</p>
<p>p=https://wikibase.kewl.org/prop/P1 o=https://wikibase.kewl.org/entity/statement/Q140-A892FB78-A479-47D7-85A1-8FFD28EFB637</p>
<p>p=https://wikibase.kewl.org/prop/P3 o=https://wikibase.kewl.org/entity/statement/Q140-B2B5E01D-DAA6-45BA-B793-BA427C930B51</p>
<p>p=https://wikibase.kewl.org/prop/P4 o=https://wikibase.kewl.org/entity/statement/Q140-C05EDADD-439A-4414-9CAE-C109FE9B8656</p>
<p>p=https://wikibase.kewl.org/prop/P7 o=https://wikibase.kewl.org/entity/statement/Q140-3C848A31-9E9F-44C2-B8DC-EF8BB19CB6E1</p>
<p>p=http://schema.org/version o=363</p>
<p>p=http://schema.org/dateModified o=2025-07-11T19:21:22Z</p>
<p>p=http://schema.org/description o=cps_deckenmalerei.db, 180</p>
<p>p=http://www.w3.org/2000/01/rdf-schema#label o=Das Eckzimmer</p>
<p>p=http://wikiba.se/ontology#statements o=4</p>
<p>p=http://wikiba.se/ontology#sitelinks o=0</p>
<p>p=http://wikiba.se/ontology#identifiers o=0</p>
<p>p=http://wikiba.se/ontology#timestamp o=2025-07-11T19:40:11Z</p>
</body>
</html>
<!--
vim: shiftwidth=4 tabstop=2 softtabstop=2 expandtab
-->
Output MARKDOWN
sparql 1.item -t md -n ### 1.item p=https://wikibase.kewl.org/prop/direct/P1 o=https://wikibase.kewl.org/entity/Q8 p=https://wikibase.kewl.org/prop/direct/P3 o=https://wikibase.kewl.org/entity/Q139 p=https://wikibase.kewl.org/prop/direct/P4 o=https://wikibase.kewl.org/entity/Q142 p=https://wikibase.kewl.org/prop/direct/P7 o=https://www.deckenmalerei.eu/fe9592b9-a451-44ff-9f4b-eabe23c8a979 p=https://wikibase.kewl.org/prop/P1 o=https://wikibase.kewl.org/entity/statement/Q140-A892FB78-A479-47D7-85A1-8FFD28EFB637 p=https://wikibase.kewl.org/prop/P3 o=https://wikibase.kewl.org/entity/statement/Q140-B2B5E01D-DAA6-45BA-B793-BA427C930B51 p=https://wikibase.kewl.org/prop/P4 o=https://wikibase.kewl.org/entity/statement/Q140-C05EDADD-439A-4414-9CAE-C109FE9B8656 p=https://wikibase.kewl.org/prop/P7 o=https://wikibase.kewl.org/entity/statement/Q140-3C848A31-9E9F-44C2-B8DC-EF8BB19CB6E1 p=http://schema.org/version o=363 p=http://schema.org/dateModified o=2025-07-11T19:21:22Z p=http://schema.org/description o=cps_deckenmalerei.db, 180 p=http://www.w3.org/2000/01/rdf-schema#label o=Das Eckzimmer p=http://wikiba.se/ontology#statements o=4 p=http://wikiba.se/ontology#sitelinks o=0 p=http://wikiba.se/ontology#identifiers o=0 p=http://wikiba.se/ontology#timestamp o=2025-07-11T19:40:11Z
WIKIBASE
Output claims
wb wikibase_item -a "entity=Q11"
title = Item:Q11
pageid = 28
lastrevid = 151
type = item
id = Q11
label = Das Vorzimmer der Äbtissin
description = cps_deckenmalerei.db, 8
claims = [('wikibase-item:P1', 'Q8'), ('url:P7', 'https://www.deckenmalerei.eu/2a729a8b-ee59-4c94-bca1-bac84853c2f5'), ('url:P6', 'https://previous.bildindex.de/bilder/fmd10045420a.jpg'), ('wikibase-item:P3', 'Q10'), ('wikibase-item:P4', 'Q12')]
Output MARKDOWN
wb wikibase_item -t md -n -a "entity=Q11"
### Item:Q11
('wikibase-item:P1', 'Q8')
('url:P7', 'https://www.deckenmalerei.eu/2a729a8b-ee59-4c94-bca1-bac84853c2f5')
('url:P6', 'https://previous.bildindex.de/bilder/fmd10045420a.jpg')
('wikibase-item:P3', 'Q10')
('wikibase-item:P4', 'Q12')
Project
A project is comprised of at least two files. A query and a template.
SPARQL
The query contains two methods.
- query
- filter
The query method returns the SPARQL query to be performed and the filter method is used to perform any function on the result set.
Impress/1.item/query.py
#! /usr/bin/env python3
def main():
pass
def query(args):
return """
# All data for one item (by Q-ID)
SELECT * WHERE {
wd:Q140 ?p ?o
}
"""
def filter(rs):
rs["title"] = "1.item"
return rs
if __name__=="__main__":
main()
# vim: shiftwidth=4 tabstop=4 softtabstop=4 expandtab
Templates use Jinja2 and will escape HTML entities by default.
Impress/1.item/html.j2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ rs["title"] }}</title>
<link href="style.css" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
{% for row in rs["bindings"] %}
<p>p={{ row['p'] }} o={{ row['o'] }}</p>
{% endfor %}
</body>
</html>
<!--
vim: shiftwidth=4 tabstop=2 softtabstop=2 expandtab
-->
Impress/1.item/md.j2
Markdown templates require the HTML escapes option to be turned off.
### {{ rs["title"] }}
{% for row in rs["bindings"] %}
p={{ row['p'] }} o={{ row['o'] }}
{% endfor %}
Notebook
Visualisation of templates can be achieved in Notebook as HTML or MARKDOWN using class methods.
SPARQL
The SPARQL object class is imported and created using the project name.
Afterwards, the object method to create output using the template is called.
HTML
# SPARQL QUERY OBJECT
from cps_impress.sparql import SPARQL
obj = SPARQL("1.item")
# HTML TEMPLATE VIEW
from IPython.display import HTML
HTML(obj.template("html"))
MARKDOWN
When displaying MARKDOWN, the two parameters are the template name and a flag to disable HTML entity escapes.
# SPARQL QUERY OBJECT
from cps_impress.sparql import SPARQL
obj = SPARQL("1.item")
# MARKDOWN TEMPLATE VIEW
from IPython.display import Markdown
Markdown(obj.template("md", False))


