Skip to content

Add support for local plotly.js/ builds to setup.py #4526

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

Merged
merged 3 commits into from
Mar 22, 2024
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
25 changes: 24 additions & 1 deletion contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,30 @@ the `plotly/plotly.js` GitHub repository (and place them in
`plotly/package_data`). It will then regenerate all of the `graph_objs`
classes based on the new schema.

For dev branches, it is also possible to use `updateplotlyjsdev --devrepo reponame --devbranch branchname` to update to development versions of `plotly.js`. This will fetch the `plotly.js` in the CircleCI artifact of the branch `branchname` of the repo `reponame`. If `--devrepo` or `--devbranch` are omitted, `updateplotlyjsdev` defaults using `plotly/plotly.js` and `master` respectively.
For dev branches, it is also possible to use `updateplotlyjsdev` in two configurations:

### CircleCI Release

If your devbranch is part of the official plotly.js repository, you can use
```bash
python setup.py updateplotlyjsdev --devrepo reponame --devbranch branchname
```
to update to development versions of `plotly.js`. This will fetch the `plotly.js` in the CircleCI artifact of the branch `branchname` of the repo `reponame`. If `--devrepo` or `--devbranch` are omitted, `updateplotlyjsdev` defaults using `plotly/plotly.js` and `master` respectively.

### Local Repository

If you have a local repository of `plotly.js` you'd like to try, you can run:

```bash
# In your plotly.js/ directory, prepare the package:

$ npm run build
$ npm pack
$ mv plotly.js-*.tgz plotly.js.tgz

# In your plotly.py/packages/python/plotly/ directory:
$ python setup.py updateplotlyjsdev --local /path/to/your/plotly.js/
```

## Testing

Expand Down
67 changes: 56 additions & 11 deletions packages/python/plotly/setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import sys
import time
import platform
import json
import shutil

from setuptools import setup, Command
from setuptools.command.egg_info import egg_info
Expand Down Expand Up @@ -137,10 +139,10 @@ class NPM(Command):
]

def initialize_options(self):
pass
self.local = None

def finalize_options(self):
pass
self.set_undefined_options("updateplotlyjsdev", ("local", "local"))

def get_npm_name(self):
npmName = "npm"
Expand Down Expand Up @@ -187,6 +189,14 @@ def run(self):
stdout=sys.stdout,
stderr=sys.stderr,
)
if self.local is not None:
plotly_archive = os.path.join(self.local, "plotly.js.tgz")
check_call(
[npmName, "install", plotly_archive],
cwd=node_root,
stdout=sys.stdout,
stderr=sys.stderr,
)
check_call(
[npmName, "run", "build:prod"],
cwd=node_root,
Expand Down Expand Up @@ -225,6 +235,11 @@ def run(self):
perform_codegen()


def overwrite_schema_local(uri):
path = os.path.join(here, "codegen", "resources", "plot-schema.json")
shutil.copyfile(uri, path)


def overwrite_schema(url):
import requests

Expand All @@ -235,6 +250,11 @@ def overwrite_schema(url):
f.write(req.content)


def overwrite_bundle_local(uri):
path = os.path.join(here, "plotly", "package_data", "plotly.min.js")
shutil.copyfile(uri, path)


def overwrite_bundle(url):
import requests

Expand Down Expand Up @@ -304,6 +324,13 @@ def get_latest_publish_build_info(repo, branch):
return {p: build[p] for p in ["vcs_revision", "build_num", "committer_date"]}


def get_bundle_schema_local(local):
plotly_archive = os.path.join(local, "plotly.js.tgz")
plotly_bundle = os.path.join(local, "dist/plotly.min.js")
plotly_schemas = os.path.join(local, "dist/plot-schema.json")
return plotly_archive, plotly_bundle, plotly_schemas


def get_bundle_schema_urls(build_num):
url = (
"https://circleci.com/api/v1.1/project/github/"
Expand Down Expand Up @@ -390,31 +417,47 @@ class UpdateBundleSchemaDevCommand(Command):
def initialize_options(self):
self.devrepo = None
self.devbranch = None
self.local = None

def finalize_options(self):
self.set_undefined_options("updateplotlyjsdev", ("devrepo", "devrepo"))
self.set_undefined_options("updateplotlyjsdev", ("devbranch", "devbranch"))
self.set_undefined_options("updateplotlyjsdev", ("local", "local"))

def run(self):
build_info = get_latest_publish_build_info(self.devrepo, self.devbranch)
if self.local is None:
build_info = get_latest_publish_build_info(self.devrepo, self.devbranch)

archive_url, bundle_url, schema_url = get_bundle_schema_urls(
build_info["build_num"]
)
archive_url, bundle_url, schema_url = get_bundle_schema_urls(
build_info["build_num"]
)

# Update bundle in package data
overwrite_bundle(bundle_url)

# Update bundle in package data
overwrite_bundle(bundle_url)
# Update schema in package data
overwrite_schema(schema_url)
else:
# this info could be more informative but
# it doesn't seem as useful in a local context
# and requires dependencies and programming.
build_info = {"vcs_revision": "local", "committer_date": str(time.time())}
self.devrepo = self.local
self.devbranch = ""

# Update schema in package data
overwrite_schema(schema_url)
archive_uri, bundle_uri, schema_uri = get_bundle_schema_local(self.local)
overwrite_bundle_local(bundle_uri)
overwrite_schema_local(schema_uri)

# Update plotly.js url in package.json
package_json_path = os.path.join(node_root, "package.json")
with open(package_json_path, "r") as f:
package_json = json.load(f)

# Replace version with bundle url
package_json["dependencies"]["plotly.js"] = archive_url
package_json["dependencies"]["plotly.js"] = (
archive_url if self.local is None else archive_uri
)
with open(package_json_path, "w") as f:
json.dump(package_json, f, indent=2)

Expand All @@ -430,11 +473,13 @@ class UpdatePlotlyJsDevCommand(Command):
user_options = [
("devrepo=", None, "Repository name"),
("devbranch=", None, "branch or pull/number"),
("local=", None, "local copy of repo, used by itself"),
]

def initialize_options(self):
self.devrepo = "plotly/plotly.js"
self.devbranch = "master"
self.local = None

def finalize_options(self):
pass
Expand Down