This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new ca73694702 refactor: Added get_extra_dejson method with nested
parameter which allows you to specify if you want the nested json as string to
be also deserialized. The extra_dejson property uses this method with nested
set to False. (#39811)
ca73694702 is described below
commit ca73694702cc389b4ffb8486a303eec0788470b4
Author: David Blain <[email protected]>
AuthorDate: Fri Jun 14 19:24:21 2024 +0200
refactor: Added get_extra_dejson method with nested parameter which allows
you to specify if you want the nested json as string to be also deserialized.
The extra_dejson property uses this method with nested set to False. (#39811)
Co-authored-by: David Blain <[email protected]>
---
airflow/models/connection.py | 32 ++++++++++++++++++++++++--------
tests/models/test_connection.py | 23 +++++++++++++++++++++++
2 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/airflow/models/connection.py b/airflow/models/connection.py
index 6e1435ebfa..95855e15fe 100644
--- a/airflow/models/connection.py
+++ b/airflow/models/connection.py
@@ -20,6 +20,7 @@ from __future__ import annotations
import json
import logging
import warnings
+from contextlib import suppress
from json import JSONDecodeError
from typing import Any
from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit
@@ -471,21 +472,36 @@ class Connection(Base, LoggingMixin):
return status, message
- @property
- def extra_dejson(self) -> dict:
- """Returns the extra property by deserializing json."""
- obj = {}
+ def get_extra_dejson(self, nested: bool = False) -> dict:
+ """
+ Deserialize extra property to JSON.
+
+ :param nested: Determines whether nested structures are also
deserialized into JSON (default False).
+ """
+ extra = {}
+
if self.extra:
try:
- obj = json.loads(self.extra)
-
+ if nested:
+ for key, value in json.loads(self.extra).items():
+ extra[key] = value
+ if isinstance(value, str):
+ with suppress(JSONDecodeError):
+ extra[key] = json.loads(value)
+ else:
+ extra = json.loads(self.extra)
except JSONDecodeError:
self.log.exception("Failed parsing the json for conn_id %s",
self.conn_id)
# Mask sensitive keys from this list
- mask_secret(obj)
+ mask_secret(extra)
+
+ return extra
- return obj
+ @property
+ def extra_dejson(self) -> dict:
+ """Returns the extra property by deserializing json."""
+ return self.get_extra_dejson()
@classmethod
def get_connection_from_secrets(cls, conn_id: str) -> Connection:
diff --git a/tests/models/test_connection.py b/tests/models/test_connection.py
index 21e5682c8d..3f7504713f 100644
--- a/tests/models/test_connection.py
+++ b/tests/models/test_connection.py
@@ -250,3 +250,26 @@ class TestConnection:
# string works as expected.
def test_sanitize_conn_id(self, connection, expected_conn_id):
assert connection.conn_id == expected_conn_id
+
+ def test_extra_dejson(self):
+ extra = (
+ '{"trust_env": false, "verify": false, "stream": true, "headers":'
+ '{\r\n "Content-Type": "application/json",\r\n "X-Requested-By":
"Airflow"\r\n}}'
+ )
+ connection = Connection(
+ conn_id="pokeapi",
+ conn_type="http",
+ login="user",
+ password="pass",
+ host="https://pokeapi.co/",
+ port=100,
+ schema="https",
+ extra=extra,
+ )
+
+ assert connection.extra_dejson == {
+ "trust_env": False,
+ "verify": False,
+ "stream": True,
+ "headers": {"Content-Type": "application/json", "X-Requested-By":
"Airflow"},
+ }