apache-airflow-providers-http 5.0.0rc2__py3-none-any.whl → 5.2.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -199,55 +199,3 @@ distributed under the License is distributed on an "AS IS" BASIS,
199
199
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
200
  See the License for the specific language governing permissions and
201
201
  limitations under the License.
202
-
203
- ============================================================================
204
- APACHE AIRFLOW SUBCOMPONENTS:
205
-
206
- The Apache Airflow project contains subcomponents with separate copyright
207
- notices and license terms. Your use of the source code for the these
208
- subcomponents is subject to the terms and conditions of the following
209
- licenses.
210
-
211
-
212
- ========================================================================
213
- Third party Apache 2.0 licenses
214
- ========================================================================
215
-
216
- The following components are provided under the Apache 2.0 License.
217
- See project link for details. The text of each license is also included
218
- at 3rd-party-licenses/LICENSE-[project].txt.
219
-
220
- (ALv2 License) hue v4.3.0 (https://github.com/cloudera/hue/)
221
- (ALv2 License) jqclock v2.3.0 (https://github.com/JohnRDOrazio/jQuery-Clock-Plugin)
222
- (ALv2 License) bootstrap3-typeahead v4.0.2 (https://github.com/bassjobsen/Bootstrap-3-Typeahead)
223
- (ALv2 License) connexion v2.7.0 (https://github.com/zalando/connexion)
224
-
225
- ========================================================================
226
- MIT licenses
227
- ========================================================================
228
-
229
- The following components are provided under the MIT License. See project link for details.
230
- The text of each license is also included at 3rd-party-licenses/LICENSE-[project].txt.
231
-
232
- (MIT License) jquery v3.5.1 (https://jquery.org/license/)
233
- (MIT License) dagre-d3 v0.6.4 (https://github.com/cpettitt/dagre-d3)
234
- (MIT License) bootstrap v3.4.1 (https://github.com/twbs/bootstrap/)
235
- (MIT License) d3-tip v0.9.1 (https://github.com/Caged/d3-tip)
236
- (MIT License) dataTables v1.10.25 (https://datatables.net)
237
- (MIT License) normalize.css v3.0.2 (http://necolas.github.io/normalize.css/)
238
- (MIT License) ElasticMock v1.3.2 (https://github.com/vrcmarcos/elasticmock)
239
- (MIT License) MomentJS v2.24.0 (http://momentjs.com/)
240
- (MIT License) eonasdan-bootstrap-datetimepicker v4.17.49 (https://github.com/eonasdan/bootstrap-datetimepicker/)
241
-
242
- ========================================================================
243
- BSD 3-Clause licenses
244
- ========================================================================
245
- The following components are provided under the BSD 3-Clause license. See project links for details.
246
- The text of each license is also included at 3rd-party-licenses/LICENSE-[project].txt.
247
-
248
- (BSD 3 License) d3 v5.16.0 (https://d3js.org)
249
- (BSD 3 License) d3-shape v2.1.0 (https://github.com/d3/d3-shape)
250
- (BSD 3 License) cgroupspy 0.2.1 (https://github.com/cloudsigma/cgroupspy)
251
-
252
- ========================================================================
253
- See 3rd-party-licenses/LICENSES-ui.txt for packages used in `/airflow/www`
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "5.0.0"
32
+ __version__ = "5.2.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.9.0"
@@ -0,0 +1,27 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ from __future__ import annotations
18
+
19
+ from airflow.exceptions import AirflowException
20
+
21
+
22
+ class HttpErrorException(AirflowException):
23
+ """Exception raised for HTTP error in Http hook."""
24
+
25
+
26
+ class HttpMethodException(AirflowException):
27
+ """Exception raised for invalid HTTP methods in Http hook."""
@@ -15,8 +15,7 @@
15
15
  # specific language governing permissions and limitations
16
16
  # under the License.
17
17
 
18
- # NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE
19
- # OVERWRITTEN WHEN PREPARING PACKAGES.
18
+ # NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!
20
19
  #
21
20
  # IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
22
21
  # `get_provider_info_TEMPLATE.py.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
@@ -28,8 +27,9 @@ def get_provider_info():
28
27
  "name": "Hypertext Transfer Protocol (HTTP)",
29
28
  "description": "`Hypertext Transfer Protocol (HTTP) <https://www.w3.org/Protocols/>`__\n",
30
29
  "state": "ready",
31
- "source-date-epoch": 1734534857,
30
+ "source-date-epoch": 1739963578,
32
31
  "versions": [
32
+ "5.2.0",
33
33
  "5.0.0",
34
34
  "4.13.3",
35
35
  "4.13.2",
@@ -68,19 +68,12 @@ def get_provider_info():
68
68
  "1.1.0",
69
69
  "1.0.0",
70
70
  ],
71
- "dependencies": [
72
- "apache-airflow>=2.9.0",
73
- "requests>=2.27.0,<3",
74
- "requests-toolbelt>=0.4.0",
75
- "aiohttp>=3.9.2,!=3.11.0",
76
- "asgiref>=2.3.0",
77
- ],
78
71
  "integrations": [
79
72
  {
80
73
  "integration-name": "Hypertext Transfer Protocol (HTTP)",
81
74
  "external-doc-url": "https://www.w3.org/Protocols/",
82
75
  "how-to-guide": ["/docs/apache-airflow-providers-http/operators.rst"],
83
- "logo": "/integration-logos/http/HTTP.png",
76
+ "logo": "/docs/integration-logos/HTTP.png",
84
77
  "tags": ["protocol"],
85
78
  }
86
79
  ],
@@ -111,4 +104,11 @@ def get_provider_info():
111
104
  "connection-types": [
112
105
  {"hook-class-name": "airflow.providers.http.hooks.http.HttpHook", "connection-type": "http"}
113
106
  ],
107
+ "dependencies": [
108
+ "apache-airflow>=2.9.0",
109
+ "requests>=2.27.0,<3",
110
+ "requests-toolbelt>=0.4.0",
111
+ "aiohttp>=3.9.2,!=3.11.0",
112
+ "asgiref>=2.3.0",
113
+ ],
114
114
  }
@@ -17,21 +17,22 @@
17
17
  # under the License.
18
18
  from __future__ import annotations
19
19
 
20
- import asyncio
21
20
  from typing import TYPE_CHECKING, Any, Callable
22
21
  from urllib.parse import urlparse
23
22
 
24
23
  import aiohttp
25
- import requests
26
24
  import tenacity
27
25
  from aiohttp import ClientResponseError
28
26
  from asgiref.sync import sync_to_async
27
+ from requests import PreparedRequest, Request, Response, Session
29
28
  from requests.auth import HTTPBasicAuth
29
+ from requests.exceptions import ConnectionError, HTTPError
30
30
  from requests.models import DEFAULT_REDIRECT_LIMIT
31
31
  from requests_toolbelt.adapters.socket_options import TCPKeepAliveAdapter
32
32
 
33
33
  from airflow.exceptions import AirflowException
34
34
  from airflow.hooks.base import BaseHook
35
+ from airflow.providers.http.exceptions import HttpErrorException, HttpMethodException
35
36
 
36
37
  if TYPE_CHECKING:
37
38
  from aiohttp.client_reqrep import ClientResponse
@@ -47,6 +48,39 @@ def _url_from_endpoint(base_url: str | None, endpoint: str | None) -> str:
47
48
  return (base_url or "") + (endpoint or "")
48
49
 
49
50
 
51
+ def _process_extra_options_from_connection(conn: Connection, extra_options: dict[str, Any]) -> dict:
52
+ extra = conn.extra_dejson
53
+ stream = extra.pop("stream", None)
54
+ cert = extra.pop("cert", None)
55
+ proxies = extra.pop("proxies", extra.pop("proxy", None))
56
+ timeout = extra.pop("timeout", None)
57
+ verify_ssl = extra.pop("verify", extra.pop("verify_ssl", None))
58
+ allow_redirects = extra.pop("allow_redirects", None)
59
+ max_redirects = extra.pop("max_redirects", None)
60
+ trust_env = extra.pop("trust_env", None)
61
+ check_response = extra.pop("check_response", None)
62
+
63
+ if stream is not None and "stream" not in extra_options:
64
+ extra_options["stream"] = stream
65
+ if cert is not None and "cert" not in extra_options:
66
+ extra_options["cert"] = cert
67
+ if proxies is not None and "proxy" not in extra_options:
68
+ extra_options["proxy"] = proxies
69
+ if timeout is not None and "timeout" not in extra_options:
70
+ extra_options["timeout"] = timeout
71
+ if verify_ssl is not None and "verify_ssl" not in extra_options:
72
+ extra_options["verify_ssl"] = verify_ssl
73
+ if allow_redirects is not None and "allow_redirects" not in extra_options:
74
+ extra_options["allow_redirects"] = allow_redirects
75
+ if max_redirects is not None and "max_redirects" not in extra_options:
76
+ extra_options["max_redirects"] = max_redirects
77
+ if trust_env is not None and "trust_env" not in extra_options:
78
+ extra_options["trust_env"] = trust_env
79
+ if check_response is not None and "check_response" not in extra_options:
80
+ extra_options["check_response"] = check_response
81
+ return extra
82
+
83
+
50
84
  class HttpHook(BaseHook):
51
85
  """
52
86
  Interact with HTTP servers.
@@ -69,6 +103,8 @@ class HttpHook(BaseHook):
69
103
  default_conn_name = "http_default"
70
104
  conn_type = "http"
71
105
  hook_name = "HTTP"
106
+ default_host = ""
107
+ default_headers: dict[str, str] = {}
72
108
 
73
109
  def __init__(
74
110
  self,
@@ -109,26 +145,31 @@ class HttpHook(BaseHook):
109
145
 
110
146
  # headers may be passed through directly or in the "extra" field in the connection
111
147
  # definition
112
- def get_conn(self, headers: dict[Any, Any] | None = None) -> requests.Session:
148
+ def get_conn(
149
+ self, headers: dict[Any, Any] | None = None, extra_options: dict[str, Any] | None = None
150
+ ) -> Session:
113
151
  """
114
152
  Create a Requests HTTP session.
115
153
 
116
154
  :param headers: Additional headers to be passed through as a dictionary.
155
+ :param extra_options: additional options to be used when executing the request
117
156
  :return: A configured requests.Session object.
118
157
  """
119
- session = requests.Session()
158
+ session = Session()
120
159
  connection = self.get_connection(self.http_conn_id)
121
160
  self._set_base_url(connection)
122
161
  session = self._configure_session_from_auth(session, connection)
123
162
  if connection.extra:
124
- session = self._configure_session_from_extra(session, connection)
163
+ session = self._configure_session_from_extra(session, connection, extra_options)
125
164
  session = self._configure_session_from_mount_adapters(session)
165
+ if self.default_headers:
166
+ session.headers.update(self.default_headers)
126
167
  if headers:
127
168
  session.headers.update(headers)
128
169
  return session
129
170
 
130
171
  def _set_base_url(self, connection: Connection) -> None:
131
- host = connection.host or ""
172
+ host = connection.host or self.default_host
132
173
  schema = connection.schema or "http"
133
174
  # RFC 3986 (https://www.rfc-editor.org/rfc/rfc3986.html#page-16)
134
175
  if "://" in host:
@@ -141,9 +182,7 @@ class HttpHook(BaseHook):
141
182
  if not parsed.scheme:
142
183
  raise ValueError(f"Invalid base URL: Missing scheme in {self.base_url}")
143
184
 
144
- def _configure_session_from_auth(
145
- self, session: requests.Session, connection: Connection
146
- ) -> requests.Session:
185
+ def _configure_session_from_auth(self, session: Session, connection: Connection) -> Session:
147
186
  session.auth = self._extract_auth(connection)
148
187
  return session
149
188
 
@@ -155,24 +194,24 @@ class HttpHook(BaseHook):
155
194
  return None
156
195
 
157
196
  def _configure_session_from_extra(
158
- self, session: requests.Session, connection: Connection
159
- ) -> requests.Session:
160
- extra = connection.extra_dejson
161
- extra.pop("timeout", None)
162
- extra.pop("allow_redirects", None)
163
- session.proxies = extra.pop("proxies", extra.pop("proxy", {}))
164
- session.stream = extra.pop("stream", False)
165
- session.verify = extra.pop("verify", extra.pop("verify_ssl", True))
166
- session.cert = extra.pop("cert", None)
167
- session.max_redirects = extra.pop("max_redirects", DEFAULT_REDIRECT_LIMIT)
168
- session.trust_env = extra.pop("trust_env", True)
197
+ self, session: Session, connection: Connection, extra_options: dict[str, Any] | None = None
198
+ ) -> Session:
199
+ if extra_options is None:
200
+ extra_options = {}
201
+ headers = _process_extra_options_from_connection(connection, extra_options)
202
+ session.proxies = extra_options.pop("proxies", extra_options.pop("proxy", {}))
203
+ session.stream = extra_options.pop("stream", False)
204
+ session.verify = extra_options.pop("verify", extra_options.pop("verify_ssl", True))
205
+ session.cert = extra_options.pop("cert", None)
206
+ session.max_redirects = extra_options.pop("max_redirects", DEFAULT_REDIRECT_LIMIT)
207
+ session.trust_env = extra_options.pop("trust_env", True)
169
208
  try:
170
- session.headers.update(extra)
209
+ session.headers.update(headers)
171
210
  except TypeError:
172
211
  self.log.warning("Connection to %s has invalid extra field.", connection.host)
173
212
  return session
174
213
 
175
- def _configure_session_from_mount_adapters(self, session: requests.Session) -> requests.Session:
214
+ def _configure_session_from_mount_adapters(self, session: Session) -> Session:
176
215
  scheme = urlparse(self.base_url).scheme
177
216
  if not scheme:
178
217
  raise ValueError(
@@ -207,25 +246,25 @@ class HttpHook(BaseHook):
207
246
  """
208
247
  extra_options = extra_options or {}
209
248
 
210
- session = self.get_conn(headers)
249
+ session = self.get_conn(headers, extra_options)
211
250
 
212
251
  url = self.url_from_endpoint(endpoint)
213
252
 
214
253
  if self.method == "GET":
215
254
  # GET uses params
216
- req = requests.Request(self.method, url, params=data, headers=headers, **request_kwargs)
255
+ req = Request(self.method, url, params=data, headers=headers, **request_kwargs)
217
256
  elif self.method == "HEAD":
218
257
  # HEAD doesn't use params
219
- req = requests.Request(self.method, url, headers=headers, **request_kwargs)
258
+ req = Request(self.method, url, headers=headers, **request_kwargs)
220
259
  else:
221
260
  # Others use data
222
- req = requests.Request(self.method, url, data=data, headers=headers, **request_kwargs)
261
+ req = Request(self.method, url, data=data, headers=headers, **request_kwargs)
223
262
 
224
263
  prepped_request = session.prepare_request(req)
225
264
  self.log.debug("Sending '%s' to url: %s", self.method, url)
226
265
  return self.run_and_check(session, prepped_request, extra_options)
227
266
 
228
- def check_response(self, response: requests.Response) -> None:
267
+ def check_response(self, response: Response) -> None:
229
268
  """
230
269
  Check the status code and raise on failure.
231
270
 
@@ -235,15 +274,15 @@ class HttpHook(BaseHook):
235
274
  """
236
275
  try:
237
276
  response.raise_for_status()
238
- except requests.exceptions.HTTPError:
277
+ except HTTPError:
239
278
  self.log.error("HTTP error: %s", response.reason)
240
279
  self.log.error(response.text)
241
280
  raise AirflowException(str(response.status_code) + ":" + response.reason)
242
281
 
243
282
  def run_and_check(
244
283
  self,
245
- session: requests.Session,
246
- prepped_request: requests.PreparedRequest,
284
+ session: Session,
285
+ prepped_request: PreparedRequest,
247
286
  extra_options: dict[Any, Any],
248
287
  ) -> Any:
249
288
  """
@@ -279,7 +318,7 @@ class HttpHook(BaseHook):
279
318
  self.check_response(response)
280
319
  return response
281
320
 
282
- except requests.exceptions.ConnectionError as ex:
321
+ except ConnectionError as ex:
283
322
  self.log.warning("%s Tenacity will retry to execute the operation", ex)
284
323
  raise ex
285
324
 
@@ -359,6 +398,7 @@ class HttpAsyncHook(BaseHook):
359
398
 
360
399
  async def run(
361
400
  self,
401
+ session: aiohttp.ClientSession,
362
402
  endpoint: str | None = None,
363
403
  data: dict[str, Any] | str | None = None,
364
404
  json: dict[str, Any] | str | None = None,
@@ -399,7 +439,7 @@ class HttpAsyncHook(BaseHook):
399
439
  if conn.login:
400
440
  auth = self.auth_type(conn.login, conn.password)
401
441
  if conn.extra:
402
- extra = self._process_extra_options_from_connection(conn=conn, extra_options=extra_options)
442
+ extra = _process_extra_options_from_connection(conn=conn, extra_options=extra_options)
403
443
 
404
444
  try:
405
445
  _headers.update(extra)
@@ -410,80 +450,51 @@ class HttpAsyncHook(BaseHook):
410
450
 
411
451
  url = _url_from_endpoint(self.base_url, endpoint)
412
452
 
413
- async with aiohttp.ClientSession() as session:
414
- if self.method == "GET":
415
- request_func = session.get
416
- elif self.method == "POST":
417
- request_func = session.post
418
- elif self.method == "PATCH":
419
- request_func = session.patch
420
- elif self.method == "HEAD":
421
- request_func = session.head
422
- elif self.method == "PUT":
423
- request_func = session.put
424
- elif self.method == "DELETE":
425
- request_func = session.delete
426
- elif self.method == "OPTIONS":
427
- request_func = session.options
428
- else:
429
- raise AirflowException(f"Unexpected HTTP Method: {self.method}")
430
-
431
- for attempt in range(1, 1 + self.retry_limit):
432
- response = await request_func(
453
+ if self.method == "GET":
454
+ request_func = session.get
455
+ elif self.method == "POST":
456
+ request_func = session.post
457
+ elif self.method == "PATCH":
458
+ request_func = session.patch
459
+ elif self.method == "HEAD":
460
+ request_func = session.head
461
+ elif self.method == "PUT":
462
+ request_func = session.put
463
+ elif self.method == "DELETE":
464
+ request_func = session.delete
465
+ elif self.method == "OPTIONS":
466
+ request_func = session.options
467
+ else:
468
+ raise HttpMethodException(f"Unexpected HTTP Method: {self.method}")
469
+
470
+ for attempt in range(1, 1 + self.retry_limit):
471
+ response = await request_func(
472
+ url,
473
+ params=data if self.method == "GET" else None,
474
+ data=data if self.method in ("POST", "PUT", "PATCH") else None,
475
+ json=json,
476
+ headers=_headers,
477
+ auth=auth,
478
+ **extra_options,
479
+ )
480
+ try:
481
+ response.raise_for_status()
482
+ except ClientResponseError as e:
483
+ self.log.warning(
484
+ "[Try %d of %d] Request to %s failed.",
485
+ attempt,
486
+ self.retry_limit,
433
487
  url,
434
- params=data if self.method == "GET" else None,
435
- data=data if self.method in ("POST", "PUT", "PATCH") else None,
436
- json=json,
437
- headers=_headers,
438
- auth=auth,
439
- **extra_options,
440
488
  )
441
- try:
442
- response.raise_for_status()
443
- except ClientResponseError as e:
444
- self.log.warning(
445
- "[Try %d of %d] Request to %s failed.",
446
- attempt,
447
- self.retry_limit,
448
- url,
449
- )
450
- if not self._retryable_error_async(e) or attempt == self.retry_limit:
451
- self.log.exception("HTTP error with status: %s", e.status)
452
- # In this case, the user probably made a mistake.
453
- # Don't retry.
454
- raise AirflowException(f"{e.status}:{e.message}")
455
- else:
456
- await asyncio.sleep(self.retry_delay)
457
- else:
458
- return response
489
+ if not self._retryable_error_async(e) or attempt == self.retry_limit:
490
+ self.log.exception("HTTP error with status: %s", e.status)
491
+ # In this case, the user probably made a mistake.
492
+ # Don't retry.
493
+ raise HttpErrorException(f"{e.status}:{e.message}")
459
494
  else:
460
- raise NotImplementedError # should not reach this, but makes mypy happy
461
-
462
- @classmethod
463
- def _process_extra_options_from_connection(cls, conn: Connection, extra_options: dict) -> dict:
464
- extra = conn.extra_dejson
465
- extra.pop("stream", None)
466
- extra.pop("cert", None)
467
- proxies = extra.pop("proxies", extra.pop("proxy", None))
468
- timeout = extra.pop("timeout", None)
469
- verify_ssl = extra.pop("verify", extra.pop("verify_ssl", None))
470
- allow_redirects = extra.pop("allow_redirects", None)
471
- max_redirects = extra.pop("max_redirects", None)
472
- trust_env = extra.pop("trust_env", None)
473
-
474
- if proxies is not None and "proxy" not in extra_options:
475
- extra_options["proxy"] = proxies
476
- if timeout is not None and "timeout" not in extra_options:
477
- extra_options["timeout"] = timeout
478
- if verify_ssl is not None and "verify_ssl" not in extra_options:
479
- extra_options["verify_ssl"] = verify_ssl
480
- if allow_redirects is not None and "allow_redirects" not in extra_options:
481
- extra_options["allow_redirects"] = allow_redirects
482
- if max_redirects is not None and "max_redirects" not in extra_options:
483
- extra_options["max_redirects"] = max_redirects
484
- if trust_env is not None and "trust_env" not in extra_options:
485
- extra_options["trust_env"] = trust_env
486
- return extra
495
+ return response
496
+
497
+ raise NotImplementedError # should not reach this, but makes mypy happy
487
498
 
488
499
  def _retryable_error_async(self, exception: ClientResponseError) -> bool:
489
500
  """
@@ -35,7 +35,12 @@ if TYPE_CHECKING:
35
35
  from requests.auth import AuthBase
36
36
 
37
37
  from airflow.providers.http.hooks.http import HttpHook
38
- from airflow.utils.context import Context
38
+
39
+ try:
40
+ from airflow.sdk.definitions.context import Context
41
+ except ImportError:
42
+ # TODO: Remove once provider drops support for Airflow 2
43
+ from airflow.utils.context import Context
39
44
 
40
45
 
41
46
  class HttpOperator(BaseOperator):
@@ -28,7 +28,11 @@ from airflow.providers.http.triggers.http import HttpSensorTrigger
28
28
  from airflow.sensors.base import BaseSensorOperator
29
29
 
30
30
  if TYPE_CHECKING:
31
- from airflow.utils.context import Context
31
+ try:
32
+ from airflow.sdk.definitions.context import Context
33
+ except ImportError:
34
+ # TODO: Remove once provider drops support for Airflow 2
35
+ from airflow.utils.context import Context
32
36
 
33
37
 
34
38
  class HttpSensor(BaseSensorOperator):
@@ -22,6 +22,7 @@ import pickle
22
22
  from collections.abc import AsyncIterator
23
23
  from typing import TYPE_CHECKING, Any
24
24
 
25
+ import aiohttp
25
26
  import requests
26
27
  from requests.cookies import RequestsCookieJar
27
28
  from requests.structures import CaseInsensitiveDict
@@ -94,13 +95,15 @@ class HttpTrigger(BaseTrigger):
94
95
  auth_type=self.auth_type,
95
96
  )
96
97
  try:
97
- client_response = await hook.run(
98
- endpoint=self.endpoint,
99
- data=self.data,
100
- headers=self.headers,
101
- extra_options=self.extra_options,
102
- )
103
- response = await self._convert_response(client_response)
98
+ async with aiohttp.ClientSession() as session:
99
+ client_response = await hook.run(
100
+ session=session,
101
+ endpoint=self.endpoint,
102
+ data=self.data,
103
+ headers=self.headers,
104
+ extra_options=self.extra_options,
105
+ )
106
+ response = await self._convert_response(client_response)
104
107
  yield TriggerEvent(
105
108
  {
106
109
  "status": "success",
@@ -181,12 +184,14 @@ class HttpSensorTrigger(BaseTrigger):
181
184
  hook = self._get_async_hook()
182
185
  while True:
183
186
  try:
184
- await hook.run(
185
- endpoint=self.endpoint,
186
- data=self.data,
187
- headers=self.headers,
188
- extra_options=self.extra_options,
189
- )
187
+ async with aiohttp.ClientSession() as session:
188
+ await hook.run(
189
+ session=session,
190
+ endpoint=self.endpoint,
191
+ data=self.data,
192
+ headers=self.headers,
193
+ extra_options=self.extra_options,
194
+ )
190
195
  yield TriggerEvent(True)
191
196
  return
192
197
  except AirflowException as exc:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: apache-airflow-providers-http
3
- Version: 5.0.0rc2
3
+ Version: 5.2.0rc1
4
4
  Summary: Provider package apache-airflow-providers-http for Apache Airflow
5
5
  Keywords: airflow-provider,http,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -20,37 +20,20 @@ Classifier: Programming Language :: Python :: 3.10
20
20
  Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Topic :: System :: Monitoring
23
- Requires-Dist: aiohttp>=3.9.2,!=3.11.0
24
23
  Requires-Dist: apache-airflow>=2.9.0rc0
25
- Requires-Dist: asgiref>=2.3.0
26
- Requires-Dist: requests-toolbelt>=0.4.0
27
24
  Requires-Dist: requests>=2.27.0,<3
25
+ Requires-Dist: requests-toolbelt>=0.4.0
26
+ Requires-Dist: aiohttp>=3.9.2,!=3.11.0
27
+ Requires-Dist: asgiref>=2.3.0
28
28
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
29
- Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-http/5.0.0/changelog.html
30
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-http/5.0.0
29
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-http/5.2.0/changelog.html
30
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-http/5.2.0
31
31
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
32
32
  Project-URL: Source Code, https://github.com/apache/airflow
33
33
  Project-URL: Twitter, https://x.com/ApacheAirflow
34
34
  Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
35
35
 
36
36
 
37
- .. Licensed to the Apache Software Foundation (ASF) under one
38
- or more contributor license agreements. See the NOTICE file
39
- distributed with this work for additional information
40
- regarding copyright ownership. The ASF licenses this file
41
- to you under the Apache License, Version 2.0 (the
42
- "License"); you may not use this file except in compliance
43
- with the License. You may obtain a copy of the License at
44
-
45
- .. http://www.apache.org/licenses/LICENSE-2.0
46
-
47
- .. Unless required by applicable law or agreed to in writing,
48
- software distributed under the License is distributed on an
49
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
50
- KIND, either express or implied. See the License for the
51
- specific language governing permissions and limitations
52
- under the License.
53
-
54
37
  .. Licensed to the Apache Software Foundation (ASF) under one
55
38
  or more contributor license agreements. See the NOTICE file
56
39
  distributed with this work for additional information
@@ -68,8 +51,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
68
51
  specific language governing permissions and limitations
69
52
  under the License.
70
53
 
71
- .. NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE
72
- OVERWRITTEN WHEN PREPARING PACKAGES.
54
+ .. NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!
73
55
 
74
56
  .. IF YOU WANT TO MODIFY TEMPLATE FOR THIS FILE, YOU SHOULD MODIFY THE TEMPLATE
75
57
  `PROVIDER_README_TEMPLATE.rst.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
@@ -77,7 +59,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
77
59
 
78
60
  Package ``apache-airflow-providers-http``
79
61
 
80
- Release: ``5.0.0.rc2``
62
+ Release: ``5.2.0``
81
63
 
82
64
 
83
65
  `Hypertext Transfer Protocol (HTTP) <https://www.w3.org/Protocols/>`__
@@ -90,7 +72,7 @@ This is a provider package for ``http`` provider. All classes for this provider
90
72
  are in ``airflow.providers.http`` python package.
91
73
 
92
74
  You can find package information and changelog for the provider
93
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-http/5.0.0/>`_.
75
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-http/5.2.0/>`_.
94
76
 
95
77
  Installation
96
78
  ------------
@@ -115,4 +97,5 @@ PIP package Version required
115
97
  ===================== ====================
116
98
 
117
99
  The changelog for the provider package can be found in the
118
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-http/5.0.0/changelog.html>`_.
100
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-http/5.2.0/changelog.html>`_.
101
+
@@ -0,0 +1,16 @@
1
+ airflow/providers/http/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
2
+ airflow/providers/http/__init__.py,sha256=pa7UNoBEbQ0auhDXexqrUNS8vw5R3RaamnJ8kquAA48,1491
3
+ airflow/providers/http/exceptions.py,sha256=WnIEj0cnAS746uRF1661tCEBc_Uuo0bMEIMrQyEb9nc,1084
4
+ airflow/providers/http/get_provider_info.py,sha256=qV688QITJrCeEudyM10Y4SFDmyHP2UJHkhstIn5eIHQ,3782
5
+ airflow/providers/http/hooks/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
6
+ airflow/providers/http/hooks/http.py,sha256=RgPIy0ccxojA5ywIRAmQCtOsTzKyPj5tb_YBivPcyPg,20788
7
+ airflow/providers/http/operators/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
8
+ airflow/providers/http/operators/http.py,sha256=d8PHAnwIMts0G7TUxLO7RUNkm2hEQY2sRGCWB9E36fQ,14650
9
+ airflow/providers/http/sensors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
10
+ airflow/providers/http/sensors/http.py,sha256=cPB2e01mH92aQYNSNkQsNmvJUTVtEvmX47Dd4rhbBYU,8240
11
+ airflow/providers/http/triggers/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
12
+ airflow/providers/http/triggers/http.py,sha256=uOhEbTyJKhVDcRt28H04l7osD4oIimPJWiRLeF7ay8s,7964
13
+ apache_airflow_providers_http-5.2.0rc1.dist-info/entry_points.txt,sha256=65Rk4MYlxxtwo7y7-uNv4KS7MfoBnILhMjRQmNbRo1Q,100
14
+ apache_airflow_providers_http-5.2.0rc1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
15
+ apache_airflow_providers_http-5.2.0rc1.dist-info/METADATA,sha256=utdPcZSZFpf572nMvzIBSU2_33gGRA4edrkSSejRQz0,4121
16
+ apache_airflow_providers_http-5.2.0rc1.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- airflow/providers/http/LICENSE,sha256=FFb4jd2AXnOOf7XLP04pQW6jbdhG49TxlGY6fFpCV1Y,13609
2
- airflow/providers/http/__init__.py,sha256=nx5slX0MkULC5inxIJHQ5FA5QR3vjo-aX2CFwGtQ3tI,1491
3
- airflow/providers/http/get_provider_info.py,sha256=CFHwcf4CT5ej6yd9d50EzybDfLFOA901r2xtCQvDZzM,3787
4
- airflow/providers/http/hooks/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
5
- airflow/providers/http/hooks/http.py,sha256=A3RRjr0-Y14CAXJ53_kXxwhpYhGnZOomfeLPi56ZDW0,20301
6
- airflow/providers/http/operators/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
7
- airflow/providers/http/operators/http.py,sha256=Tt16jlJ2eSyUXs7jh9zsQkJXHHcZ0Hg0U-xlpXGPRUc,14487
8
- airflow/providers/http/sensors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
9
- airflow/providers/http/sensors/http.py,sha256=pH-hNqMcSQDuyntD6IWzIy-E1mUPM4Yhb4DEFozULDA,8078
10
- airflow/providers/http/triggers/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
11
- airflow/providers/http/triggers/http.py,sha256=XMdM-pGythuJXkfYb22Kl-qthKLtQR4j5O3Tx5j7pls,7697
12
- apache_airflow_providers_http-5.0.0rc2.dist-info/entry_points.txt,sha256=65Rk4MYlxxtwo7y7-uNv4KS7MfoBnILhMjRQmNbRo1Q,100
13
- apache_airflow_providers_http-5.0.0rc2.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
14
- apache_airflow_providers_http-5.0.0rc2.dist-info/METADATA,sha256=fflRBYwM9qlnfdS8S885vvCWsnVFhcbJlBqir0mCxXU,4950
15
- apache_airflow_providers_http-5.0.0rc2.dist-info/RECORD,,