Minimal Viable Product: Start small, Start sucky

mvp

What is a minimum viable product?

Start small or start sucky. Rescue yourself from “perfection paralysis”

“The minimum viable product is a version of a new product that allows you to start small  and quicker. It is used to collect the maximum amount of validated learning about customers with the least effort

It is a development technique in which a new product or website is developed with just enough features to satisfy the early customers. The main aim of the product is not only to get the wheel moving, but to be able to get valuable input on which features should be expanded on rather than building a whole artefact only to realise customers do not find real value in it. The final, complete set of features is only designed and developed after considering the feedback from the product’s initial users. This is the shorter and smarter route to take from having an idea to a finalised product.

To use this method, you need to remove the idea that a product must wait for perfection before being taken to market. No product is ever finished  and this mentality also keeps a lot of products from reaching market or has a development team working on features that may have no real value to the actual customer. Perfection in reality does not exist, even a product which you find to be great now will most probably be updated in future if it is to stay relevant. Rather than spend years on development get the work out in tiny batches of improvement taking in the input received after every release.

 

 

 

Building Apps for Shopify and MailChimp: Understanding the APIs

So I grammed a while back that I was looking into the shopify API and thinking of ways to automate a bit of the processes and communication I have to handle with my customers on Luxury Craft. I have finally (After very long procrastination) decided to get a new side project going and build my github cred.

In this blog I’ll give a quick run down of the project I have in mind, look at the APIs and the different end points I would have to use to get the project going.  We will make a few pull requests to get data out from  Shopify and eventually The next blog will go more into the actual design and architecture

PROJECT IDEA

So one of the most important things with an online store is continuous engagement, because you are not physically visible to trigger that need to buy, you need good communication protocols and methods to ensure you stay fresh and relevant in your customers mind. There are a lot of ways to keep the communication going from monthly or weekly emails, to calls and even smses with the main aim of the communication being conversion to sales.

One of the most neglected ways to convert communication to sales, is through the order notification emails. Research has shown that emails received to notify a customer of an order’s process  state have a high read rate. This means if you are to advertise here you have a greater chance of turning the communication to a sale. Not only are  you advertising to someone who is already a customer and therefore more likely to buy again but you also now know a bit about what the customer likes through the ordered products .

I am looking to create an app that can do the above.

On order fulfilment,  the application will send out an email telling the customer that the order has been shipped or fulfilled but also add to that email, recommended  products likely to be bought by that customer

This means you need to have some way of telling that if a customer bought product A, they would be likely to buy product E and F and not C. How you decide to link and relate the products is not really important for this exercise. You could use some AI to learn which products are “co-bought” (Would really have to have a large number of orders for this) Whichever way you decide, you will need to associate each product with a number related product.

Not a ground breaking project or idea and could be possible to get an app that does the same if I looked well enough but the point of this exercise is not to create great IP but to  explore the shopify and mailchimp API

We will need to interface with both the Shopify and MailChimp APIs as our work heavily relies on their data and services. So a great starting point would be understanding the two APIs

WHAT IS AN API (Application Programming Interface)

In very simple terms, an API is the middle man that takes requests from  application A to  application B, tells application B what you want to do  and returns the response given by application B back to A, the requestor. It is basically the unsung hero of all the behind the scenes connectivity allowing us to get data from anywhere. The middle man who understands what you want from a specific platform and returns it to you without you having to understand all the complexities of the implementation of that platform.

So for example Shopify  has their software which has their DataStore holding your  store data and all the thousands of other stores registered with them. Your store data holds all your products, orders and customer information.  Through their  web User Interface or mobile app you can see and manage your shop and all the products and orders in your store.

shopify

Say one day you decided you wanted to use products  and customers information  in your store (like we have now) . Say we are a very big company with thousands of customers, we cant possibly sit down to right out each order and customer info.  For us to get this information without their API, we would need to somehow get access to their datastore, understand their database model, and figure out how to be able to get just our information out from the thousands of store’s data they have in their datastore with the many tables. Now that would just be a headache and security nightmare

So what the nice guys at Shopify (and many other companies including Mailchimp) do is give you an API from which you can interface with their data. They create a middle man and give that middle man some pre-defined language that you can use to communicate with him (or her, most likely her with her good communication skills:) ) by to get the data you would like.  So all you need to do, is understand this language that the middle man speaks. This is clearly documented in their API documentation.

apimain

Now that thats out of the way let’s have a look at the shopify API documentation to see what we are allowed to ask the middle man for and how we should ask for her to understand our request.

If you do not have a Shopify store you can register to become a partner to create a mock store with mock data. You can follow here  to get started to become a partner and then create your fake store. To keep this short I wont have this included here. If you need assistance you can comment below and I’ll help.

A look at the Shopify API

Authentication

When building applications to integrate with shopify, you would need to select whether you are creating a public application which would be used by more than one store  or a private application to be used by one specific store. Your authentication process depends on this decision. I will only be focusing on the private application for this blogpost.

To connect with the API you need to make http calls to the middle man and authentication credentials must be sent with every call. The credentials are used to let the middle man know and trust who you are and know which data you are eligible for.

Your credentials can be sent through by passing your  Shopify’s store token prepended with the string “Basic ” in your headers with  Authorization as Key. To generating your store credentials, have a quick look here .

An example call using my store data to make a call for my shop data in json  below

Screen Shot 2017-04-27 at 10.50.54 PM

 

Responses

When a call is made you will get one of the responses described in detail here

EndPoints

The API documentation lets you know of all the possible requests you can make and the data you can expect from them. For example with the example above,the documentation specified that to get my store customers in json format, i would need to make a call to  this endpoint

https://<store url>/admin/customers.json

Get the detailed documentation here

Webhooks

Webhooks are what will make it possible to take action based on an activity that occurred in the store.  They are useful when building applications that need to do something after an event has occurred without having to make continuous calls to the API to check if the event has occurred.

Webhooks send a HTTP Post  to a specified url to notify you of the event. Your application would then respond to the post and then continue to fulfil any action required on that event. We will look into this in more detail in the following posts

A look at the MailChimp API

The application needs to be able to be notified on order and send out an email to the specified customer.

Authentication

Just like Shopify (Or any self respecting API really), Mailchimp will want to ensure that it is talking to a real and verified person before sending out data. This is again done through token based authentication. Follow steps here to get your token referred to as the APIkey here

EndPoints

All calls are to be made to the following url :https://<dc&gt;.api.mailchimp.com/3.0

Where <dc> refers to the dat centre for your specific Mailchimp account. For example, if the last part of your MailChimp account is us6, All API endpoints for your account are available at https://us6.api.mailchimp.com/3.0/.

See an example of a call for my mailchimp info.

Screen Shot 2017-05-17 at 6.03.00 AM

 

Sending Emails: Mandrill

As of  v3.0 of the Mailchimp API Sending out of  transactional emails  is now handled by Mandrill.

You would also need to authenticate yourself similarly to above with https://mandrillapp.com/api/1.0/ as the base url. You would also need to get another token

When accessing the Mandrill API, All API calls should be made with HTTP POST with the token parsed with the key “key”

See below an example calling to https://mandrillapp.com/api/1.0/users/info.json which returns information about the API-connected user

The full API documentation can be found  here

 

WRAPPING UP

This post covered the API required to create an application integrating with Shopify and MailChimp.  We describe a small problem that we will solve over a mini series.

Please  comment, correct and give input

“The only legacy I will  accept is to know that how far I got, was as far as I was capable of going, to drown in my own sweat, knowing there was nothing left”

-FIGHTING MEDIOCRITY : One thread at a time

Python client side SSH and SFTP with paramiko

So i’m employed at a social media type of company with a product working a lot like facebook and the past week had to sort out an issue with loosing the linking between video urls on our db with the actual content on the server. Some mismatch with Kaltura. But anyways long story short, I had to write a little script which would download videos from a remote server to upload to Kaltura to and get new urls to replace old ones int the db.

SSH is the method typically used to access a remote machine and run commands, retrieve files or upload files.

You can transfer files from the remote machine to the local or vice versa using SFTP (Secure File Transfer Protocol) and SCP(Secure Copy Protocol).

According to paramiko.org, The python paramiko model gives an abstraction of the SSHv2 protocol with both the client side and server side functionality. As a client, you can authenticate yourself using a password or key and as a server you can decide which users are allowed accesss and the channels you allow

In this blog I focus on the client side.

Let’s get on with it

The primary client of Paramiko as documented in the API, is Paramiko.SSHClient. An instance of the Paramiko.SSHClient can be used to make connections to the remote server and transfer files

MAKING A CONNECTION

import paramiko
ssh_client=paramiko.SSHClient()
ssh_client.connect(hostname='hostname',username='mokgadi',password='mypassword')
#Raises BadHostKeyException,AuthenticationException,SSHException,socket error

when you try this, you get the following error:

missing_host_key raise SSHException(‘Server %r not found in known_hosts’ % hostname) paramiko.ssh_exception.SSHException: Server ‘hostname’ not found in known_hosts

Understanding Known Hosts:

You see this error because you have not informed your machine that you “trust” the server you are trying to access. If you go onto you command line or terminal and try to connect to a server for the first time, You will get a message similar to this:

The authenticity of host ‘hostname’ can’t be established.RSA key fingerprint is ‘key’. Are you sure you want to continue connecting (yes/no)?

When you select yes here, you let your machine know that it can trust the machine and you can now access it without the prompt until the key for that machine changes.

Paramiko similarly requires that you validate your trust with the machine. This validation is handled by calling set_missing_host_key_policy() on the SSHClient and parsing the policy you want implemented when accessing a new remote machine. By default,  the paramiko.SSHclient sets the policy to the  RejectPolicy. The policy rejects connection without validation as we saw above. Paramiko does however give you a way to sort of “Trust all” , the AutoAddPolicy. Parsing an instance of the AutoAddPolicy to set_missing_host_key_policy() changes it to allow any host.

import paramiko
ssh_client =paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname='hostname',username='mokgadi',password='mypassword'

You should now be in the green

RUNNING COMMANDS ON THE REMOTE MACHINE
To run a command exec_command is called on the SSHClient with the command given. The response is returned as a tuple (stdin,stdout,stderr)
For example to list all the files in a directory:

stdin,stdout,stderr=ssh_client.exec_command("ls")

Getting the type for each of the returned,
type(stdin) and type(stdout) is ‘paramiko.channel.ChannelFile’
type(stderr) is class ‘paramiko.channel.ChannelStderrFile’

According to paramiko.org they are all python file like objects.

The stdin is a write-only file which can be used for commands requiring input
The stdout file give the output of the command
The stderr gives the errors returned on executing the command. Will be empty if there is no error

for the command above
>>>print(stdout.readlines()) --> [u'anaconda-ks.cfg\n', u'database_backup\n', u'Desktop\n', u'Documents\n', u'Downloads\n', .... u'Public\n', u'Templates\n', u'Videos\n']

>>>print(stderr.readlines) –> []

COMMANDS REQUIRING INPUT
Sometimes you need to provide a password or extra input to run a command. This is what stdin is used for. Let’s run the same command above with sudo.

stdin, stdout, stderr = ssh.exec_command("sudo ls")
stdin.write('mypassword\n')
print stdout.readlines()

Should return list of files and folders as above.

FILE TRANSFERS
File transfers are handled by the Pparamiko.SFTPClient which you get from calling open_sftp() on an instance of Paramiko.SSHClient.

Downloading a file from remote machine

ftp_client=ssh_client.open_sftp()
ftp.get(‘remotefileth’,’localfilepath’)
ftp.close()

Uploading file from local to remote machine

ftp_client=ssh.open_sftp()
ftp_client.put(‘localfilepath’,remotefilepath’)
ftp.close()

Give it a go and correct me where you must :). Please do follow or subscribe to my blog to get notified on any new posts

Entrepreneurship is a lifestyle

One of the biggest challenges I had with running my business was getting comfortable with having a very defined priority list. One that did not suit society’s norms and sadly also one that did away with some of the things I loved. Getting used to the idea of an “out of balance” life to keep focus on youR ONE THING.

This is not as easy as it sounds as we humans are generally not geared to do or enjoy just one thing. For instance, I personally would love to get home and cook for my little girl, read a story and play a bit but I must settle for going without the cooking and having shorter than preferred periods with my daughter to allow the necessary time to be invested in growing the business. Any one who has spent long enough time with me will know about my obsession with mothering, perhaps why this is my hardest sacrifice. I have for as long back as I can remember wanted to be the “idol mommy and wife”. Get home cook, love and devote of my whole self to my team. This does not easily fit into the entrepreneurship lifestyle.

This need for sacrifice does not just end with the family construct. It creeps in everywhere. from allocating time down to money.Another example, One of my guilty pleasures is spending a considerable amount of money on good brands.  With understanding the process of building a powerful  good brand more so, South African black brands,  I would love to indulge in spending but I must continuously learn to live a very spend savy lifestyle with running a very machinery intensive startup all self-funded

Entrepreneurship is a lifestyle and a very strenuous one at that. You need to, at your core be comfortable with many parts of your life being off balance to keep the one thing striving. Anything great requires that type of sacrificial love.Too many people glamourise it: The continuous killing off of your wants to focus on the one thing you see as important.

In this process, there will be critics. I can’t tell you the number of times i have been told of being a bad mommy for spending longer hours at the office or being told I would be so far if only  I didn’t spend on… The only way you can pull through it is if you openly accept and acknowledge these sacrifices. There is no right or wrong way. Create a schedule that works for you. It does not even have to stick for ever. If or when you feel, change it to suit you. Remain your number one star player and remain relentless in the pursuit of becoming

“Balance is a myth. The only way you do GREAT work is to move from the middle, out of the “normal” balance. What separates the great from the average is knowing when to pursue the middle and when to stay at the extremes.

Learn to counter balance. Choose what matters most and give it all the time it needs and get used to the “other” being out of balance. Every now and then step back to the balance just  so to correct the imbalance ”

EVEN THE TALLEST AND MOST FORMIDABLE OF TOWERS WAS ONCE JUST A PILE OF BRICKS! STAY RELENTLESS

Sometimes there is just no market

The thin line between “they will adjust” and “There is simply no market”

“Be you, The world will adjust”

Probably one of the most reblogged and hash tagged quotes in the world of self love and authenticity. Every now and then you see it in an entrepreneurship blog and while I am one of the biggest advocates for self love, this is sometimes the biggest killer of many businesses: The idea that your love and passion for an idea directly implies there being a big enough market group that equally or will eventually, equally love it.

This is perhaps one of the hardest lines to tread as a business and the point where most businesses fail. The point where, you have to consolidate your 1.passion and confidence in not only yourself but also your product with 2. the probability of creating a big enough following for the product. In other words the probability of a big enough market share, that is if there even is a market to begin with.

This does not necessarily mean a complete throw away of your idea or at least not right away. The best among us enterpreneurs, are those who after identifying this misalignment, of their vision and their intended market, are able to tirelessly tweak, and change the product or simply redirect to a new market and are able to do this, not only once, but as many times as is necessary to find the perfect fit.

At those dreadful times that you realize the fit does not exist and there exists no place for it in the market,count your losses, take the lessons and move on. No matter how good the idea seemed, how much time spent and how much money invested, move on. Forgive yourself for the horror of the first draft and start again on a blank page. Attach no self worth to any failed try. Those missed take offs always make for greater stories when looking back.

First post! comment, share and follow.