Skip to content

Commit b28e279

Browse files
first commit
0 parents  commit b28e279

File tree

11 files changed

+232
-0
lines changed

11 files changed

+232
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
**sublime**
2+
*.pyc
3+
dist
4+
*.egg-info
5+
dist
6+
MANIFEST
7+
build
8+
.eggs
9+
venv

LICENSE

Whitespace-only changes.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Interakt.Track.PythonSdk

setup.cfg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[metadata]
2+
description-file = README.md
3+
license_file = LICENSE
4+
5+
[bdist_wheel]
6+
universal = 1

setup.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
2+
import os
3+
import sys
4+
5+
try:
6+
from setuptools import setup
7+
except ImportError:
8+
from distutils.core import setup
9+
10+
# Don't import interakt-track-python module here, since deps may not be installed
11+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'track'))
12+
from track.version import VERSION # noqa
13+
14+
15+
# 'setup.py publish' shortcut
16+
if sys.argv[-1] == 'publish':
17+
os.system('python3 setup.py sdist bdist_wheel')
18+
os.system('twine upload dist/*')
19+
sys.exit()
20+
21+
# TODO: update long description in README.md
22+
with open(file='README.md', mode='r', encoding='utf-8') as f:
23+
readme = f.read()
24+
25+
install_requires = [
26+
"requests>=2.20,<3.0"
27+
]
28+
29+
tests_require = [
30+
"mock==4.0.2",
31+
"pylint==2.6.0",
32+
"flake8==3.8.3",
33+
"coverage==5.2.1"
34+
]
35+
36+
37+
setup(
38+
name='interakt-track-python',
39+
packages=['track'],
40+
version=VERSION,
41+
# TODO : Add repository url
42+
url='',
43+
author="Amar Jaiswal",
44+
author_email="amar.j@cawstudios.com",
45+
maintainer="interakt.ai",
46+
# Chose a license from here: https://help.github.com/articles/licensing-a-repository
47+
# TODO : Add License
48+
license='',
49+
description='The easy way to integrate track apis for interakt',
50+
keywords=['INTERAKT', 'KIWI'],
51+
install_requires=install_requires,
52+
long_description=readme,
53+
long_description_content_type='text/markdown',
54+
classifiers=[
55+
# TODO: Update Dev status
56+
# Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable"
57+
'Development Status :: 3 - Alpha',
58+
'Intended Audience :: Developers',
59+
'Topic :: Software Development :: Build Tools',
60+
# TODO: Add license
61+
# 'License :: OSI Approved :: MIT License', # Again, pick a license
62+
"Operating System :: OS Independent",
63+
'Programming Language :: Python :: 3',
64+
'Programming Language :: Python :: 3.4',
65+
'Programming Language :: Python :: 3.5',
66+
'Programming Language :: Python :: 3.6',
67+
'Programming Language :: Python :: 3.7',
68+
'Programming Language :: Python :: 3.8',
69+
],
70+
)

track/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from track.version import VERSION
2+
from track.client import Client
3+
__version__ = VERSION
4+
5+
"""Settings"""
6+
write_key = None
7+
default_client = None
8+
host = None
9+
sync_mode = True
10+
debug = False
11+
timeout = 10
12+
13+
14+
def identify(user_id=None, country_code='+91', phone_number=None, traits={}):
15+
"""Send an identify call for customer"""
16+
return _proxy('identify', user_id=user_id, country_code=country_code, phone_number=phone_number, traits=traits)
17+
18+
19+
def event(user_id=None, event=None, traits={}):
20+
"""Send an event track call."""
21+
return _proxy('event', user_id=user_id, event=event, traits=traits)
22+
23+
24+
def _proxy(method, *args, **kwargs):
25+
"""Create an analytics client if one doesn't exist and send to it."""
26+
global default_client
27+
if not default_client:
28+
default_client = Client(
29+
write_key, host=host, debug=debug, sync_mode=sync_mode, timeout=timeout)
30+
31+
fn = getattr(default_client, method)
32+
return fn(*args, **kwargs)

track/client.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from track.utils import require, stringify
2+
from track.request import post
3+
from track.const import ApiPaths
4+
import logging
5+
import numbers
6+
ID_TYPES = (numbers.Number, str)
7+
8+
9+
class Client(object):
10+
logger = logging.getLogger('interakt')
11+
12+
def __init__(self, write_key=None, host=None, debug=False, sync_mode=True, timeout=10):
13+
"""Create a new interakt client"""
14+
require('write_key', write_key, str)
15+
self.write_key = write_key
16+
self.debug = debug
17+
self.host = host
18+
self.sync_mode = sync_mode
19+
self.timeout = timeout
20+
if debug:
21+
self.logger.setLevel(logging.DEBUG)
22+
23+
def identify(self, user_id=None, country_code='+91', phone_number=None, traits={}):
24+
"""Tie a user to their actions and record traits about them."""
25+
if not user_id and not phone_number:
26+
raise AssertionError("Either user_id or phone_number is required")
27+
if user_id:
28+
require('user_id', user_id, ID_TYPES)
29+
if phone_number:
30+
require('phone_number', phone_number, str)
31+
require('traits', traits, dict)
32+
msg = {
33+
'userId': stringify(val=user_id),
34+
'countryCode': country_code,
35+
'phoneNumber': phone_number,
36+
'traits': traits
37+
}
38+
return self.__send_request(path=ApiPaths.Identify.value, msg=msg)
39+
40+
def event(self, user_id=None, event=None, traits={}):
41+
"""To record user events"""
42+
traits = traits or {}
43+
require('user_id', user_id, ID_TYPES)
44+
require('traits', traits, dict)
45+
require('event', event, str)
46+
msg = {
47+
'userId': stringify(val=user_id),
48+
'event': event,
49+
'traits': traits
50+
}
51+
return self.__send_request(path=ApiPaths.Event.value, msg=msg)
52+
53+
def __send_request(self, path, msg):
54+
return post(self.write_key, host=self.host, path=path, body=msg, timeout=self.timeout)

track/const.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import enum
2+
3+
DEFAULT_HOST = 'https://api.interakt.ai'
4+
5+
6+
class ApiPaths(enum.Enum):
7+
Identify = '/v1/public/track/users/'
8+
Event = '/v1/public/track/events/'

track/request.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import logging
2+
3+
from requests import sessions
4+
from requests.auth import HTTPBasicAuth
5+
6+
from track.utils import remove_trailing_slash
7+
from track.version import VERSION
8+
from track.const import DEFAULT_HOST
9+
10+
_session = sessions.session()
11+
logger = logging.getLogger('interakt')
12+
13+
14+
def post(write_key, host=None, path=None, body=None, timeout=10):
15+
"""Post the msg to the API"""
16+
headers = {
17+
'Content-Type': 'application/json',
18+
'User-Agent': f'interakt-track-python/{VERSION}',
19+
'Authorization': write_key
20+
}
21+
url = remove_trailing_slash(host or DEFAULT_HOST) + path
22+
logger.debug(f'Making request: {body}')
23+
response = _session.post(url=url, headers=headers,
24+
json=body, timeout=timeout)
25+
payload = response.json()
26+
logger.debug(f'Received response: {payload}')
27+
return response

track/utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import logging
2+
3+
logger = logging.getLogger('interakt')
4+
5+
6+
def require(name, field, data_type):
7+
"""Require that the named `field` has the right `data_type`"""
8+
if not isinstance(field, data_type):
9+
msg = '{0} must have {1}, got: {2}'.format(name, data_type, field)
10+
raise AssertionError(msg)
11+
12+
13+
def remove_trailing_slash(host):
14+
if host.endswith('/'):
15+
return host[:-1]
16+
return host
17+
18+
19+
def stringify(val):
20+
if val is None:
21+
return None
22+
if isinstance(val, str):
23+
return val
24+
return str(val)

0 commit comments

Comments
 (0)