Repository: Azure/azure-cli-extensions

Issue:
az monitor app-insights query Execute a simple query over past 3.5 days.
## Describe the bug
Trying to query Application Insights via the example provided via the [az monitor app-insights query](https://docs.microsoft.com/en-us/cli/azure/ext/application-insights/monitor/app-insights?view=azure-cli-latest#ext-application-insights-az-monitor-app-insights-query) docs.

**Command Name**
`az monitor app-insights query
Extension Name: application-insights. Version: 0.1.1.`

**Errors:**
```
unsupported operand type(s) for -: 'datetime.datetime' and 'str'
Traceback (most recent call last):
python3.6/site-packages/knack/cli.py, ln 206, in invoke
    cmd_result = self.invocation.execute(args)
cli/core/commands/__init__.py, ln 603, in execute
    raise ex
cli/core/commands/__init__.py, ln 661, in _run_jobs_serially
    results.append(self._run_job(expanded_arg, cmd_copy))
...
cliextensions/application-insights/azext_applicationinsights/util.py, ln 40, in get_timespan
    start_time = (dateutil.parser.parse(end_time) - offset).isoformat()
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'str'
```

## To Reproduce:
Steps to reproduce the behavior. Note that argument values have been redacted, as they may contain sensitive information.

- _Put any pre-requisite steps here..._
- `az monitor app-insights query --app <Your-GUID> --analytics-query 'requests | summarize count() by bin(timestamp, 1h)' --offset P3DT12H`

## Expected Behavior
Execute a simple query over the past 3.5 days.

## Environment Summary
```
Linux-4.4.0-18362-Microsoft-x86_64-with-debian-buster-sid
Python 3.6.5
Shell: bash

azure-cli 2.0.75

Extensions:
application-insights 0.1.1
log-analytics 0.1.3

```
## Additional Context

<!--Please don't remove this:-->
<!--auto-generated-->



Discussion:
@alexkoepke Thanks. I'm looking at this issue.
add to S171

Resolving patch:
diff --git a/src/application-insights/azext_applicationinsights/custom.py b/src/application-insights/azext_applicationinsights/custom.py
--- a/src/application-insights/azext_applicationinsights/custom.py
+++ b/src/application-insights/azext_applicationinsights/custom.py
@@ -5,6 +5,8 @@
 
 # pylint: disable=line-too-long, protected-access
 
+import datetime
+import isodate
 from knack.util import CLIError
 from knack.log import get_logger
 from azext_applicationinsights.vendored_sdks.applicationinsights.models import ErrorResponseException
@@ -19,6 +21,8 @@ def execute_query(cmd, client, application, analytics_query, start_time=None, en
     """Executes a query against the provided Application Insights application."""
     from .vendored_sdks.applicationinsights.models import QueryBody
     targets = get_query_targets(cmd.cli_ctx, application, resource_group_name)
+    if not isinstance(offset, datetime.timedelta):
+        offset = isodate.parse_duration(offset)
     try:
         return client.query.execute(targets[0], QueryBody(query=analytics_query, timespan=get_timespan(cmd.cli_ctx, start_time, end_time, offset), applications=targets[1:]))
     except ErrorResponseException as ex:
diff --git a/src/application-insights/setup.py b/src/application-insights/setup.py
--- a/src/application-insights/setup.py
+++ b/src/application-insights/setup.py
@@ -8,7 +8,7 @@
 from codecs import open
 from setuptools import setup, find_packages
 
-VERSION = "0.1.7"
+VERSION = "0.1.8"
 
 CLASSIFIERS = [
     'Development Status :: 4 - Beta',
@@ -24,7 +24,9 @@
     'License :: OSI Approved :: MIT License',
 ]
 
-DEPENDENCIES = []
+DEPENDENCIES = [
+    "isodate~=0.6.0"
+]
 
 with open('README.rst', 'r', encoding='utf-8') as f:
     README = f.read()


Test patch:
diff --git a/src/application-insights/azext_applicationinsights/tests/latest/recordings/test_query_execute_with_different_offset.yaml b/src/application-insights/azext_applicationinsights/tests/latest/recordings/test_query_execute_with_different_offset.yaml
new file mode 100644
--- /dev/null
+++ b/src/application-insights/azext_applicationinsights/tests/latest/recordings/test_query_execute_with_different_offset.yaml
@@ -0,0 +1,92 @@
+interactions:
+- request:
+    body: '{"query": "availabilityResults | distinct name | order by name asc", "timespan":
+      "2020-06-01T19:21:28.027311/2020-06-05T07:21:28.027311", "applications": []}'
+    headers:
+      Accept:
+      - application/json
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '157'
+      Content-Type:
+      - application/json; charset=utf-8
+      User-Agent:
+      - python/3.8.0 (Windows-10-10.0.18362-SP0) msrest/0.6.9 azure-applicationinsights/0.1.0
+    method: POST
+    uri: https://api.applicationinsights.io/v1/apps/db709f0e-cb4e-4f43-ba80-05e10d6a4447/query
+  response:
+    body:
+      string: '{"tables":[{"name":"PrimaryResult","columns":[{"name":"name","type":"string"}],"rows":[]}]}'
+    headers:
+      access-control-allow-origin:
+      - '*'
+      access-control-expose-headers:
+      - Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location
+      connection:
+      - keep-alive
+      content-length:
+      - '91'
+      content-type:
+      - application/json; charset=utf-8
+      date:
+      - Fri, 05 Jun 2020 07:21:29 GMT
+      strict-transport-security:
+      - max-age=15724800; includeSubDomains
+      vary:
+      - Accept-Encoding
+      via:
+      - 1.1 draft-oms-5f5bbdf49d-pgt7m
+      x-content-type-options:
+      - nosniff
+    status:
+      code: 200
+      message: OK
+- request:
+    body: '{"query": "availabilityResults | distinct name | order by name asc", "timespan":
+      "2020-06-01T19:20:29.882273/2020-06-05T07:21:29.882273", "applications": []}'
+    headers:
+      Accept:
+      - application/json
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '157'
+      Content-Type:
+      - application/json; charset=utf-8
+      User-Agent:
+      - python/3.8.0 (Windows-10-10.0.18362-SP0) msrest/0.6.9 azure-applicationinsights/0.1.0
+    method: POST
+    uri: https://api.applicationinsights.io/v1/apps/db709f0e-cb4e-4f43-ba80-05e10d6a4447/query
+  response:
+    body:
+      string: '{"tables":[{"name":"PrimaryResult","columns":[{"name":"name","type":"string"}],"rows":[]}]}'
+    headers:
+      access-control-allow-origin:
+      - '*'
+      access-control-expose-headers:
+      - Retry-After,Age,WWW-Authenticate,x-resource-identities,x-ms-status-location
+      connection:
+      - keep-alive
+      content-length:
+      - '91'
+      content-type:
+      - application/json; charset=utf-8
+      date:
+      - Fri, 05 Jun 2020 07:21:30 GMT
+      strict-transport-security:
+      - max-age=15724800; includeSubDomains
+      vary:
+      - Accept-Encoding
+      via:
+      - 1.1 draft-oms-5f5bbdf49d-548wj
+      x-content-type-options:
+      - nosniff
+    status:
+      code: 200
+      message: OK
+version: 1
diff --git a/src/application-insights/azext_applicationinsights/tests/latest/test_applicationinsights_commands.py b/src/application-insights/azext_applicationinsights/tests/latest/test_applicationinsights_commands.py
--- a/src/application-insights/azext_applicationinsights/tests/latest/test_applicationinsights_commands.py
+++ b/src/application-insights/azext_applicationinsights/tests/latest/test_applicationinsights_commands.py
@@ -23,6 +23,11 @@ def test_query_execute(self):
         assert len(query_guid['tables'][0]['rows']) == 37
         assert isinstance(query_guid['tables'][0]['rows'][0][1], (int, float, complex))
 
+    def test_query_execute_with_different_offset(self):
+        """Tests data plane query capabilities for Application Insights."""
+        self.cmd('az monitor app-insights query --apps db709f0e-cb4e-4f43-ba80-05e10d6a4447 --analytics-query "availabilityResults | distinct name | order by name asc" --offset P3DT12H')
+        self.cmd('az monitor app-insights query --apps db709f0e-cb4e-4f43-ba80-05e10d6a4447 --analytics-query "availabilityResults | distinct name | order by name asc" --offset 3d12h1m')
+
     def test_metrics_show(self):
         self.cmd('az monitor app-insights metrics show --app 578f0e27-12e9-4631-bc02-50b965da2633 --metrics requests/duration --aggregation count sum --start-time 2019-03-06 00:31 +00:00 --end-time 2019-03-06 01:31 +00:00', checks=[
             self.check('value."requests/duration".count', 0),