From 4525d446ba5400d66658e9479aaf7492518db14f Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 25 Oct 2024 11:49:22 +0200 Subject: [PATCH] Add basic files --- .gitignore | 120 ++++++++++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 7 +++ .readthedocs.yaml | 20 +++++++ LICENSE | 25 +++++++++ README.md | 80 +++++++++++++++++++++++++++ pyproject.toml | 60 ++++++++++++++++++++ 6 files changed, 312 insertions(+) create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .readthedocs.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ddeb4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,120 @@ +# Special for this repo +nogit/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Renderdoc captures +*.cap +*.rdc + +# C extensions +*.so + +# Distribution / packaging +.DS_Store +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +wheelhouse/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +docs/generated + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# VSCode project settings +.vscode + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# jetbrains idea +.idea/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..19fcd76 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.0 + hooks: + - id: ruff + args: [ --fix ] + - id: ruff-format diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..9e73a7b --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,20 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.12" + +sphinx: + configuration: docs/conf.py + fail_on_warning: true + +python: + install: + - method: pip + path: . + extra_requirements: + - docs diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ae30960 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2019-2024, Almar Klein, Korijn van Golen +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5df4ea9 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +[![CI](https://github.com/pygfx/rendercanvas/workflows/CI/badge.svg)](https://github.com/pygfx/rendercanvas/actions) +[![Documentation Status](https://readthedocs.org/projects/rendercanvas/badge/?version=stable)](https://rendercanvas.readthedocs.io) +[![PyPI version](https://badge.fury.io/py/rendercanvas.svg)](https://badge.fury.io/py/rendercanvas) + + +# rendercanvas + +One canvas API, multiple backends 🚀 + +
+ + +
+ + +## Introduction + +See how the two windows above look the same? That's the idea; they also look the +same to the code that renders to them. Yet, the GUI systems are very different +(Qt vs glfw in this case). Now that's a powerful abstraction! + + +## Purpose + +* Provide a generic canvas API to render to. +* Provide various canvas implementations: + * One that is light and easily installed (glfw). + * For various GUI libraries (e.g. qt and wx), so visuzalizations can be embedded in a GUI. + * For specific platforms (e.g. Jupyter, browser). +* Provide a simple but powerful event system with standardized event objects. +* Provide an event loop for scheduling events and draws. + +The main use-case is rendering with [wgpu](https://github.com/pygfx/wgpu-py), +but ``rendercanvas``can be used by anything that can render based on a window-id or +by producing rgba images. + + +## Installation + +``` +pip install rendercanvas +``` + +To have at least one GUI backend, we recommend: +``` +pip install rendercanvas glfw +``` + +## Usage + +Also see the [online documentation](https://rendercanvas.readthedocs.io) and the [examples](https://github.com/pygfx/rendercanvas/tree/main/examples). + +```py +# Select either the glfw, qt or jupyter backend +from rendercanvas.gui.auto import WgpuCanvas, loop + +# Visualizations can be embedded as a widget in a Qt application. +# Supported qt libs are PySide6, PyQt6, PySide2 or PyQt5. +from wgpu.gui.pyside6 import QWgpuWidget + + +# Now specify what the canvas should do on a draw +TODO + +``` + + +## License + +This code is distributed under the 2-clause BSD license. + + +## Developers + +* Clone the repo. +* Install `rendercanvas` and developer deps using `pip install -e .[dev]`. +* Use `ruff format` to apply autoformatting. +* Use `ruff check` to check for linting errors. +* Optionally, if you install [pre-commit](https://github.com/pre-commit/pre-commit/) hooks with `pre-commit install`, lint fixes and formatting will be automatically applied on `git commit`. +* Use `pytest tests` to run the tests. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..776cc0e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,60 @@ +# ===== Project info + +[project] +dynamic = ["version"] +name = "rendercanvas" +description = "One canvas API, multiple backends" +readme = "README.md" +license = { file = "LICENSE" } +authors = [{ name = "Almar Klein" }, { name = "Korijn van Golen" }] +keywords = [ + "canvas", + "rendering", + "graphics", + "wgpu", + "qt", + "wx", + "glfw", + "jupyter", +] +requires-python = ">= 3.9" +dependencies = [] # no dependencies! +[project.optional-dependencies] +# For users +jupyter = ["jupyter_rfb>=0.4.2"] +glfw = ["glfw>=1.9"] +# For devs / ci +lint = ["ruff", "pre-commit"] +examples = ["numpy", "wgpu", "glfw", "pyside6"] +docs = ["sphinx>7.2", "sphinx_rtd_theme", "sphinx-gallery"] +tests = ["pytest", "psutil", "glfw", "pyside6"] +dev = ["rendercanvas[lint,tests,examples,docs]"] + +[project.entry-points."pyinstaller40"] +hook-dirs = "rendercanvas.__pyinstaller:get_hook_dirs" +tests = "rendercanvas.__pyinstaller:get_test_dirs" + +[project.urls] +Homepage = "https://github.com/pygfx/rendercanvas" +Documentation = "https://rendercanvas.readthedocs.io" +Repository = "https://github.com/pygfx/rendercanvas" + +# ===== Building + +# Flit is great solution for simple pure-Python projects. +[build-system] +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +# ===== Tooling + +[tool.ruff] +line-length = 88 + +[tool.ruff.lint] +select = ["F", "E", "W", "N", "B", "RUF"] +ignore = [ + "E501", # Line too long + "E731", # Do not assign a `lambda` expression, use a `def` + "B007", # Loop control variable `x` not used within loop body +]