Skip to content

Commit d67b237

Browse files
Merge pull request #77 from skyflowapi/SK-678-add-metrices-in-python-sdk
SK-678 add metrices in python-sdk
2 parents 442a7d7 + a501618 commit d67b237

File tree

11 files changed

+125
-14
lines changed

11 files changed

+125
-14
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
- "setup.py"
88
- "*.yml"
99
- "*.md"
10+
- "version.py"
1011

1112
jobs:
1213
build-and-deploy:
@@ -39,6 +40,7 @@ jobs:
3940
git config user.name ${{ github.actor }}
4041
git config user.email ${{ github.actor }}@users.noreply.github.com
4142
git add setup.py
43+
git add version.py
4244
git commit -m "[AUTOMATED] Public Release - ${{ steps.previoustag.outputs.tag }}"
4345
git push origin
4446

ci-scripts/bump_version.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ then
66
echo "Bumping package version to $1"
77

88
sed -E "s/current_version = .+/current_version = \'$SEMVER\'/g" setup.py > tempfile && cat tempfile > setup.py && rm -f tempfile
9+
sed -E "s/SDK_VERSION = .+/SDK_VERSION = \'$SEMVER\'/g" version.py > tempfile && cat tempfile > version.py && rm -f tempfile
10+
911
echo --------------------------
1012
echo "Done, Package now at $1"
1113

1214
else
1315
echo "Bumping package version to $1-dev.$2"
1416

1517
sed -E "s/current_version = .+/current_version = \'$SEMVER-dev.$2\'/g" setup.py > tempfile && cat tempfile > setup.py && rm -f tempfile
18+
sed -E "s/SDK_VERSION = .+/SDK_VERSION = \'$SEMVER-dev.$2\'/g" version.py > tempfile && cat tempfile > version.py && rm -f tempfile
1619

1720
echo --------------------------
1821
echo "Done, Package now at $1-dev.$2"

skyflow/_utils.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import urllib.parse
55
import logging
66
from enum import Enum
7+
import platform
8+
import sys
9+
from version import SDK_VERSION
710

811
skyflowLog = logging.getLogger('skyflow')
912
skyflowLog.setLevel(logging.ERROR)
@@ -127,3 +130,31 @@ def render_key(parents):
127130
outStr += s % str(x)
128131
depth += 1
129132
return outStr
133+
134+
def getMetrics():
135+
''' fetch metrics
136+
'''
137+
sdk_name_version = "skyflow-python@" + SDK_VERSION
138+
139+
try:
140+
sdk_client_device_model = platform.node()
141+
except Exception:
142+
sdk_client_device_model = ""
143+
144+
try:
145+
sdk_client_os_details = sys.platform
146+
except Exception:
147+
sdk_client_os_details = ""
148+
149+
try:
150+
sdk_runtime_details = sys.version
151+
except Exception:
152+
sdk_runtime_details = ""
153+
154+
details_dic = {
155+
'sdk_name_version': sdk_name_version,
156+
'sdk_client_device_model': sdk_client_device_model,
157+
'sdk_client_os_details': sdk_client_os_details,
158+
'sdk_runtime_details': "Python " + sdk_runtime_details,
159+
}
160+
return details_dic

skyflow/service_account/_token.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import requests
88
from warnings import warn
99
from collections import namedtuple
10-
from skyflow._utils import log_info, InterfaceName, InfoMessages
10+
from skyflow._utils import log_info, InterfaceName, InfoMessages, getMetrics
1111

1212

1313
from skyflow.errors._skyflow_errors import *
@@ -126,7 +126,8 @@ def getSignedJWT(clientID, keyID, tokenURI, privateKey):
126126

127127
def sendRequestWithToken(url, token):
128128
headers = {
129-
"content-type": "application/json"
129+
"content-type": "application/json",
130+
"sky-metadata": json.dumps(getMetrics())
130131
}
131132
payload = {
132133
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",

skyflow/vault/_client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'''
22
Copyright (c) 2022 Skyflow, Inc.
33
'''
4+
import json
45
import types
56
import requests
67
from ._insert import getInsertRequestBody, processResponse, convertResponse
@@ -13,7 +14,7 @@
1314
from ._get import sendGetRequests
1415
import asyncio
1516
from skyflow.errors._skyflow_errors import SkyflowError, SkyflowErrorCodes, SkyflowErrorMessages
16-
from skyflow._utils import log_info, InfoMessages, InterfaceName
17+
from skyflow._utils import log_info, InfoMessages, InterfaceName, getMetrics
1718
from ._token import tokenProviderWrapper
1819

1920

@@ -52,7 +53,8 @@ def insert(self, records: dict, options: InsertOptions = InsertOptions()):
5253
self.storedToken = tokenProviderWrapper(
5354
self.storedToken, self.tokenProvider, interface)
5455
headers = {
55-
"Authorization": "Bearer " + self.storedToken
56+
"Authorization": "Bearer " + self.storedToken,
57+
"sky-metadata": json.dumps(getMetrics())
5658
}
5759

5860
response = requests.post(requestURL, data=jsonBody, headers=headers)
@@ -131,6 +133,8 @@ def invoke_connection(self, config: ConnectionConfig):
131133
if not 'X-Skyflow-Authorization'.lower() in request.headers:
132134
request.headers['x-skyflow-authorization'] = self.storedToken
133135

136+
request.headers['sky-metadata'] = json.dumps(getMetrics())
137+
134138
response = session.send(request)
135139
session.close()
136140
return processResponse(response, interface=interface)

skyflow/vault/_detokenize.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import asyncio
66
from aiohttp import ClientSession, request
77
import json
8-
from skyflow._utils import InterfaceName
8+
from skyflow._utils import InterfaceName, getMetrics
99

1010
interface = InterfaceName.DETOKENIZE.value
1111

@@ -48,7 +48,9 @@ async def sendDetokenizeRequests(data, url, token):
4848
async with ClientSession() as session:
4949
for record in validatedRecords:
5050
headers = {
51-
"Authorization": "Bearer " + token
51+
"Authorization": "Bearer " + token,
52+
"sky-metadata": json.dumps(getMetrics())
53+
5254
}
5355
task = asyncio.ensure_future(post(url, record, headers, session))
5456
tasks.append(task)

skyflow/vault/_get.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
'''
22
Copyright (c) 2022 Skyflow, Inc.
33
'''
4+
import json
45
from skyflow.errors._skyflow_errors import SkyflowError, SkyflowErrorCodes, SkyflowErrorMessages
56
import asyncio
67
from aiohttp import ClientSession
78
from ._config import RedactionType
8-
from skyflow._utils import InterfaceName
9+
from skyflow._utils import InterfaceName, getMetrics
910
from ._get_by_id import get
1011

1112
interface = InterfaceName.GET.value
@@ -83,7 +84,8 @@ async def sendGetRequests(data, url, token):
8384
async with ClientSession() as session:
8485
for record in validatedRecords:
8586
headers = {
86-
"Authorization": "Bearer " + token
87+
"Authorization": "Bearer " + token,
88+
"sky-metadata": json.dumps(getMetrics())
8789
}
8890
params = {"redaction": redaction}
8991
if ids is not None:

skyflow/vault/_get_by_id.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from aiohttp import ClientSession
77
import json
88
from ._config import RedactionType
9-
from skyflow._utils import InterfaceName
9+
from skyflow._utils import InterfaceName, getMetrics
1010

1111
interface = InterfaceName.GET_BY_ID.value
1212

@@ -66,7 +66,8 @@ async def sendGetByIdRequests(data, url, token):
6666
async with ClientSession() as session:
6767
for record in validatedRecords:
6868
headers = {
69-
"Authorization": "Bearer " + token
69+
"Authorization": "Bearer " + token,
70+
"sky-metadata": json.dumps(getMetrics())
7071
}
7172
params = {"skyflow_ids": record[0], "redaction": record[2]}
7273
task = asyncio.ensure_future(

skyflow/vault/_update.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import asyncio
77
from skyflow.errors._skyflow_errors import SkyflowError, SkyflowErrorCodes, SkyflowErrorMessages
88
from ._insert import getTableAndFields
9-
from skyflow._utils import InterfaceName
9+
from skyflow._utils import InterfaceName, getMetrics
1010
from aiohttp import ClientSession
1111
from ._config import UpdateOptions
1212

@@ -40,7 +40,8 @@ async def sendUpdateRequests(data,options: UpdateOptions,url,token):
4040
}
4141
reqBody = json.dumps(reqBody)
4242
headers = {
43-
"Authorization": "Bearer " + token
43+
"Authorization": "Bearer " + token,
44+
"sky-metadata": json.dumps(getMetrics())
4445
}
4546
task = asyncio.ensure_future(put(recordUrl, reqBody, headers, session))
4647
tasks.append(task)

tests/vault/test_url_encoder.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
'''
22
Copyright (c) 2022 Skyflow, Inc.
33
'''
4+
import platform
5+
import sys
46
import unittest
5-
from skyflow._utils import http_build_query
6-
7+
from unittest import mock
8+
from skyflow._utils import http_build_query, getMetrics
9+
from version import SDK_VERSION
710

811
class TestUrlEncoder(unittest.TestCase):
912
def setUp(self) -> None:
@@ -50,3 +53,63 @@ def test_encoder_array(self):
5053

5154
self.assertEqual(
5255
http_data, "key=value&nested%5Barray%5D%5B0%5D=one&nested%5Barray%5D%5B1%5D=two&nested%5Bkey%5D=value")
56+
57+
# Test Case 1: Success case
58+
def test_get_metrics(self):
59+
expected = {
60+
'sdk_name_version': "skyflow-python@" + SDK_VERSION,
61+
'sdk_client_device_model': platform.node(),
62+
'sdk_client_os_details': sys.platform,
63+
'sdk_runtime_details': "Python " + sys.version,
64+
}
65+
actual = getMetrics()
66+
self.assertEqual(actual, expected)
67+
68+
@mock.patch('platform.node', return_value='')
69+
def test_getMetrics_no_device_model(self, mock_node):
70+
expected_output = {
71+
'sdk_name_version': 'skyflow-python@' + SDK_VERSION,
72+
'sdk_client_device_model': '',
73+
'sdk_client_os_details': sys.platform,
74+
'sdk_runtime_details': "Python " + sys.version
75+
}
76+
77+
actual_output = getMetrics()
78+
expected_output['sdk_client_device_model'] = ''
79+
self.assertEqual(actual_output, expected_output)
80+
81+
@mock.patch('platform.node', return_value='Mocked Device Model')
82+
def test_getMetrics_with_device_model(self, mock_node):
83+
expected_output = {
84+
'sdk_name_version': 'skyflow-python@' + SDK_VERSION,
85+
'sdk_client_device_model': 'Mocked Device Model',
86+
'sdk_client_os_details': sys.platform,
87+
'sdk_runtime_details': "Python " + sys.version
88+
}
89+
90+
actual_output = getMetrics()
91+
self.assertEqual(actual_output, expected_output)
92+
93+
@mock.patch('sys.platform', return_value='mocked_os')
94+
def test_getMetrics_with_os_details(self, mock_platform):
95+
expected_output = {
96+
'sdk_name_version': 'skyflow-python@' + SDK_VERSION,
97+
'sdk_client_device_model': platform.node(),
98+
'sdk_client_os_details': sys.platform,
99+
'sdk_runtime_details': "Python " + sys.version
100+
}
101+
actual_output = getMetrics()
102+
self.assertEqual(actual_output, expected_output)
103+
104+
def test_getMetrics_with_runtime_details(self):
105+
expected_output = {
106+
'sdk_name_version': 'skyflow-python@' + SDK_VERSION,
107+
'sdk_client_device_model': platform.node(),
108+
'sdk_client_os_details': sys.platform,
109+
'sdk_runtime_details': 'Python ' + 'mocked_version'
110+
}
111+
112+
with mock.patch('sys.version', 'mocked_version'), \
113+
mock.patch('sys.version_info', new=(3, 11, 2)):
114+
actual_output = getMetrics()
115+
self.assertEqual(actual_output, expected_output)

0 commit comments

Comments
 (0)