首页 > 编程问答 >从 IFRAME javascript 到 google colab 的回调函数

从 IFRAME javascript 到 google colab 的回调函数

时间:2024-07-24 13:56:01浏览次数:8  
标签:javascript python iframe callback google-colaboratory

所以我在学习 google colab 时遇到了一个问题,在 google colab 中运行我的代码,我打开服务器并使用 IFRAME 查看我的网站,我试图解决的问题是选择 json 文件并单击上传时我希望该文件上传到我的笔记本本地内存,我的index.html文件有一个回调函数:

<script>
        function uploadJson() {
           google.colab.kernel.invokeFunction('notebook.uploadJSON', [file.name, content], {})
...
....

在colab本身中,我已经注册了该函数:

output.register_callback('notebook.uploadJSON', upload_json)

它位于该函数下:

def upload_json(filename, content): ...

我在控制台中遇到的问题是google 未定义,基本上回调不起作用。

我读到回调在使用 iframe 等时可能会遇到问题,有人知道原因或如何修复它吗?我还尝试在不使用 iframe 的情况下从 colab 中的单元格注入这些函数,这有点工作,但后来我遇到了 css 和 js 文件不工作的其他问题

from google.colab import output
import IPython
from IPython.display import display, IFrame
import json
import os
import requests
import time


def upload_json(filename, content):
    data = json.loads(content)
    filepath = os.path.join(os.getcwd(), filename)
    with open(filepath, 'w') as f:
        json.dump(data, f, indent=2)
    print(f"File '{filename}' has been saved successfully in the Colab folder.")
    if isinstance(data, dict):
        first_key = next(iter(data))
        print(f"First item in the JSON: {first_key}: {data[first_key]}")
    elif isinstance(data, list) and len(data) > 0:
        print(f"First item in the JSON: {data[0]}")
    else:
        print("The JSON file is empty or has an unexpected structure.")

output.register_callback('notebook.uploadJSON', upload_json)

# Function to download files from Firebase Storage
def download_file_from_firebase(bucket_name, file_name, local_path):
    url = f'https://firebasestorage.googleapis.com/v0/b/{bucket_name}/o/{file_name}?alt=media'
    response = requests.get(url)
    if response.status_code == 200:
        with open(local_path, 'wb') as file:
            file.write(response.content)
        print(f'File {file_name} downloaded to {local_path}.')
    else:
        print(f'Failed to download {file_name}. Status code: {response.status_code}')

# Download necessary files
bucket_name = 'KEY.com'
file_names = [
    'index.html',
    'TeamGraph.html',
    'glossary.html',
    'notifications.html',
    'style.css',
    'KEY.json',
    'app.js',
    'notifications.js'
]

for file_name in file_names:
    download_file_from_firebase(bucket_name, file_name, file_name)

# List downloaded files
print("Downloaded files:", os.listdir())

# Serve the downloaded HTML files from Colab
time.sleep(2)
os.chdir('/content')
get_ipython().system_raw('python3 -m http.server 8000 &')

# Get the server URL
server_url = output.eval_js("google.colab.kernel.proxyPort(8000)")

# Function to display an HTML file in an iframe
def display_html(filename):
    display(IFrame(src=f"{server_url}/{filename}", width='100%', height='600px'))

# Display the initial HTML file
display_html('index.html')

,这就是我的 index.html 中的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON Upload</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://apis.google.com/js/platform.js"></script>
</head>
<body>
    <div class="button-container">
        <a href="index.html" class="nav-button" id="btnIndex">JSON Upload</a>
        <a href="glossary.html" class="nav-button" id="btnGlossary">Glossary</a>
        <a href="TeamGraph.html" class="nav-button" id="btnTeamGraph">Team Stats</a>
        <a href="notifications.html" class="nav-button" id="btnNotifications">Notifications</a>
    </div>
    <div class="container">
        <h2>Upload JSON File</h2>
        <form id="jsonUploadForm">
            <input type="file" id="fileInput" accept=".json">
            <button type="button" id="uploadButton" onclick="uploadJson()">Upload</button>
        </form>
    </div>
    <script>
        function uploadJson() {
            console.log("uploadJson function called"); // Debugging statement
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];

            if (file) {
                const reader = new FileReader();
                reader.onload = function(event) {
                    const content = event.target.result;
                    console.log("File content:", content); // Debugging statement
                    google.colab.kernel.invokeFunction('notebook.uploadJSON', [file.name, content], {})
                        .then(response => {
                            console.log('Upload successful:', response);
                            alert('Upload successful');
                        })
                        .catch(error => {
                            console.error('Invoke function error:', error);
                            alert('Invoke function error: ' + error);
                        });
                };
                reader.onerror = function(event) {
                    console.error("Error reading file:", event.target.error);
                    alert("Error reading file: " + event.target.error);
                };
                reader.readAsText(file);
            } else {
                alert('No file selected');
            }
        }

        // Disable the button for the current page
        const currentPage = window.location.pathname.split("/").pop();
        document.querySelector(`a[href="${currentPage}"]`).classList.add('active');
        document.querySelector(`a[href="${currentPage}"]`).disabled = true;
    </script>
</body>
</html>


绝对说对了,在 iframe 和 Google Colab 之间进行通信时会出现问题,尤其是在涉及 google.colab 对象时。这是因为在的 iframe 中运行的网页和的 Colab 笔记本本身在不同的 JavaScript 上下文中运行。

以下是解决此问题并使的 JSON 上传功能正常工作的分步指南:

1. 使用 postMessage 进行跨域消息传递

  • 在 Colab 笔记本中(Python 代码):

    ```python from google.colab import output import json import os

    def upload_json(filename, content): data = json.loads(content) filepath = os.path.join(os.getcwd(), filename) with open(filepath, 'w') as f: json.dump(data, f, indent=2) print(f"文件 '{filename}' 已成功保存在 Colab 文件夹中。")

    output.register_callback('notebook.uploadJSON', upload_json)

    # 添加消息处理程序 def handle_message(message): if message['data']['type'] == 'UPLOAD_JSON': upload_json(message['data']['filename'], message['data']['content'])

    output.register_callback('notebook.handleMessage', handle_message) ```

  • 在的 index.html 文件中(JavaScript):

    ```javascript <script> function uploadJson() { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0];

     if (file) {
         const reader = new FileReader();
         reader.onload = function(event) {
             const content = event.target.result;
    
             // 向父窗口(Colab 笔记本)发送消息
             parent.postMessage({
                 type: 'UPLOAD_JSON',
                 filename: file.name,
                 content: content
             }, '*'); // '*' 表示可以将消息发送到任何来源
         };
         reader.onerror = function(event) {
             console.error("读取文件时出错:", event.target.error);
         };
         reader.readAsText(file);
     } else {
         alert('未选择文件');
     }
    

    } </script> ```

2. 使 Colab 环境可访问

需要确保的 iframe 代码可以访问 parent 对象。如果在不同的域或子域中提供 index.html ,请将 * 替换为 iframe 源的特定来源。

说明:

  1. postMessage : 这是在窗口或 iframe 之间进行通信的标准方法。父窗口(的 Colab 笔记本)侦听消息,iframe(的 index.html )发送消息。

  2. 消息处理程序: 在 Colab 中, output.register_callback('notebook.handleMessage', handle_message) 设置一个侦听传入消息的处理程序。当接收到类型为 'UPLOAD_JSON' 的消息时,它会调用 upload_json 函数。

  3. 消息结构: 我们发送的消息有一个 type 字段(用于标识消息目的)以及 filename content

其他提示:

  • 调试: 在 Colab 笔记本和 iframe 的 JavaScript 代码中使用 console.log 语句来检查消息是否已正确发送和接收。

  • 错误处理: 实现稳健的错误处理,以便在出现问题时通知用户。

通过进行这些更改,就可以从 iframe 中的 JavaScript 代码上传 JSON 文件,并让的 Colab 笔记本接收和处理该文件。

标签:javascript,python,iframe,callback,google-colaboratory
From: 78786576

相关文章

  • [附开题]flask框架的基于用户行为分析的商品推荐系统APP1qut6APP(python+源码)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在移动互联网时代,电子商务平台的竞争日益激烈,如何精准地推荐商品给用户,提升用户体验与购买转化率,成为电商企业关注的焦点。传统的推荐算法......
  • [附开题]flask框架的教务管理系统q6190(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和教育改革的不断深入,教务管理工作日益复杂且重要。传统的手工管理方式已难以满足当前高校教务管理的需求,特别是在......
  • python闭包和装饰器
    一、闭包1.闭包的三要素1.外部函数嵌套内部函数2.内部函数可以调用外部函数的局部变量3.外部函数返回内部函数2.示例代码 #外部函数deffunc1():print("func1")#内部函数deffunc2():print("func2")#外部函数返回内部函数re......
  • python Subprocess 模块
    Subprocess介绍subprocess模块是Python标准库中的一个模块,用于管理子进程(子程序)。通过subprocess模块,可以在Python脚本中启动新的进程、连接到它们的输入/输出流以及获取它们的返回值。Subprocess主要功能1.执行外部命令:subprocess允许你在Python脚本中执行系统命......
  • Python 类型提示:自引用类型检查
    我认为静态类型确实会让我在Python中的生活更轻松,考虑到我通常使用C语言工作。我创建了一个像这样的类:classnode(object):"""properties,constructor,etc."""defadd_outneighbor(self,neighbor:node)->None:"""d......
  • Python用shp文件裁剪多个遥感影像的方法
      本文介绍基于Python中ArcPy模块,基于矢量数据范围,对大量栅格遥感影像加以批量裁剪掩膜的方法。  首先,话不多说,本文所需要的代码如下所示。#-*-coding:utf-8-*-"""CreatedonTueDec1320:07:482022@author:fkxxgis"""importarcpyfromarcpy.saimport*......
  • 以编程方式删除 Python 源中的类型提示
    我有一些为Python3.5编写的源代码,我想使其在Python3.4下可执行。我使用的3.5中唯一在3.4中不可用的功能是类型提示,因此我想编写一个脚本来完全删除这些功能。乍一看这似乎很容易,我决定编写一些正则表达式这样做,但后来我想到了一些边缘情况,我不确定如何解决像这样的......
  • Python 类型暗示​​一个充满 myclass 对象的双端队列
    使用Python3.6或更高版本,我想输入提示一个返回MyClass对象的函数myfunc我如何提示myqueue是一个deque|||充满MyClass对象?objects?fromcollectionsimportdequeglobal_queue=deque()classMyClass:passdefmyfunc(m......
  • python之名称空间和作用域(关键字:global和nonlocal的使用)
    文章目录前言1、名称空间和作用域1.1引言1.2名称空间1.2.1内置名称空间1.2.2全局名称空间1.2.3局部名称空间1.2.4名称空间的产生和销毁顺序1.3作用域1.3.1全局作用域1.3.2局部作用域1.3.3名字的查找顺序1.4关键字:global1.5关键字:nonlocal前言本篇文章......
  • 用于 isinstance() 检查的 dict_keys 的显式 python3 类型是什么?
    在Python3中,我应该使用什么类型来检查字典键是否属于它?>>>d={1:2}>>>type(d.keys())<class'dict_keys'>所以我很自然地尝试了这个:>>>isinstance(d.keys(),dict_keys)Traceback(mostrecentcalllast):File"<stdin>",......