Hello Docker!

02/11/2018

This post is about working with containers and python web applications. But first, a little bit on containers and their use in a development ecosystem. Docker is a technology that provides abstraction and automation at an operating system level offering reusability, automation control, version control, per review, and testing capabilities.
This virtualization of bare-bones operating systems into containers enables a micro-services model where all the units of work are divided into separate units of work, facilitating scalability, relability and testing. In essence, docker containers allows developers to be accountable for programming features without having to worry about machine dependencies.

The following code blocks gives a walk-through on building a dockerized web app, the hello world of docker.

First create a new directory called “hello_docker” to contain our webserver. Then inside the hello_docker directory create a another directory creatively named “app.” Inside the app directory, create a file called hellodocker.py with the following contents.

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
 return 'Hello World!\n'
if __name__ == '__main__':
 app.run(debug=True, host='0.0.0.0')

 

This web server will run off a docker container so lets create a dockerfile that will be used to create our docker image. In the hello_docker directory create a file called Dockerfile with the following contents.

FROM python:3.4
RUN pip install Flask==0.10.1
WORKDIR /app
COPY app /app
CMD ["python", "hellodocker.py"]

 

Dockerfiles contain a set of instructions for docker to create an image to specifications. The first line pulls the python 3 image as a base installation and installs flask, the next lines copy the code from our directory to the image on build and runs the server.

Next to build the sample app run in the terminal,

cd hello_docker
docker build -t hello_docker .
docker run -d -p 5000:5000 hello_docker

 

Docker run with flags -d -p run the app in the background and forward port 5000 in the container to port 5000 on the host. The command should output a hash confirming a successful execution.

Screen Shot 2018-02-11 at 6.41.17 PM

Our docker image is now built and running! To test the application run the following command verifying the message “Hello Docker!”:

curl $(docker-machine ip default):5000
Hello Docker!

 

This walkthrough barely scratched the surface of  some of dockers capabilities so if you are interested in experimenting with docker I’ve listed a few links to get started with.

https://aws.amazon.com/what-are-containers/

https://www.docker.com/

https://docs.docker.com/

https://docs.docker.com/registry/#alternatives

https://hub.docker.com/

Here are a few more helpful cmds.

#To see your all docker containers
docker ps -a

#to see your running docker containers
docker ps

#to see your docker images
docker images

If you like these blog posts or want to comment and or share something do so below and follow py-guy!

Python Operating System Calls

12/13/2017

Python’s lightweight dynamic interface is proven excellent for networking, data scraping and gui generating tasks. Python’s powerful and possibly overlooked os module enables you to take a dynamic approach to operating system programming. With python you can read or write to and from files across different areas on your hard drive and interface with the cmd line simply utilizing a few lines of code. This becomes useful in managing dependencies and project states.

First import sys and os

# lister.py
import sys, os

Then we will create a new method lets call it lister which will take an argument root to create our directory tree. The for loop will iterate through each directory containing files and os.walk() will generate a list of directories either top-down or bottom-up. This will print each directory to the command line console encapsulated by braces.

def lister(root):
....for (thisdir, subshere, fileshere) in os.walk(root):
........print('[' + thisdir + ']')

Each directory at its root yields a tuple containing three variables: dirpath, dirnames, filenames. These variables make up a tree-like data structure (where *  represents many).

                                                        Screen Shot 2017-12-13 at 2.06.33 PM.png

The nested for loop iterates through all the files contained by the directory.

........for fname in fileshere:
............path = os.path.join(thisdir, fname)
............print(path)

The path is collected and concatenated with the filename and then printed to the console.

if __name__ == '__main__':
....lister(sys.argv[1])

When lister.py is run the root directory must be called with the root directory to pass as an argument so sys knows where to begin the os walk.

Screen Shot 2017-12-13 at 2.13.26 PM

The resulting output might be similar to the stream below.

Screen Shot 2017-12-13 at 2.12.33 PM.png

If you like these blog posts or want to comment and or share something do so below and follow py-guy!

Python Web services, JSON, and ISS Oh My!

11/14/2017

In this post I will talk about how to handle JSON data from an external API utilizing python. Making calls to web services is made simple with python, with just a few lines of code you can track the International Space Station’s (ISS) position and time, realtime with a sleek graphical user interface. The following is a link to the project files download, https://codeclubprojects.org/en-GB/python/iss/.

The Turtle module is an object oriented graphics tool that draws to a canvas or screen. Turtle’s methods derived include forward(), backwards(), left() and right() like telling a turtle in what direction to draw. Turtle will draw over a NASA curated 2D map of Earth, so you should place the ‘map.jpg’ file in your project directory.

So one of the first things we need to do is instantiate a turtle screen with the following command.

# turtle provides a simple graphical interface to display data
# we need a screen to plot our space station position
import turtle
screen= turtle.Screen()

The image size is 720w by 360h so our turtle screen size should fit the image size.


# the image size is 720w x 360h
screen.setup(720,360)
# set coordinates to map longitude and latitude
screen.setworldcoordinates(-180,-90,180,90)
# set background picture to NASA world map, centered at 0
screen.bgpic('map.jpg')

 

iss

To represent the ISS on the 2D map let’s choose an image, it doesn’t have to be the following icon but it’s a nice icon so Houston we have liftoff!

# adds turtle object with name iss to list of objects
screen.register_shape('iss.png')
iss= turtle.Turtle()
iss.shape('iss.png')

 

Our location object will tell turtle to write the ISS png file to the screen at a specific position given the latitude and longitude of the ISS. Instantiate a Turtle() to create an object with the following code.

 

# location object for turtle to plot
location= turtle.Turtle()

# used later to write text
style=('Arial',6,'bold')
location.color('yellow')

Now, before we can tell our turtle to draw the ISS overhead-time we need the actual latitude and longitude coordinates of the passing ISS. A quick google search gives us the coordinates to store in a dictionary.

# Cape Canaveral ---> 28.392218, -80.607713
# Central Park, NYC ---> 40.782865, -73.965355
# create python dictionary to iterate and plot time of overhead location
coords={}
coords['nasa_fl']=(28.523397, -80.681874)
coords['centralp']=(40.782865, -73.965355)

To call the api we first need the url, ‘http://api.open-notify.org/astros.json,’ this will tell the api to give us the data we need to extrapolate the ISS data.

import urllib.request
import json
url='http://api.open-notify.org/astros.json'
response=urllib.request.urlopen(url)
result=json.loads(response.read())
print(result['people'])

Then to make the call to the url use urllib.request to access the url, querying for each given location. The data is then stored as a result,  loaded in json format. Json stands for JavaScript Object Notation and is used to conveniently organize data.

Screenshot (76)

The lines above are the contents of the json data, data is accessed similar to a python dictionary utilizing keys and indices.

import time

# setup loop to iterate and plot when the iss will be at the plotted location.
for k,v in coords.items():
 pass_url= 'http://api.open-notify.org/iss-pass.json'
 pass_url= pass_url+'?lat='+str(v[0])+'&lon='+str(v[1])
 pass_response= urllib.request.urlopen(pass_url)
 pass_result= json.loads(pass_response.read())
 over=pass_result['response'][1]['risetime']
# write turtle at new location coords
 location.penup()
 location.color('yellow')
 location.goto(v[1],v[0])
 location.write(time.ctime(over), font=style)
 location.pendown()

The above code block makes a call to the api, loads the json data, parses the overhead pass time (when the iss will be over the specified position) and then plots the time at the given location.

Screenshot (77)

# init current loc off iss coord
# make call to api
loc_url= 'http://api.open-notify.org/iss-now.json'
loc_response=urllib.request.urlopen(loc_url)
loc_result=json.loads(loc_response.read())</pre>
# the coords are pcked into jso, iss_position key
location= loc_result['iss_position']
lat= float(location['latitude'])
lon= float(location['longitude'])
<pre># set up while loop to plot moving iss
while(1):
# iss loc updates approx 3 sec
 time.sleep(1.5)

# update call to webservice to get new coords
 loc_url= 'http://api.open-notify.org/iss-now.json'
 loc_response=urllib.request.urlopen(loc_url)
 loc_result=json.loads(loc_response.read())
 location= loc_result['iss_position']
 lat= float(location['latitude'])
 lon= float(location['longitude'])
# write turtle at new location coords
 iss.setheading(90.0)
 iss.penup()
 iss.goto(lon,lat)
 iss.pendown()

 

The above code block makes a call to the api, loads the json data, parses the overhead position at the current geographic coordinates and plots the iss icon. The while loop is infinite to constantly track the iss.

Screenshot (75)

If you like these blog posts or want to comment and or share something do so below and follow py-guy!

Object Oriented Python Programming

9-24-2017

In python object oriented programming is a simple way to build powerful applications. Consider a real-world object like a pair of shorts. This pair of shorts has a set of attributes and properties to make that pair of shorts unique. For example this pair of shorts might have pockets, buttons and zippers to put on and take off the shorts. Essentially, we have a blueprint to make any pair of shorts (give or take a few unique properties), this is known as a class and is the fundamental concept of object oriented programming and design. Each class defines attributes and methods instantiated by objects. Let’s take a look at some example code of out shorts class.

class shorts:
    def __init__(self,waist,length,color):
        self.waist=waist
        self.length=length
        self.color=color
        self.wearing=False

In python each class has an __init__ constructor to define unique parameters for each object. Self is the reference to the object at reference and initializes attributes unique to that class. Above, the constructor class takes parameters self, waist length and color and initializes those values as arguments utilized later in the program. Put on and take off methods pass those arguments by reference and updates self.wearing to false to let us know the shorts are off.

    def put_on(self):
        print("Putting on {}x{} {} shorts".format(self.waist,self.length,self.color))
        self.wearing=True

    def take_off(self):
       print("Taking off {}x{} {} shorts".format(self.waist,self.length,self.color))

 

The code above defines methods to handle attributes of the shorts object ie. self.waist, self.length, self.color and self.wearing. When executed the passed attributes are printed to the console. The code below shows the class, instantiated as an object calling the defined methods.

new_shorts= shorts(32,33,"blue")
new_shorts.put_on()
new_shorts.take_off()

 

Screenshot (6)

If you like these blog posts or want to comment and or share something do so below and follow py-guy!