Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Friday, 1 May 2015

REST Api with Flask-Restful and MongoDB

What is REST



REST (Representational State Transfer) is an architecture style for designing networked applications. The idea is using simple HTTP methods for making calls between machines rather than complex mechanisms such as CORBA, RPC or SOAP. 
So a RESTful system typically communicates over the Hypertext Transfer Protocol with the same HTTP verbs (GET, POST, PUT, DELETE, etc.)

Flask and Flask-RESTful

Flask is a microframework for Python based on Werkzeug, Jinja2. Flask-RESTful provides an extension to Flask for building REST APIs.

Installing packages

For the api, we need to install some packages like Flask-Restful, pymongo etc. It's good practice to install packages and modules for a project in a virtual environment. So i am going to create a virtual environment and activate it.

$ virtualenv env
$ source env/bin/activate

Now the required packages can be installed using pip. (Link: requirements.txt)
$ pip install -r requirements.txt


Api

Lets Code the API first.


This is a basic api with only one Resource Student. First we created an instance of Flask,
app = Flask(__name__)
after that we configured app with MongoDB.

The resource Student has HTTP methods defined in it as it's own method. By calling different HTTP methods we can perform basic CRUD operations. Like post for inserting/creating, put for updating, get for reading and delete for deleting a document.

In the code post, put, delete methods are basic.  These methods perform create, update and delete operation on the collection student. 

But in the get method, by calling different url we can perform different operations. If no parameter passed with url, the method will return all the documents in the collection. If a registration number passed with the url then, it will check the parameter name and will return one document. If request is made in /api/department/<string:department> url, it will check for parameter name department in the get method and returns all the documents for a particular department.

There are several urls for same resource so we added different endpoints for them.

Testing the Api

We will use python requests module (version > 2.4.2) for testing the api. But also curl and other mechanism can be used. For get request we can view the data in browsers also.


requests module gives us convenient way to test our api. Enough REST. Lets take some rest ;)

Tuesday, 10 March 2015

PYTHONPATH and importing modules in python

What is PYTHONPATH

PYTHONPATH is an environment variable that defines additional locations of Python modules. This is the default search path for module files. This means that python interpreter will search for modules in the location of the PYTHONPATH.

How importing works in python

When a module named mymodule is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named mymodule.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
  • The directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • the installation-dependent default.

problem scenario and solve:

A
|--__init__.py
|
|--B
|--|--__init__.py
|--|--greetings.py
|
|--C
|--|--__init_.py
|--|--mymodule.py

Here A is a python package. Inside A, there are two packages B and C. 

greetings.py
def my_function():
    print "Congrats Bangladesh Cricket Team!! :D"

mymodule.py
from B.greetings import my_function
my_function()

Now, there is a problem. Package A  is not in python interpreter's search path. So it can not import greetings function from B  within C. If mymodule.py is run, it will raise an ImportError as expected.

$ python mymodule.py
Traceback (most recent call last):
  File "mymodule.py", line 3, in <module>
    from B.greetings import my_function
ImportError: No module named A.B.greetings

To solve it, we need to add the absolute path of package A in sys.path inside mymodule.py before importing greetings from B. Path will be appended in sys.path. This will not affect other python program because the path will not be modified for any other Python processes. 

mymodule.py
import os
import sys

PATH = os.path.abspath(os.path.join(os.pardir))
sys.path.append(PATH)

from B.greetings import my_function
my_function()

Now as the path of A is added, Python interpreter can find the package B inside A. Let's run again this function

$ python mymodule.py
Congrats Bangladesh Cricket Team!! :D



Sunday, 18 January 2015

Python map, filter, lambda explained with example

map(function, sequence[, sequence, ...]) -> list

map(function, iterable, ...) is a python builtin function.
  • It returns a list of results applying the function to the items of the argument sequence(iterable) or sequences.
  • If more than one iterable arguments are passed, the function must take that many arguments. The function is called with an argument list consisting of the corresponding item of each sequence.
  • If one iterable is shorter than another it is assumed to be extended with None items.
We can examine these rule with some codes.

def square(a):
    return a ** 2

Here  square is a function that makes a number square. We want the square of number 0 to 5. Using map(),

>>> map(square, range(6))
[0, 1, 4, 9, 16, 25]

So map() takes a function square and a list as arguments and returns a list of square(item).  Here item is elements in the list range(6).
If we pass two iterable in map(), the function must take two arguments.

def my_pow(a, n):
    return a ** n


Now my_pow function takes two arguments a, n and returns an.

>>> map(my_pow, [2, 3], [3, 2])
[8, 9]

But what if the two iterables are not of same length? In this particular case it will  generate a TypeError.



filter(function or None, sequence) -> list, tuple, or string

filter(function, iterable) is a python builtin function.
  • It returns those items of sequence for which function(item) is True.
  • If function is None, return the items that are True.
  • If sequence is a tuple or string, return the same type, else return a list.
We want to filter out the even integer from a list and we have written a function for this.

def is_odd(n):
    if n % 2 == 1:
        return True    
    return False

is_odd  function takes an integer and returns True if it's odd number otherwise returns False.

>>> filter(is_odd, range(10))
[1, 3, 5, 7, 9]

What happens here is, filter() applies the is_odd function on each item of the list range(10) and returns a list of those items for which is_odd returned True. It filters out the other items.


>>> filter(None, k = [True, False, True, False])
[True, True]

If the function is None it return the items that are True


lmabda function:

Now, fun begins with lambda functions. in Python,
  • lambda operator is a way to create small anonymous function. An anonymous function is a function without a name.
  • lambda function can be used wherever a normal function is used but it's restricted to a single expression.
  • function require multiple expression can not be expressed using lambda.
lambda functions are written as:
lambda arguments: expression (operation to perform on arguments)
lambda function returns the result of the operation.

What we have done in map() and filter() examples is, separately wrote a function and pass those in map(), filter()

We can do the same using lambda function.

>>>  map(lambda n: n**2, range(6))
[0, 1, 4, 9, 16, 25]

what happens here is same in the map() example but in this case a lambda function is used.

lambda n: n**2

On the left of : are the arguments. Here n is the argument and on right side is the expression that will be applied to the argument. The return value is the result.

>>> map(lambda a, n: a**n, [2, 3], [3, 2]) 
[8, 9]

This is equivalent to the my_pow() example.

Suppose we want to get all the digits from a string. According to our filter() and lambda knowledge,

>>> filter(lambda s: s.isdigit(), "adf9df215")
'9215'

We can write a little complex expression in lambda.

>>> filter(lambda s: False if s.isspace() else True, "This is SPARTAAAAAAA")
'ThisisSPARTAAAAAAA'

This filters out all the space from the string. Hope king  Leonidas don't mind.

Friday, 26 December 2014

Python built-in: setattr(), getattr()

setattr(object, name, value)


setattr() sets a named attribute on an object. The arguments are an object, a string and an arbitrary value.
setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.

Example Usage:

Lets assume Peter's mother has to write a class for preparing tiffin box for her son Peter who does not want to eat very regularly. Everyday in a week she puts random sandwichs and fruits in the tiffin box and checks if peter has eaten that or not. Let help her write the class using setattr()

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['bacon', 'egg', 'jam']),
             random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), 
             random.choice(range(1, 4)))

Here we are setting a random food with a random number from 1 to 3. The number defines the amount of that food in Peter's tiffin box.
Now we also want Peter to drink something and check if he has eaten the food. Let's write some methods in this class to do those.

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['apple', 'banana', 'oranges']), 

             random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), 

             random.choice(range(1, 4)))

    def take_drink(self):
        drinks = random.choice(['coffee', 'tea'])
        setattr(self, 'drink', drinks)

    def eat_food(self):
        for food in self.__dict__:
            setattr(self, food, 0)
        setattr(self, 'eaten', True)


Peter can eat using eat_food method and if he eats that food we will add a new attribute to the object named eaten set it to Boolean True and make the all the food count 0 assuming Peter ate all the foods.
We can also add a weekday attribute here. Now the class looks like this.

# -*- coding: utf-8 -*-
import random
from datetime import datetime

class TiffinBox(object):
    def __init__(self):
        setattr(self, random.choice(['apple', 'banana', 'oranges']), random.choice(range(1, 4)))
        setattr(self, random.choice(['bacon', 'egg', 'jam']), random.choice(range(1, 4)))
        self.tiffin_day = self.get_weekday(datetime.now().weekday()) + '_tiffin'
    def __str__(self):
        return self.tiffin_day

    def take_drink(self):
        drinks = random.choice(['coffee', 'tea'])
        setattr(self, 'drink', drinks)

    def get_weekday(self, weekday):
        py_week = {
            0: 'monday', 1: 'tuesday', 2: 'wednesday', 3: 'thursday', 4: 'friday', 5: 'saturday',6: 'sunday' }
        return py_week.get(weekday)

    def eat_food(self):
        for food in self.__dict__:
            setattr(self, food, 0)
        setattr(self, 'eaten', True)

Now Peter's mother can prepare tiffin for him.

>>>tiffin =TiffinBox()
>>>tiffin.__dict__
>>>{'apple': 3, 'jam': 3, 'tiffin_day': 'friday_tiffin'}
>>>tiffin.eat_food() 
>>>tiffin.__dict__
>>>{'eaten': True, 'apple': 0, 'jam': 0, 'tiffin_day': 'friday_tiffin'}

Neat !!

getattr(object, name[, default]) -> value


getattr() is a python built-in that gets a named attribute from an object and return the value of that attribute.
The attribute name must be a string. getattr(x, 'y') is equivalent to x.y. default is an optional argument.
If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

>>>la = range(5)
>>>getattr(la, 'pop') 
<built-in method pop of list object at 0xb7470eac>
>>>la.pop
<built-in method pop of list object at 0xb7470eac>

so getattr(la, 'pop') is equivalent to la.pop. It can be used like a function also.

>>>getattr(la, 'pop')()
4
>>>getattr(la, 'abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'abc' 

A  list object has no attribute named 'abc'. So a AttributeError is raised here. But if we use the optional default argument, then the default value is returned.

>>> getattr(la, 'abc', 'no such attribute')
'no such attribute'

Example Usage:

Let's help Peter to find out what his mother has put in the box and in how many amount. He does not know if it's a apple or banana, bacon or jam! Time to use getattr()

mybox = TiffinBox()

for atr in mybox.__dict__:
    print atr, ': ', getattr(mybox, atr)


tiffin_day :  friday_tiffin
bacon :  2
oranges :  3


Hope Peter likes bacons and oranges!




Wednesday, 24 December 2014

Python built-in: any(), all()


any(iterable) -> bool


any(iterable)  is a built-in function in python's  __builtin__ module. It returns True if bool(x) is True for any x in the iterable. If the iterable is empty, return False.
Now let's take a list.

>>>la = [True, False, False]
>>>any(ls)
>>>True

This returns True because at least one of the value in la was True. Let's take another list,

>>>lb = [False, False, False, False]
>>>any(lb)
>>>False 

So any() will return True if at least one of the value in the iterable is True else it will return False.

Example Usage:


>>>str = "Wikipedia is the seventh-most popular website \
...and constitutes the internet's largest and most popular \
...general reference work"
>>>keywords = ['Google', 'Wikipedia', 'Facebook', 'Microsoft']

We want to check if there is keyword from keywords list is present in the string str. With the use of any() function it can be done in a one-liner!

>>>any(keyword in str for keyword in keywords)
>>>True

That's awesome!! isn't it? But what sorcery is this? Breaking it down:

>>>[keyword in str for keyword in keywords]
>>>[False, True, False, False]

So it's like the earlier la, lb type list. It's returning True for the keyword 'Wikipedia'. Now what is happening in the list
compression is:

for keyword in keywords:
    if keyword in str:
        # append True in a_list
    return <a_list>

 

all(iterable) -> bool


This function takes an iterable as argument and returns True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True.

It will return if all the values in the iterable are True.

>>>all(la)
>>>False
>>>all(lb)
>>>False

>>>lc = [True]*3
>>>all(lc)
>>>True

 

Example Usage:


We are going to check if a list is a odd number list.

>>>all(map(lambda x:x%2==1, range(1, 10, 2)))
>>>True

Breaking it down:

>>> range(1, 10, 2)
>>>[1, 3, 5, 7, 9]

map() is a built-in which will return a list of result applying the lambda function to the item of the [1, 3, 5, 7, 9] list.

>>>map(lambda x:x%2==1, range(1, 10, 2))
>>>[True, True, True, True, True]
>>> all([True, True, True, True, True])
>>>True

Nice!!