jupyterhub / jupyter-server-proxy

Jupyter notebook server extension to proxy web services.
https://jupyter-server-proxy.readthedocs.io
BSD 3-Clause "New" or "Revised" License
354 stars 147 forks source link

Editable install is broken #389

Closed mahendrapaipuri closed 1 year ago

mahendrapaipuri commented 1 year ago

Bug description

pip install -e . does not work anymore. More precisely jupyter labextension develop --overwrite . command fails. This command will be executed in the labextension folder and looking at the source code, the command expects either setup.py or pyproject.toml in the current directory which is labextension here. Obviously both of them exists only in the root of the repo.

Expected behaviour

pip install -e . works and gives us a developmental install

Actual behaviour

Does not install package in developmental mode. Maybe re-organising the repo to move contents of labextension to the root of repo is the way to go? jupyterlab-git extension have files organised in such a way

How to reproduce

  1. Clone repo git clone https://github.com/jupyterhub/jupyter-server-proxy.git
  2. Change directory cd jupyter-server-proxy
  3. Try editable install pip install -e .

Your personal set up

Full environment ``` # Name Version Build Channel anyio 3.6.2 pypi_0 pypi appnope 0.1.3 pypi_0 pypi argon2-cffi 21.3.0 pypi_0 pypi argon2-cffi-bindings 21.2.0 pypi_0 pypi arrow 1.2.3 pypi_0 pypi asttokens 2.2.1 pypi_0 pypi attrs 22.2.0 pypi_0 pypi babel 2.12.1 pypi_0 pypi backcall 0.2.0 pypi_0 pypi beautifulsoup4 4.12.2 pypi_0 pypi bleach 6.0.0 pypi_0 pypi bzip2 1.0.8 h1de35cc_0 ca-certificates 2023.01.10 hecd8cb5_0 certifi 2022.12.7 py310hecd8cb5_0 cffi 1.15.1 pypi_0 pypi charset-normalizer 3.1.0 pypi_0 pypi comm 0.1.3 pypi_0 pypi debugpy 1.6.7 pypi_0 pypi decorator 5.1.1 pypi_0 pypi defusedxml 0.7.1 pypi_0 pypi distlib 0.3.6 py310hecd8cb5_0 executing 1.2.0 pypi_0 pypi fastjsonschema 2.16.3 pypi_0 pypi filelock 3.9.0 py310hecd8cb5_0 fqdn 1.5.1 pypi_0 pypi idna 3.4 pypi_0 pypi ipykernel 6.22.0 pypi_0 pypi ipython 8.12.0 pypi_0 pypi ipython-genutils 0.2.0 pypi_0 pypi isoduration 20.11.0 pypi_0 pypi jedi 0.18.2 pypi_0 pypi jinja2 3.1.2 pypi_0 pypi json5 0.9.11 pypi_0 pypi jsonpointer 2.3 pypi_0 pypi jsonschema 4.17.3 pypi_0 pypi jupyter-client 8.1.0 pypi_0 pypi jupyter-core 5.3.0 pypi_0 pypi jupyter-events 0.6.3 pypi_0 pypi jupyter-server 2.5.0 pypi_0 pypi jupyter-server-terminals 0.4.4 pypi_0 pypi jupyterlab 3.5.0 pypi_0 pypi jupyterlab-pygments 0.2.2 pypi_0 pypi jupyterlab-server 2.22.0 pypi_0 pypi libcxx 14.0.6 h9765a3e_0 libffi 3.3 hb1e8313_2 markupsafe 2.1.2 pypi_0 pypi matplotlib-inline 0.1.6 pypi_0 pypi mistune 2.0.5 pypi_0 pypi nbclassic 0.5.5 pypi_0 pypi nbclient 0.7.3 pypi_0 pypi nbconvert 7.3.0 pypi_0 pypi nbformat 5.8.0 pypi_0 pypi ncurses 6.4 hcec6c5f_0 nest-asyncio 1.5.6 pypi_0 pypi notebook 6.5.4 pypi_0 pypi notebook-shim 0.2.2 pypi_0 pypi openssl 1.1.1t hca72f7f_0 packaging 23.0 pypi_0 pypi pandocfilters 1.5.0 pypi_0 pypi parso 0.8.3 pypi_0 pypi pexpect 4.8.0 pypi_0 pypi pickleshare 0.7.5 pypi_0 pypi pip 23.0.1 py310hecd8cb5_0 platformdirs 2.5.2 py310hecd8cb5_0 prometheus-client 0.16.0 pypi_0 pypi prompt-toolkit 3.0.38 pypi_0 pypi psutil 5.9.4 pypi_0 pypi ptyprocess 0.7.0 pypi_0 pypi pure-eval 0.2.2 pypi_0 pypi pycparser 2.21 pypi_0 pypi pygments 2.14.0 pypi_0 pypi pyrsistent 0.19.3 pypi_0 pypi python 3.10.0 hdfd78df_5 python-dateutil 2.8.2 pypi_0 pypi python-json-logger 2.0.7 pypi_0 pypi pyyaml 6.0 pypi_0 pypi pyzmq 25.0.2 pypi_0 pypi readline 8.2 hca72f7f_0 requests 2.28.2 pypi_0 pypi rfc3339-validator 0.1.4 pypi_0 pypi rfc3986-validator 0.1.1 pypi_0 pypi send2trash 1.8.0 pypi_0 pypi setuptools 65.6.3 py310hecd8cb5_0 six 1.16.0 pypi_0 pypi sniffio 1.3.0 pypi_0 pypi soupsieve 2.4 pypi_0 pypi sqlite 3.41.1 h6c40b1e_0 stack-data 0.6.2 pypi_0 pypi terminado 0.17.1 pypi_0 pypi tinycss2 1.2.1 pypi_0 pypi tk 8.6.12 h5d9f67b_0 tomli 2.0.1 pypi_0 pypi tornado 6.2 pypi_0 pypi traitlets 5.9.0 pypi_0 pypi tzdata 2023c h04d1e81_0 uri-template 1.2.0 pypi_0 pypi urllib3 1.26.15 pypi_0 pypi virtualenv 20.17.1 py310hecd8cb5_0 wcwidth 0.2.6 pypi_0 pypi webcolors 1.13 pypi_0 pypi webencodings 0.5.1 pypi_0 pypi websocket-client 1.5.1 pypi_0 pypi wheel 0.38.4 py310hecd8cb5_0 xz 5.2.10 h6c40b1e_1 zlib 1.2.13 h4dc903c_0 ```
Logs ``` Obtaining file:///[redacted]/jupyter-server-proxy Installing build dependencies ... done Checking if build backend supports build_editable ... done Getting requirements to build editable ... done Preparing editable metadata (pyproject.toml) ... error error: subprocess-exited-with-error × Preparing editable metadata (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [47 lines of output] INFO:hatch_jupyter_builder.utils:Running jupyter-builder INFO:hatch_jupyter_builder.utils:Building with hatch_jupyter_builder.npm_builder INFO:hatch_jupyter_builder.utils:With kwargs: {'path': 'labextension', 'build_cmd': 'install:extension', 'npm': ['jlpm'], 'source_dir': 'labextension/src', 'build_dir': 'jupyter_server_proxy/labextension'} INFO:hatch_jupyter_builder.utils:Installing build dependencies with npm. This may take a while... INFO:hatch_jupyter_builder.utils:> /private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/bin/jlpm install yarn install v1.21.1 [1/4] Resolving packages... success Already up-to-date. Done in 0.28s. INFO:hatch_jupyter_builder.utils:> /private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/bin/jlpm run install:extension yarn run v1.21.1 $ jupyter labextension develop --overwrite . /[redacted]/jupyter-server-proxy/venv/bin/python: can't open file '/[redacted]/jupyter-server-proxy/labextension/setup.py': [Errno 2] No such file or directory An error occurred. FileNotFoundError: The Python package `.` is not a valid package, it is missing the `setup.py` file. See the log file for details: /var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/jupyterlab-debug-86d9ewnq.log error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. Traceback (most recent call last): File "/[redacted]/jupyter-server-proxy/venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 165, in prepare_metadata_for_build_editable hook = backend.prepare_metadata_for_build_editable AttributeError: module 'hatchling.build' has no attribute 'prepare_metadata_for_build_editable' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/[redacted]/jupyter-server-proxy/venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 351, in main() File "/[redacted]/jupyter-server-proxy/venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 333, in main json_out['return_val'] = hook(**hook_input['kwargs']) File "/[redacted]/jupyter-server-proxy/venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 174, in prepare_metadata_for_build_editable whl_basename = build_hook(metadata_directory, config_settings) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatchling/build.py", line 78, in build_editable return os.path.basename(next(builder.build(wheel_directory, ['editable']))) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatchling/builders/plugin/interface.py", line 150, in build build_hook.initialize(version, build_data) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatch_jupyter_builder/plugin.py", line 83, in initialize raise e File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatch_jupyter_builder/plugin.py", line 78, in initialize build_func(self.target_name, version, **build_kwargs) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatch_jupyter_builder/utils.py", line 116, in npm_builder run(npm_cmd + ["run", build_cmd], cwd=str(abs_path)) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/hatch_jupyter_builder/utils.py", line 227, in run return subprocess.check_call(cmd, **kwargs) File "/[redacted]/venv/lib/python3.10/subprocess.py", line 369, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/bin/jlpm', 'run', 'install:extension']' returned non-zero exit status 1. [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. error: metadata-generation-failed × Encountered error while generating package metadata. ╰─> See above for output. note: This is an issue with the package mentioned above, not pip. hint: See above for details. ``` JupyterLab Log: ``` Traceback (most recent call last): File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/federated_labextensions.py", line 447, in _get_labextension_metadata subprocess.check_output([sys.executable, "setup.py", "--name"], cwd=mod_path) File "/[redacted]/venv/lib/python3.10/subprocess.py", line 420, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/[redacted]/venv/lib/python3.10/subprocess.py", line 524, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['/[redacted]/jupyter-server-proxy/venv/bin/python', 'setup.py', '--name']' returned non-zero exit status 2. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/debuglog.py", line 47, in debug_logging yield File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/labextensions.py", line 161, in start ans = self.run_task() File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/labextensions.py", line 252, in run_task develop_labextension_py( File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/federated_labextensions.py", line 166, in develop_labextension_py m, labexts = _get_labextension_metadata(module) File "/private/var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/pip-build-env-byrtsxzc/overlay/lib/python3.10/site-packages/jupyterlab/federated_labextensions.py", line 452, in _get_labextension_metadata raise FileNotFoundError( FileNotFoundError: The Python package `.` is not a valid package, it is missing the `setup.py` file. Exiting application: lab ```
consideRatio commented 1 year ago

I noticed this also recently, where the CONTRIBUTING.md docs mentions pip install -e . directly. If one does pip install . first then you can do pip install -e . after though.

mahendrapaipuri commented 1 year ago

@consideRatio Is it should be the case? I would expect it to work with pip install -e . on a clean env. I mean, I could see why is it working after doing pip install . by the way jupyter labextension commands are written. I am not quite if this regression is due to the migration to hatchling build system though.

Even if we re-organise the repo or change install:extension command to jupyter labextension develop --overwrite .., it still fails. When we invoke editable install on a clean env (without doing pip install . before), the way pyproject.toml is setup, pip install -e . invokes jlpm run install:extension which invokes again pip install . due to this block of code which make sures the package is installed. If we already installed the package before, this nested pip install . would not be invoked. But it does not mean that editable install is working as it should. The command jupyter labextension develop --overwrite . is supposed to create a symlink to the built labextension in sys.prefix/share/jupyter/labextension folder. But that does not happen. Turning on verbosity for pip install -vvvv -e ., we see following lines

INFO:hatch_jupyter_builder.utils:Running jupyter-builder
  INFO:hatch_jupyter_builder.utils:Building with hatch_jupyter_builder.npm_builder
  INFO:hatch_jupyter_builder.utils:With kwargs: {'path': 'labextension', 'build_cmd': 'install:extension', 'npm': ['jlpm'], 'source_dir': 'labextension/src', 'build_dir': 'jupyter_server_proxy/labextension'}
  INFO:hatch_jupyter_builder.utils:No build required
  INFO:hatch_jupyter_builder.utils:Finished running jupyter-builder
  Preparing editable metadata (pyproject.toml) ... done

So, I guess it is effectively a no-op as jupyter_builder is skipping the build? In any case, if we execute jlpm run install:extension, it will fail.

Users/[redacted]/venv/bin/python: can't open file '/[redacted]/jupyter-server-proxy/labextension/setup.py': [Errno 2] No such file or directory
An error occurred.
FileNotFoundError: The Python package `.` is not a valid package, it is missing the `setup.py` file.
See the log file for details:  /var/folders/l1/rr42hgv95bl4ys939_cqnw6m0000gn/T/jupyterlab-debug-z0_n3p_v.log
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Let's say we fixed this, still jupyter labextension develop --overwrite . command would not work as it looks for _jupyter_labextension_paths in the package which is not defined. So, I guess we need to add _jupyter_labextension_paths as well?

consideRatio commented 1 year ago

I'm not sure about these details and lack time to look into it, but its a bug that we error by following the CONTRIBUTING.md docs.

Should the docs be updated or something else to make "pip install -e ." work as expected out of the box? I'm not sure.

If you think it can be solved in a clean way, please feel free to open a PR!

mahendrapaipuri commented 1 year ago

Fair enough! I will put up a PR!

mahendrapaipuri commented 1 year ago

@consideRatio I have put up a PR. Feel free to review it!