{"action":"created","comment":{"url":"https://api.github.com/repos/apache/incubator-airflow/pulls/comments/229741920","pull_request_review_id":170312632,"id":229741920,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyOTc0MTkyMA==","diff_hunk":"@@ -0,0 +1,288 @@\n+# -*- coding: utf-8 -*-\n+#\n+# Licensed to the Apache Software Foundation (ASF) under one\n+# or more contributor license agreements.  See the NOTICE file\n+# distributed with this work for additional information\n+# regarding copyright ownership.  The ASF licenses this file\n+# to you under the Apache License, Version 2.0 (the\n+# \"License\"); you may not use this file except in compliance\n+# with the License.  You may obtain a copy of the License at\n+#\n+#   http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing,\n+# software distributed under the License is distributed on an\n+# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+# KIND, either express or implied.  See the License for the\n+# specific language governing permissions and limitations\n+# under the License.\n+from googleapiclient.errors import HttpError\n+\n+from airflow import AirflowException\n+from airflow.contrib.hooks.gcp_sql_hook import CloudSqlHook\n+from airflow.contrib.utils.gcp_field_validator import GcpBodyFieldValidator\n+from airflow.models import BaseOperator\n+from airflow.utils.decorators import apply_defaults\n+\n+SETTINGS = 'settings'\n+SETTINGS_VERSION = 'settingsVersion'\n+\n+CLOUD_SQL_VALIDATION = [\n+    dict(name=\"name\", allow_empty=False),\n+    dict(name=\"settings\", type=\"dict\", fields=[\n+        dict(name=\"tier\", allow_empty=False),\n+        dict(name=\"backupConfiguration\", type=\"dict\", fields=[\n+            dict(name=\"binaryLogEnabled\", optional=True),\n+            dict(name=\"enabled\", optional=True),\n+            dict(name=\"replicationLogArchivingEnabled\", optional=True),\n+            dict(name=\"startTime\", allow_empty=False, optional=True)\n+        ], optional=True),\n+        dict(name=\"activationPolicy\", allow_empty=False, optional=True),\n+        dict(name=\"authorizedGaeApplications\", type=\"list\", optional=True),\n+        dict(name=\"crashSafeReplicationEnabled\", optional=True),\n+        dict(name=\"dataDiskSizeGb\", optional=True),\n+        dict(name=\"dataDiskType\", allow_empty=False, optional=True),\n+        dict(name=\"databaseFlags\", type=\"list\", optional=True),\n+        dict(name=\"ipConfiguration\", type=\"dict\", fields=[\n+            dict(name=\"authorizedNetworks\", type=\"list\", fields=[\n+                dict(name=\"expirationTime\", optional=True),\n+                dict(name=\"name\", allow_empty=False, optional=True),\n+                dict(name=\"value\", allow_empty=False, optional=True)\n+            ], optional=True),\n+            dict(name=\"ipv4Enabled\", optional=True),\n+            dict(name=\"privateNetwork\", allow_empty=False, optional=True),\n+            dict(name=\"requireSsl\", optional=True),\n+        ], optional=True),\n+        dict(name=\"locationPreference\", type=\"dict\", fields=[\n+            dict(name=\"followGaeApplication\", allow_empty=False, optional=True),\n+            dict(name=\"zone\", allow_empty=False, optional=True),\n+        ], optional=True),\n+        dict(name=\"maintenanceWindow\", type=\"dict\", fields=[\n+            dict(name=\"hour\", optional=True),\n+            dict(name=\"day\", optional=True),\n+            dict(name=\"updateTrack\", allow_empty=False, optional=True),\n+        ], optional=True),\n+        dict(name=\"pricingPlan\", allow_empty=False, optional=True),\n+        dict(name=\"replicationType\", allow_empty=False, optional=True),\n+        dict(name=\"storageAutoResize\", optional=True),\n+        dict(name=\"storageAutoResizeLimit\", optional=True),\n+        dict(name=\"userLabels\", type=\"dict\", optional=True),\n+    ]),\n+    dict(name=\"databaseVersion\", allow_empty=False, optional=True),\n+    dict(name=\"failoverReplica\", type=\"dict\", fields=[\n+        dict(name=\"name\", allow_empty=False)\n+    ], optional=True),\n+    dict(name=\"masterInstanceName\", allow_empty=False, optional=True),\n+    dict(name=\"onPremisesConfiguration\", type=\"dict\", optional=True),\n+    dict(name=\"region\", allow_empty=False, optional=True),\n+    dict(name=\"replicaConfiguration\", type=\"dict\", fields=[\n+        dict(name=\"failoverTarget\", optional=True),\n+        dict(name=\"mysqlReplicaConfiguration\", type=\"dict\", fields=[\n+            dict(name=\"caCertificate\", allow_empty=False, optional=True),\n+            dict(name=\"clientCertificate\", allow_empty=False, optional=True),\n+            dict(name=\"clientKey\", allow_empty=False, optional=True),\n+            dict(name=\"connectRetryInterval\", optional=True),\n+            dict(name=\"dumpFilePath\", allow_empty=False, optional=True),\n+            dict(name=\"masterHeartbeatPeriod\", optional=True),\n+            dict(name=\"password\", allow_empty=False, optional=True),\n+            dict(name=\"sslCipher\", allow_empty=False, optional=True),\n+            dict(name=\"username\", allow_empty=False, optional=True),\n+            dict(name=\"verifyServerCertificate\", optional=True)\n+        ], optional=True),\n+    ], optional=True)\n+]\n+\n+\n+class CloudSqlBaseOperator(BaseOperator):\n+    \"\"\"\n+    Abstract base operator for Google Cloud SQL operators to inherit from.\n+    \"\"\"\n+    @apply_defaults\n+    def __init__(self,\n+                 project_id,\n+                 instance,\n+                 gcp_conn_id='google_cloud_default',\n+                 api_version='v1beta4',\n+                 *args, **kwargs):\n+        self.project_id = project_id\n+        self.instance = instance\n+        self.gcp_conn_id = gcp_conn_id\n+        self.api_version = api_version\n+        self._validate_inputs()\n+        self._hook = CloudSqlHook(gcp_conn_id=self.gcp_conn_id,\n+                                  api_version=self.api_version)\n+        super(CloudSqlBaseOperator, self).__init__(*args, **kwargs)\n+\n+    def _validate_inputs(self):\n+        if not self.project_id:\n+            raise AirflowException(\"The required parameter 'project_id' is empty\")\n+        if not self.instance:\n+            raise AirflowException(\"The required parameter 'instance' is empty\")\n+\n+    def _check_if_instance_exists(self, instance):\n+        try:\n+            return self._hook.get_instance(self.project_id, instance)\n+        except HttpError as e:\n+            status = e.resp.status\n+            if status == 404:\n+                return False\n+            raise e\n+\n+    def execute(self, context):\n+        pass\n+\n+    @staticmethod\n+    def _get_settings_version(instance):\n+        return instance.get(SETTINGS).get(SETTINGS_VERSION)\n+\n+\n+class CloudSqlInstanceInsertOperator(CloudSqlBaseOperator):\n+    \"\"\"\n+    Creates a new Cloud SQL instance.\n+    If an instance with the same name exists, no action will be taken and\n+    the operator will succeed.\n+\n+    :param project_id: Project ID of the project to which the newly created Cloud SQL\n+        instances should belong.\n+    :type project_id: str\n+    :param body: Body required by the Cloud SQL insert API, as described in\n+        https://cloud.google.com/sql/docs/mysql/admin-api/v1beta4/instances/insert\n+        #request-body\n+    :type body: dict\n+    :param instance: Cloud SQL instance ID. This does not include the project ID.\n+    :type instance: str\n+    :param gcp_conn_id: The connection ID used to connect to Google Cloud Platform.\n+    :type gcp_conn_id: str\n+    :param api_version: API version used (e.g. v1).\n+    :type api_version: str\n+    :param validate_body: True if body should be validated, False otherwise.\n+    :type validate_body: bool\n+    \"\"\"\n+    # [START gcp_sql_insert_template_fields]\n+    template_fields = ('project_id', 'instance', 'gcp_conn_id', 'api_version')\n+    # [END gcp_sql_insert_template_fields]","path":"airflow/contrib/operators/gcp_sql_operator.py","position":null,"original_position":163,"commit_id":"68ff70b2332b57e1f9fe89087ddbb2bea217f96f","original_commit_id":"db8f4a7ca9da8c7f9df9975dc45e3fb6ee6d2f05","user":{"login":"sprzedwojski","id":4280682,"node_id":"MDQ6VXNlcjQyODA2ODI=","avatar_url":"https://avatars3.githubusercontent.com/u/4280682?v=4","gravatar_id":"","url":"https://api.github.com/users/sprzedwojski","html_url":"https://github.com/sprzedwojski","followers_url":"https://api.github.com/users/sprzedwojski/followers","following_url":"https://api.github.com/users/sprzedwojski/following{/other_user}","gists_url":"https://api.github.com/users/sprzedwojski/gists{/gist_id}","starred_url":"https://api.github.com/users/sprzedwojski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sprzedwojski/subscriptions","organizations_url":"https://api.github.com/users/sprzedwojski/orgs","repos_url":"https://api.github.com/users/sprzedwojski/repos","events_url":"https://api.github.com/users/sprzedwojski/events{/privacy}","received_events_url":"https://api.github.com/users/sprzedwojski/received_events","type":"User","site_admin":false},"body":"Thanks, it was Jarek's idea ;)","created_at":"2018-10-31T15:21:42Z","updated_at":"2018-10-31T15:21:42Z","html_url":"https://github.com/apache/incubator-airflow/pull/4097#discussion_r229741920","pull_request_url":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/comments/229741920"},"html":{"href":"https://github.com/apache/incubator-airflow/pull/4097#discussion_r229741920"},"pull_request":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097"}},"in_reply_to_id":228532061},"pull_request":{"url":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097","id":226041626,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI2MDQxNjI2","html_url":"https://github.com/apache/incubator-airflow/pull/4097","diff_url":"https://github.com/apache/incubator-airflow/pull/4097.diff","patch_url":"https://github.com/apache/incubator-airflow/pull/4097.patch","issue_url":"https://api.github.com/repos/apache/incubator-airflow/issues/4097","number":4097,"state":"open","locked":false,"title":"[AIRFLOW-3231] Basic operators for Google Cloud SQL","user":{"login":"sprzedwojski","id":4280682,"node_id":"MDQ6VXNlcjQyODA2ODI=","avatar_url":"https://avatars3.githubusercontent.com/u/4280682?v=4","gravatar_id":"","url":"https://api.github.com/users/sprzedwojski","html_url":"https://github.com/sprzedwojski","followers_url":"https://api.github.com/users/sprzedwojski/followers","following_url":"https://api.github.com/users/sprzedwojski/following{/other_user}","gists_url":"https://api.github.com/users/sprzedwojski/gists{/gist_id}","starred_url":"https://api.github.com/users/sprzedwojski/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sprzedwojski/subscriptions","organizations_url":"https://api.github.com/users/sprzedwojski/orgs","repos_url":"https://api.github.com/users/sprzedwojski/repos","events_url":"https://api.github.com/users/sprzedwojski/events{/privacy}","received_events_url":"https://api.github.com/users/sprzedwojski/received_events","type":"User","site_admin":false},"body":"### Jira\r\n\r\n- [x] My PR addresses the following [Airflow Jira](https://issues.apache.org/jira/browse/AIRFLOW-3231) issue and references it in the PR title.\r\n\r\n### Description\r\n\r\n- [x] Here are some details about my PR, including screenshots of any UI changes:\r\n\r\nAdd CloudSqlInstanceInsertOperator, CloudSqlInstancePatchOperator and CloudSqlInstanceDeleteOperator.\r\n\r\nEach operator includes:\r\n- core logic\r\n- input params validation\r\n- unit tests\r\n- presence in the example DAG\r\n- docstrings\r\n- How-to and Integration documentation\r\n\r\nAdditionally, small improvements to GcpBodyFieldValidator were made:\r\n- add simple list validation capability (type=\"list\")\r\n- introduced parameter allow_empty, which can be set to False\r\n\tto test for non-emptiness of a string instead of specifying\r\n\ta regexp.\r\n\r\n### Tests\r\n\r\n- [x] My PR adds the following unit tests __OR__ does not need testing for this extremely good reason:\r\n\r\n`test_gcp_sql_operator.py`\r\n\r\n### Commits\r\n\r\n- [x] My commits all reference Jira issues in their subject lines, and I have squashed multiple commits if they address the same issue. In addition, my commits follow the guidelines from \"[How to write a good git commit message](http://chris.beams.io/posts/git-commit/)\":\r\n  1. Subject is separated from body by a blank line\r\n  1. Subject is limited to 50 characters (not including Jira issue reference)\r\n  1. Subject does not end with a period\r\n  1. Subject uses the imperative mood (\"add\", not \"adding\")\r\n  1. Body wraps at 72 characters\r\n  1. Body explains \"what\" and \"why\", not \"how\"\r\n\r\n### Documentation\r\n\r\n- [x] In case of new functionality, my PR adds documentation that describes how to use it.\r\n  - When adding new operators/hooks/sensors, the autoclass documentation generation needs to be added.\r\n\r\n### Code Quality\r\n\r\n- [x] Passes `flake8`\r\n\r\nCo-authored-by: sprzedwojski <szymon.przedwojski@polidea.com>\r\nCo-authored-by: potiuk <jarek.potiuk@polidea.com>","created_at":"2018-10-26T09:59:40Z","updated_at":"2018-10-31T15:21:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f5687cb66684f334419240876b72c9407d08465a","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097/commits","review_comments_url":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097/comments","review_comment_url":"https://api.github.com/repos/apache/incubator-airflow/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/incubator-airflow/issues/4097/comments","statuses_url":"https://api.github.com/repos/apache/incubator-airflow/statuses/68ff70b2332b57e1f9fe89087ddbb2bea217f96f","head":{"label":"PolideaInternal:cloud-sql","ref":"cloud-sql","sha":"68ff70b2332b57e1f9fe89087ddbb2bea217f96f","user":{"login":"PolideaInternal","id":31278126,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMxMjc4MTI2","avatar_url":"https://avatars2.githubusercontent.com/u/31278126?v=4","gravatar_id":"","url":"https://api.github.com/users/PolideaInternal","html_url":"https://github.com/PolideaInternal","followers_url":"https://api.github.com/users/PolideaInternal/followers","following_url":"https://api.github.com/users/PolideaInternal/following{/other_user}","gists_url":"https://api.github.com/users/PolideaInternal/gists{/gist_id}","starred_url":"https://api.github.com/users/PolideaInternal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PolideaInternal/subscriptions","organizations_url":"https://api.github.com/users/PolideaInternal/orgs","repos_url":"https://api.github.com/users/PolideaInternal/repos","events_url":"https://api.github.com/users/PolideaInternal/events{/privacy}","received_events_url":"https://api.github.com/users/PolideaInternal/received_events","type":"Organization","site_admin":false},"repo":{"id":147329695,"node_id":"MDEwOlJlcG9zaXRvcnkxNDczMjk2OTU=","name":"incubator-airflow","full_name":"PolideaInternal/incubator-airflow","private":false,"owner":{"login":"PolideaInternal","id":31278126,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMxMjc4MTI2","avatar_url":"https://avatars2.githubusercontent.com/u/31278126?v=4","gravatar_id":"","url":"https://api.github.com/users/PolideaInternal","html_url":"https://github.com/PolideaInternal","followers_url":"https://api.github.com/users/PolideaInternal/followers","following_url":"https://api.github.com/users/PolideaInternal/following{/other_user}","gists_url":"https://api.github.com/users/PolideaInternal/gists{/gist_id}","starred_url":"https://api.github.com/users/PolideaInternal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PolideaInternal/subscriptions","organizations_url":"https://api.github.com/users/PolideaInternal/orgs","repos_url":"https://api.github.com/users/PolideaInternal/repos","events_url":"https://api.github.com/users/PolideaInternal/events{/privacy}","received_events_url":"https://api.github.com/users/PolideaInternal/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/PolideaInternal/incubator-airflow","description":"Apache Airflow (Incubating)","fork":true,"url":"https://api.github.com/repos/PolideaInternal/incubator-airflow","forks_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/forks","keys_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/teams","hooks_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/hooks","issue_events_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/issues/events{/number}","events_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/events","assignees_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/assignees{/user}","branches_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/branches{/branch}","tags_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/tags","blobs_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/statuses/{sha}","languages_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/languages","stargazers_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/stargazers","contributors_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/contributors","subscribers_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/subscribers","subscription_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/subscription","commits_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/contents/{+path}","compare_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/merges","archive_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/downloads","issues_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/issues{/number}","pulls_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/pulls{/number}","milestones_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/milestones{/number}","notifications_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/labels{/name}","releases_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/releases{/id}","deployments_url":"https://api.github.com/repos/PolideaInternal/incubator-airflow/deployments","created_at":"2018-09-04T10:35:22Z","updated_at":"2018-10-30T11:14:14Z","pushed_at":"2018-10-31T15:20:43Z","git_url":"git://github.com/PolideaInternal/incubator-airflow.git","ssh_url":"git@github.com:PolideaInternal/incubator-airflow.git","clone_url":"https://github.com/PolideaInternal/incubator-airflow.git","svn_url":"https://github.com/PolideaInternal/incubator-airflow","homepage":"https://airflow.apache.org","size":26588,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":5,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":5,"watchers":1,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"e703d6beeb379ee88ef5e7df495e8a785666f8af","user":{"login":"apache","id":47359,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQ3MzU5","avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":33884891,"node_id":"MDEwOlJlcG9zaXRvcnkzMzg4NDg5MQ==","name":"incubator-airflow","full_name":"apache/incubator-airflow","private":false,"owner":{"login":"apache","id":47359,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQ3MzU5","avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/apache/incubator-airflow","description":"Apache Airflow (Incubating)","fork":false,"url":"https://api.github.com/repos/apache/incubator-airflow","forks_url":"https://api.github.com/repos/apache/incubator-airflow/forks","keys_url":"https://api.github.com/repos/apache/incubator-airflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/incubator-airflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/incubator-airflow/teams","hooks_url":"https://api.github.com/repos/apache/incubator-airflow/hooks","issue_events_url":"https://api.github.com/repos/apache/incubator-airflow/issues/events{/number}","events_url":"https://api.github.com/repos/apache/incubator-airflow/events","assignees_url":"https://api.github.com/repos/apache/incubator-airflow/assignees{/user}","branches_url":"https://api.github.com/repos/apache/incubator-airflow/branches{/branch}","tags_url":"https://api.github.com/repos/apache/incubator-airflow/tags","blobs_url":"https://api.github.com/repos/apache/incubator-airflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/incubator-airflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/incubator-airflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/incubator-airflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/incubator-airflow/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/incubator-airflow/languages","stargazers_url":"https://api.github.com/repos/apache/incubator-airflow/stargazers","contributors_url":"https://api.github.com/repos/apache/incubator-airflow/contributors","subscribers_url":"https://api.github.com/repos/apache/incubator-airflow/subscribers","subscription_url":"https://api.github.com/repos/apache/incubator-airflow/subscription","commits_url":"https://api.github.com/repos/apache/incubator-airflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/incubator-airflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/incubator-airflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/incubator-airflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/incubator-airflow/contents/{+path}","compare_url":"https://api.github.com/repos/apache/incubator-airflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/incubator-airflow/merges","archive_url":"https://api.github.com/repos/apache/incubator-airflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/incubator-airflow/downloads","issues_url":"https://api.github.com/repos/apache/incubator-airflow/issues{/number}","pulls_url":"https://api.github.com/repos/apache/incubator-airflow/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/incubator-airflow/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/incubator-airflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/incubator-airflow/labels{/name}","releases_url":"https://api.github.com/repos/apache/incubator-airflow/releases{/id}","deployments_url":"https://api.github.com/repos/apache/incubator-airflow/deployments","created_at":"2015-04-13T18:04:58Z","updated_at":"2018-10-31T14:55:03Z","pushed_at":"2018-10-31T15:20:50Z","git_url":"git://github.com/apache/incubator-airflow.git","ssh_url":"git@github.com:apache/incubator-airflow.git","clone_url":"https://github.com/apache/incubator-airflow.git","svn_url":"https://github.com/apache/incubator-airflow","homepage":"https://airflow.apache.org","size":26588,"stargazers_count":9760,"watchers_count":9760,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":3378,"mirror_url":null,"archived":false,"open_issues_count":338,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":3378,"open_issues":338,"watchers":9760,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097"},"html":{"href":"https://github.com/apache/incubator-airflow/pull/4097"},"issue":{"href":"https://api.github.com/repos/apache/incubator-airflow/issues/4097"},"comments":{"href":"https://api.github.com/repos/apache/incubator-airflow/issues/4097/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/incubator-airflow/pulls/4097/commits"},"statuses":{"href":"https://api.github.com/repos/apache/incubator-airflow/statuses/68ff70b2332b57e1f9fe89087ddbb2bea217f96f"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"sprzedwojski"}}