-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add telemetry (initialised when intake.cat.access_nri entrypoint acce…
…ssed)
- Loading branch information
1 parent
d74943d
commit 1b6f54a
Showing
3 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ dependencies = [ | |
"jsonschema", | ||
"pooch", | ||
"xarray", | ||
"httpx>=0.28" | ||
] | ||
dynamic = ["version"] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import ast | ||
import asyncio | ||
import warnings | ||
|
||
import httpx | ||
from IPython import get_ipython | ||
|
||
TELEMETRY_SERVER_URL = "https://intake-telemetry-bb870061f91a.herokuapp.com" | ||
|
||
|
||
def send_api_request(function_name, kwargs): | ||
telemetry_data = { | ||
"name": f"CT_testing_{function_name}_ipy_extensions", | ||
"search": kwargs, | ||
} | ||
|
||
endpoint = f"{TELEMETRY_SERVER_URL}/telemetry/update" | ||
|
||
async def send_telemetry(data): | ||
headers = {"Content-Type": "application/json"} | ||
async with httpx.AsyncClient() as client: | ||
try: | ||
response = await client.post(endpoint, json=data, headers=headers) | ||
response.raise_for_status() | ||
|
||
print(f"Telemetry data sent: {response.json()}") | ||
except httpx.RequestError as e: | ||
warnings.warn( | ||
f"Request failed: {e}", category=RuntimeWarning, stacklevel=2 | ||
) | ||
|
||
# Schedule the telemetry data to be sent in the background | ||
asyncio.create_task(send_telemetry(telemetry_data)) | ||
return None | ||
|
||
|
||
def capture_datastore_searches(info): | ||
""" | ||
Use the AST module to parse the code that we are executing & send an API call | ||
if we | ||
""" | ||
code = info.raw_cell | ||
|
||
# Remove lines that contain IPython magic commands | ||
code = "\n".join( | ||
line for line in code.splitlines() if not line.strip().startswith("%") | ||
) | ||
|
||
tree = ast.parse(code) | ||
user_namespace = get_ipython().user_ns | ||
|
||
for node in ast.walk(tree): | ||
if isinstance(node, ast.Call): | ||
if isinstance(node.func, ast.Name): | ||
func_name = node.func.id | ||
elif isinstance(node.func, ast.Attribute): | ||
# Check if the attribute is a method call on a class instance or a module function | ||
if isinstance(node.func.value, ast.Name): | ||
instance_name = node.func.value.id | ||
method_name = node.func.attr | ||
try: | ||
# Evaluate the instance to get its class name | ||
instance = eval(instance_name, globals(), user_namespace) | ||
class_name = instance.__class__.__name__ | ||
func_name = f"{class_name}.{method_name}" | ||
except Exception as e: | ||
print(f"Error evaluating instance: {e}") | ||
continue | ||
|
||
if func_name in [ | ||
"esm_datastore.search", | ||
]: | ||
# args = [ast.dump(arg) for arg in node.args] | ||
kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in node.keywords} | ||
send_api_request( | ||
func_name, | ||
# args, | ||
kwargs, | ||
) | ||
else: | ||
print(f"Function call: {func_name}; not tracking") |