Development & Testing¶
Setup¶
git clone https://github.com/TimurSeyidov/jodit-python
cd jodit-python
make sync # uv sync --all-groups
make menu # interactive list of every command
Or open the folder in VS Code (or another IDE with Dev Containers) and choose Reopen in Container; everything below works inside.
All caches (uv, ruff, mypy, pytest, coverage, bytecode) live in .cache/. On macOS the Makefile points WeasyPrint to Homebrew's libraries (DYLD_FALLBACK_LIBRARY_PATH); export it yourself when running uv run ... directly.
Commands¶
| Command | What it does |
|---|---|
make run / make dev |
Serve on port 8081 / with auto-reload |
make lint / make lint-fix |
ruff check |
make format / make format-check |
ruff format |
make typecheck |
mypy --strict over src, tests, scripts, examples |
make test / make coverage |
pytest / with branch coverage (fails under 90%) |
make openapi / make openapi-check |
Regenerate / verify docs/content/api-swagger/openapi.{json,yaml} |
make docs / make docs-build |
Serve / build this site (--strict) |
make check |
Everything CI runs |
Code style: 79-character lines, Google-style docstrings stating what a function does and its contract (Args, Returns, Raises).
Tests¶
tests/
├── unit/ # helpers, config, ACL, storage, SSRF guard, ...
├── integration/ # HTTP requests through the ASGI app
├── fixtures/ # expected values generated from the npm packages
└── conftest.py # app/client factories, temporary sources
- Requests go through the real application in-process (
httpx.ASGITransport), with sources intmp_path. - Client-visible formats (bracket parameters, sizes, dates, safe names, slugs, paths, sort order, the SVG icon...) are checked against reference fixtures; the generators are in
scripts/fixtures/. - S3 tests run against MinIO in Docker (Testcontainers) and are skipped when no Docker daemon is reachable; unit tests of the adapter use botocore's
Stubber. - Unclosed files and sockets fail the test that leaks them (
ResourceWarningis an error). - Every program in
examples/is imported and exercised.
Writing a test¶
from typing import TYPE_CHECKING
from tests.conftest import source_config, write_file
if TYPE_CHECKING:
from pathlib import Path
from tests.conftest import ClientFactory
async def test_lists_uploaded_file(
connector_client: ClientFactory, tmp_path: Path
) -> None:
write_file(tmp_path, "a.txt", "hello")
async with connector_client(source_config(tmp_path)) as http:
response = await http.get("/files", params={"source": "test"})
(source,) = response.json()["data"]["sources"]
assert [item["file"] for item in source["files"]] == ["a.txt"]
Documentation¶
The site is built with MkDocs Material from docs/:
Continuous integration¶
| Workflow | Runs on | Does |
|---|---|---|
ci.yml |
pushes to main, pull requests |
lint, format check, mypy, OpenAPI check, documentation build, tests with coverage (uploaded to Codecov), production image build and /ping smoke test |
ci.yml (core job) |
pushes to main, pull requests |
installs the package without extras and checks that it imports, serves files and answers 501 for PDF, DOCX and S3 (scripts/check_core_install.py) |
docs.yml |
pushes to main |
builds this site and publishes it to GitHub Pages |
release.yml |
tags v* |
runs the whole CI, checks the tag against the version, builds the package, publishes it to PyPI and the image to Docker Hub (linux/amd64, linux/arm64), creates the GitHub release |
dockerhub-description.yml |
README changes on main, manual run |
copies README.md to the Docker Hub repository page |
Releasing¶
One-time setup:
- PyPI → Account settings → Publishing → Add a pending publisher: project
jodit-python, ownerTimurSeyidov, repositoryjodit-python, workflowrelease.yml, environmentpypi. - GitHub → Settings → Environments → create
pypi. - Docker Hub → Account settings → Personal access tokens: a token with Read, Write, Delete access (Delete is required to update the repository description). GitHub → Settings → Secrets and variables → Actions: secrets
DOCKERHUB_USERNAME,DOCKERHUB_TOKENand the variableDOCKERHUB_IMAGE(e.g.user/jodit-python). - GitHub → Settings → Pages → Source: GitHub Actions.
- Codecov: sign in with GitHub and enable the repository (uploads use OIDC, no token needed).
Each release: