Spaces:
Sleeping
Sleeping
| """Export code-use session to Jupyter notebook format.""" | |
| import json | |
| import re | |
| from pathlib import Path | |
| from browser_use.code_use.service import CodeAgent | |
| from .views import CellType, NotebookExport | |
| def export_to_ipynb(agent: CodeAgent, output_path: str | Path) -> Path: | |
| """ | |
| Export a NotebookSession to a Jupyter notebook (.ipynb) file. | |
| Now includes JavaScript code blocks that were stored in the namespace. | |
| Args: | |
| session: The NotebookSession to export | |
| output_path: Path where to save the notebook file | |
| agent: Optional CodeAgent instance to access namespace for JavaScript blocks | |
| Returns: | |
| Path to the saved notebook file | |
| Example: | |
| ```python | |
| session = await agent.run() | |
| notebook_path = export_to_ipynb(agent, 'my_automation.ipynb') | |
| print(f'Notebook saved to {notebook_path}') | |
| ``` | |
| """ | |
| output_path = Path(output_path) | |
| # Create notebook structure | |
| notebook = NotebookExport( | |
| metadata={ | |
| 'kernelspec': {'display_name': 'Python 3', 'language': 'python', 'name': 'python3'}, | |
| 'language_info': { | |
| 'name': 'python', | |
| 'version': '3.11.0', | |
| 'mimetype': 'text/x-python', | |
| 'codemirror_mode': {'name': 'ipython', 'version': 3}, | |
| 'pygments_lexer': 'ipython3', | |
| 'nbconvert_exporter': 'python', | |
| 'file_extension': '.py', | |
| }, | |
| } | |
| ) | |
| # Add setup cell at the beginning with proper type hints | |
| setup_code = """import asyncio | |
| import json | |
| from typing import Any | |
| from browser_use import BrowserSession | |
| from browser_use.code_use import create_namespace | |
| # Initialize browser and namespace | |
| browser = BrowserSession() | |
| await browser.start() | |
| # Create namespace with all browser control functions | |
| namespace: dict[str, Any] = create_namespace(browser) | |
| # Import all functions into the current namespace | |
| globals().update(namespace) | |
| # Type hints for better IDE support (these are now available globally) | |
| # navigate, click, input, evaluate, search, extract, scroll, done, etc. | |
| print("Browser-use environment initialized!") | |
| print("Available functions: navigate, click, input, evaluate, search, extract, done, etc.")""" | |
| setup_cell = { | |
| 'cell_type': 'code', | |
| 'metadata': {}, | |
| 'source': setup_code.split('\n'), | |
| 'execution_count': None, | |
| 'outputs': [], | |
| } | |
| notebook.cells.append(setup_cell) | |
| # Add JavaScript code blocks as variables FIRST | |
| if hasattr(agent, 'namespace') and agent.namespace: | |
| # Look for JavaScript variables in the namespace | |
| code_block_vars = agent.namespace.get('_code_block_vars', set()) | |
| for var_name in sorted(code_block_vars): | |
| var_value = agent.namespace.get(var_name) | |
| if isinstance(var_value, str) and var_value.strip(): | |
| # Check if this looks like JavaScript code | |
| # Look for common JS patterns | |
| js_patterns = [ | |
| r'function\s+\w+\s*\(', | |
| r'\(\s*function\s*\(\)', | |
| r'=>\s*{', | |
| r'document\.', | |
| r'Array\.from\(', | |
| r'\.querySelector', | |
| r'\.textContent', | |
| r'\.innerHTML', | |
| r'return\s+', | |
| r'console\.log', | |
| r'window\.', | |
| r'\.map\(', | |
| r'\.filter\(', | |
| r'\.forEach\(', | |
| ] | |
| is_js = any(re.search(pattern, var_value, re.IGNORECASE) for pattern in js_patterns) | |
| if is_js: | |
| # Create a code cell with the JavaScript variable | |
| js_cell = { | |
| 'cell_type': 'code', | |
| 'metadata': {}, | |
| 'source': [f'# JavaScript Code Block: {var_name}\n', f'{var_name} = """{var_value}"""'], | |
| 'execution_count': None, | |
| 'outputs': [], | |
| } | |
| notebook.cells.append(js_cell) | |
| # Convert cells | |
| python_cell_count = 0 | |
| for cell in agent.session.cells: | |
| notebook_cell: dict = { | |
| 'cell_type': cell.cell_type.value, | |
| 'metadata': {}, | |
| 'source': cell.source.splitlines(keepends=True), | |
| } | |
| if cell.cell_type == CellType.CODE: | |
| python_cell_count += 1 | |
| notebook_cell['execution_count'] = cell.execution_count | |
| notebook_cell['outputs'] = [] | |
| # Add output if available | |
| if cell.output: | |
| notebook_cell['outputs'].append( | |
| { | |
| 'output_type': 'stream', | |
| 'name': 'stdout', | |
| 'text': cell.output.split('\n'), | |
| } | |
| ) | |
| # Add error if available | |
| if cell.error: | |
| notebook_cell['outputs'].append( | |
| { | |
| 'output_type': 'error', | |
| 'ename': 'Error', | |
| 'evalue': cell.error.split('\n')[0] if cell.error else '', | |
| 'traceback': cell.error.split('\n') if cell.error else [], | |
| } | |
| ) | |
| # Add browser state as a separate output | |
| if cell.browser_state: | |
| notebook_cell['outputs'].append( | |
| { | |
| 'output_type': 'stream', | |
| 'name': 'stdout', | |
| 'text': [f'Browser State:\n{cell.browser_state}'], | |
| } | |
| ) | |
| notebook.cells.append(notebook_cell) | |
| # Write to file | |
| output_path.parent.mkdir(parents=True, exist_ok=True) | |
| with open(output_path, 'w', encoding='utf-8') as f: | |
| json.dump(notebook.model_dump(), f, indent=2, ensure_ascii=False) | |
| return output_path | |
| def session_to_python_script(agent: CodeAgent) -> str: | |
| """ | |
| Convert a CodeAgent session to a Python script. | |
| Now includes JavaScript code blocks that were stored in the namespace. | |
| Args: | |
| agent: The CodeAgent instance to convert | |
| Returns: | |
| Python script as a string | |
| Example: | |
| ```python | |
| await agent.run() | |
| script = session_to_python_script(agent) | |
| print(script) | |
| ``` | |
| """ | |
| lines = [] | |
| lines.append('# Generated from browser-use code-use session\n') | |
| lines.append('import asyncio\n') | |
| lines.append('import json\n') | |
| lines.append('from browser_use import BrowserSession\n') | |
| lines.append('from browser_use.code_use import create_namespace\n\n') | |
| lines.append('async def main():\n') | |
| lines.append('\t# Initialize browser and namespace\n') | |
| lines.append('\tbrowser = BrowserSession()\n') | |
| lines.append('\tawait browser.start()\n\n') | |
| lines.append('\t# Create namespace with all browser control functions\n') | |
| lines.append('\tnamespace = create_namespace(browser)\n\n') | |
| lines.append('\t# Extract functions from namespace for direct access\n') | |
| lines.append('\tnavigate = namespace["navigate"]\n') | |
| lines.append('\tclick = namespace["click"]\n') | |
| lines.append('\tinput_text = namespace["input"]\n') | |
| lines.append('\tevaluate = namespace["evaluate"]\n') | |
| lines.append('\tsearch = namespace["search"]\n') | |
| lines.append('\textract = namespace["extract"]\n') | |
| lines.append('\tscroll = namespace["scroll"]\n') | |
| lines.append('\tdone = namespace["done"]\n') | |
| lines.append('\tgo_back = namespace["go_back"]\n') | |
| lines.append('\twait = namespace["wait"]\n') | |
| lines.append('\tscreenshot = namespace["screenshot"]\n') | |
| lines.append('\tfind_text = namespace["find_text"]\n') | |
| lines.append('\tswitch_tab = namespace["switch"]\n') | |
| lines.append('\tclose_tab = namespace["close"]\n') | |
| lines.append('\tdropdown_options = namespace["dropdown_options"]\n') | |
| lines.append('\tselect_dropdown = namespace["select_dropdown"]\n') | |
| lines.append('\tupload_file = namespace["upload_file"]\n') | |
| lines.append('\tsend_keys = namespace["send_keys"]\n\n') | |
| # Add JavaScript code blocks as variables FIRST | |
| if hasattr(agent, 'namespace') and agent.namespace: | |
| code_block_vars = agent.namespace.get('_code_block_vars', set()) | |
| for var_name in sorted(code_block_vars): | |
| var_value = agent.namespace.get(var_name) | |
| if isinstance(var_value, str) and var_value.strip(): | |
| # Check if this looks like JavaScript code | |
| js_patterns = [ | |
| r'function\s+\w+\s*\(', | |
| r'\(\s*function\s*\(\)', | |
| r'=>\s*{', | |
| r'document\.', | |
| r'Array\.from\(', | |
| r'\.querySelector', | |
| r'\.textContent', | |
| r'\.innerHTML', | |
| r'return\s+', | |
| r'console\.log', | |
| r'window\.', | |
| r'\.map\(', | |
| r'\.filter\(', | |
| r'\.forEach\(', | |
| ] | |
| is_js = any(re.search(pattern, var_value, re.IGNORECASE) for pattern in js_patterns) | |
| if is_js: | |
| lines.append(f'\t# JavaScript Code Block: {var_name}\n') | |
| lines.append(f'\t{var_name} = """{var_value}"""\n\n') | |
| for i, cell in enumerate(agent.session.cells): | |
| if cell.cell_type == CellType.CODE: | |
| lines.append(f'\t# Cell {i + 1}\n') | |
| # Indent each line of source | |
| source_lines = cell.source.split('\n') | |
| for line in source_lines: | |
| if line.strip(): # Only add non-empty lines | |
| lines.append(f'\t{line}\n') | |
| lines.append('\n') | |
| lines.append('\tawait browser.stop()\n\n') | |
| lines.append("if __name__ == '__main__':\n") | |
| lines.append('\tasyncio.run(main())\n') | |
| return ''.join(lines) | |