Skip to content

Bug: solara server hits Internal Server Error due to get_nbextensions logic #714

@sjdemartini

Description

@sjdemartini

(Solara looks awesome; thank you for building it! I'm just trying it out for the first time.)

Copying the example ipywidgets code from the Solara docs and putting it into a solara-ipywidgets-test.ipynb file, then running the Solara server, it results in an error in solara's code for nbextensions. This shows Internal Server Error in the browser and the following stack trace in the shell:

❯ solara run solara-ipywidgets-test.ipynb:button
Solara server is starting at http://localhost:8765
I get run at startup, and for every page request
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/path/to/env/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/path/to/env/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/path/to/env/lib/python3.10/site-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/middleware/gzip.py", line 24, in __call__
    await responder(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/middleware/gzip.py", line 44, in __call__
    await self.app(scope, receive, self.send_with_gzip)
  File "/path/to/env/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/path/to/env/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/path/to/env/lib/python3.10/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/path/to/env/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/path/to/env/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/path/to/env/lib/python3.10/site-packages/starlette/routing.py", line 72, in app
    response = await func(request)
  File "/path/to/env/lib/python3.10/site-packages/solara/server/starlette.py", line 354, in root
    content = server.read_root(request_path, root_path)
  File "/path/to/env/lib/python3.10/site-packages/solara/server/server.py", line 289, in read_root
    nbextensions, nbextensions_hashes = get_nbextensions()
  File "/path/to/env/lib/python3.10/site-packages/solara/cache.py", line 112, in __call__
    value = self.function(*args, **kwargs)
  File "/path/to/env/lib/python3.10/site-packages/solara/server/server.py", line 463, in get_nbextensions
    nbextensions_hashes = {name: hash_extension(name) for name in nbextensions}
  File "/path/to/env/lib/python3.10/site-packages/solara/server/server.py", line 463, in <dictcomp>
    nbextensions_hashes = {name: hash_extension(name) for name in nbextensions}
  File "/path/to/env/lib/python3.10/site-packages/solara/server/server.py", line 455, in hash_extension
    data = file.read_bytes()
  File "/path/to/env/lib/python3.10/pathlib.py", line 1126, in read_bytes
    with self.open(mode='rb') as f:
  File "/path/to/env/lib/python3.10/pathlib.py", line 1119, in open
    return self._accessor.open(self, mode, buffering, encoding, errors,
IsADirectoryError: [Errno 21] Is a directory: '/path/to/env/share/jupyter/nbextensions/latex_envs/doc/.ipynb_checkpoints'

It seems the latex_envs extension (https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/latex_envs/README.html) contains a folder which include a .ipynb_checkpoints directory. The Solara glob logic seems to be looking for files (as opposed to directories) with the pattern **/*.* here

for file in directory.glob("**/*.*"):
data = file.read_bytes()

but this mistakenly will include directories that include or start with ., like .ipynb_checkpoints, leading to the error. I'm new to Solara and not familiar with the get_nbextensions functionality, but I can open a PR with a simple fix to skip directories, which I confirmed sidesteps the error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions