python-3.x - 如何使用 Google Cloud Function 将文件从 Cloud Storage 存储桶推送到实例中?
问题描述
我有一项任务分配给我,让我想办法在 GCP 中设置云功能,该功能执行以下操作:
监控 Google Cloud Storage 存储分区中的新文件
当它检测到存储桶中的新文件时触发
将该文件复制到计算实例 (Ubuntu) 内的目录
我一直在做一些研究,结果一无所获。我知道我可以轻松地设置一个 cron 作业,每分钟同步存储桶/目录或类似的东西,但是我们正在构建的系统的设计理念之一是操作触发器而不是计时器。
我要问的可能吗?
解决方案
您可以从 Google Cloud Storage 存储桶触发 Cloud Function,通过选择 Event Type 为Finalize/Create,每次在存储桶中上传文件时,都会调用 Cloud Function。
每次在存储桶中创建新对象时,云函数都会收到一个Cloud Storage 对象格式的通知。
现在,进入第二步,我找不到任何可以将文件从云存储上传到实例 VM 的 API。但是,我做了以下解决方法,假设您的实例 VM 配置了可以接收 HTTP 请求的服务器(例如 Apache 或 Nginx):
主文件
import requests
from google.cloud import storage
def hello_gcs(data, context):
"""Background Cloud Function to be triggered by Cloud Storage.
Args:
data (dict): The Cloud Functions event payload.
context (google.cloud.functions.Context): Metadata of triggering event.
Returns:
None; the file is sent as a request to
"""
print('Bucket: {}'.format(data['bucket']))
print('File: {}'.format(data['name']))
client = storage.Client()
bucket = client.get_bucket(data['bucket'])
blob = bucket.get_blob(data['name'])
contents = blob.download_as_string()
headers = {
'Content-type': 'text/plain',
}
data = '{"text":"{}"}'.format(contents)
response = requests.post('https://your-instance-server/endpoint-to-download-files', headers=headers, data=data)
return "Request sent to your instance with the data of the object"
要求.txt
google-cloud-storage
requests
最有可能的是,最好将对象名称和存储桶名称发送到您的服务器端点,然后使用Cloud Client Library从那里下载文件。
现在你可能会问...
如何让 Compute Engine 实例来处理请求?
创建一个 Compute Engine 实例虚拟机。确保它与云函数位于同一区域,并在创建它时允许对其进行 HTTP 连接。文档。我
debian-9
在这个测试中使用了一张图片。SSH 进入实例,并运行以下命令:
安装apache服务器
sudo apt-get update sudo apt-get install apache2 sudo apt-get install libapache2-mod-wsgi
也安装这个 python 库:
sudo apt-get install python-pip sudo pip install flask
为您的应用程序设置环境:
cd ~/ mkdir app sudo ln -sT ~/app /var/www/html/app
最后一行应该指向 apache 提供 index.html 文件的文件夹路径。
- 在以下位置创建您的应用程序
/home/<user_name>/app
:
主文件
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def receive_file():
file_content = request.form['data']
# TODO
# Implement process to save this data onto a file
return 'Hello from Flask!'
if __name__ == '__main__':
app.run()
- 在同一目录中创建 wsgi 服务器入口点:
主文件
import sys
sys.path.insert(0, '/var/www/html/app')
from main import app as application
将以下行添加到标记
/etc/apache2/sites-enabled/000-default.conf
之后:DocumentRoot
WSGIDaemonProcess flaskapp threads=5 WSGIScriptAlias / /var/www/html/app/main.wsgi <Directory app> WSGIProcessGroup main WSGIApplicationGroup %{GLOBAL} Order deny,allow Allow from all </Directory>
运行
sudo apachectl restart
。您应该能够将发布请求发送到您的应用程序,发送到 VM 实例的内部 IP(您可以在控制台的 Compute Engine 部分中看到它)。拥有它后,在您的云功能中,您应该将响应行更改为:response = requests.post('<INTERNAL_INSTANCE_IP>/', headers=headers, data=data) return "Request sent to your instance with the data of the object"
推荐阅读
- average - 50 次 Netlogo Simulation_Agent Based Simulation 的平均结果
- flask - 单元测试 Flask-Admin 模块?
- gcc - 如何从 gcc 隐藏单个头文件
- python - Pandas df.style.bar 同时保持舍入
- angular - 为什么动态创建的(SVG)矩形组件只出现在 DOM 中而不出现在视图中?
- php - Cakephp 从 3.6.16 升级到 4.2 rector 命令不起作用 bin/cake upgrade rector --rules phpunit80 C:\Apache24\htdocs\Techno\tests
- javascript - 访问函数外的 JSON response.status (Axios)
- python - a[:,:,0] 和 a[:][:][0] 之间的差异
- c# - 将鼠标指针移到原始图像上时如何找到它所属的文件?
- amazon-web-services - 如何在 AWS Athena 中用 0 填充空值