MyAffiliates API Integration¶
MyAffiliates API Integration model details:
As per the MyAffiliates API integration Documentation unlike other API authentication MyAffiliates uses Basic HTTP1.0 authentication with username and password. To store the basic authentication details for Cubed clients we have APIMyAffiliatesConnection
with records username
, password
and cubed_user_id
.
APIMyAffiliatesConnection
model looks like this:
class APIMyAffiliatesConnection(DeactivateBase):
username = models.CharField(max_length=200)
password = models.CharField(max_length=200)
domain = models.CharField(max_length=200)
active = models.BooleanField(default=True)
cubed_user_id = models.IntegerField()
created = models.DateField(auto_now_add=True, db_index=True)
updated = models.DateTimeField(auto_now=True, db_index=True)
def save(self, *args, **kwargs):
fernet = Fernet(settings.CUBED_ATTRIB_FERNET_KEY)
encrypted_password = fernet.encrypt(str.encode(self.password, 'utf-8')).decode()
self.password = encrypted_password
super().save(*args, **kwargs)
A username
and password
belongs to admin account of MyAffiliates. cubed_user_id
is related to Auth User
to recognize which Cubed user it belongs to.
To protect and hide the MyAffiliates admin account password
we are using Fernet
from cryptography.fernet
python module to encrypt and then decrypt when needed the password
. Fernet
module uses a URL-safe base64-encoded 32-byte secret key which will be once generated should be stored safe and securely. This secret key is different for each cubed environment such as Local, UAT, Staging and Production. We have added the secret key as backend_fernet_key
in YAML
files.
For UAT
, Staging
and Prod
are sharing same Fernet
keys by adding this to YAML
file:
backend_fernet_key: "{{ lookup('env', 'CUBED_ATTRIB_FERNET_KEY') }}"
Command to pull MyAffiliates token based data:
To pull data and decode tokens from API, MyAffiliates uses XML API interface with Basic HTTP/1.0
authentication request with admin username
and password
.
A GET
request with parameters FEED_ID
and list of comma separated tokens
is passed. Response is in xml format and for that we are using ElementTree
XML parsing python module to extract desired information from tokens. We are then storing this data in MyAffiliatesVisit
model and it is as follows:
class MyAffiliatesVisit(models.Model):
referrer_url = models.CharField(max_length=2000, db_index=True)
token = models.CharField(max_length=1000, unique=True)
visit = models.ForeignKey('Visit', related_name="my_affiliates_tokens", on_delete=models.PROTECT)
user_id = models.CharField(max_length=100)
campaign_id = models.CharField(max_length=100, db_index=True)
description = models.CharField(max_length=500)
class Meta:
db_table = "myaffiliates_visit"
We request the the data as follows:
response = requests.get(domain, params = {'FEED_ID': 4, 'TOKENS': LIST OF TOKENS }, auth = HTTPBasicAuth(username, password))
GET
request is built-up url of MyAffiliates admin domain, params {'FEED_ID': 4, 'TOKENS': LIST OF TOKENS }
and HTTPBasicAuth credentials stored in APIMyAffiliatesConnection
. FEED_ID: 4
is specifically to pull decoded tokens from the XML API.
An example of XML
response from API:
1 2 3 4 5 6 7 8 9 10 |
|
From Above XML
response we are extracting by details such as TOKEN PREFIX
, USER_ID
, CAMPAIGN_ID
, REFERRING_URL
and OBJECT_DESCRIPTION
using ElementTree
XML parsing python module