Skip to content

Commit

Permalink
feat: cli & export to pdf
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverlambson committed Aug 31, 2024
1 parent 755dd1f commit 3e15ab5
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ __pycache__
node_modules/

boredcharts/static/plotlyjs.min.js
*.pdf
60 changes: 60 additions & 0 deletions bored-charts/boredcharts/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import argparse
from pathlib import Path


def init() -> None:
"""create a new project scaffolding"""
raise NotImplementedError


def list_() -> None:
"""list available reports"""
raise NotImplementedError


def export(report: str) -> None:
"""write to pdf"""
import asyncio

from boredcharts.pdf import print_to_pdf

url = f"http://localhost:4000/{report}" # TODO: spin up server & fill dynamically
asyncio.run(print_to_pdf(url, Path(report).with_suffix(".pdf")))
print(f"Exported {report} to {report}.pdf")


def dev() -> None:
"""run uvicorn with reload"""
raise NotImplementedError


def serve() -> None:
"""run uvicorn without reload"""
raise NotImplementedError


def main() -> None:
parser = argparse.ArgumentParser(description="boredcharts CLI")
subparsers = parser.add_subparsers(dest="command")
subparsers.required = True

parser_init = subparsers.add_parser("init", help="Create a new project scaffolding")
parser_init.set_defaults(func=init)

parser_init = subparsers.add_parser("list", help="List available reports")
parser_init.set_defaults(func=list_)

parser_export = subparsers.add_parser("export", help="Write to PDF")
parser_export.add_argument("report", type=str, help="The report to export")
parser_export.set_defaults(func=export)

parser_dev = subparsers.add_parser("dev", help="Run uvicorn with reload")
parser_dev.set_defaults(func=dev)

parser_serve = subparsers.add_parser("serve", help="Run uvicorn without reload")
parser_serve.set_defaults(func=serve)

args = parser.parse_args()

func_args = {k: v for k, v in vars(args).items() if k != "func" and k != "command"}
args.func(**func_args)
21 changes: 21 additions & 0 deletions bored-charts/boredcharts/pdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from pathlib import Path

from playwright.async_api import async_playwright


async def print_to_pdf(url: str, file: Path) -> Path:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()

await page.goto(url, wait_until="networkidle")
await page.pdf(
path=file,
format="A4",
print_background=True,
margin={"top": "1cm", "right": "1cm", "bottom": "1cm", "left": "1cm"},
)
await browser.close()

return file
4 changes: 4 additions & 0 deletions bored-charts/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies = [
"plotly>=5.23.0",
"altair>=5.4.0",
"seaborn>=0.13.2",
"playwright>=1.46.0",
]
readme = "README.md"
license = "MIT"
Expand Down Expand Up @@ -47,6 +48,9 @@ classifiers = [
Repository = "https://github.com/oliverlambson/bored-charts.git"
Issues = "https://github.com/oliverlambson/bored-charts/issues"

[project.scripts]
boredcharts = "boredcharts.cli:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Expand Down
51 changes: 50 additions & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3e15ab5

Please sign in to comment.