Skip to content

Conversation

@Zsailer
Copy link
Contributor

@Zsailer Zsailer commented Jul 29, 2025

Summary

  • Add create_notebook function to notebook toolkit that creates new empty Jupyter notebooks
  • Function includes proper nbformat structure initialization
  • Includes directory creation if needed and file existence checks

Zsailer added 2 commits July 29, 2025 14:36
This change ensures consistent filepath handling across all toolkit functions by using the normalize_filepath utility function. This handles URL-encoded paths, relative paths, and special characters consistently.

- Updated file_system toolkit: read, write, edit, search_and_replace, glob, grep, ls
- Updated notebook toolkit: all functions that take file_path parameter
- Updated git toolkit: all functions that take path parameter
- Added comprehensive tests for normalize_filepath functionality

All tools now properly decode URL-encoded paths (e.g., my%20notebook.ipynb → my notebook.ipynb) and resolve relative paths against the Jupyter server's root directory.
This function creates a new empty Jupyter notebook at the specified file path with proper nbformat structure, including directory creation if needed.
Copy link
Contributor

@3coins 3coins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Zsailer
Thanks for submitting this, this should greatly improve the path handling consistency across the toolkit. Left some minor suggestions to improve performance.


# Resolve relative path against the root directory
resolved_path = Path(root_dir) / path
return str(resolved_path.resolve())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check if the path stays within root directory?

Suggested change
return str(resolved_path.resolve())
if not str(resolved_path).startswith(str(root_path)):
raise ValueError(f"{file_path} resolves outside Jupyter root directory")
return str(resolved_path.resolve())

Comment on lines +47 to +48
# URL decode the path in case it contains encoded characters
decoded_path = unquote(file_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do a slight optimization here, to skip decoding for abs paths.

Suggested change
# URL decode the path in case it contains encoded characters
decoded_path = unquote(file_path)
if os.path.isabs(file_path) and '%' not in file_path:
return str(Path(file_path).resolve())
# URL decode the path in case it contains encoded characters
decoded_path = unquote(file_path)

return server


def normalize_filepath(file_path: str) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might benefit from caching, since this is called in numerous places.

Suggested change
def normalize_filepath(file_path: str) -> str:
@functools.lru_cache(maxsize=256)
def normalize_filepath(file_path: str) -> str:

@3coins 3coins merged commit 87e75d2 into jupyter-ai-contrib:main Aug 20, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants