有没有一种方法可以在GCP中自动化这个Python脚本



我是使用GCP函数/产品的完全初学者。我在下面写了以下代码,从本地文件夹中获取城市列表,并调用该列表中每个城市的天气数据,最终将这些天气值上传到BigQuery中的表中。我不需要再更改代码了,因为它会在新的一周开始时创建新的表,现在我想"部署";(我甚至不确定这是否被称为部署代码),以便它在云中自动运行。我尝试使用应用程序引擎和云功能,但在这两个地方都遇到了问题。

import requests, json, sqlite3, os, csv, datetime, re
from google.cloud import bigquery
#from google.cloud import storage
list_city = []
with open("list_of_cities.txt", "r") as pointer:
for line in pointer:
list_city.append(line.strip())
API_key = "PLACEHOLDER"
Base_URL = "http://api.weatherapi.com/v1/history.json?key="
yday = datetime.date.today() - datetime.timedelta(days = 1)
Date = yday.strftime("%Y-%m-%d")
table_id = f"sonic-cat-315013.weather_data.Historical_Weather_{yday.isocalendar()[0]}_{yday.isocalendar()[1]}"
credentials_path = r"PATH_TO_JSON_FILE"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = credentials_path
client = bigquery.Client()
try:
schema = [
bigquery.SchemaField("city", "STRING", mode="REQUIRED"),
bigquery.SchemaField("Date", "Date", mode="REQUIRED"),
bigquery.SchemaField("Hour", "INTEGER", mode="REQUIRED"),
bigquery.SchemaField("Temperature", "FLOAT", mode="REQUIRED"),
bigquery.SchemaField("Humidity", "FLOAT", mode="REQUIRED"),
bigquery.SchemaField("Condition", "STRING", mode="REQUIRED"),
bigquery.SchemaField("Chance_of_rain", "FLOAT", mode="REQUIRED"),
bigquery.SchemaField("Precipitation_mm", "FLOAT", mode="REQUIRED"),
bigquery.SchemaField("Cloud_coverage", "INTEGER", mode="REQUIRED"),
bigquery.SchemaField("Visibility_km", "FLOAT", mode="REQUIRED")
]

table = bigquery.Table(table_id, schema=schema)
table.time_partitioning = bigquery.TimePartitioning(
type_=bigquery.TimePartitioningType.DAY,
field="Date",  # name of column to use for partitioning
)
table = client.create_table(table)  # Make an API request.
print(
"Created table {}.{}.{}".format(table.project, table.dataset_id, table.table_id)
)
except:
print("Table {}_{} already exists".format(yday.isocalendar()[0], yday.isocalendar()[1]))

def get_weather():
try:
x["location"]
except:
print(f"API could not call city {city_name}")

global day, time, dailytemp, dailyhum, dailycond, chance_rain, Precipitation, Cloud_coverage, Visibility_km    

day = []
time = []
dailytemp = []
dailyhum = []
dailycond = []
chance_rain = []
Precipitation = []
Cloud_coverage = []
Visibility_km = []

for i in range(24):
dayval = re.search("^S*s" ,x["forecast"]["forecastday"][0]["hour"][i]["time"])
timeval = re.search("s(.*)" ,x["forecast"]["forecastday"][0]["hour"][i]["time"])

day.append(dayval.group()[:-1])
time.append(timeval.group()[1:])
dailytemp.append(x["forecast"]["forecastday"][0]["hour"][i]["temp_c"])
dailyhum.append(x["forecast"]["forecastday"][0]["hour"][i]["humidity"])
dailycond.append(x["forecast"]["forecastday"][0]["hour"][i]["condition"]["text"])
chance_rain.append(x["forecast"]["forecastday"][0]["hour"][i]["chance_of_rain"])
Precipitation.append(x["forecast"]["forecastday"][0]["hour"][i]["precip_mm"])
Cloud_coverage.append(x["forecast"]["forecastday"][0]["hour"][i]["cloud"])
Visibility_km.append(x["forecast"]["forecastday"][0]["hour"][i]["vis_km"])
for i in range(len(time)):
time[i] = int(time[i][:2])
def main():
i = 0
while i < len(list_city):
try:
global city_name
city_name = list_city[i]
complete_URL = Base_URL + API_key + "&q=" + city_name + "&dt=" + Date
response = requests.get(complete_URL, timeout = 10)
global x
x = response.json()
get_weather()
table = client.get_table(table_id)
varlist = []
for j in range(24):
variables = city_name, day[j], time[j], dailytemp[j], dailyhum[j], dailycond[j], chance_rain[j], Precipitation[j], Cloud_coverage[j], Visibility_km[j]
varlist.append(variables)

client.insert_rows(table, varlist)
print(f"City {city_name}, ({i+1} out of {len(list_city)}) successfully inserted")
i += 1
except Exception as e:
print(e)
continue

在代码中,直接引用了位于本地的两个文件,一个是城市列表,另一个是JSON文件,其中包含访问GCP中我的项目的凭据。我相信将这些文件上传到云存储并引用它们不会有问题,但后来我意识到,如果不使用凭据文件,我实际上无法在云存储中访问我的Buckets。

这让我不确定整个过程是否可行,如果我需要在本地引用第一个,我如何首先从云中进行身份验证?这似乎是一个无休止的循环,我会从云存储中的文件进行身份验证,但我需要首先进行身份验证才能访问该文件。

我真的很感激这里的帮助,我不知道从哪里开始,而且我在SE/CS方面也没有很好的知识,我只知道Python R和SQL。

对于云功能,默认情况下,部署的功能将使用项目服务帐户凭据运行,而不需要单独的凭据文件。只需确保此服务帐户被授予访问它将尝试访问的任何资源的权限。

您可以在此处阅读有关此方法的更多信息(如果您愿意,还可以选择使用其他服务帐户):https://cloud.google.com/functions/docs/securing/function-identity

这种方法非常简单,使您完全不必处理服务器上的凭据文件。请注意,您应该删除os.environ行,因为它是不需要的。BigQuery客户端将使用如上所述的默认凭据。

如果你想让代码在本地机器上或部署到云上运行,只需设置一个";GOOGLE_APPLICATION_CREDENTIALS";环境变量永久存在于您机器上的操作系统中。这与你在发布的代码中所做的类似;但是,每次使用os.environ都会临时设置它,而不是在机器上永久设置环境变量。os.environ调用仅为该进程执行设置该环境变量。

如果出于某种原因,您不想使用上面概述的默认服务帐户方法,那么您可以在实例化bigquery时直接引用它。客户端()

https://cloud.google.com/bigquery/docs/authentication/service-account-file

您只需要将凭证文件与代码打包(即与main.py文件在同一文件夹中),并将其一起部署,使其处于执行环境中。在这种情况下,它可以从脚本中引用/加载,而不需要任何特殊权限或凭据。只需提供文件的相对路径(即,假设它与python脚本位于同一目录中,只需引用文件名)

部署应用程序可能有不同的风格和选项,这些将取决于应用程序的语义和执行约束。

很难涵盖所有这些,谷歌云平台的官方文档非常详细地涵盖了所有这些:

  • 谷歌计算引擎
  • Google Kubernetes引擎
  • 谷歌应用程序引擎
  • 谷歌云功能
  • 谷歌云运行

根据我对您的应用程序设计的理解,最合适的是:

  • 谷歌应用引擎
  • 谷歌云功能
  • 谷歌云运行:检查这些标准,看看你的应用程序是否适合这种部署风格

我建议使用云功能作为部署选项,在这种情况下,您的应用程序将默认使用项目应用程序引擎服务帐户进行身份验证并执行允许的操作。因此,您应该只检查默认帐户PROJECT_ID@appspot.gserviceaccount.comIAM配置部分下的可以正确访问所需的API(在您的情况下为BigQuery)。

在这样的设置中,您需要将您的服务帐户密钥推送到云存储,我建议在这两种情况下都不要这样做,并且您需要提取它,因为运行时将为您处理身份验证功能。

相关内容

  • 没有找到相关文章