我是使用 GCP 功能/產品的完全初學者。我在下面撰寫了以下代碼,它從本地檔案夾中獲取城市串列,并呼叫該串列中每個城市的天氣資料,最終將這些天氣值上傳到 BigQuery 的表中。我不再需要更改代碼,因為它會在新的一周開始時創建新表,現在我想在云中“部署”(我什至不確定這是否稱為部署代碼)以使其在那里自動運行。我嘗試使用 App Engine 和 Cloud Functions,但在這兩個地方都遇到了問題。
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
在代碼中,直接參考了兩個位于本地的檔案,一個是城市串列,另一個是包含在 GCP 中訪問我的專案的憑據的 JSON 檔案。我相信將這些檔案上傳到 Cloud Storage 并參考它們不會有問題,但后來我意識到如果不使用憑證檔案,我實際上無法訪問 Cloud Storage 中的存盤桶。
這讓我不確定整個程序是否可行,如果我需要首先在本地參考它,我如何首先從云端進行身份驗證?似乎是一個無限回圈,我從 Cloud Storage 中的檔案進行身份驗證,但我需要先進行身份驗證才能訪問該檔案。
我真的很感謝這里的一些幫助,我不知道從哪里開始,而且我在 SE/CS 方面也沒有很多知識,我只知道 Python R 和 SQL。
uj5u.com熱心網友回復:
對于 Cloud Functions,默認情況下,部署的函式將使用專案服務帳戶憑據運行,無需單獨的憑據檔案。只需確保此服務帳戶有權訪問它將嘗試訪問的任何資源。
您可以在此處閱讀有關此方法的更多資訊(以及根據需要使用其他服務帳戶的選項):https : //cloud.google.com/functions/docs/securing/function-identity
這種方法非常簡單,讓您完全不必處理服務器上的憑據檔案。請注意,您應該洗掉 os.environ 行,因為它是不需要的。BigQuery 客戶端將使用上述默認憑據。
如果您希望代碼無論是在本地機器上還是部署到云上都能以相同的方式運行,只需在您機器上的作業系統中永久設定一個“GOOGLE_APPLICATION_CREDENTIALS”環境變數。這與您在發布的代碼中所做的類似;但是,您每次使用 os.environ 都會臨時設定它,而不是在您的機器上永久設定環境變數。os.environ 呼叫僅為該行程執行設定該環境變數。
如果由于某種原因您不想使用上面概述的默認服務帳戶方法,則可以在實體化 bigquery.Client() 時直接參考它
https://cloud.google.com/bigquery/docs/authentication/service-account-file
您只需要將憑證檔案與您的代碼打包在一起(即與您的 main.py 檔案在同一檔案夾中),并將其部署在執行環境中。在這種情況下,它可以從您的腳本中參考/加載,而無需任何特殊權限或憑據。只需提供檔案的相對路徑(即假設您將它與您的 python 腳本放在同一目錄中,只需參考檔案名)
uj5u.com熱心網友回復:
可能有不同的風格和選項來部署您的應用程式,這些將取決于您的應用程式語意和執行約束。
涵蓋所有這些內容太難了,Google Cloud Platform 官方檔案非常詳細地涵蓋了所有這些內容:
- 谷歌計算引擎
- 谷歌 Kubernetes 引擎
- 谷歌應用引擎
- 谷歌云函式
- 谷歌云運行
根據我對您的應用程式設計的理解,最合適的將是:
- 谷歌應用引擎
- 谷歌云函式
- Google Cloud Run:檢查這些標準,看看您的應用程式是否適合這種部署方式
我建議使用Cloud Functions作為您的部署選項,在這種情況下,您的應用程式將默認使用專案App Engine服務帳戶進行身份驗證并執行允許的操作。因此,您應該只檢查IAM配置部分下的默認帳戶[email protected]是否可以正確訪問所需的 API(在您的情況下為BigQuery)。
在這樣的設定中,您需要將您的服務帳戶密鑰推送到Cloud Storage,我建議在任何一種情況下都避免這種情況,并且您需要拉動它,因為運行時將為您處理身份驗證功能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/384658.html
