diff --git a/elasticsearch/client/tasks.py b/elasticsearch/client/tasks.py
index 0f253ca1..4c4f6d1f 100644
--- a/elasticsearch/client/tasks.py
+++ b/elasticsearch/client/tasks.py
@@ -1,3 +1,4 @@
+import warnings
 from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
 
 
@@ -58,7 +59,7 @@ class TasksClient(NamespacedClient):
         )
 
     @query_params("timeout", "wait_for_completion")
-    def get(self, task_id, params=None, headers=None):
+    def get(self, task_id=None, params=None, headers=None):
         """
         Returns information about a task.
         `<https://www.elastic.co/guide/en/elasticsearch/reference/master/tasks.html>`_
@@ -70,7 +71,11 @@ class TasksClient(NamespacedClient):
             complete (default: false)
         """
         if task_id in SKIP_IN_PATH:
-            raise ValueError("Empty value passed for a required argument 'task_id'.")
+            warnings.warn(
+                "Calling client.tasks.get() without a task_id is deprecated "
+                "and will be removed in v8.0. Use client.tasks.list() instead.",
+                DeprecationWarning,
+            )
 
         return self.transport.perform_request(
             "GET", _make_path("_tasks", task_id), params=params, headers=headers
diff --git a/utils/generate_api.py b/utils/generate_api.py
index 0e76617d..183934e4 100644
--- a/utils/generate_api.py
+++ b/utils/generate_api.py
@@ -146,6 +146,13 @@ class API:
                 p in url.get("parts", {}) for url in self._def["url"]["paths"]
             )
 
+            # This piece of logic corresponds to calling
+            # client.tasks.get() w/o a task_id which was erroneously
+            # allowed in the 7.1 client library. This functionality
+            # is deprecated and will be removed in 8.x.
+            if self.namespace == "tasks" and self.name == "get":
+                parts["task_id"]["required"] = False
+
         for k, sub in SUBSTITUTIONS.items():
             if k in parts:
                 parts[sub] = parts.pop(k)
diff --git a/utils/templates/overrides/tasks/get b/utils/templates/overrides/tasks/get
new file mode 100644
index 00000000..ca855ab9
--- /dev/null
+++ b/utils/templates/overrides/tasks/get
@@ -0,0 +1,12 @@
+{% extends "base" %}
+{% block request %}
+        if task_id in SKIP_IN_PATH:
+            warnings.warn(
+                "Calling client.tasks.get() without a task_id is deprecated "
+                "and will be removed in v8.0. Use client.tasks.list() instead.",
+                DeprecationWarning,
+            )
+
+        {{ super()|trim }}
+{% endblock %}
+

diff --git a/test_elasticsearch/test_client/__init__.py b/test_elasticsearch/test_client/__init__.py
index b7fa18ad..5fa01f76 100644
--- a/test_elasticsearch/test_client/__init__.py
+++ b/test_elasticsearch/test_client/__init__.py
@@ -1,4 +1,5 @@
 from __future__ import unicode_literals
+import warnings
 
 from elasticsearch.client import _normalize_hosts, Elasticsearch
 
@@ -110,3 +111,27 @@ class TestClient(ElasticsearchTestCase):
         self.client.index(index="my-index", id=0, body={})
 
         self.assert_url_called("PUT", "/my-index/_doc/0")
+
+    def test_tasks_get_without_task_id_deprecated(self):
+        warnings.simplefilter("always", DeprecationWarning)
+        with warnings.catch_warnings(record=True) as w:
+            self.client.tasks.get()
+
+        self.assert_url_called("GET", "/_tasks")
+        self.assertEquals(len(w), 1)
+        self.assertIs(w[0].category, DeprecationWarning)
+        self.assertEquals(
+            str(w[0].message),
+            "Calling client.tasks.get() without a task_id is deprecated "
+            "and will be removed in v8.0. Use client.tasks.list() instead.",
+        )
+
+    def test_tasks_get_with_task_id_not_deprecated(self):
+        warnings.simplefilter("always", DeprecationWarning)
+        with warnings.catch_warnings(record=True) as w:
+            self.client.tasks.get("task-1")
+            self.client.tasks.get(task_id="task-2")
+
+        self.assert_url_called("GET", "/_tasks/task-1")
+        self.assert_url_called("GET", "/_tasks/task-2")
+        self.assertEquals(len(w), 0)

TasksClient.get() requiring an argument on v7.5.1
<!--

** Please read the guidelines below. **

1.  GitHub is reserved for bug reports and feature requests. The best place to
    ask a general question is at the Elastic [forums](https://discuss.elastic.co).
    GitHub is not the place for general questions.

2.  Please fill out EITHER the feature request block or the bug report block
    below, and delete the other block.

3.  For issues with API definition please note that the API is [auto
    generated](https://github.com/elastic/elasticsearch-py/blob/master/CONTRIBUTING.md#api-code-generation)
    so any problems should be checked and reported against [the Elasticsearch
    repo](https://github.com/elastic/elasticsearch) instead.

Thank you!

-->

<!-- Bug report -->

**Elasticsearch version** (`bin/elasticsearch --version`): 7.1.1, 7.5.1

**`elasticsearch-py` version (`elasticsearch.__versionstr__`)**: 7.5.1

Please make sure the major version matches the Elasticsearch server you are running.

**Description of the problem including expected versus actual behavior**:

Elasticsearch().tasks.get() fails using elasticsearch-py 7.5.1, whereas it succeeds using 7.1.1.

```
>>> import elasticsearch
>>> elasticsearch.__versionstr__
'7.5.1'
>>> elasticsearch.Elasticsearch().tasks.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/nfox/myenv-7.5.1/lib/python3.7/site-packages/elasticsearch/client/utils.py", line 84, in _wrapped
    return func(*args, params=params, **kwargs)
TypeError: get() missing 1 required positional argument: 'task_id'
```

```
>>> import elasticsearch
>>> elasticsearch.__versionstr__
'7.1.0'
>>> elasticsearch.Elasticsearch().tasks.get()
{'nodes': {'GkSSDiZPTBq4Tlv5xV9wtg': {'name': 'e6a01a4d549f', 'transport_address': '172.17.0.3:9300', 'host': '172.17.0.3', 'ip': '172.17.0.3:9300', 'roles': ['ingest', 'master', 'data', 'ml'], 'attributes': {'ml.machine_memory': '4129972224', 'xpack.installed': 'true', 'ml.max_open_jobs': '20'}, 'tasks': {'GkSSDiZPTBq4Tlv5xV9wtg:56': {'node': 'GkSSDiZPTBq4Tlv5xV9wtg', 'id': 56, 'type': 'direct', 'action': 'cluster:monitor/tasks/lists[n]', 'start_time_in_millis': 1582238526445, 'running_time_in_nanos': 8142200, 'cancellable': False, 'parent_task_id': 'GkSSDiZPTBq4Tlv5xV9wtg:55', 'headers': {}}, 'GkSSDiZPTBq4Tlv5xV9wtg:55': {'node': 'GkSSDiZPTBq4Tlv5xV9wtg', 'id': 55, 'type': 'transport', 'action': 'cluster:monitor/tasks/lists', 'start_time_in_millis': 1582238526442, 'running_time_in_nanos': 11192200, 'cancellable': False, 'headers': {}}}}}}
```

I've verified this against running both ES 7.5.1 and ES 7.1.1 (via docker on localhost)

**Steps to reproduce**:
run `elasticsearch.Elasticsearch().tasks.get()` while using elasticsearch-py 7.5.1

Ultimately, this is breaking curator's DeleteSnapshot as it checks for tasks.
test_elasticsearch/test_client/__init__.py::TestClient::test_tasks_get_without_task_id_deprecated
test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_dicts_are_left_unchanged test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_none_uses_defaults test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_single_string_is_wrapped_in_list test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_strings_are_parsed_for_port_and_user test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_strings_are_parsed_for_scheme test_elasticsearch/test_client/__init__.py::TestNormalizeHosts::test_strings_are_used_as_hostnames test_elasticsearch/test_client/__init__.py::TestClient::test_from_in_search test_elasticsearch/test_client/__init__.py::TestClient::test_headers_is_copied_when test_elasticsearch/test_client/__init__.py::TestClient::test_index_uses_post_if_id_is_empty test_elasticsearch/test_client/__init__.py::TestClient::test_index_uses_put_if_id_is_not_empty test_elasticsearch/test_client/__init__.py::TestClient::test_params_is_copied_when test_elasticsearch/test_client/__init__.py::TestClient::test_repr_contains_hosts test_elasticsearch/test_client/__init__.py::TestClient::test_repr_contains_hosts_passed_in test_elasticsearch/test_client/__init__.py::TestClient::test_repr_subclass test_elasticsearch/test_client/__init__.py::TestClient::test_repr_truncates_host_to_5 test_elasticsearch/test_client/__init__.py::TestClient::test_request_timeout_is_passed_through_unescaped test_elasticsearch/test_client/__init__.py::TestClient::test_tasks_get_with_task_id_not_deprecated