You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by el...@apache.org on 2022/04/03 07:51:16 UTC
[airflow] branch main updated: Adding ArangoDB Provider (#22548)
This is an automated email from the ASF dual-hosted git repository.
eladkal 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 c758c76 Adding ArangoDB Provider (#22548)
c758c76 is described below
commit c758c76ac336c054fd17d4b878378aa893b7a979
Author: Ashish Patel <as...@gmail.com>
AuthorDate: Sun Apr 3 08:50:04 2022 +0100
Adding ArangoDB Provider (#22548)
* Adding ArangoDB Provider
---
.../airflow_providers_bug_report.yml | 1 +
CONTRIBUTING.rst | 10 +-
INSTALL | 10 +-
airflow/providers/arangodb/CHANGELOG.rst | 25 ++++
airflow/providers/arangodb/__init__.py | 16 +++
.../providers/arangodb/example_dags/__init__.py | 16 +++
.../arangodb/example_dags/example_arangodb.py | 75 ++++++++++++
airflow/providers/arangodb/hooks/__init__.py | 16 +++
airflow/providers/arangodb/hooks/arangodb.py | 129 +++++++++++++++++++++
airflow/providers/arangodb/operators/__init__.py | 16 +++
airflow/providers/arangodb/operators/arangodb.py | 64 ++++++++++
airflow/providers/arangodb/provider.yaml | 48 ++++++++
airflow/providers/arangodb/sensors/__init__.py | 16 +++
airflow/providers/arangodb/sensors/arangodb.py | 54 +++++++++
docs/apache-airflow-providers-arangodb/commits.rst | 31 +++++
.../connections/arangodb.rst | 33 ++++++
docs/apache-airflow-providers-arangodb/index.rst | 90 ++++++++++++++
.../installing-providers-from-sources.rst | 18 +++
.../operators/index.rst | 66 +++++++++++
docs/apache-airflow/extra-packages-ref.rst | 2 +
docs/spelling_wordlist.txt | 4 +
setup.py | 3 +
tests/providers/arangodb/__init__.py | 16 +++
tests/providers/arangodb/hooks/__init__.py | 16 +++
tests/providers/arangodb/hooks/test_arangodb.py | 120 +++++++++++++++++++
tests/providers/arangodb/operators/__init__.py | 16 +++
.../providers/arangodb/operators/test_arangodb.py | 32 +++++
tests/providers/arangodb/sensors/__init__.py | 16 +++
tests/providers/arangodb/sensors/test_arangodb.py | 65 +++++++++++
29 files changed, 1014 insertions(+), 10 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
index 639d2b2..d997af5 100644
--- a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml
@@ -38,6 +38,7 @@ body:
- apache-pinot
- apache-spark
- apache-sqoop
+ - arangodb
- asana
- celery
- cloudant
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 34b2204..2cb7e9d 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -617,11 +617,11 @@ This is the full list of those extras:
airbyte, alibaba, all, all_dbs, amazon, apache.atlas, apache.beam, apache.cassandra, apache.drill,
apache.druid, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig, apache.pinot,
-apache.spark, apache.sqoop, apache.webhdfs, asana, async, atlas, aws, azure, cassandra, celery,
-cgroups, cloudant, cncf.kubernetes, crypto, dask, databricks, datadog, dbt.cloud, deprecated_api,
-devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc, docker, druid, elasticsearch,
-exasol, facebook, ftp, gcp, gcp_api, github, github_enterprise, google, google_auth, grpc,
-hashicorp, hdfs, hive, http, imap, influxdb, jdbc, jenkins, jira, kerberos, kubernetes, ldap,
+apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas, aws, azure, cassandra,
+celery, cgroups, cloudant, cncf.kubernetes, crypto, dask, databricks, datadog, dbt.cloud,
+deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc, docker, druid,
+elasticsearch, exasol, facebook, ftp, gcp, gcp_api, github, github_enterprise, google, google_auth,
+grpc, hashicorp, hdfs, hive, http, imap, influxdb, jdbc, jenkins, jira, kerberos, kubernetes, ldap,
leveldb, microsoft.azure, microsoft.mssql, microsoft.psrp, microsoft.winrm, mongo, mssql, mysql,
neo4j, odbc, openfaas, opsgenie, oracle, pagerduty, pandas, papermill, password, pinot, plexus,
postgres, presto, qds, qubole, rabbitmq, redis, s3, salesforce, samba, segment, sendgrid, sentry,
diff --git a/INSTALL b/INSTALL
index 4354d5e3..8773e86 100644
--- a/INSTALL
+++ b/INSTALL
@@ -97,11 +97,11 @@ The list of available extras:
airbyte, alibaba, all, all_dbs, amazon, apache.atlas, apache.beam, apache.cassandra, apache.drill,
apache.druid, apache.hdfs, apache.hive, apache.kylin, apache.livy, apache.pig, apache.pinot,
-apache.spark, apache.sqoop, apache.webhdfs, asana, async, atlas, aws, azure, cassandra, celery,
-cgroups, cloudant, cncf.kubernetes, crypto, dask, databricks, datadog, dbt.cloud, deprecated_api,
-devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc, docker, druid, elasticsearch,
-exasol, facebook, ftp, gcp, gcp_api, github, github_enterprise, google, google_auth, grpc,
-hashicorp, hdfs, hive, http, imap, influxdb, jdbc, jenkins, jira, kerberos, kubernetes, ldap,
+apache.spark, apache.sqoop, apache.webhdfs, arangodb, asana, async, atlas, aws, azure, cassandra,
+celery, cgroups, cloudant, cncf.kubernetes, crypto, dask, databricks, datadog, dbt.cloud,
+deprecated_api, devel, devel_all, devel_ci, devel_hadoop, dingding, discord, doc, docker, druid,
+elasticsearch, exasol, facebook, ftp, gcp, gcp_api, github, github_enterprise, google, google_auth,
+grpc, hashicorp, hdfs, hive, http, imap, influxdb, jdbc, jenkins, jira, kerberos, kubernetes, ldap,
leveldb, microsoft.azure, microsoft.mssql, microsoft.psrp, microsoft.winrm, mongo, mssql, mysql,
neo4j, odbc, openfaas, opsgenie, oracle, pagerduty, pandas, papermill, password, pinot, plexus,
postgres, presto, qds, qubole, rabbitmq, redis, s3, salesforce, samba, segment, sendgrid, sentry,
diff --git a/airflow/providers/arangodb/CHANGELOG.rst b/airflow/providers/arangodb/CHANGELOG.rst
new file mode 100644
index 0000000..1bafa2d
--- /dev/null
+++ b/airflow/providers/arangodb/CHANGELOG.rst
@@ -0,0 +1,25 @@
+
+
+ .. 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.
+
+Changelog
+---------
+1.0.0
+.....
+
+Initial version of the provider.
diff --git a/airflow/providers/arangodb/__init__.py b/airflow/providers/arangodb/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/airflow/providers/arangodb/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/airflow/providers/arangodb/example_dags/__init__.py b/airflow/providers/arangodb/example_dags/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/airflow/providers/arangodb/example_dags/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/airflow/providers/arangodb/example_dags/example_arangodb.py b/airflow/providers/arangodb/example_dags/example_arangodb.py
new file mode 100644
index 0000000..f9da187
--- /dev/null
+++ b/airflow/providers/arangodb/example_dags/example_arangodb.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.
+from datetime import datetime
+
+from airflow.models.dag import DAG
+from airflow.providers.arangodb.operators.arangodb import AQLOperator
+from airflow.providers.arangodb.sensors.arangodb import AQLSensor
+
+dag = DAG(
+ 'example_arangodb_operator',
+ start_date=datetime(2021, 1, 1),
+ tags=['example'],
+ catchup=False,
+)
+
+# [START howto_aql_sensor_arangodb]
+
+sensor = AQLSensor(
+ task_id="aql_sensor",
+ query="FOR doc IN students FILTER doc.name == 'judy' RETURN doc",
+ timeout=60,
+ poke_interval=10,
+ dag=dag,
+)
+
+# [END howto_aql_sensor_arangodb]
+
+# [START howto_aql_sensor_template_file_arangodb]
+
+sensor = AQLSensor(
+ task_id="aql_sensor_template_file",
+ query="search_judy.sql",
+ timeout=60,
+ poke_interval=10,
+ dag=dag,
+)
+
+# [END howto_aql_sensor_template_file_arangodb]
+
+
+# [START howto_aql_operator_arangodb]
+
+operator = AQLOperator(
+ task_id='aql_operator',
+ query="FOR doc IN students RETURN doc",
+ dag=dag,
+ result_processor=lambda cursor: print([document["name"] for document in cursor]),
+)
+
+# [END howto_aql_operator_arangodb]
+
+# [START howto_aql_operator_template_file_arangodb]
+
+operator = AQLOperator(
+ task_id='aql_operator_template_file',
+ dag=dag,
+ result_processor=lambda cursor: print([document["name"] for document in cursor]),
+ query="search_all.sql",
+)
+
+# [END howto_aql_operator_template_file_arangodb]
diff --git a/airflow/providers/arangodb/hooks/__init__.py b/airflow/providers/arangodb/hooks/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/airflow/providers/arangodb/hooks/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/airflow/providers/arangodb/hooks/arangodb.py b/airflow/providers/arangodb/hooks/arangodb.py
new file mode 100644
index 0000000..f88ed9f
--- /dev/null
+++ b/airflow/providers/arangodb/hooks/arangodb.py
@@ -0,0 +1,129 @@
+#
+# 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.
+
+"""This module allows connecting to a ArangoDB."""
+from typing import Any, Dict, Optional
+
+from arango import AQLQueryExecuteError, ArangoClient as ArangoDBClient
+from arango.result import Result
+
+from airflow import AirflowException
+from airflow.hooks.base import BaseHook
+
+
+class ArangoDBHook(BaseHook):
+ """
+ Interact with ArangoDB.
+
+ Performs a connection to ArangoDB and retrieves client.
+
+ :param arangodb_conn_id: Reference to :ref:`ArangoDB connection id <howto/connection:arangodb>`.
+ """
+
+ conn_name_attr = 'arangodb_conn_id'
+ default_conn_name = 'arangodb_default'
+ conn_type = 'arangodb'
+ hook_name = 'ArangoDB'
+
+ def __init__(self, arangodb_conn_id: str = default_conn_name, *args, **kwargs) -> None:
+ super().__init__(*args, **kwargs)
+ self.hosts = None
+ self.database = None
+ self.username = None
+ self.password = None
+ self.db_conn = None
+ self.arangodb_conn_id = arangodb_conn_id
+ self.client: Optional[ArangoDBClient] = None
+ self.get_conn()
+
+ def get_conn(self) -> ArangoDBClient:
+ """Function that initiates a new ArangoDB connection"""
+ if self.client is not None:
+ return self.client
+
+ conn = self.get_connection(self.arangodb_conn_id)
+ self.hosts = conn.host.split(",")
+ self.database = conn.schema
+ self.username = conn.login
+ self.password = conn.password
+
+ self.client = ArangoDBClient(hosts=self.hosts)
+ self.db_conn = self.client.db(name=self.database, username=self.username, password=self.password)
+ return self.client
+
+ def query(self, query, **kwargs) -> Result:
+ """
+ Function to create a arangodb session
+ and execute the AQL query in the session.
+
+ :param query: AQL query
+ :return: Result
+ """
+ try:
+ if self.db_conn:
+ result = self.db_conn.aql.execute(query, **kwargs)
+ return result
+ else:
+ raise AirflowException(
+ f"Failed to execute AQLQuery, error connecting to database: {self.database}"
+ )
+ except AQLQueryExecuteError as error:
+ raise AirflowException(f"Failed to execute AQLQuery, error: {str(error)}")
+
+ def create_collection(self, name):
+ if not self.db_conn.has_collection(name):
+ self.db_conn.create_collection(name)
+ return True
+ else:
+ self.log.info('Collection already exists: %s', name)
+ return False
+
+ def create_database(self, name):
+ if not self.db_conn.has_database(name):
+ self.db_conn.create_database(name)
+ return True
+ else:
+ self.log.info('Database already exists: %s', name)
+ return False
+
+ def create_graph(self, name):
+ if not self.db_conn.has_graph(name):
+ self.db_conn.create_graph(name)
+ return True
+ else:
+ self.log.info('Graph already exists: %s', name)
+ return False
+
+ @staticmethod
+ def get_ui_field_behaviour() -> Dict[str, Any]:
+ return {
+ "hidden_fields": ['port', 'extra'],
+ "relabeling": {
+ 'host': 'ArangoDB Host URL or comma separated list of URLs (coordinators in a cluster)',
+ 'schema': 'ArangoDB Database',
+ 'login': 'ArangoDB Username',
+ 'password': 'ArangoDB Password',
+ },
+ "placeholders": {
+ 'host': 'eg."http://127.0.0.1:8529" or "http://127.0.0.1:8529,http://127.0.0.1:8530"'
+ ' (coordinators in a cluster)',
+ 'schema': '_system',
+ 'login': 'root',
+ 'password': 'password',
+ },
+ }
diff --git a/airflow/providers/arangodb/operators/__init__.py b/airflow/providers/arangodb/operators/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/airflow/providers/arangodb/operators/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/airflow/providers/arangodb/operators/arangodb.py b/airflow/providers/arangodb/operators/arangodb.py
new file mode 100644
index 0000000..716ca45
--- /dev/null
+++ b/airflow/providers/arangodb/operators/arangodb.py
@@ -0,0 +1,64 @@
+#
+# 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 typing import TYPE_CHECKING, Callable, Optional, Sequence
+
+from airflow.models import BaseOperator
+from airflow.providers.arangodb.hooks.arangodb import ArangoDBHook
+
+if TYPE_CHECKING:
+ from airflow.utils.context import Context
+
+
+class AQLOperator(BaseOperator):
+ """
+ Executes AQL query in a ArangoDB database
+
+ .. seealso::
+ For more information on how to use this operator, take a look at the guide:
+ :ref:`howto/operator:AQLOperator`
+
+ :param query: the AQL query to be executed. Can receive a str representing a
+ AQL statement, or you can provide .sql file having the query
+ :param result_processor: function to further process the Result from ArangoDB
+ :param arangodb_conn_id: Reference to :ref:`ArangoDB connection id <howto/connection:arangodb>`.
+ """
+
+ template_fields: Sequence[str] = ('query',)
+
+ template_ext: Sequence[str] = (".sql",)
+ template_fields_renderers = {"query": "sql"}
+
+ def __init__(
+ self,
+ *,
+ query: str,
+ arangodb_conn_id: str = 'arangodb_default',
+ result_processor: Optional[Callable] = None,
+ **kwargs,
+ ) -> None:
+ super().__init__(**kwargs)
+ self.arangodb_conn_id = arangodb_conn_id
+ self.query = query
+ self.result_processor = result_processor
+
+ def execute(self, context: 'Context'):
+ self.log.info('Executing: %s', self.query)
+ hook = ArangoDBHook(arangodb_conn_id=self.arangodb_conn_id)
+ result = hook.query(self.query)
+ if self.result_processor:
+ self.result_processor(result)
diff --git a/airflow/providers/arangodb/provider.yaml b/airflow/providers/arangodb/provider.yaml
new file mode 100644
index 0000000..129be5b
--- /dev/null
+++ b/airflow/providers/arangodb/provider.yaml
@@ -0,0 +1,48 @@
+# 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.
+
+---
+package-name: apache-airflow-providers-arangodb
+name: ArangoDB
+description: |
+ `ArangoDB <https://www.arangodb.com/>`__
+versions:
+ - 1.0.0
+
+integrations:
+ - integration-name: ArangoDB
+ external-doc-url: https://www.arangodb.com/
+ tags: [software]
+
+hooks:
+ - integration-name: ArangoDB
+ python-modules:
+ - airflow.providers.arangodb.hooks.arangodb
+
+operators:
+ - integration-name: ArangoDB
+ python-modules:
+ - airflow.providers.arangodb.operators.arangodb
+
+sensors:
+ - integration-name: ArangoDB
+ python-modules:
+ - airflow.providers.arangodb.sensors.arangodb
+
+connection-types:
+ - hook-class-name: airflow.providers.arangodb.hooks.arangodb.ArangoDBHook
+ connection-type: arangodb
diff --git a/airflow/providers/arangodb/sensors/__init__.py b/airflow/providers/arangodb/sensors/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/airflow/providers/arangodb/sensors/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/airflow/providers/arangodb/sensors/arangodb.py b/airflow/providers/arangodb/sensors/arangodb.py
new file mode 100644
index 0000000..e27bd78
--- /dev/null
+++ b/airflow/providers/arangodb/sensors/arangodb.py
@@ -0,0 +1,54 @@
+#
+# 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 typing import TYPE_CHECKING, Sequence
+
+from airflow.providers.arangodb.hooks.arangodb import ArangoDBHook
+from airflow.sensors.base import BaseSensorOperator
+
+if TYPE_CHECKING:
+ from airflow.utils.context import Context
+
+
+class AQLSensor(BaseSensorOperator):
+ """
+ Checks for the existence of a document which
+ matches the given query in ArangoDB. Example:
+
+ :param collection: Target DB collection.
+ :param query: The query to poke, or you can provide .sql file having the query
+ :param arangodb_conn_id: The :ref:`ArangoDB connection id <howto/connection:arangodb>` to use
+ when connecting to ArangoDB.
+ :param arangodb_db: Target ArangoDB name.
+ """
+
+ template_fields: Sequence[str] = ('query',)
+
+ template_ext: Sequence[str] = (".sql",)
+ template_fields_renderers = {"query": "sql"}
+
+ def __init__(self, *, query: str, arangodb_conn_id: str = "arangodb_default", **kwargs) -> None:
+ super().__init__(**kwargs)
+ self.arangodb_conn_id = arangodb_conn_id
+ self.query = query
+
+ def poke(self, context: 'Context') -> bool:
+ self.log.info(f"Sensor running following query: {self.query}")
+ hook = ArangoDBHook(self.arangodb_conn_id)
+ records = hook.query(self.query, count=True).count()
+ self.log.info(f"Total Records found: {records}")
+ return 0 != records
diff --git a/docs/apache-airflow-providers-arangodb/commits.rst b/docs/apache-airflow-providers-arangodb/commits.rst
new file mode 100644
index 0000000..3031e96
--- /dev/null
+++ b/docs/apache-airflow-providers-arangodb/commits.rst
@@ -0,0 +1,31 @@
+
+ .. 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.
+
+
+Package apache-airflow-providers-arangodb
+------------------------------------------------------
+
+`ArangoDB <https://www.arangodb.com/>`__
+
+
+This is detailed commit list of changes for versions provider package: ``arangodb``.
+For high-level changelog, see :doc:`package information including changelog <index>`.
+
+
+1.0.0
+.....
diff --git a/docs/apache-airflow-providers-arangodb/connections/arangodb.rst b/docs/apache-airflow-providers-arangodb/connections/arangodb.rst
new file mode 100644
index 0000000..b8502ed
--- /dev/null
+++ b/docs/apache-airflow-providers-arangodb/connections/arangodb.rst
@@ -0,0 +1,33 @@
+ .. 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.
+
+.. _howto/connection:arangodb:
+
+ArangoDB Connection
+====================
+The ArangoDB connection provides credentials for accessing the ArangoDB.
+
+Configuring the Connection
+--------------------------
+ArangoDB Host (required)
+ Specify ArangoDB Host URL or comma separated list of URLs (coordinators in a cluster) `eg. "http://127.0.0.1:8529"` or `"http://127.0.0.1:8529,http://127.0.0.1:8530 so on.`
+ArangoDB Database/Schema (required)
+ Specify `Database/Schema` for the ArangoDB. eg. `_system`
+ArangoDB Username (required)
+ Specify `username` for the ArangoDB, eg. `root`
+ArangoDB Password (required)
+ Specify `password` for the ArangoDB
diff --git a/docs/apache-airflow-providers-arangodb/index.rst b/docs/apache-airflow-providers-arangodb/index.rst
new file mode 100644
index 0000000..538c437
--- /dev/null
+++ b/docs/apache-airflow-providers-arangodb/index.rst
@@ -0,0 +1,90 @@
+
+ .. 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.
+
+``apache-airflow-providers-arangodb``
+=====================================
+
+Content
+-------
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Guides
+
+ Connection types <connections/arangodb>
+ Operators <operators/index>
+
+.. toctree::
+ :maxdepth: 1
+ :caption: References
+
+ Python API <_api/airflow/providers/arangodb/index>
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Resources
+
+ Example DAGs <https://github.com/apache/airflow/tree/main/airflow/providers/arangodb/example_dags>
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Resources
+
+ PyPI Repository <https://pypi.org/project/apache-airflow-providers-arangodb/>
+ Installing from sources <installing-providers-from-sources>
+
+.. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN AT RELEASE TIME!
+
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Commits
+
+ Detailed list of commits <commits>
+
+
+Package apache-airflow-providers-arangodb
+------------------------------------------------------
+
+`ArangoDB <https://www.arangodb.com/>`__
+
+
+Release: 1.0.0
+
+Provider package
+----------------
+
+This is a provider package for ``arangodb`` provider. All classes for this provider package
+are in ``airflow.providers.arangodb`` python package.
+
+Installation
+------------
+
+You can install this package on top of an existing Airflow 2.1+ installation via
+``pip install apache-airflow-providers-arangodb``
+
+PIP requirements
+----------------
+
+=================== ==================
+PIP package Version required
+=================== ==================
+``python-arangodb`` ``>=7.3.1``
+=================== ==================
+
+.. include:: ../../airflow/providers/arangodb/CHANGELOG.rst
diff --git a/docs/apache-airflow-providers-arangodb/installing-providers-from-sources.rst b/docs/apache-airflow-providers-arangodb/installing-providers-from-sources.rst
new file mode 100644
index 0000000..1c90205
--- /dev/null
+++ b/docs/apache-airflow-providers-arangodb/installing-providers-from-sources.rst
@@ -0,0 +1,18 @@
+ .. 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.
+
+.. include:: ../installing-providers-from-sources.rst
diff --git a/docs/apache-airflow-providers-arangodb/operators/index.rst b/docs/apache-airflow-providers-arangodb/operators/index.rst
new file mode 100644
index 0000000..ec9c5ef
--- /dev/null
+++ b/docs/apache-airflow-providers-arangodb/operators/index.rst
@@ -0,0 +1,66 @@
+ .. 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.
+
+
+
+.. _howto/operator:AQLOperator:
+
+Operators
+=======================
+You can build your own Operator hook in :class:`~airflow.providers.arangodb.hooks.ArangoDBHook`,
+
+
+Use the :class:`~airflow.providers.arangodb.operators.AQLOperator` to execute
+AQL query in `ArangoDB <https://www.arangodb.com/>`__.
+
+You can further process your result using :class:`~airflow.providers.arangodb.operators.AQLOperator` and
+further process the result using **result_processor** Callable as you like.
+
+An example of Listing all Documents in **students** collection can be implemented as following:
+
+.. exampleinclude:: /../../airflow/providers/arangodb/example_dags/example_arangodb.py
+ :language: python
+ :start-after: [START howto_aql_operator_arangodb]
+ :end-before: [END howto_aql_operator_arangodb]
+
+You can also provide file template (.sql) to load query, remember path is relative to **dags/** folder, if you want to provide any other path
+please provide **template_searchpath** while creating **DAG** object,
+
+.. exampleinclude:: /../../airflow/providers/arangodb/example_dags/example_arangodb.py
+ :language: python
+ :start-after: [START howto_aql_operator_template_file_arangodb]
+ :end-before: [END howto_aql_operator_template_file_arangodb]
+
+Sensors
+=======
+
+Use the :class:`~airflow.providers.arangodb.sensors.AQLSensor` to wait for a document or collection using
+AQL query in `ArangoDB <https://www.arangodb.com/>`__.
+
+An example for waiting a document in **students** collection with student name **judy** can be implemented as following:
+
+.. exampleinclude:: /../../airflow/providers/arangodb/example_dags/example_arangodb.py
+ :language: python
+ :start-after: [START howto_aql_sensor_arangodb]
+ :end-before: [END howto_aql_sensor_arangodb]
+
+Similar to **AQLOperator**, You can also provide file template to load query -
+
+.. exampleinclude:: /../../airflow/providers/arangodb/example_dags/example_arangodb.py
+ :language: python
+ :start-after: [START howto_aql_sensor_template_file_arangodb]
+ :end-before: [END howto_aql_sensor_template_file_arangodb]
diff --git a/docs/apache-airflow/extra-packages-ref.rst b/docs/apache-airflow/extra-packages-ref.rst
index ad4fa01..d2adf1a 100644
--- a/docs/apache-airflow/extra-packages-ref.rst
+++ b/docs/apache-airflow/extra-packages-ref.rst
@@ -256,6 +256,8 @@ Those are extras that add dependencies needed for integration with other softwar
+---------------------+-----------------------------------------------------+-------------------------------------------+
| trino | ``pip install 'apache-airflow[trino]'`` | All Trino related operators & hooks |
+---------------------+-----------------------------------------------------+-------------------------------------------+
+| arangodb | ``pip install 'apache-airflow[arangodb]'`` | ArangoDB operators, sensors and hook |
++---------------------+-----------------------------------------------------+-------------------------------------------+
Other extras
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 30b4026..744ea20 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1,3 +1,4 @@
+AQL
Ack
Acyclic
AddressesType
@@ -16,6 +17,7 @@ Aneesh
AnnotateTextResponse
Ansible
AppBuilder
+ArangoDB
Arg
Args
Asana
@@ -476,6 +478,8 @@ apikey
apis
appbuilder
approle
+arango
+arangodb
aren
arg
args
diff --git a/setup.py b/setup.py
index 7935b76..4c2a9c8 100644
--- a/setup.py
+++ b/setup.py
@@ -204,6 +204,7 @@ amazon = [
apache_beam = [
'apache-beam>=2.33.0',
]
+arangodb = ['python-arango>=7.3.2']
asana = ['asana>=0.10']
async_packages = [
'eventlet>=0.9.7',
@@ -688,6 +689,7 @@ PROVIDERS_REQUIREMENTS: Dict[str, List[str]] = {
'apache.pinot': pinot,
'apache.spark': spark,
'apache.sqoop': [],
+ 'arangodb': arangodb,
'asana': asana,
'celery': celery,
'cloudant': cloudant,
@@ -879,6 +881,7 @@ ALL_DB_PROVIDERS = [
'apache.hdfs',
'apache.hive',
'apache.pinot',
+ 'arangodb',
'cloudant',
'databricks',
'exasol',
diff --git a/tests/providers/arangodb/__init__.py b/tests/providers/arangodb/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/tests/providers/arangodb/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/tests/providers/arangodb/hooks/__init__.py b/tests/providers/arangodb/hooks/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/tests/providers/arangodb/hooks/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/tests/providers/arangodb/hooks/test_arangodb.py b/tests/providers/arangodb/hooks/test_arangodb.py
new file mode 100644
index 0000000..45e20d0
--- /dev/null
+++ b/tests/providers/arangodb/hooks/test_arangodb.py
@@ -0,0 +1,120 @@
+# 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.
+
+import unittest
+from unittest.mock import Mock, patch
+
+from airflow.models import Connection
+from airflow.providers.arangodb.hooks.arangodb import ArangoDBHook
+from airflow.utils import db
+
+arangodb_client_mock = Mock(name="arangodb_client_for_test")
+
+
+class TestArangoDBHook(unittest.TestCase):
+ def setUp(self):
+ super().setUp()
+ db.merge_conn(
+ Connection(
+ conn_id='arangodb_default',
+ conn_type='arangodb',
+ host='http://127.0.0.1:8529',
+ login='root',
+ password='password',
+ schema='_system',
+ )
+ )
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_get_conn(self, arango_mock):
+ arangodb_hook = ArangoDBHook()
+
+ assert arangodb_hook.hosts == ['http://127.0.0.1:8529']
+ assert arangodb_hook.username == 'root'
+ assert arangodb_hook.password == 'password'
+ assert arangodb_hook.database == '_system'
+ assert arangodb_hook.client is not None
+ assert arango_mock.called
+ assert isinstance(arangodb_hook.client, Mock)
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_query(self, arango_mock):
+ arangodb_hook = ArangoDBHook()
+ arangodb_hook.db_conn = Mock(name="arangodb_database_for_test")
+
+ arangodb_query = "FOR doc IN students RETURN doc"
+ arangodb_hook.query(arangodb_query)
+
+ assert arango_mock.called
+ assert isinstance(arangodb_hook.client, Mock)
+ assert arango_mock.return_value.db.called
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_create_database(self, arango_mock):
+ arangodb_hook = ArangoDBHook()
+ arangodb_hook.create_database(name="_system")
+
+ arango_mock.return_value.db.return_value.has_database.return_value = False
+
+ assert arango_mock.called
+ assert isinstance(arangodb_hook.client, Mock)
+ assert arango_mock.return_value.db.called
+ assert arango_mock.return_value.db.return_value.has_database.called
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_create_collection(self, arango_mock):
+ arangodb_hook = ArangoDBHook()
+ arangodb_hook.create_collection(name="student")
+
+ arango_mock.return_value.db.return_value.has_collection.return_value = False
+
+ assert arango_mock.called
+ assert isinstance(arangodb_hook.client, Mock)
+ assert arango_mock.return_value.db.called
+ assert arango_mock.return_value.db.return_value.has_collection.called
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_create_graph(self, arango_mock):
+ arangodb_hook = ArangoDBHook()
+ arangodb_hook.create_graph(name="student_network")
+
+ arango_mock.return_value.db.return_value.has_graph.return_value = False
+
+ assert arango_mock.called
+ assert isinstance(arangodb_hook.client, Mock)
+ assert arango_mock.return_value.db.called
+ assert arango_mock.return_value.db.return_value.has_graph.called
diff --git a/tests/providers/arangodb/operators/__init__.py b/tests/providers/arangodb/operators/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/tests/providers/arangodb/operators/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/tests/providers/arangodb/operators/test_arangodb.py b/tests/providers/arangodb/operators/test_arangodb.py
new file mode 100644
index 0000000..73e8dbe
--- /dev/null
+++ b/tests/providers/arangodb/operators/test_arangodb.py
@@ -0,0 +1,32 @@
+# 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.
+
+import unittest
+from unittest import mock
+
+from airflow.providers.arangodb.operators.arangodb import AQLOperator
+
+
+class TestAQLOperator(unittest.TestCase):
+ @mock.patch('airflow.providers.arangodb.operators.arangodb.ArangoDBHook')
+ def test_arangodb_operator_test(self, mock_hook):
+
+ arangodb_query = "FOR doc IN students RETURN doc"
+ op = AQLOperator(task_id='basic_aql_task', query=arangodb_query)
+ op.execute(mock.MagicMock())
+ mock_hook.assert_called_once_with(arangodb_conn_id='arangodb_default')
+ mock_hook.return_value.query.assert_called_once_with(arangodb_query)
diff --git a/tests/providers/arangodb/sensors/__init__.py b/tests/providers/arangodb/sensors/__init__.py
new file mode 100644
index 0000000..13a8339
--- /dev/null
+++ b/tests/providers/arangodb/sensors/__init__.py
@@ -0,0 +1,16 @@
+# 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.
diff --git a/tests/providers/arangodb/sensors/test_arangodb.py b/tests/providers/arangodb/sensors/test_arangodb.py
new file mode 100644
index 0000000..3d03724
--- /dev/null
+++ b/tests/providers/arangodb/sensors/test_arangodb.py
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+import unittest
+from unittest.mock import Mock, patch
+
+from airflow.models import Connection
+from airflow.models.dag import DAG
+from airflow.providers.arangodb.sensors.arangodb import AQLSensor
+from airflow.utils import db, timezone
+
+DEFAULT_DATE = timezone.datetime(2017, 1, 1)
+arangodb_client_mock = Mock(name="arangodb_client_for_test")
+
+
+class TestAQLSensor(unittest.TestCase):
+ def setUp(self):
+ args = {'owner': 'airflow', 'start_date': DEFAULT_DATE}
+ dag = DAG('test_dag_id', default_args=args)
+ self.dag = dag
+ db.merge_conn(
+ Connection(
+ conn_id='arangodb_default',
+ conn_type='arangodb',
+ host='http://127.0.0.1:8529',
+ login='root',
+ password='password',
+ schema='_system',
+ )
+ )
+
+ @patch(
+ "airflow.providers.arangodb.hooks.arangodb.ArangoDBClient",
+ autospec=True,
+ return_value=arangodb_client_mock,
+ )
+ def test_arangodb_document_created(self, arangodb_mock):
+ query = "FOR doc IN students FILTER doc.name == 'judy' RETURN doc"
+
+ arangodb_tag_sensor = AQLSensor(
+ task_id='aql_search_document',
+ query=query,
+ timeout=60,
+ poke_interval=10,
+ dag=self.dag,
+ )
+
+ arangodb_tag_sensor.run(start_date=DEFAULT_DATE, end_date=DEFAULT_DATE, ignore_ti_state=True)
+ assert arangodb_mock.return_value.db.called