日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Airflow的SimpleHttpOperator不支持https问题解决

發(fā)布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Airflow的SimpleHttpOperator不支持https问题解决 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

首先創(chuàng)建一個SimpleHttpOperator

http_test_operator = SimpleHttpOperator(http_coon_id='http_test_1',endpoint='https://free-api.heweather.com/s6/weather/forecast?unit=m&location=北京&lang=zh&key=*******************',method='GET',response_check=http_resp_check, )

在測試的時候發(fā)現(xiàn)問題如下:

[2018-04-27 11:58:31,880] {http_hook.py:77} INFO - Sending 'GET' to url: https://www.google.com/s6/weather/forecast?unit=m&location=朝陽,北京&lang=zh&key=*********

很明顯url和我們想的不一樣,查詢官方文檔得到如下解釋:

Airflow還能夠通過操作系統(tǒng)的環(huán)境變量來引用連接。環(huán)境變量需要加上前綴AIRFLOW_CONN_才能被視為連接。在Airflow管道中引用連接時,conn_id應(yīng)該是沒有前綴的變量的名稱。例如,如果conn_id 名為postgres_master環(huán)境變量應(yīng)該被命名 AIRFLOW_CONN_POSTGRES_MASTER(注意環(huán)境變量必須全部為大寫)。Airflow假定從環(huán)境變量返回的值是URI格式(例如 postgres://user:password@localhost:5432/master或s3://accesskey:secretkey@S3)。

airflow會首先根據(jù)conn_id在環(huán)境變量中尋找對應(yīng)的host,如果沒有則使用默認的,數(shù)據(jù)庫中connection表的http_default的host值:https://www.google.com/。

于是先設(shè)置環(huán)境變量吧

export AIRFLOW_CONN_WEATHER=https://free-api.heweather.com/

并修改代碼中endpoint參數(shù)如下:

http_test_operator = SimpleHttpOperator(http_coon_id='http_test_1',endpoint='/s6/weather/forecast?unit=m&location=北京&lang=zh&key=*******************',method='GET',response_check=http_resp_check, )

繼續(xù)測試,發(fā)現(xiàn)調(diào)試信息如下:

[2018-04-27 12:21:13,131] {http_hook.py:77} INFO - Sending 'GET' to url: http://free-api.heweather.com/s6/weather/forecast?unit=m&location=北京&lang=zh&key=********************

我們明明設(shè)置的https://,怎么變成了http://

查看源碼

class HttpHook(BaseHook):def get_conn(self, headers):"""Returns http session for use with requests"""conn = self.get_connection(self.http_conn_id)session = requests.Session()if "://" in conn.host:self.base_url = conn.hostelse:# schema defaults to HTTPschema = conn.schema if conn.schema else "http"self.base_url = schema + "://" + conn.host

實際請求的正是這個self.base_url,那么這個conn.schema是哪來的呢?

class BaseHook(LoggingMixin):@classmethoddef get_connections(cls, conn_id):conn = cls._get_connection_from_env(conn_id)if conn:conns = [conn]else:conns = cls._get_connections_from_db(conn_id)return conns

其實到這里已經(jīng)看到我們的環(huán)境變量是怎么起作用了,也看到了如果環(huán)境變量沒有設(shè)置,是會從數(shù)據(jù)庫中選擇的。在數(shù)據(jù)庫中connection表的schema字段正是我們要找的。

@classmethoddef _get_connection_from_env(cls, conn_id):environment_uri = os.environ.get(CONN_ENV_PREFIX + conn_id.upper())conn = Noneif environment_uri:conn = Connection(conn_id=conn_id, uri=environment_uri)return conn

在這個地方,我們明顯可以看到官方文檔中的描述(環(huán)境變量的設(shè)置)是如何被執(zhí)行的。

class Connection(Base, LoggingMixin): def __init__(self, conn_id=None, conn_type=None,host=None, login=None, password=None,schema=None, port=None, extra=None,uri=None):self.conn_id = conn_idif uri:self.parse_from_uri(uri)else:self.conn_type = conn_typeself.host = hostself.login = loginself.password = passwordself.schema = schemaself.port = portself.extra = extra def parse_from_uri(self, uri):temp_uri = urlparse(uri)hostname = temp_uri.hostname or ''if '%2f' in hostname:hostname = hostname.replace('%2f', '/').replace('%2F', '/')conn_type = temp_uri.schemeif conn_type == 'postgresql':conn_type = 'postgres'self.conn_type = conn_typeself.host = hostnameself.schema = temp_uri.path[1:]self.login = temp_uri.usernameself.password = temp_uri.passwordself.port = temp_uri.port

到這里基本上就明白了schema是哪里來的

self.schema = temp_uri.path[1:]

這是什么意思?難道我要寫成"https://free-api.heweather.com/https"

各位看官,到這里基本上我們就明白問題所在了

你可以修改這里的源碼為

self.schema = conn_type

進行測試。

也可以寫成

環(huán)境變量也可以設(shè)置為"https://free-api.heweather.com/https"

如果你的airflow版本和我的不同,源碼可能是下面這個樣子:

# headers is required to make it requireddef get_conn(self, headers):"""Returns http session for use with requests"""conn = self.get_connection(self.http_conn_id)session = requests.Session()self.base_url = conn.hostif not self.base_url.startswith('http'):self.base_url = 'http://' + self.base_urlif conn.port:self.base_url = self.base_url + ":" + str(conn.port) + "/"if conn.login:session.auth = (conn.login, conn.password)if headers:session.headers.update(headers)return session

關(guān)鍵在這里

self.base_url = conn.hostif not self.base_url.startswith('http'):self.base_url = 'http://' + self.base_url

這里的判斷條件(not self.base_url.startswith('http'))必然為真,所以只會拼接“http://”(頭大)

除了更改環(huán)境變量或者上述代碼還要更改代碼如下:

def get_conn(self, headers):"""Returns http session for use with requests"""conn = self.get_connection(self.http_conn_id)session = requests.Session()self.base_url = '{}://{}'.format(conn.sharem, conn.host)# if not self.base_url.startswith('http'):# self.base_url = 'http://' + self.base_urlif conn.port:self.base_url = self.base_url + ":" + str(conn.port) + "/"if conn.login:session.auth = (conn.login, conn.password)if headers:session.headers.update(headers)return session

注意:這樣是沒有添加證書驗證的!

運行會警告:

/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

運行結(jié)果:

{'HeWeather6': [{'basic': {'cid': 'CN101010300', 'location': '朝陽', 'parent_city': '北京', 'admin_area': '北京', 'cnty': '中國', 'lat': '39.92148972', 'lon': '116.48641205', 'tz': '+8.00'}, 'update': {'loc': '2018-04-27 17:47', 'utc': '2018-04-27 09:47'}, 'status': 'ok', 'daily_forecast': [{'cond_code_d': '100', 'cond_code_n': '100', 'cond_txt_d': '晴', 'cond_txt_n': '晴', 'date': '2018-04-27', 'hum': '40', 'mr': '16:06', 'ms': '04:04', 'pcpn': '0.0', 'pop': '0', 'pres': '1021', 'sr': '05:20', 'ss': '19:04', 'tmp_max': '27', 'tmp_min': '13', 'uv_index': '7', 'vis': '10', 'wind_deg': '0', 'wind_dir': '無持續(xù)風向', 'wind_sc': '1-2', 'wind_spd': '7'}, {'cond_code_d': '100', 'cond_code_n': '100', 'cond_txt_d': '晴', 'cond_txt_n': '晴', 'date': '2018-04-28', 'hum': '41', 'mr': '17:11', 'ms': '04:35', 'pcpn': '0.0', 'pop': '0', 'pres': '1013', 'sr': '05:18', 'ss': '19:05', 'tmp_max': '27', 'tmp_min': '16', 'uv_index': '8', 'vis': '20', 'wind_deg': '188', 'wind_dir': '南風', 'wind_sc': '1-2', 'wind_spd': '7'}, {'cond_code_d': '101', 'cond_code_n': '305', 'cond_txt_d': '多云', 'cond_txt_n': '小雨', 'date': '2018-04-29', 'hum': '43', 'mr': '18:15', 'ms': '05:07', 'pcpn': '0.0', 'pop': '0', 'pres': '1005', 'sr': '05:17', 'ss': '19:06', 'tmp_max': '30', 'tmp_min': '18', 'uv_index': '8', 'vis': '20', 'wind_deg': '181', 'wind_dir': '南風', 'wind_sc': '1-2', 'wind_spd': '10'}]}]}

總結(jié)

以上是生活随笔為你收集整理的Airflow的SimpleHttpOperator不支持https问题解决的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。