Skip to content

Instantly share code, notes, and snippets.

@mbotsu
Last active December 9, 2022 00:42
Show Gist options
  • Save mbotsu/5d87dff8cf240062eda24e1af15ce92d to your computer and use it in GitHub Desktop.
Save mbotsu/5d87dff8cf240062eda24e1af15ce92d to your computer and use it in GitHub Desktop.
Pyodide with reportlab support

Reference

pyodide/pyodide#3008

pyodide 0.21.1 setup

$ git clone --depth 1 https://github.com/pyodide/pyodide.git -b 0.21.1
$ cd pyodide
$ sudo bash run_docker
$ pip install ./pyodide-build
$ cd emsdk
$ make
$ cd ..
$ sudo apt update
$ sudo apt install vim libfreetype6-dev
$ source pyodide_env.sh
$ make -C cpython
$ make

pyodide add package

edited: plist.txt

$ vi plist.txt
$ python pyodide_meta.py

edited: packages/reportlab/meta.yaml

@@ -4,6 +4,11 @@
 source:
   url: https://files.pythonhosted.org/packages/a6/d0/bdee3e8a7ba5f2dc8bacea10f4fdd1264b1dd9e53d96d318773180634a00/reportlab-3.6.11.tar.gz
   sha256: 04fc4420f0548815d0623e031c86a1f7f3f3003e699d9af7148742e2d72b024a
+  patches:
+    - patches/gt1-namecontext.patch
+build:
+  cflags: |
+    -s USE_FREETYPE=1
 test:
   imports:
     - reportlab

create patch

packages/reportlab/patches/gt1-namecontext.patch

https://gist.github.com/mbotsu/5d87dff8cf240062eda24e1af15ce92d#file-gt1-namecontext-patch

make reportlab

$ PYODIDE_PACKAGES="core,CLAPACK,Pillow,reportlab" make -C packages

run

$ python3 -m http.server

access to localhost:8000/pdf.html

https://gist.github.com/mbotsu/d5d567b7ed3d555a382aacb0da0ca732#file-pyodide_meta-py

--- a/src/rl_addons/renderPM/gt1/gt1-namecontext.c
+++ b/src/rl_addons/renderPM/gt1/gt1-namecontext.c
@@ -6,6 +6,7 @@
#if defined(_WIN32) || defined(macintosh) || defined(__APPLE__)
# include <string.h>
#endif
+#include <string.h>
/* btw, I do not know who wrote the following comment. I modified this
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script src="./pyodide.js"></script>
<script type="text/javascript">
async function main() {
let pyodide = await loadPyodide();
await pyodide.loadPackage([
"micropip", "Pillow", "reportlab"
]);
await pyodide.runPythonAsync(`
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, portrait
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
import base64
FILENAME = 'HelloWorld.pdf'
c = canvas.Canvas(FILENAME, pagesize=portrait(A4))
font_size = 20
pdfmetrics.registerFont(UnicodeCIDFont('HeiseiMin-W3'))
c.setFont('HeiseiMin-W3', font_size)
width, height = A4
c.drawCentredString(width / 2, height / 2 - font_size * 0.4, 'Hello World')
c.showPage()
c.save()
`)
const fileName = pyodide.globals.get("FILENAME")
const file = pyodide.FS.readFile(fileName, { encoding: "utf8" });
const mimeString = "application/pdf";
const blob = new Blob([file], { type: mimeString });
const htmlElement = document.getElementById("download");
htmlElement.innerText = "Download";
htmlElement.download = fileName;
htmlElement.href = window.URL.createObjectURL(blob);
}
main();
</script>
</body>
<a id="download" href="#"></a>
</html>
reportlab 3.6.11
import os
from pathlib import Path
from pyodide_build.mkpkg import make_package
import logging
import coloredlogs
logger = logging.getLogger('app')
coloredlogs.install(level='DEBUG')
def _make_package(tmpdir, package,version=None, source_fmt=None):
base_dir = Path(str(tmpdir))
meta_path = base_dir / package / "meta.yaml"
if (meta_path.exists()):
return
try:
make_package(base_dir, package, version, source_fmt)
except:
logger.warning("No wheel or sdist found for package " + package)
package_dir = "./packages"
ignore_dirs = ["pip", "greenlet"]
check_dirs = os.listdir(package_dir)
check_dirs.extend(ignore_dirs)
path = "plist.txt"
with open(path) as f:
for s_line in f:
lib_name, version = s_line.split()
package = lib_name.lower()
print(lib_name, version)
if (package in check_dirs):
continue
_make_package(package_dir, package, version)
@mbotsu
Copy link
Author

mbotsu commented Dec 9, 2022

It's great to be able to create it.
Hmm, the CORS problem is essentially different from the WHL creation.

I'm python3 -m http.server is running.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment