<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Building an ML App
Now that we have a machine learning model to predict the defaults, let us try to build a web application to lend loans. 
It'll have two parts
Step1:  Let us run it as a service using firefly by running the following command in your terminal.
$ firefly sq.square
[2017-07-13 09
Step2:  The function will be available with the same name in the client. Please note that the client functions takes parameters only by name.
If you want to run on a different port, you can specify that as an argument.
$ firefly -b 0.0.0.0
Step5:  Credit Grade Service
Banks will have a access to the credit grade of each customer. Since we haven't have real data, let us build a simple mock credit grade service.
It'll take the email address of the person and gives a grade at random.
Step6:  Deploy it as a servive using Firefly.
firefly credit_grade.find_credit_grade
Step9:  Deploying the ML model
To deploy the machine learning model as a service, we need to read the model and all the encodings that we have used in building the model.
Step10:  Run it as a service using firefly, again from your terminal. Let us use port 9000 now as port 8000 is used by the credit grade service.
$ firefly -b 127.0.0.1
<ASSISTANT_TASK:>
Python Code:
%%file sq.py
def square(n):
    return n*n
Explanation: Building an ML App
Now that we have a machine learning model to predict the defaults, let us try to build a web application to lend loans. 
It'll have two parts: 
a form to submit the loans
admin panel to look at the submitted loans and their probability of defaults
The source code for the ML app is available in the github repo in credit-risk/webap folder.
It has all the moving parts except integration with the model.
Start the application using:
python webapp.py
ML as a Service
While we can package the model with the webapp and use it, it created tight coupling between the two. Everytime the model changes, the webapp will have to change. What if there are more than one application using the same model? 
It is lot simpler to deploy the ML model as a service exposing it's functionality through an HTTP API.
In this turorial we are going to use a tool called firefly for running the model as a service.
Introduction to Firefly
Firefly makes it very easy to deploy functions as a service without having to worry about writing a web app, managing request/response formats etc. and also provides a very simple client interface.
The detailed documentation of Firefly is available at:
http://firefly-python.readthedocs.io/
Let's try a simple example. Here We're creating a file sq.py with a square function. We'll see how deploy it a service and use in other programs.
End of explanation
import firefly
remote_sq = firefly.Client("http://127.0.0.1:8000")
remote_sq.square(n=4)
Explanation: Let us run it as a service using firefly by running the following command in your terminal.
$ firefly sq.square
[2017-07-13 09:48:07 +0200] [5001] [INFO] Starting gunicorn 19.7.1
[2017-07-13 09:48:07 +0200] [5001] [INFO] Listening at: http://127.0.0.1:8000 (5001)
It takes the &lt;module_name&gt;.&lt;function_name&gt; as argument and exposes the function as an API. The argument the function takes and the return value must be JSON-friendly for it work.
Once that is running, we can try to access it using the firefly client.
End of explanation
%%file add.py
# your code here
Explanation: The function will be available with the same name in the client. Please note that the client functions takes parameters only by name.
If you want to run on a different port, you can specify that as an argument.
$ firefly -b 0.0.0.0:9000 sq.square
For more help on the available command-line options, try:
$ firefly --help
Problem: Write funciton add_numbers in a file add.py and deploy it as a service using Firefly. Once that is ready, try to use it in another program using the Firefly Client.
End of explanation
%%file credit_grade.py
Program to find the credit grade of a person.
import zlib
import random
def find_credit_grade(email):
    Returns the credit grade of the person identified by the given email address.
    
    The credit grade can be either A, B, C, D, E, F or G.
    
    # since we need to give the same grade everytime the function is called
    # with the same email. Using the checksum of the string as random seed 
    # to get the same result everytime when used with the same email.
    seed = zlib.adler32(email.encode("utf-8"))
    r = random.Random(seed)
    return r.choice(["A", "B", "C", "D", "E", "F", "G"])
    
Explanation: Credit Grade Service
Banks will have a access to the credit grade of each customer. Since we haven't have real data, let us build a simple mock credit grade service.
It'll take the email address of the person and gives a grade at random.
End of explanation
credit_grade_api = firefly.Client("http://127.0.0.1:8000/")
credit_grade_api.find_credit_grade(email="alice@example.com")
Explanation: Deploy it as a servive using Firefly.
firefly credit_grade.find_credit_grade
End of explanation
%%file credit_risk_service.py
Service to expose the credit risk model as an API.
from sklearn.externals import joblib
# read the encoders and the model
grade_encoder = joblib.load("../notebooks/le_grade.pkl")
ownership_encoder = joblib.load("../notebooks/le_ownership.pkl")
model = joblib.load("../notebooks/model.pkl")
def predict(amount, years, age, ownership, income, grade):
    Returns the probablity of default for given features.
    
    # encoders work on a vector. Wrapping in a list as we only have a single value
    ownership_code = ownership_encoder.transform([ownership])[0]
    grade_code = grade_encoder.transform([grade])[0]
    
    # important to pass the features in the same order as we built the model
    features = [amount, grade_code, years, ownership_code, income, age]
    
    # probablity for not-defaulting and defaulting
    # Again, wrapping in a list as a list of features is expected
    p0, p1 = model.predict_proba([features])[0]
    return p1
    
Explanation: Deploying the ML model
To deploy the machine learning model as a service, we need to read the model and all the encodings that we have used in building the model.
End of explanation
import firefly
credit_risk_api = firefly.Client("http://127.0.0.1:9000")
credit_risk_api.predict(amount=10000, 
                        years=2, 
                        age=35, 
                        ownership='RENT', 
                        income=12345, 
                        grade='A')
Explanation: Run it as a service using firefly, again from your terminal. Let us use port 9000 now as port 8000 is used by the credit grade service.
$ firefly -b 127.0.0.1:9000 credit_risk_service.predict
Now let us predict.
End of explanation
<END_TASK>