Click here to Skip to main content
13,898,359 members
Click here to Skip to main content
Add your own
alternative version

Stats

19.6K views
292 downloads
43 bookmarked
Posted 6 Feb 2018
Licenced CPOL

Python for .NET developer

, 13 Feb 2018
Rate this:
Please Sign up or sign in to vote.
Python from the .NET developer point of view

Introduction

We are going to explor Python from the .NET developer point of view. It's my experience that whenever we learn something new but similar we, always try to find things which we already know and check how same can be done here.

Using the code

Download PCC.DataAPI.zip

Download PCC.DataAPI-v1-withNoVE.zip

Installation and Setup

There are basically two ways to install and setup Python. As we all know Microsoft make lots of things easy for us so, let's take a look at first

a.The .NET Way

Microsoft's Flagship VS2017 comes with an inbuilt option for Python. Checked option to install same and update setup and pretty much it will do all things for you.

 

b.Rest of the world

Believe it or not but there are developer who doesn't use Visual Studio ;)

  • Download latest stable version from https://www.python.org/downloads/ and install same
  • After installation, open command prompt and type pip –version, this command should recognize and expect to see Python version installed

c.MySQL

Let's be fully open source, get MySQL also that we are going to use for Rest API

Get setup from here and install it

https://dev.mysql.com/downloads/windows/installer/

And create a table  and insert some test data

CREATE TABLE `graphdata` (

  `id` int(11) NOT NULL,

  `descrption` varchar(45) DEFAULT NULL,

  `value` decimal(10,0) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

Default server:

d.Some common packages

  1. Get httpie to call Rest API from command prompt

pip install --upgrade httpie

  1. Get web server

pip install waitress

  1. Connection to MySQL

pip install pymysql

Jump start a sanity check

  • Create “Hellp.py” text file and write
    • print("Hello Python! I am from .NET world")
  • Open command prompt
  • Go to file location
  • Type file name- “Hellp.py and enter

Wow, it ran and I can see the result in the console, at this point it got my attention. I mean really just one line of code work with no import/ using/class or function.

Oky its just console, let's see what it can do with Rest API, let’s park this for now and continue with main topics

  Project templets in Visual Studio

Visual Studio comes with some nice and popular inbuilt Python project templets. You can select anyone from this and start writing code, these comes with all package required.

I gave try to Django, just because catchy name but didn't like it much.

  Install Python package in Visual Studio

If you like to install any package in Visual Studio, can also be done easily right in VS and it comes with IntelliSense (the first love of all bad spellers)

Search and Install Falcon that we are going to use here

 

My choice- The Falcon

I found (or at least felt) Falcon is easy and fast, you can get good reading here https://falconframework.org/

Now we are done with story building, it’s time to get into action

a.       Solution structure

  • Let's create a solution structure like this (add folder and file with same name)

  • Right-click in project and go to properties
  • Set main.py as startup file

 

b.      Before you write code

  • Python doesn't use { } for scope, instead, it uses TAB so careful with tabbing and intending.
  • One py file cannot have both tab andmanual spacing

c.       Class creation

Let's create a common class which uses to encode decimal for JSON, surprisingly Python’s JSON package can't handle decimal in json.dumps(..)

decimalEncoder.py

import falcon
import json
from decimal import Decimal as D

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, D):
            return float(obj)
        return json.JSONEncoder.default(self, obj)

In this file:

  • Import= using c#
  • decimal import Decimal as D
    • D = using alias in c#
    • Decimal is class from decimal file/package

d.       Configuration file

We have many choices of config files, We are using sweet simple ini file.

It's simple key-value pair file with different sections. [DEV]  and [QA]

Config.ini

[DEV]

DBServer = localhost

User=root

Password=admin

Db=db1


[QA]

DBServer = localhost

User=root

Password=admin

Db=db1

We will be going to use it in secData.py

e.       Module

Let's add code in secData.py which is the module with most of the code

secData.py

import json
import falcon
import pymysql
import configparser

from Utilities.decimalEncoder import DecimalEncoder

class SecData(object):

    def __init__(self,comingFrom):
        print("__init__, comingFrom:",comingFrom)
        config = configparser.ConfigParser()
        config.sections()
        config.read("config.ini")
        
        #Global level variable
        self.DBServer = config['DEV']['DBServer']
        self.Db = config['DEV']['Db']
        self.User = config['DEV']['User']
        self.Password = config['DEV']['Password']
    
    def getData(self,companyName):
        try:
             dbConnetion = pymysql.connect(host=self.DBServer,user=self.User,password=self.Password,db=self.Db)
             cursor = dbConnetion.cursor()
             sql = sql = "SELECT * FROM db1.table1"
             if (companyName.lower() != "all"):
                sql = "SELECT * FROM db1.table1 where descrption ='" + companyName + "'"
             print("sql:",sql)
             rowCount = cursor.execute(sql)
             rows = cursor.fetchall()
             jsonRows = []
             
             for row in rows:
                jsonRow = {
                        'id':row[0]
                        ,'descrption':row[1]
                        ,'value':DecimalEncoder().encode(row[2])}
                jsonRows.append(jsonRow)

        except OSError as err:
            print("OS error: {0}".format(err))
        except:
            print("Unexpected error:", sys.exc_info()[0])
        finally:
            cursor.close()
            return (jsonRows)
            

    def on_get(self, req, resp,companyName):
       
            print("companyName:",companyName)
            print("req.query_string:",req.query_string)
            jsonRows = self.getData(companyName)
        
            # Create a JSON representation of the resource
            resp.body = json.dumps(jsonRows, ensure_ascii=False)
            resp.status = falcon.HTTP_200

 

Now will walk-thru code and explain some key things

f.      Which code execute first

def __init__(self,comingFrom):

I added comingFrom, just to track who it instantiating this.

          It reminds me page life-cycle of ASP.NET

g.       Global variable

Anything using self.xyz

Just like ViewBag in ASP.NET MVC

h.      Read confi file

self.DBServer = config['DEV']['DBServer']

Just like getting data from C# DataTable

i.       Routing

def on_get(self, req, resp,companyName):

First three are standers parameters; fourth one is for getting value from routing

Will use it on main.py

j.        Query string

def on_get(self, req, resp,companyName):

req has lots of information about request, for now req.query_string will get you query string

k.       DB Connection

It's pretty state forward to connect DB

dbConnetion = pymysql.connect(host=self.DBServer,user=self.User,password=self.Password,db=self.Db)

is our connection object and cursor = dbConnetion.cursor() is data reader

l.      JSON output

json.dumps(..) will create JSON from object and assign it to response object

resp.body = json.dumps(jsonRows, ensure_ascii=False)

also set response to 200 to make all happy

resp.status = falcon.HTTP_200

m.        Exception handling

Just like C# Python also has more specific to more generic type of exception handling

  try:

       # any code

except OSError as err:

           print("OS error: {0}".format(err))

       except:

           print("Unexpected error:", sys.exc_info()[0])

       finally:

cursor.close()  

n.        Code execution entry point

As we already made main.py our startup, let's see whats inside it

main.py

import falcon

from SecDataModule.secData import SecData

api = application = falcon.API()

secData = SecData("main")

api.add_route('/secdata', secData)

api.add_route('/secdata/{companyName}', secData)

if __name__ == "__main__":

    # Use Python's built-in WSGI reference implementation to run

    # a web server for the application.

    from wsgiref.simple_server import make_server

    # Run the web server on localhost:8080

    print("Starting web app server")

    srv = make_server('localhost', 8080, api)

    srv.serve_forever()

 

  • .secData is way to import files in different folder
  • '/secdata/{companyName}', secData) just like MVC routing. secData is the one which is going to handle request coming  from  this route.

o.      Start  own web server

Start wsgiref console base server

from wsgiref.simple_server import make_server

srv = make_server('localhost', 8080, api)

srv.serve_forever()

Check it out

Lest do some basic testing

A simple request to get all data

http://localhost:8080/secdata/all

Get specific data

 

Test query string

http://localhost:8080/secdata/Test1?id=1

In server console

 

Response

 

<!--[if !supportLists]-->  <!--[endif]--><o:p>

Virtual Environments

As a wise man said, “Setting up and using virtual envt for python as its very standard practice” so let's touch base on adding new virtual environments.

As name imply virtual environments let us create environments where we can have set of different versions of packages, library other than installed in Global environments without causing any conflict.

a.       Add Virtual Environment

Lucky VS got it cover too, just right click on Python Environments and select Add Virtual Environment

Name it and also have option to change Interpreter version

 

b.      Quick fail test

At this point code is not going to run and should throw error for falcon ModuleNotFoundError. Remember we installed two packages Falcon and PyMySQL, now there are in separate environment. In order to get it working we need to get these two package added in our v.e.

c.       Requirements.txt

It’s like packages.config of C# which contains all required package although I found it much simple and cleaner.

Add requirements.txt

Add requirements in it

==x.x is use to specify package version, if no version given it always install latest version.

Then right click on your v.e and select Install from requirements.txt

All set it’s ready to roll now.

You can also check where it’s dumping package files

Unit testing

It’s always good idea to unit test our code. We can add Python unit test file in our project and write C# like unit test and run it thru default Text Explorer.

And write unit test to check db connection

test1.py

import unittest


from SecDataModule.secData import SecData


class Test_test1(unittest.TestCase):

    def test_A(self):

        jsonRows = []

        secData = SecData("FromUnitTest")

        jsonRows = secData.getData("Test2")

        self.assertIsNotNone(jsonRows)


if __name__ == '__main__':

    unittest.main()

 

Run test

Download PCC.DataAPI.zip

TODO           

So there are lots to do, but I am stopping here. Setup is done, a barer minimum code is up and running, the wheel is started rolling in the right direction. I believe any experience .NET developer can pull it forward.

Thanks for reading it thru, feel free to shoot any questions (I can handle .22LR but not ready for magnum round yetJ)

Points of Interest  

Reference

Python official tutorial:
https://docs.python.org/3.7/tutorial/index.html

Falcon:
https://falconframework.org

VS 2017-Python
https://docs.microsoft.com/en-us/visualstudio/python/managing-python-environments-in-visual-studio

History

Keep a running update of any changes or improvements you've made here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Himanshu Thawait
Technical Lead Sapient Global Market
United States United States
Himanshu Thawait is Associate Arch at Sapient Global Markets.

He is expert in developing EAI, BizTalk with EDI(HIPPA)., Web applications, Micro web services, Angular, ASP.NET MVC, C#, VB.NE T, VB 6, SQL Server, Oracle, No SQL, Classic ASP, XML and JavaScript, IBM MQSC, IBM DB2.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionHow does freeing memory work in both .Net and Python? Pin
RAND 4558667-Mar-18 22:53
memberRAND 4558667-Mar-18 22:53 
QuestionHow does this have anything to do with .Net? Pin
Casey Shaar14-Feb-18 11:04
memberCasey Shaar14-Feb-18 11:04 
GeneralPerfect for getting started. Pin
birari_chetan@yahoo.co.in8-Feb-18 4:39
memberbirari_chetan@yahoo.co.in8-Feb-18 4:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190306.1 | Last Updated 13 Feb 2018
Article Copyright 2018 by Himanshu Thawait
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid