I might have a solution:
#!/bin/env python3
# adapted from https://pymupdf.readthedocs.io/en/latest/faq.html#how-to-insert-text
# and https://pymupdf.readthedocs.io/en/latest/faq.html#how-to-combine-single-pages
import fitz # in fact, pip install pymupdf
#from sys import argv # in a future, I might get all the parameter via command line
width, height = fitz.paper_size("A4")
r = fitz.Rect(0, 0, width, height)
doc = fitz.open("mock up.pdf")
page = doc[0]
print("input file information:")
print(doc.metadata)
print("rotation=",page.rotation)
print("cropbox=",page.cropbox)
print("mediabox=",page.mediabox)
print("rect=",page.rect)
page.set_rotation(0)
artsize=page.rect
(nx, ny) = (200,140) # position of the ticket number inside the pdf
(dx, dy) = page.mediabox_size # the displacement of the ticket inside the output pdf
ntickets=25
nrows=5 # of tickets vertically
ncols=2 # of tickets horizontally
ntickets_per_page = nrows*ncols
outpdf = fitz.open()
nrow = ncol = 0
i = 0
while i < ntickets:
if i % ntickets_per_page == 0:
#print("new page for ticket #",i)
newpage = outpdf.new_page()
nrow, ncol = 0, 0
for ncol in range(1,ncols+1):
for nrow in range(1,nrows+1):
i += 1
if i > ntickets:
break
text = "{:04d}".format(i)
locr = fitz.Rect((ncol-1)*dx,(nrow-1)*dy,ncol*dx,nrow*dy)
#print("location of the ticket:", locr)
newpage.show_pdf_page(locr,doc,0)
p = fitz.Point(nx+(ncol-1)*dx,ny+(nrow-1)*dy)
#print("location of the number for ticket ", i, ": ", p)
rc = newpage.insert_text(p, # bottom left of 1st char
text,
fontname="tibo", # Times, bold
fontsize=12,
rotate=0,
)
i -= 1
print("%i lines printed on %i tickets." % (rc, i))
outpdf.save("tmp{:04d}.pdf".format(i))