Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/publish_testpypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# .github/workflows/publish_testpypi.yml
---
name: test-n-build
on:
push:
tags:
- v*
jobs:
super-test:
strategy:
max-parallel: 2
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python_v: ['3.8', '3.9', '3.10', '']
chrome_v: ['-1']
name: Build and Test
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- name: Install Dependencies
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get update && sudo apt-get install xvfb
timeout-minutes: 1
# must actually checkout for version determination
- run: git checkout ${{ github.ref_name }}
- run: uv python install ${{ matrix.python_v }}
- run: uv python pin ${{ matrix.python_v }}
if: ${{ matrix.python_v != '' }}
# don't modify sync file! messes up version!
- run: uv sync --no-sources --all-extras --frozen # does order matter?
- run: uv build
- name: Reinstall from wheel
run: >
uv pip install dist/choreographer-$(uv
run --no-sync --with setuptools-git-versioning
setuptools-git-versioning)-py3-none-any.whl
- run: uv run --no-sync choreo_get_chrome -v --i ${{ matrix.chrome_v }}
- name: Diagnose
run: uv run --no-sync choreo_diagnose --no-run

- name: Test mocker
run: >
uv run
--no-sources kaleido_mocker
--random 100
--logistro-level INFO

- name: Test
if: ${{ ! runner.debug && matrix.os != 'ubuntu-latest' }}
run: uv run --no-sync poe test
timeout-minutes: 8

- name: Test (Linux)
if: ${{ ! runner.debug && matrix.os == 'ubuntu-latest' }}
run: xvfb-run uv run --no-sync poe test
timeout-minutes: 8

- name: Test (Debug)
if: runner.debug
run: uv run --no-sync poe debug-test
timeout-minutes: 20

- name: Test (Debug, Linux)
if: ${{ runner.debug && matrix.os == 'ubuntu-latest' }}
run: xvfb-run uv run --no-sync poe debug-test
timeout-minutes: 8

testpypi-publish:
name: Upload release to TestPyPI
needs: super-test
if: always() && !cancelled() && !failure()
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/choreographer
# Signs this workflow so pypi trusts it
permissions:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
- run: git checkout ${{ github.ref_name }}
- run: uv sync --no-sources --frozen --all-extras
- run: uv build
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ jobs:
- name: Install dependencies
run: >
uv sync
--index-strategy=unsafe-first-match
--no-sources
--all-extras

Expand Down
1 change: 1 addition & 0 deletions src/py/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.8
2 changes: 1 addition & 1 deletion src/py/kaleido/_fig_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def build_fig_spec(fig, path, opts):
path = Path(path)

if path and path.suffix and not opts.get("format"):
opts["format"] = path.suffix.removeprefix(".")
opts["format"] = path.suffix.lstrip(".")

spec = to_spec(fig, opts)

Expand Down
10 changes: 7 additions & 3 deletions src/py/kaleido/_mocker.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,20 @@ def _get_jsons_in_paths(path: str | Path) -> list[Path]:
path = Path(path) if isinstance(path, str) else path

if path.is_dir():
return [path / a for a in path.glob("*.json")]
else:
_logger.info(f"Input is path {path}")
return list(path.glob("*.json"))
elif path.is_file():
_logger.info(f"Input is file {path}")
return [path]
else:
raise TypeError("--input must be file or directory")


def _load_figures_from_paths(paths: list[Path]):
# Set json
for path in paths:
if path.is_file():
with path.open() as file:
with path.open(encoding="utf-8") as file:
figure = orjson.loads(file.read())
_logger.info(f"Yielding {path.stem}")
yield {
Expand Down
2 changes: 1 addition & 1 deletion src/py/kaleido/_page_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, *, plotly=None, mathjax=None, others=None):
self._scripts = []
if not plotly:
try:
import plotly
import plotly # type: ignore [import-not-found]

plotly = (
(
Expand Down
8 changes: 7 additions & 1 deletion src/py/kaleido/kaleido.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
_stepper = False


async def _to_thread(func, *args, **kwargs):
_loop = asyncio.get_running_loop()
fn = partial(func, *args, **kwargs)
await _loop.run_in_executor(None, fn)


# this is kinda public but undocumented
def set_stepper():
"""
Expand Down Expand Up @@ -370,7 +376,7 @@ def write_image(binary):
file.write(binary)

_logger.info(f"Starting write of {full_path.name}")
await asyncio.to_thread(write_image, img)
await _to_thread(write_image, img)
_logger.info(f"Wrote {full_path.name}")
if profiler is not None:
self._finish_profile(profile, e, full_path.stat().st_size / 1000000)
Expand Down
21 changes: 6 additions & 15 deletions src/py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name = "kaleido"
description = "Plotly graph export library"
license = {file = "LICENSE.md"}
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.8"
dynamic = ["version"]
authors = [
{name = "Andrew Pikul", email="ajpikul@gmail.com"},
Expand All @@ -27,7 +27,7 @@ maintainers = [
]
dependencies = [
"async-timeout>=5.0.1",
"choreographer>=1.0.0",
"choreographer>=1.0.3",
"logistro>=1.0.8",
"orjson>=3.10.15",
]
Expand All @@ -46,8 +46,8 @@ dev = [
"pytest-asyncio",
"pytest-xdist",
"async-timeout",
"poethepoet>=0.31.1",
"mypy>=1.14.1",
"poethepoet>=0.30.0",
]

#docs = [
Expand All @@ -56,19 +56,10 @@ dev = [
# "mkdocs-material>=9.5.49",
#]

[[tool.uv.index]]
name = "pypi"
url = "https://pypi.org/simple/"

[[tool.uv.index]]
name = "test.pypi"
url = "https://test.pypi.org/simple/"


[tool.uv.sources]
mkquixote = { path = "../../../mkquixote", editable = true }
choreographer = { path = "../../../devtools_protocol", editable = true }
logistro = { path = "../../../logistro", editable = true }
#mkquixote = { path = "../../../mkquixote", editable = true }
#choreographer = { path = "../../../devtools_protocol", editable = true }
#logistro = { path = "../../../logistro", editable = true }

[tool.ruff.lint]
select = ["ALL"]
Expand Down
Loading