Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-05-25 Thread via GitHub


potiuk commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4538700952

   @jacobcbeaudin — There are 1 unresolved review thread(s) on this PR, and you 
have engaged with each one (post-review commits and/or in-thread replies). 
Could you confirm whether you believe the feedback is fully addressed and the 
PR is ready for maintainer review confirmation?
   
   If yes, reply here (a short "yes / ready" is fine) and an Apache Airflow 
maintainer will pick the PR up from the review queue on the next sweep.
   
   If you are still working on a thread, please reply with what is outstanding 
so the threads stay unresolved on purpose.
   
   ---
   
   _Note: This comment was drafted by an AI-assisted triage tool and may 
contain mistakes. Once you have addressed the points above, an Apache Airflow 
maintainer — a real person — will take the next look at your PR. We use this 
[two-stage triage 
process](https://github.com/apache/airflow/blob/main/contributing-docs/25_maintainer_pr_triage.md#why-the-first-pass-is-automated)
 so that our maintainers' limited time is spent where it matters most: the 
conversation with you._
   
   ---
   Drafted-by: Claude Code (Opus 4.7); reviewed by @potiuk before posting
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-05-18 Thread via GitHub


potiuk commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4476938392

   @jacobcbeaudin — There are 1 unresolved review thread on this PR from 
@eladkal. Could you either push a fix or reply in each thread explaining why 
the feedback doesn't apply? Once you believe the feedback is addressed, mark 
the thread as resolved so the reviewer isn't re-pinged needlessly. Thanks!
   
   ---
   
   _Note: This comment was drafted by an AI-assisted triage tool and may 
contain mistakes. Once you have addressed the points above, an Apache Airflow 
maintainer — a real person — will take the next look at your PR. We use this 
[two-stage triage 
process](https://github.com/apache/airflow/blob/main/contributing-docs/25_maintainer_pr_triage.md#why-the-first-pass-is-automated)
 so that our maintainers' limited time is spent where it matters most: the 
conversation with you._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-27 Thread via GitHub


jroachgolf84 commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4331785685

   One other thing; were you able to test this E2E in Snowflake? Does this work 
as expected?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-17 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3102871989


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+

Review Comment:
   Good question. Template fields **do** get mutated in place by Airflow's 
template renderer. From 
[`templater.py`](https://github.com/apache/airflow/blob/main/task-sdk/src/airflow/sdk/definitions/_internal/templater.py#L170-L175):
   
   > Render template fields on *parent* in-place. [...] the result is written 
back via `setattr`.
   
   So if a DAG author writes `parameters=["{{ params.p1 }}"]`, after rendering 
`self.parameters` becomes `["actual_value"]`.
   
   The rebuild is needed so that single-quote (and backslash) escaping applies 
to the **rendered value**, not the Jinja template string. Concrete example:
   
   ```python
   SnowflakeNotebookOperator(
   notebook="MY_NB",
   parameters=["{{ params.name }}"],  # where params.name = "O'Brien"
   )
   ```
   
   - `__init__`: escaping runs on the literal `"{{ params.name }}"` (no-op, no 
quotes to escape). Pre-render SQL is `"EXECUTE NOTEBOOK MY_NB('{{ params.name 
}}')"`.
   - After template rendering: `self.parameters = ["O'Brien"]`. Without the 
rebuild, the SQL just gets its Jinja rendered directly, producing `"EXECUTE 
NOTEBOOK MY_NB('O'Brien')"` — broken SQL with an unescaped quote.
   - With the rebuild: `execute()` calls `_build_execute_notebook_query()` from 
the now-rendered `self.parameters`, producing `"EXECUTE NOTEBOOK 
MY_NB('O''Brien')"` — correct.
   
   Your question also prompted a deeper review that uncovered a related bug: 
`self.parameters` was being clobbered to `None` by the parent 
`SQLExecuteQueryOperator.__init__` (which owns its own `parameters` attribute 
for SQL bind parameters). I've fixed that in the latest push, along with adding 
backslash escaping (Snowflake interprets `\` in string literals per [their 
docs](https://docs.snowflake.com/en/sql-reference/data-types-text)). Thanks for 
pushing on this.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-17 Thread via GitHub


jroachgolf84 commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3100353485


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+

Review Comment:
   Hmmm, I don't think that `self.notebook` or `self.parameters` are "going to 
change" after templating... What would cause these to change?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-10 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3066945174


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+

Review Comment:
   Good catch. Fixed — added an `execute()` override that rebuilds `self.sql` 
from the rendered `self.notebook` and `self.parameters` before calling 
`super().execute()`. This ensures single-quote escaping applies to the actual 
rendered values, not Jinja template strings.



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}

Review Comment:
   The parent `SnowflakeSqlApiOperator` uses the same `set()` pattern, as do 
`SnowflakeCheckOperator`, `GKEOperatorMixin`, and many other operators across 
the repo. Airflow renders template fields independently regardless of order, so 
this has no functional impact. Keeping it consistent with the existing pattern.



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted 

Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-10 Thread via GitHub


Copilot commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3066476616


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+

Review Comment:
   `sql` is built once in `__init__`, but `notebook`/`parameters` are declared 
as `template_fields`. After templating, `self.notebook` / `self.parameters` may 
change but `self.sql` will not, so the executed statement can be stale. Rebuild 
`self.sql` after template rendering (e.g., at the start of `execute()` / before 
deferral) or remove `notebook`/`parameters` from `template_fields` and rely 
solely on templating `sql`.



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.

Review Comment:
   The docstring states non-string parameter types are interpreted as `NULL`, 
but the implementation assumes every element supports `.replace(...)` and 
always emits quoted string literals. Either (a) update the docs to match the 
actual supported type (`list[str]` only) and raise a clear error for 
non-strings, or (b) implement the documented behavior by converting non-strings 
to `NULL` (unquoted) when building the SQL.



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -526,3 +526,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass 

Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-07 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3047801085


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake_notebook.py:
##


Review Comment:
   updated



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-07 Thread via GitHub


eladkal commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3046539518


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake_notebook.py:
##


Review Comment:
   Don't forget to unify the tests under the equivalent files as well



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-07 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3046392159


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+
+def _build_execute_notebook_query(self) -> str:
+"""Build the ``EXECUTE NOTEBOOK`` SQL statement."""
+params_clause = ""
+if self.parameters:
+escaped = ", ".join(f"'{p.replace(chr(39), chr(39) + chr(39))}'" 
for p in self.parameters)
+params_clause = escaped

Review Comment:
   This escapes single quotes in notebook parameter values using standard SQL 
escaping (`'` → `''`), then wraps each parameter in single quotes to build the 
`EXECUTE NOTEBOOK` SQL string. I've cleaned it up — previously it used 
`chr(39)` which was hard to read. Now it's two clear steps:
   
   ```python
   sanitized = [p.replace("'", "''") for p in self.parameters]
   params_clause = ", ".join(f"'{p}'" for p in sanitized)
   ```
   
   These parameters are set by DAG authors (not user input), so this is 
consistent with how other Airflow operators handle object names and literal 
values in SQL construction.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-07 Thread via GitHub


eladkal commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3043492320


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,48 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+"""
+
+template_fields: Sequence[str] = tuple(
+set(SnowflakeSqlApiOperator.template_fields) | {"notebook", 
"parameters"}
+)
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+**kwargs: Any,
+) -> None:
+self.notebook = notebook
+self.parameters = parameters
+sql = self._build_execute_notebook_query()
+super().__init__(sql=sql, statement_count=1, **kwargs)
+
+def _build_execute_notebook_query(self) -> str:
+"""Build the ``EXECUTE NOTEBOOK`` SQL statement."""
+params_clause = ""
+if self.parameters:
+escaped = ", ".join(f"'{p.replace(chr(39), chr(39) + chr(39))}'" 
for p in self.parameters)
+params_clause = escaped

Review Comment:
   Can you please explain this part?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-01 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r3024880258


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,70 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+The operator supports the following authentication methods via the 
Snowflake connection:
+
+- **Key pair**: provide ``private_key_file`` or ``private_key_content`` in 
the connection extras.
+- **OAuth**: provide ``refresh_token``, ``client_id``, and 
``client_secret`` in the connection extras.
+- **Programmatic Access Token (PAT)**: set ``authenticator`` to 
``programmatic_access_token`` in
+  the connection extras and put the PAT value in the connection 
``password`` field.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+:param snowflake_conn_id: Reference to the Snowflake connection.
+:param warehouse: Snowflake warehouse name (overrides connection default).
+:param database: Snowflake database name (overrides connection default).
+:param schema: Snowflake schema name (overrides connection default).
+:param role: Snowflake role name (overrides connection default).
+:param authenticator: Snowflake authenticator type.
+:param session_parameters: Snowflake session-level parameters.
+:param poll_interval: Seconds between status checks (default 5).

Review Comment:
   Actually `poll_interval` is used in both modes — the parent's 
`poll_on_queries()` calls `time.sleep(self.poll_interval)` during synchronous 
polling too. I've removed all inherited param docs from this subclass docstring 
since they're already documented on the parent.



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,70 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+The operator supports the following authentication methods via the 
Snowflake connection:
+
+- **Key pair**: provide ``private_key_file`` or ``private_key_content`` in 
the connection extras.
+- **OAuth**: provide ``refresh_token``, ``client_id``, and 
``client_secret`` in the connection extras.
+- **Programmatic Access Token (PAT)**: set ``authenticator`` to 
``programmatic_access_token`` in
+  the connection extras and put the PAT value in the connection 
``password`` field.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_

Review Comment:
   Good point — removed. The parent class and connection docs already cover 
this.



##
providers/snowflake/tests/system/snowflake/example_snowflake_notebook.py:
##
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied

Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-04-01 Thread via GitHub


potiuk commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4169282822

   @jacobcbeaudin This PR has been converted to **draft** because it does not 
yet meet our [Pull Request quality 
criteria](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-quality-criteria).
   
   **Issues found:**
   - :x: **Pre-commit / static checks**: Failing: CI image checks / Static 
checks. Run `prek run --from-ref main` locally to find and fix issues. See 
[Pre-commit / static checks 
docs](https://github.com/apache/airflow/blob/main/contributing-docs/08_static_code_checks.rst).
   - :warning: **Unresolved review comments**: This PR has 2 unresolved review 
threads from maintainers: **@eladkal** (MEMBER): 2 unresolved threads. Please 
review and resolve all inline review comments before requesting another review. 
You can resolve a conversation by clicking 'Resolve conversation' on each 
thread after addressing the feedback. See [pull request 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst).
   
   > **Note:** Your branch is **182 commits behind `main`**. Some check 
failures may be caused by changes in the base branch rather than by your PR. 
Please rebase your branch and push again to get up-to-date CI results.
   
   **What to do next:**
   - The comment informs you what you need to do.
   - Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - 
but only after making sure that all the issues are fixed.
   - There is no rush — take your time and work at your own pace. We appreciate 
your contribution and are happy to wait for updates.
   - Maintainers will then proceed with a normal review.
   
   Converting a PR to draft is **not** a rejection — it is an invitation to 
bring the PR up to the project's standards so that maintainer review time is 
spent productively. There is no rush — take your time and work at your own 
pace. We appreciate your contribution and are happy to wait for updates. If you 
have questions, feel free to ask on the [Airflow 
Slack](https://s.apache.org/airflow-slack).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-24 Thread via GitHub


eladkal commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r2982939259


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,70 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+The operator supports the following authentication methods via the 
Snowflake connection:
+
+- **Key pair**: provide ``private_key_file`` or ``private_key_content`` in 
the connection extras.
+- **OAuth**: provide ``refresh_token``, ``client_id``, and 
``client_secret`` in the connection extras.
+- **Programmatic Access Token (PAT)**: set ``authenticator`` to 
``programmatic_access_token`` in
+  the connection extras and put the PAT value in the connection 
``password`` field.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+:param snowflake_conn_id: Reference to the Snowflake connection.
+:param warehouse: Snowflake warehouse name (overrides connection default).
+:param database: Snowflake database name (overrides connection default).
+:param schema: Snowflake schema name (overrides connection default).
+:param role: Snowflake role name (overrides connection default).
+:param authenticator: Snowflake authenticator type.
+:param session_parameters: Snowflake session-level parameters.
+:param poll_interval: Seconds between status checks (default 5).

Review Comment:
   ```suggestion
   :param poll_interval: Seconds between status checks (default 5). Used 
only in deferrable mode.
   ```
   
   I assume?



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake.py:
##
@@ -524,3 +524,70 @@ def on_kill(self) -> None:
 self.log.info("Cancelling the query ids %s", self.query_ids)
 self._hook.cancel_queries(self.query_ids)
 self.log.info("Query ids %s cancelled successfully", 
self.query_ids)
+
+
+class SnowflakeNotebookOperator(SnowflakeSqlApiOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Builds an ``EXECUTE NOTEBOOK`` statement and delegates execution to
+
:class:`~airflow.providers.snowflake.operators.snowflake.SnowflakeSqlApiOperator`,
+which handles query submission, polling, deferral, and cancellation.
+
+The operator supports the following authentication methods via the 
Snowflake connection:
+
+- **Key pair**: provide ``private_key_file`` or ``private_key_content`` in 
the connection extras.
+- **OAuth**: provide ``refresh_token``, ``client_id``, and 
``client_secret`` in the connection extras.
+- **Programmatic Access Token (PAT)**: set ``authenticator`` to 
``programmatic_access_token`` in
+  the connection extras and put the PAT value in the connection 
``password`` field.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_

Review Comment:
   Do we need this here? feels more like things we should explain in the 
provider connection docs?



##
providers/snowflake/tests/system/snowflake/example_snowflake_notebook.py:
##
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""
+Examp

Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-24 Thread via GitHub


jacobcbeaudin commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r2982716996


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake_notebook.py:
##


Review Comment:
   @eladkal Done — moved `SnowflakeNotebookOperator` into `snowflake.py` and 
removed the separate file.



##
airflow-core/newsfragments/63470.feature.rst:
##


Review Comment:
   @eladkal Removed, thanks for the heads up.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-23 Thread via GitHub


eladkal commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r2938910169


##
airflow-core/newsfragments/63470.feature.rst:
##


Review Comment:
   newsfragments are not needed for providers



##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake_notebook.py:
##


Review Comment:
   I don't think this needs a new file?
   it can just be another class in snowflake.py



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-16 Thread via GitHub


SameerMesiah97 commented on code in PR #63470:
URL: https://github.com/apache/airflow/pull/63470#discussion_r2943638361


##
providers/snowflake/src/airflow/providers/snowflake/operators/snowflake_notebook.py:
##
@@ -0,0 +1,236 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import time
+from collections.abc import Sequence
+from datetime import timedelta
+from functools import cached_property
+from typing import TYPE_CHECKING, Any
+
+from airflow.providers.common.compat.sdk import AirflowException, 
BaseOperator, conf
+from airflow.providers.snowflake.hooks.snowflake_sql_api import 
SnowflakeSqlApiHook
+from airflow.providers.snowflake.triggers.snowflake_trigger import 
SnowflakeSqlApiTrigger
+
+if TYPE_CHECKING:
+from airflow.providers.common.compat.sdk import Context
+
+
+class SnowflakeNotebookOperator(BaseOperator):
+"""
+Execute a Snowflake Notebook via the Snowflake SQL API.
+
+Submits an ``EXECUTE NOTEBOOK`` statement through the Snowflake SQL API,
+polls for completion, and pushes the statement query id to XCom.
+Supports both synchronous polling and deferrable (async) mode for
+long-running notebook executions.
+
+The operator supports the following authentication methods via the 
Snowflake connection:
+
+- **Key pair**: provide ``private_key_file`` or ``private_key_content`` in 
the connection extras.
+- **OAuth**: provide ``refresh_token``, ``client_id``, and 
``client_secret`` in the connection extras.
+- **Programmatic Access Token (PAT)**: set ``authenticator`` to 
``programmatic_access_token`` in
+  the connection extras and put the PAT value in the connection 
``password`` field.
+
+.. seealso::
+`Snowflake EXECUTE NOTEBOOK
+`_
+
+:param notebook: Fully-qualified notebook name
+(e.g. ``MY_DB.MY_SCHEMA.MY_NOTEBOOK``).
+:param parameters: Optional list of parameter strings to pass to the
+notebook.  Only string values are supported by Snowflake; other
+data types are interpreted as NULL.  Parameters are accessible in
+the notebook via ``sys.argv``.
+:param snowflake_conn_id: Reference to the Snowflake connection.
+:param warehouse: Snowflake warehouse name (overrides connection default).
+:param database: Snowflake database name (overrides connection default).
+:param schema: Snowflake schema name (overrides connection default).
+:param role: Snowflake role name (overrides connection default).
+:param authenticator: Snowflake authenticator type.
+:param session_parameters: Snowflake session-level parameters.
+:param poll_interval: Seconds between status checks (default 5).
+:param token_life_time: Lifetime of the JWT token.
+:param token_renewal_delta: When to renew the JWT token before expiry.
+:param deferrable: If True, run in deferrable mode (frees the worker
+slot while waiting).  Defaults to the ``operators.default_deferrable``
+Airflow config.
+:param snowflake_api_retry_args: Optional dict of arguments forwarded to
+``tenacity.Retrying`` for API call retries.
+"""
+
+LIFETIME = timedelta(minutes=59)
+RENEWAL_DELTA = timedelta(minutes=54)
+
+template_fields: Sequence[str] = (
+"notebook",
+"parameters",
+"snowflake_conn_id",
+)
+
+ui_color = "#ededed"
+
+def __init__(
+self,
+*,
+notebook: str,
+parameters: list[str] | None = None,
+snowflake_conn_id: str = "snowflake_default",
+warehouse: str | None = None,
+database: str | None = None,
+schema: str | None = None,
+role: str | None = None,
+authenticator: str | None = None,
+session_parameters: dict[str, Any] | None = None,
+poll_interval: int = 5,
+token_life_time: timedelta = LIFETIME,
+token_renewal_delta: timedelta = RENEWAL_DELTA,
+deferrable: bool = conf.getboolean("operators", "default_deferrable", 
fallback=False),
+snowflake_api_retry_args: dict[str, Any] | None = None,
+**kwargs: Any,
+) -> Non

Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-13 Thread via GitHub


jacobcbeaudin commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4058075451

   > @jacobcbeaudin This PR has been converted to **draft** because it does not 
yet meet our [Pull Request quality 
criteria](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-quality-criteria).
   > 
   > **Issues found:**
   > 
   > * ❌ **Pre-commit / static checks**: Failing: CI image checks / Static 
checks. Run `prek run --from-ref main` locally to find and fix issues. See 
[Pre-commit / static checks 
docs](https://github.com/apache/airflow/blob/main/contributing-docs/08_static_code_checks.rst).
   > 
   > 
   > > **Note:** Your branch is **18 commits behind `main`**. Some check 
failures may be caused by changes in the base branch rather than by your PR. 
Please rebase your branch and push again to get up-to-date CI results.
   > 
   > **What to do next:**
   > 
   > * The comment informs you what you need to do.
   > 
   > * Fix each issue, then mark the PR as "Ready for review" in the GitHub 
UI - but only after making sure that all the issues are fixed.
   > 
   > * Maintainers will then proceed with a normal review.
   > 
   > 
   > Converting a PR to draft is **not** a rejection — it is an invitation to 
bring the PR up to the project's standards so that maintainer review time is 
spent productively. If you have questions, feel free to ask on the [Airflow 
Slack](https://s.apache.org/airflow-slack).
   
   @potiuk Thanks for the feedback. I've addressed the issues:
   
   - Rebased onto main
   - Added the `missing get_provider_info.py` update
   
   I've marked the PR as ready for review. As a first-time contributor, I 
believe the CI workflows need maintainer approval before they can run. Would 
someone be able to approve the workflow run so we can verify the checks pass?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-13 Thread via GitHub


potiuk commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4054754494

   @jacobcbeaudin This PR has been converted to **draft** because it does not 
yet meet our [Pull Request quality 
criteria](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-quality-criteria).
   
   **Issues found:**
   - :x: **Pre-commit / static checks**: Failing: CI image checks / Static 
checks. Run `prek run --from-ref main` locally to find and fix issues. See 
[Pre-commit / static checks 
docs](https://github.com/apache/airflow/blob/main/contributing-docs/08_static_code_checks.rst).
   
   > **Note:** Your branch is **18 commits behind `main`**. Some check failures 
may be caused by changes in the base branch rather than by your PR. Please 
rebase your branch and push again to get up-to-date CI results.
   
   **What to do next:**
   - The comment informs you what you need to do.
   - Fix each issue, then mark the PR as "Ready for review" in the GitHub UI - 
but only after making sure that all the issues are fixed.
   - Maintainers will then proceed with a normal review.
   
   Converting a PR to draft is **not** a rejection — it is an invitation to 
bring the PR up to the project's standards so that maintainer review time is 
spent productively. If you have questions, feel free to ask on the [Airflow 
Slack](https://s.apache.org/airflow-slack).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



Re: [PR] Add SnowflakeNotebookOperator for executing Snowflake Notebooks [airflow]

2026-03-12 Thread via GitHub


boring-cyborg[bot] commented on PR #63470:
URL: https://github.com/apache/airflow/pull/63470#issuecomment-4049050045

   Congratulations on your first Pull Request and welcome to the Apache Airflow 
community! If you have any issues or are unsure about any anything please check 
our Contributors' Guide 
(https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
   Here are some useful points:
   - Pay attention to the quality of your code (ruff, mypy and type 
annotations). Our [prek-hooks]( 
https://github.com/apache/airflow/blob/main/contributing-docs/08_static_code_checks.rst#prerequisites-for-prek-hooks)
 will help you with that.
   - In case of a new feature add useful documentation (in docstrings or in 
`docs/` directory). Adding a new operator? Check this short 
[guide](https://github.com/apache/airflow/blob/main/airflow-core/docs/howto/custom-operator.rst)
 Consider adding an example DAG that shows how users should use it.
   - Consider using [Breeze 
environment](https://github.com/apache/airflow/blob/main/dev/breeze/doc/README.rst)
 for testing locally, it's a heavy docker but it ships with a working Airflow 
and a lot of integrations.
   - Be patient and persistent. It might take some time to get a review or get 
the final approval from Committers.
   - Please follow [ASF Code of 
Conduct](https://www.apache.org/foundation/policies/conduct) for all 
communication including (but not limited to) comments on Pull Requests, Mailing 
list and Slack.
   - Be sure to read the [Airflow Coding style]( 
https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#coding-style-and-best-practices).
   - Always keep your Pull Requests rebased, otherwise your build might fail 
due to changes not related to your commits.
   Apache Airflow is a community-driven project and together we are making it 
better 🚀.
   In case of doubts contact the developers at:
   Mailing List: [email protected]
   Slack: https://s.apache.org/airflow-slack
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]