Repository: ploomber/jupysql
Pull request #101 (2023-01-30 15:50:20)

Doc - Telemetry doc - Add more details on what's collected
Context:
Respond to https://github.com/ploomber/jupysql/issues/72 
We need to add a doc to explain user about our telemetry part. Since we are using the shared telemetry module, we may refer to the detail section of [User Statistics](https://docs.ploomber.io/en/latest/community/user-stats.html)

However, something we can do:
1. Add the support page under community in jupysql doc, which contains the Support + Telemetry section
2. Polish original [User Statistics](https://docs.ploomber.io/en/latest/community/user-stats.html) doc in the ploomber project, I've raised [the PR](https://github.com/ploomber/jupysql/pull/101) for patching

Changes in this PR:
- Add support doc
- Add coc doc
- Remove community doc (replaced by new coc doc and new support doc)
- Reorder the _toc ordering (Page Navigation)


## Preview

Page Navigation
Before:
<img width="283" alt="Screenshot 2023-01-30 at 12 50 18 PM" src="https://user-images.githubusercontent.com/123580782/215555454-143323bb-cb80-450d-b794-a3dec5a945f9.png">

After (Remove `Community`, Add `Code of Conduct` & `Support`):
<img width="268" alt="Screenshot 2023-01-30 at 12 51 26 PM" src="https://user-images.githubusercontent.com/123580782/215555465-bf151160-87f9-4b31-8cad-c6718d548d81.png">

New Code of Conduct
<img width="1672" alt="Screenshot 2023-01-30 at 12 53 34 PM" src="https://user-images.githubusercontent.com/123580782/215555699-713be589-382a-4338-aad8-2e7d698c9b38.png">

New Support & Telemetry
<img width="1694" alt="Screenshot 2023-01-30 at 12 51 37 PM" src="https://user-images.githubusercontent.com/123580782/215555723-3434f039-c448-43f8-b0ca-a10ff61b57b5.png">

<!-- readthedocs-preview jupysql start -->
----
:books: Documentation preview :books:: https://jupysql--101.org.readthedocs.build/en/101/

<!-- readthedocs-preview jupysql end -->

tonykploomber: @idomic
Seems I still can't assign you in GitHub, just tag you for FYI
idomic: Why do we need 2 PRs here instead of 1?
Also, we need to reference this in jupysql so users are aware.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b135261..037bfb2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # CHANGELOG
 
 ## 0.5.3dev
+* [Fix] Adds telemetry collect for `%sqlplot` invocation ([#89](https://github.com/ploomber/jupysql/pull/89))
 * [Fix] `setup.py` fix due to change in setuptools 67.0.0
 
 ## 0.5.2 (2023-01-03)
diff --git a/doc/_toc.yml b/doc/_toc.yml
index 701c49f..8a464ad 100644
--- a/doc/_toc.yml
+++ b/doc/_toc.yml
@@ -37,6 +37,7 @@ parts:
 
   - caption: Community
     chapters:
+    - file: community/coc
+    - file: community/support
     - file: community/projects
-    - file: community/community
     - file: community/credits
\ No newline at end of file
diff --git a/doc/community/coc.md b/doc/community/coc.md
new file mode 100644
index 0000000..f25a76e
--- /dev/null
+++ b/doc/community/coc.md
@@ -0,0 +1,5 @@
+# Code of Conduct
+
+Ploomber has been committed to build the product by making it easy for community users to facilitate the day-to-day work.
+
+For more details, see [here](https://docs.ploomber.io/en/latest/community/coc.html)
\ No newline at end of file
diff --git a/doc/community/community.md b/doc/community/community.md
deleted file mode 100644
index 6a0baca..0000000
--- a/doc/community/community.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Community
-
-## Code of Conduct
-
-[See here](https://docs.ploomber.io/en/latest/community/coc.html)
-
-## Telemetry
-
-[See here](https://docs.ploomber.io/en/latest/community/user-stats.html)
\ No newline at end of file
diff --git a/doc/community/support.md b/doc/community/support.md
new file mode 100644
index 0000000..f4b997a
--- /dev/null
+++ b/doc/community/support.md
@@ -0,0 +1,7 @@
+# Support
+
+For support, feature requests, and product updates: [join our community](https://ploomber.io/community) or follow us on [Twitter](https://twitter.com/ploomber)/[LinkedIn](https://www.linkedin.com/company/ploomber/).
+
+# Telemetry
+
+We collect (optional) anonymous statistics to understand and improve usage. For more details of what we collect and how to opt-out the telemetry collection, [see here](https://docs.ploomber.io/en/latest/community/user-stats.html).
\ No newline at end of file
diff --git a/src/sql/plot.py b/src/sql/plot.py
index 718d9a3..ffe5c52 100644
--- a/src/sql/plot.py
+++ b/src/sql/plot.py
@@ -17,6 +17,7 @@ except ModuleNotFoundError:
 
 from sql.store import store
 import sql.connection
+from sql.telemetry import telemetry
 
 
 def _summary_stats(con, table, column, with_=None):
@@ -190,6 +191,7 @@ def _boxplot_stats(con, table, column, whis=1.5, autorange=False, with_=None):
 
 # https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915
 @requires(["matplotlib"])
+@telemetry.log_call("boxplot")
 def boxplot(table, column, *, orient="v", with_=None, conn=None):
     """Plot boxplot
 
@@ -280,6 +282,7 @@ FROM "{{table}}"
 
 
 @requires(["matplotlib"])
+@telemetry.log_call("histogram")
 def histogram(table, column, bins, with_=None, conn=None):
     """Plot histogram
 


Test patch:
diff --git a/src/tests/test_telemetry.py b/src/tests/test_telemetry.py
new file mode 100644
index 0000000..910215c
--- /dev/null
+++ b/src/tests/test_telemetry.py
@@ -0,0 +1,87 @@
+from pathlib import Path
+from unittest.mock import ANY, Mock
+import pytest
+import urllib.request
+import duckdb
+from sql.telemetry import telemetry
+from sql import plot
+
+# Ref: https://pytest.org/en/7.2.x/how-to/tmp_path.html#
+# Utilize tmp directory to store downloaded csv
+
+
+@pytest.fixture
+def simple_file_path(tmpdir):
+    file_path_str = str(tmpdir.join("iris.csv"))
+
+    if not Path(file_path_str).is_file():
+        urllib.request.urlretrieve(
+            "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv",
+            file_path_str,
+        )
+
+    yield file_path_str
+
+
+@pytest.fixture
+def simple_db_conn():
+    conn = duckdb.connect(database=":memory:")
+    return conn
+
+
+@pytest.fixture
+def mock_log_api(monkeypatch):
+    mock_log_api = Mock()
+    monkeypatch.setattr(telemetry, "log_api", mock_log_api)
+    yield mock_log_api
+
+
+def test_boxplot_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path):
+    plot.boxplot(simple_file_path, "petal width", conn=simple_db_conn, orient="h")
+
+    mock_log_api.assert_called_with(
+        action="jupysql-boxplot-success", total_runtime=ANY, metadata=ANY
+    )
+
+
+def test_histogram_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path):
+    # Test the injected log_api gets called
+    plot.histogram(simple_file_path, "petal width", bins=50, conn=simple_db_conn)
+
+    mock_log_api.assert_called_with(
+        action="jupysql-histogram-success", total_runtime=ANY, metadata=ANY
+    )
+
+
+def test_data_frame_telemetry_execution(mock_log_api, ip, simple_file_path):
+    # Simulate the cell query & get the DataFrame
+    ip.run_cell("%sql duckdb://")
+    ip.run_cell("result = %sql SELECT * FROM read_csv_auto('" + simple_file_path + "')")
+    ip.run_cell("result.DataFrame()")
+    mock_log_api.assert_called_with(
+        action="jupysql-data-frame-success", total_runtime=ANY, metadata=ANY
+    )
+
+
+def test_sqlrender_telemetry_execution(mock_log_api, ip, simple_file_path):
+    # Simulate the sqlrender query
+    ip.run_cell("%sql duckdb://")
+    ip.run_cell(
+        "%sql --save class_setosa --no-execute \
+            SELECT * FROM read_csv_auto('"
+        + simple_file_path
+        + "' WHERE class='Iris-setosa'"
+    )
+    ip.run_cell("%sqlrender class_setosa")
+
+    mock_log_api.assert_called_with(
+        action="jupysql-sqlrender-success", total_runtime=ANY, metadata=ANY
+    )
+
+
+def test_execute_telemetry_execution(mock_log_api, ip):
+    ip.run_cell("%sql duckdb://")
+
+    mock_log_api.assert_called_with(
+        action="jupysql-execute-success", total_runtime=ANY, metadata=ANY
+    )