Skip to content

feat: converting documentation to mkdocs #5276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ tests/test_orca/images/linux/failed/

doc/python/raw.githubusercontent.com/

docs/

# Don't ignore dataset files
!*.csv.gz
!*.geojson.gz
Expand Down
23 changes: 13 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ then explains the technical aspects of preparing your contribution.

## Code of Conduct

Please note that all contributos are required to abide by our [Code of Conduct](CODE_OF_CONDUCT.md).
Please note that all contributos are required to abide by our Code of Conduct.

## Different Ways to Contribute

Expand All @@ -19,7 +19,7 @@ it is important to understand the structure of the code and the repository.
- The [`plotly.graph_objects`](https://plotly.com/python/graph-objects/) module (usually imported as `go`)
is [generated from the plotly.js schema](https://plotly.com/python/figure-structure/),
so changes to be made in this package need to be contributed to [plotly.js](https://github.com/plotly/plotly.js)
or to the code generation system in `./codegen/`.
or to the code generation system in `./bin/codegen/`.
Code generation creates traces and layout classes that have a direct correspondence to their JavaScript counterparts,
while higher-level methods that work on figures regardless of the current schema (e.g., `BaseFigure.for_each_trace`)
are defined in `plotly/basedatatypes.py`.
Expand All @@ -38,16 +38,17 @@ it is important to understand the structure of the code and the repository.
These are organized in subdirectories according to what they test:
see the "Setup" section below for more details.

- Documentation is found in `doc/`, and its structure is described in [its README file](doc/README.md).
- Documentation is found in `doc/`, and its structure is described in its README file.
The documentation is a great place to start contributing,
since you can add or modify examples without setting up a full environment.

Code and documentation are not the only way to contribute:
you can also help by:
Code and documentation are not the only way to contribute.
You can also help by:

- Reporting bugs at <https://github.com/plotly/plotly.py/issues>.
Please take a moment to see if your problem has already been reported, and if so, add a comment to the existing issue;
we will try to prioritize those that affect the most people.
we will try to prioritize those that affect the most people
and that are accompanied by small, runnable examples.

- Submitting feature requests (also at <https://github.com/plotly/plotly.py/issues>).
Again, please add a comment to an existing issue if the feature you want has already been requested.
Expand Down Expand Up @@ -219,11 +220,11 @@ Once you have done that,
run the `updateplotlyjs` command:

```bash
python commands.py updateplotlyjs
python bin/updatejs.py
```

This downloads new versions of `plot-schema.json` and `plotly.min.js` from the `plotly/plotly.js` GitHub repository
and places them in `plotly/package_data`.
and places them in `resources` and `plotly/package_data` respectively.
It then regenerates all of the `graph_objs` classes based on the new schema.

### Using a Development Branch of Plotly.js
Expand All @@ -232,7 +233,8 @@ If your development branch is in [the plotly.js repository](https://github.com/p
you can update to development versions of `plotly.js` with this command:

```bash
python commands.py updateplotlyjsdev --devrepo reponame --devbranch branchname
# FIXME commands.py didn't provide --devrepo or --devbranch
python bin/updatejs.py --dev --devrepo reponame --devbranch branchname
```

This fetches the `plotly.js` in the CircleCI artifact of the branch `branchname` of the repo `reponame`.
Expand All @@ -255,5 +257,6 @@ You can then run the following command
*in your local plotly.py repository*:

```bash
python commands.py updateplotlyjsdev --local /path/to/your/plotly.js/
# FIXME: commands.py didn't provide --local
python bin/updatejs.py --dev --local /path/to/your/plotly.js/
```
49 changes: 49 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Manage snailz project.

PYTHON = uv run python
CODE_DIRS = _plotly_utils plotly scripts

## commands: show available commands
commands:
@grep -h -E '^##' ${MAKEFILE_LIST} | sed -e 's/## //g' | column -t -s ':'

## docs: rebuild documentation
.PHONY: docs
docs:
${PYTHON} -m mkdocs build

## format: reformat code
format:
${PYTHON} -m ruff format ${CODE_DIRS}

## generate: generate code
generate:
${PYTHON} bin/generate_code.py --codedir plotly
${PYTHON} -m ruff format plotly

## lint: check the code
lint:
${PYTHON} -m ruff check ${CODE_DIRS}

## test: run tests
test:
${PYTHON_M} pytest tests

## updatejs: update JavaScript bundle
updatejs:
${PYTHON} bin/updatejs.py --codedir plotly

## --: --

## clean: clean up repository
clean:
@find . -name '*~' -delete
@find . -name '.DS_Store' -delete
@rm -rf .coverage
@rm -rf .pytest_cache
@rm -rf .ruff_cache
@rm -rf dist

## sync: update Python packages
sync:
uv sync --extra dev
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,21 @@ Built on top of [plotly.js](https://github.com/plotly/plotly.js), `plotly.py` is

## Installation

plotly.py may be installed using pip
plotly.py may be installed using pip:

```
pip install plotly
```

or conda.
or conda:

```
conda install -c conda-forge plotly
```

### Jupyter Widget Support

For use as a Jupyter widget, install `jupyter` and `anywidget`
packages using `pip`:
For use as a Jupyter widget, install the `jupyter` and `anywidget` packages using `pip`:

```
pip install jupyter anywidget
Expand All @@ -112,14 +111,14 @@ command line utility (legacy as of `plotly` version 4.9).

#### Kaleido

The [`kaleido`](https://github.com/plotly/Kaleido) package has no dependencies and can be installed
using pip
The [`kaleido`](https://github.com/plotly/Kaleido) package has no dependencies
and can be installed using pip:

```
pip install -U kaleido
```

or conda
or conda:

```
conda install -c conda-forge python-kaleido
Expand All @@ -129,13 +128,13 @@ conda install -c conda-forge python-kaleido

Some plotly.py features rely on fairly large geographic shape files. The county
choropleth figure factory is one such example. These shape files are distributed as a
separate `plotly-geo` package. This package can be installed using pip...
separate `plotly-geo` package. This package can be installed using pip:

```
pip install plotly-geo==1.0.0
```

or conda
or conda:

```
conda install -c plotly plotly-geo=1.0.0
Expand All @@ -145,7 +144,7 @@ conda install -c plotly plotly-geo=1.0.0

## Copyright and Licenses

Code and documentation copyright 2019 Plotly, Inc.
Code and documentation copyright Plotly, Inc.

Code released under the [MIT license](https://github.com/plotly/plotly.py/blob/main/LICENSE.txt).

Expand Down
67 changes: 23 additions & 44 deletions codegen/__init__.py → bin/codegen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import json
import os
import os.path as opath
import shutil
import subprocess
import sys

from codegen.datatypes import build_datatype_py, write_datatype_py # noqa: F401
Expand Down Expand Up @@ -87,45 +85,30 @@ def preprocess_schema(plotly_schema):
items["colorscale"] = items.pop("concentrationscales")


def make_paths(outdir):
"""Make various paths needed for formatting and linting."""
def make_paths(codedir):
"""Make various paths needed for code generation."""

validators_dir = opath.join(outdir, "validators")
graph_objs_dir = opath.join(outdir, "graph_objs")
graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py")
validators_dir = codedir / "validators"
graph_objs_dir = codedir / "graph_objs"
graph_objects_path = codedir / "graph_objects" / "__init__.py"
return validators_dir, graph_objs_dir, graph_objects_path


def lint_code(outdir):
"""Check Python code using settings in pyproject.toml."""

subprocess.call(["ruff", "check", *make_paths(outdir)])


def reformat_code(outdir):
"""Reformat Python code using settings in pyproject.toml."""

subprocess.call(["ruff", "format", *make_paths(outdir)])


def perform_codegen(outdir, noformat=False):
"""Generate code (and possibly reformat)."""
def perform_codegen(codedir, noformat=False):
"""Generate code."""

# Get paths
validators_dir, graph_objs_dir, graph_objects_path = make_paths(outdir)
validators_dir, graph_objs_dir, graph_objects_path = make_paths(codedir)

# Delete prior codegen output
if opath.exists(validators_dir):
if validators_dir.exists():
shutil.rmtree(validators_dir)
if opath.exists(graph_objs_dir):
if graph_objs_dir.exists():
shutil.rmtree(graph_objs_dir)

# Load plotly schema
project_root = opath.dirname(outdir)
plot_schema_path = opath.join(
project_root, "codegen", "resources", "plot-schema.json"
)

project_root = codedir.parent
plot_schema_path = project_root / "resources" / "plot-schema.json"
with open(plot_schema_path, "r") as f:
plotly_schema = json.load(f)

Expand Down Expand Up @@ -193,26 +176,26 @@ def perform_codegen(outdir, noformat=False):

# Write out the JSON data for the validators
os.makedirs(validators_dir, exist_ok=True)
write_validator_json(outdir, validator_params)
write_validator_json(codedir, validator_params)

# Alls
alls = {}

# Write out datatypes
for node in all_compound_nodes:
write_datatype_py(outdir, node)
write_datatype_py(codedir, node)

# Deprecated
# These are deprecated legacy datatypes like graph_objs.Marker
write_deprecated_datatypes(outdir)
write_deprecated_datatypes(codedir)

# Write figure class to graph_objs
data_validator = get_data_validator_instance(base_traces_node)
layout_validator = layout_node.get_validator_instance()
frame_validator = frame_node.get_validator_instance()

write_figure_classes(
outdir,
codedir,
base_traces_node,
data_validator,
layout_validator,
Expand Down Expand Up @@ -242,7 +225,7 @@ def perform_codegen(outdir, noformat=False):
# Write plotly/graph_objs/graph_objs.py
# This is for backward compatibility. It just imports everything from
# graph_objs/__init__.py
write_graph_objs_graph_objs(outdir)
write_graph_objs_graph_objs(codedir)

# Add Figure and FigureWidget
root_datatype_imports = datatype_rel_class_imports[()]
Expand Down Expand Up @@ -287,12 +270,13 @@ def __getattr__(import_name):
# __all__
for path_parts, class_names in alls.items():
if path_parts and class_names:
filepath = opath.join(outdir, "graph_objs", *path_parts, "__init__.py")
filepath = codedir / "graph_objs"
filepath = filepath.joinpath(*path_parts) / "__init__.py"
with open(filepath, "at") as f:
f.write(f"\n__all__ = {class_names}")

# Output datatype __init__.py files
graph_objs_pkg = opath.join(outdir, "graph_objs")
graph_objs_pkg = codedir / "graph_objs"
for path_parts in datatype_rel_class_imports:
rel_classes = sorted(datatype_rel_class_imports[path_parts])
rel_modules = sorted(datatype_rel_module_imports.get(path_parts, []))
Expand All @@ -317,18 +301,13 @@ def __getattr__(import_name):
graph_objects_rel_classes,
init_extra=optional_figure_widget_import,
)
graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py")
os.makedirs(opath.join(outdir, "graph_objects"), exist_ok=True)
graph_objects_path = codedir / "graph_objects"
graph_objects_path.mkdir(parents=True, exist_ok=True)
graph_objects_path /= "__init__.py"
with open(graph_objects_path, "wt") as f:
f.write("# ruff: noqa: F401\n")
f.write(graph_objects_init_source)

# Run code formatter on output directories
if noformat:
print("skipping reformatting")
else:
reformat_code(outdir)


if __name__ == "__main__":
if len(sys.argv) != 2:
Expand Down
Loading