diff --git a/airflow/models/connection.py b/airflow/models/connection.py index da67410a394a9..5f7406d9d4835 100644 --- a/airflow/models/connection.py +++ b/airflow/models/connection.py @@ -206,13 +206,16 @@ def _parse_from_uri(self, uri: str): def get_uri(self) -> str: """Return connection in URI format""" - if "_" in self.conn_type: + if self.conn_type and "_" in self.conn_type: self.log.warning( "Connection schemes (type: %s) shall not contain '_' according to RFC3986.", self.conn_type, ) - uri = f"{str(self.conn_type).lower().replace('_', '-')}://" + if self.conn_type: + uri = f"{self.conn_type.lower().replace('_', '-')}://" + else: + uri = "//" authority_block = "" if self.login is not None: diff --git a/tests/always/test_connection.py b/tests/always/test_connection.py index dac7bb110458f..750b36ef53cfc 100644 --- a/tests/always/test_connection.py +++ b/tests/always/test_connection.py @@ -735,3 +735,11 @@ def test_extra_warnings_non_json(self): def test_extra_warnings_non_dict_json(self): with pytest.warns(DeprecationWarning, match="not parse as a dictionary"): Connection(conn_id="test_extra", conn_type="none", extra='"hi"') + + def test_get_uri_no_conn_type(self): + # no conn type --> scheme-relative URI + assert Connection().get_uri() == "//" + # with host, still works + assert Connection(host="abc").get_uri() == "//abc" + # parsing back as conn still works + assert Connection(uri="//abc").host == "abc"