2015년 12월 30일 수요일

구글 API 서비스 사용 퀵가이드

구글의 어마무시한 서비스 API를 사용하는 퀵가이드를 다룬다.
요약하면 다음과 같다.

1. 관리 콘솔을 통한 인증 정보 발급 받기
2. 프로그램 언어 및 사용 방법에 따른 인증
3. 서비스 API 사용 가이드에 따른 개발

Google Developer Console

구글 개발을 위한 관리 콘솔

1. 프로젝트 생성

2. 사용자 인증 정보 생성

API 키
 - API 호출시 사용할 토큰을 발급한다.
OAuth 2.0 클라이언트 ID
 - 인증 정보가 있는 client_secrets.json을 다운로드 한다.

API Client Library for Python

파이썬을 위한 API 클라이언트 가이드

3. 설치형 어플리케이션을 위한 OAuth 2.0 인증 예제

import webbrowser
import httplib2

from apiclient import discovery
from oauth2client import client

flow = client.flow_from_clientsecrets(
        'client_secrets.json',
        scope='https://www.googleapis.com/auth/blogger.readonly',
        redirect_uri='urn:ietf:wg:oauth:2.0:oob')

auth_uri = flow.step1_get_authorize_url()
webbrowser.open(auth_uri)

# Python 2.x raw_input()
auth_code = input('Enter the auth code: ')

credentials = flow.step2_exchange(auth_code)
http_auth = credentials.authorize(httplib2.Http())

blogger_service = discovery.build('blogger', 'v3', http=http_auth)
blogger_service.users().get(userId='self').execute()

OUTPUT >>
{'about': '',
 'blogs': {'selfLink': 'https://www.googleapis.com/blogger/v3/users/g107745812829425907154/blogs'},
 'displayName': '김주훈',
 'id': 'g107745812829425907154',
 'kind': 'blogger#user',
 'selfLink': 'https://www.googleapis.com/blogger/v3/users/g107745812829425907154',
 'url': 'https://www.blogger.com/profile/14043740031094632533'}


References

구글 개발 콘솔
https://console.developers.google.com

구글 API 탐색
https://developers.google.com/apis-explorer/

구글 Python 클라이언트 라이브러리 가이드
https://developers.google.com/api-client-library/python/




2015년 12월 29일 화요일

파이썬 단순 문장 표현 정리

파이썬에서는 싱글 라인에 로직을 구현하는 단순 문장 표현을 제공한다.
본문은 원문 가이드 내용 중에 부가 설명이 필요한 부분을 다룬다.

Simple statements

단순함을 지향하는 파이썬을 더욱 단순하게 만들어 주는 한 줄 코드에 대한 내용이다.

Assignment statements

어싸인 문장을 통해서 로직을 쉽게 표현 할 수 있다.

# 교환 로직
temp = a 
a = b
b = temp

=> 

a, b = b, a

The assert statement

어서트 문장을 통해서 디버깅 코드를 간단하게 삽입 할 수 있다.

if __debug__:
   if not expression: raise AssertionError(<message>)

=> 

assert expression, <message>


Future statements

퓨처 문장을 통해서 미래 버전의 문법을 강제 할 수 있다.

Python 2.x에서
from __future__ import print_function
print 1
  File "<ipython-input-2-08890221e919>", line 1
    print 1
          ^
SyntaxError: invalid syntax


이건 장난 같은 거다.
미래에 갈호를 사용할 것인가? 그럴 기회는 없다.

from __future__ import braces
  File "<ipython-input-34-2aebb3fc8ecf>", line 1
    from __future__ import braces
SyntaxError: not a chance


References

단순 문장
https://docs.python.org/3.5/reference/simple_stmts.html


파이썬 PostgreSQL 라이브러리 py-postgresql 퀵 가이드

PostgreSQL을 사용 위해서 psycopg2 라이브러리 구성시 pg_config가 필요한 이유로 패키지를 추가 설치하는 불편함이 있었다.
본문은 (신속하고 편리한 사용을 위해)  py-postgresql 라이브러리로 작업하는 샘플을 요약한다.

py-postgresql 사용

간단한 설치 방법이다.

pip install py-postgresql

문서에서 제공되는 메인 예제이다.

import postgresql



db = postgresql.open("pq://user:password@host/name_of_database")

db.execute("CREATE TABLE emp (emp_name text PRIMARY KEY, emp_salary numeric)")



# Create the statements.

make_emp = db.prepare("INSERT INTO emp VALUES ($1, $2)")

raise_emp = db.prepare("UPDATE emp SET emp_salary = emp_salary + $2 WHERE emp_name = $1")

get_emp_with_salary_lt = db.prepare("SELECT emp_name FROM emp WHERE emp_salay < $1")



# Create some employees, but do it in a transaction--all or nothing.

with db.xact():

    make_emp("John Doe", "150,000")

    make_emp("Jane Doe", "150,000")

    make_emp("Andrew Doe", "55,000")

    make_emp("Susan Doe", "60,000")



# Give some raises

with db.xact():

    for row in get_emp_with_salary_lt("125,000"):

    print(row["emp_name"])

    raise_emp(row["emp_name"], "10,000")

동적 쿼리가 필요한 경우는 prepare 대신에 다음을 사용할 수 있다.

for row in db.query.rows(<query>):
    #row는 dict 형태로 사용됨
    pass

Pandas와 함께 사용하는 방법이다.

from sqlalchemy import create_engine
db = create_engine(“postgresql+pypostgresql://user:password@host/name_of_database”)

참고 자료

SQLAlchemy ORM (Object Relational Mapper)
 - http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html
py-postgresql 라이브러리
 - http://pythonhosted.org/py-postgresql/index.html


커버 사진

2015년 12월 23일 수요일

이베이 API 시작 가이드

전번 아마존(amazon) API 관련 블로그에 이어 이베이(ebay)를 다룬다.
본글은 이베이(ebay) API 사용을 위한 퀵가이드를 제공한다.

API 사용 방법은 다음과 같다.

1. 서비스 및 개발자 계정 생성

이베이 : ebay.com, developer.ebay.com
페이팔 : paypal.com, developer.paypal.com

2. API 테스트를 위한 환경에 대한 이해

 - Sandbox : API 테스트를 위해 만든 가상의 환경이다.
 - Production : 실제 환경이다.

* API 호출 시에, 도메인(domain) 속성을 통해서 환경을 식별한다.
  예) sandbox trade api 사용을 위한 도메인은 api.sandbox.ebay.com이다.

3. 키 발급 받기

Sandbox
 - TESTUSER_<some id name> 계정을 생성 후, 토큰을 발급 받는다.
Production
 - 실제 판매 계정으로 토큰을 발급 받는다.

* API 종류에 따라 appid, certid, devid, token 값을 요구한다.

4. 페이팔 계정 연결

해당 sandbox나 production에 계정 설정에서 paypal 계정과 링크한다.
이때 로그인을 물어 보는데, 연결할 paypal 계정을 사용하면 된다.

페이팔의 경우 개발 계정을 생성 했다면, 자동으로 sandbox 계정이 생성되어 있다.
비번을 등록하고 paypal 계정 링크시에 사용한다.


참고 사항

파이썬 및 개발

 - 경매 기반이라 그런지, CategoryID와 ConditionID라는 코드 리스트는 필수이다.
 - Python을 위해서는 ebaysdk 라이브러리를 제공한다.
 - 정신건강을 위해서 당분간은 Python 2.x 기반으로 개발 하기를 권장한다.

용어 정리

이베이(Ebay)
 - 경매 방식에서 출발한 쇼핑 웹사이트이다.
 - 페이팔(Paypal)을 통한 결제 편의를 제공한다.

페이팔(Paypal)
 - 이베이에 인수 되었으나 최근에 다시 분사 결정된다.
 - 커지는 전자결제 시장 확보를 위한 포석으로 보인다.

드랍쉬핑(Drop Shipping)
 - 제조사에서 구매자에게 바로 배송하는 방식으로, 판매자 입장에서는 재고 없이 물건을 판매하는 일종의 SCM 기술이다.

SCM(Supply chain management)
 - 유통공급망에 참여하는 모든 업체들의 협력을 바탕으로 정보기술을 활용한 양질의 서비스 제공 전략이다.

2015년 12월 22일 화요일

파이썬 데코레이터(@ : decorator) 요약

먼저 Python의 Decorator를 알아 보자.
 - Function, Method 그리고 Class 정의를 수정하기 위해 사용되어 지는 일종의 호출이다.
 - 원조 오브젝트를 가지고 수정된 오브젝트를 반환한다.
 - 자바의 Annotations에서 영감을 받았으며, 유사한 Syntax 를 가지고 있다.
 - “@“ 예약 문자를 통해 문법적인 편의를 제공한다.

용도는 데코레이터를 통해서 정의될 객체의 꾸밈을 할 수 있다는 것이 포인트이다.
본문은 예제를 통해서 데코레이터에 대한 이해를 돕는 것을 목표로한다.

냉장고에 사과를 넣는 것을 보자.
1. 문을 연다.
2. 사과를 넣는다.
3. 문을 닫는다.

이때, 냉장고 기능(1,3)을 미리 정의 하고, 행동 기능(2)를 만들때 냉장고 기능으로 데코레이팅하는 것이다.

데코레이터를 클래스로 정의한 예제이다.

class 냉장고:
    def __init__(self, f):
        print ('Decorator was started.')
        self.func = f;

    def __call__(self,q):
        print ('문을 연다.')
        self.func(q);
        print ('문을 닫는다.')

def 물건넣기(q):
    print('%s를 넣는다' % q)

먼저 새로운 객체(냉장고물건넣기) 사용 예제이다.

냉장고물건넣기 = 냉장고(물건넣기)
냉장고물건넣기(‘사과')

Decorator was started.
문을 연다.
사과를 넣는다
문을 닫는다.

데이코레이터를 함수의 관계로 표현한 것이다.
함수들의 플로우는 객체를 통해서 디자인 형태로 남을 수 있다.

데코레이터를 사용한 예제이다.

@냉장고
def 물건넣기(q):
    print('%s를 넣는다' % q)
물건넣기(‘사과')

Decorator was started.
문을 연다.
사과를 넣는다
문을 닫는다.

데코레이터는 함수 형태로도 가능하다.

def 박스(f):
    print ('Decorator was started.')
    
    def new_func(q):
        print ('뚜껑을 연다.')
        f(q);
        print ('뚜껑을 닫는다.')
    return new_func

@박스
def 물건찾기(q):
    print('%s를 찾아서 뺀다.' %q)

Decorator was started.

물건찾기(‘장난감')

뚜껑을 연다.
장난감를 찾아서 뺀다.
뚜껑을 닫는다.

객체지향 요소가 강한 파이썬에서 편리하게 사용할 수 있었다.


데코에 대한 이해가 되었다면, 실제 사례를 보자.

ebaysdk 에서 실제로 구현된 python 2에 대한 유니코드 호환을 위해 데코레이터를 사용한 예제이다.

def python_2_unicode_compatible(klass):
    """
    A decorator that defines __unicode__ and __str__ methods under Python 2.
    Under Python 3 it does nothing.
    To support Python 2 and 3 with a single code base, define a __str__ method
    returning text and apply this decorator to the class.
    """
    if sys.version_info[0] < 3:
        if '__str__' not in klass.__dict__:
            raise ValueError("@python_2_unicode_compatible cannot be applied "
                             "to %s because it doesn't define __str__()." %
                             klass.__name__)
        klass.__unicode__ = klass.__str__
        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
    return klass

@python_2_unicode_compatible
class ResponseDataObject(object):
    ...

클래스의 __unicode__에 Unicode를 넣고, __str__에 'utf-8'로 encode 해서 저장한다.
 - Python3 에서는 기본적으로 String을 Unicode(유니코드)를 사용한다.
 - Python2 에서는 String을 Encoding 된 byte(바이트) 코드로 사용된다.


커버 사진


2015년 12월 18일 금요일

동네 예보 좌표 변환용 C 코드 변환

공공 데이터(동네 예보) 개발 가이드에 보면 위/경도 좌표를 격자 좌표로 변환 하는 C 코드가 있다.
바이너리로 만들어 subprocess로 호출 해서 해도 되지만 OS 환경에 따라 빌드해야 하는 번거로움이 있다.
이에, 파이썬 코드로 변환했다.

변환 과정에서 주의 사항은 다음과 같다.

math.pow()의 경우 결과를 float 타입으로 변경하는 과정이 있고, 여기서 복소수 같은 복합 연산 결과를 만났을때, 에러를 일으킬 수 있다.
So, 기본적으로 제공하는 pow 함수를 사용하면, 결과를 그대로 넘겨 준다.

math.pow 사용 예제
In [7]: math.pow(-2.6050890646938014, 0.715566847180628)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-7fb3d71c4e22> in <module>()
----> 1 math.pow(-2.6050890646938014, 0.715566847180628)
ValueError: math domain error

pow 사용 예제
In [8]: pow(-2.6050890646938014, 0.715566847180628)
Out[8]: (-1.2432573697690525+1.5461879897834474j)

In [9]: type(pow(-2.6050890646938014, 0.715566847180628))
Out[9]: complex

* complex(복소수)의 경우, real(실수)만 뽑아서 사용하면 된다.

코드가 하는 역활에 대해서 찾아 봤다.

지도 투영법은 위경도로 이루어진 가상의 좌표를 평면상에 옮기는 방법이다.
지도 투영법 중에 람베르트 정각원추도법(람베르트正角圓錐圖法, Lambert conformal conic projection)
을 사용한다.

마지막으로 실제 변경된 코드이다.

격자 좌표에서 위/경도 좌표로 변환하는 역방향은 제외 했다.
from math import asin, sin, cos, tan, log

NX = 149  # X축 격자점 수
NY = 253  # Y축 격자점 수


def main(lon, lat):
    # 동네예보 지도 정보
    class map:
        pass

    map.Re = 6371.00877  # 지도반경
    map.grid = 5.0  # 격자간격 (km)
    map.slat1 = 30.0  # 표준위도 1
    map.slat2 = 60.0  # 표준위도 2
    map.olon = 126.0  # 기준점 경도
    map.olat = 38.0  # 기준점 위도
    map.xo = 210 / map.grid  # 기준점 X좌표
    map.yo = 675 / map.grid  # 기준점 Y좌표

    return map_conv(lon, lat, map)  # x, y


# 좌표 변환
def map_conv(lon, lat, map):
    _x, _y = lamcproj(lon, lat, map)
    _x = int(_x + 1.5)
    _y = int(_y + 1.5)
    return _x, _y


# Lambert Conformal Conic Projection
def lamcproj(lon, lat, map):
    PI = asin(1.0) * 2.0
    DEGRAD = PI / 180.0

    re = map.Re / map.grid
    slat1 = map.slat1 * DEGRAD
    slat2 = map.slat2 * DEGRAD
    olon = map.olon * DEGRAD
    olat = map.olat * DEGRAD

    sn = tan(PI * 0.25 + slat2 * 0.5) / tan(PI * 0.25 + slat1 * 0.5)
    sn = log(cos(slat1) / cos(slat2)) / log(sn)
    sf = tan(PI * 0.25 + slat1 * 0.5)
    sf = pow(sf, sn) * cos(slat1) / sn
    ro = tan(PI * 0.25 + olat * 0.5)
    ro = re * sf / pow(ro, sn)

    ra = tan(PI * 0.25 + lat * DEGRAD * 0.5)
    ra = re * sf / pow(ra, sn)
    theta = lon * DEGRAD - olon
    if theta > PI:
        theta -= 2.0 * PI
    if theta < -PI:
        theta += 2.0 * PI
    theta *= sn
    x = ((ra * sin(theta)) + map.xo).real
    y = ((ro - ra * cos(theta)) + map.yo).real
    return x, 


커버 사진

아마존 MWS 개발 참고 사항 - API 시작 가이드

IT를 선도하는 기업답게 가이드가 매우 상세하다. 다만 방대한 가이드로 인해서 (번역 안된) 원하는 자료를 속독 하는 것이 쉽지 않다.
본문은 아마존(Amazon) API에 접근 하기 위한 퀵가이드 제공을 목표로 한다.

먼저 아마존 API 두 가지이다.

아마존 MWS

 - 아마존 셀러를 위한 통합 웹 서비스 API이다.
 - 셀러는 프로그램을 통해서 효율적인 관리가 가능하다.
 - API 정보
https://developer.amazonservices.com
필수 정보: Access Key, Secret Key

아마존 Product Advertising API

 - 아마존에서 발생되는 다양한 정보에 접근 할 수 있는 방법을 제공한다.
 - 예를 들면, 판매 아이템, 사용자/판매자 리뷰, 상품 프로모션과 같은 정보이다.
 - API 정보
http://docs.aws.amazon.com/ko_kr/AWSECommerceService/latest/DG/Welcome.html
필수 정보: Access Key, Secret Key, Associate Tag


다음은 필수 정보를 발급 받는 방법이다.

Access Key, Secret Key 발급 방법

루트 엑세스 키 (Root Access Key)
 - 편리하게 발급 받아서 사용 가능
 - AWS의 루트 사용자 설정에서 발급
IAM 엑세스 키 (IAM Access Key)
 - IAM의 섬세한 정책 적용 가능
 - IAM에서 생성한 사용자 계정에서 발급

Associate Tag 발급 방법

Amazonassociates에 가입(등록) 후 발급

참고 화면: 1.루트 엑세스 키 발급, 2. IAM 엑세스 키 발급



남은 부분은 방대한 API와 시름하는 것이다.

파이썬으로 개발한다면 boto가 도와 줄 것이다.
 - AWS와 파이썬 커뮤니티의 지속적인 지원을 통해서 만들어진 선물이다.
http://docs.pythonboto.org/en/latest/index.html#

* boto3를 보면 클라이언트 클래스가 데이터 기반으로 호출 되는 것을 볼 수 있는데 이는 일관성있는 인터페이스를 제공한다.
* 기존 boto 버전 또한 운영되고 있고, 신규 사용자에게는 boto3 사용을 권장한다.

아마존 MWS 개발 참고 사항 - 주요 요소

일반 쇼핑몰과 다르게 아마존을 사용 할 때 판매자가 알아야 할 주요 사항을 다룬다.
아마존(Amazon) MWS로 어플리케이션을 개발 할 때 꼭 이해해야 할 내용이다.

상품 등록을 위해서는 상품 코드가 필요하다.

 - UPC (Universal Product Code) : 미국에서 개발된 12자리 상품 바코딩 표준
 - EAN (European Article Number) : 표준 단체 GS1이 정의한 13자리 상품 바코딩 표준
 - 한국은 EAN에 국가코드 “880”을 부여 받았다.

 * GTIN (Global Trade Item Number) : GS1에서 정의한 상품 식별자 표준
 * 의미: GTIN -> Identifier, EAN/UPC -> Former

이미지 출처: https://www.nationwidebarcode.com/are-upc-a-and-ean-13-the-same/

아마존 내부적으로 ASIN 코드로 관리 된다.

 - 상품 코드를 통해 물건을 등록하면 ASIN 코드가 부여된다.
 - 같은 지역 내에서 ASIN은 유일성을 가진다. (US, JP, …)

 * ASIN(Amazon Standard Identification Number)


FBA (Fulfillment by Amazon)를 이해해야 한다.

 - 3자 판매상(third-party sellers)을 위한 물류 배송 시스템이다.
 - 전세계적인 물류망과 관리 시스템을 이용해 안전하고 신속한 배송 서비스를 제공한다.
 - 이베이나 독립 쇼핑몰에서도 이용할 수 있다.
 - 주문관리, 배송, 고객서비스(CS) 대행 서비스를 제공한다.
 - 구매자에게는 배송이 무료이다.
 - FBA 방식으로 변경하고, 매출 증대 사례가 많다.
이미지 출처: 아마존

제휴 광고 시스템으로 Amazonassociate를 제공한다.

 - 1996년에 최초 출시된 온라인 제휴 마켓팅 프로그램이다.
 - 자신의 웹에 등록된 제휴 광고를 통해 고객이 상품을 결제하면 소정의 이윤을 얻을 수 있다.
 - 구글 애드센스와 비교 된다.
이미지 출처 : 아마존

2015년 12월 15일 화요일

아파치 WSGI 모듈(mod_wsgi)을 통한 Flask 연동

아파치(apache)의 WSGI 모듈(mod_wsgi)을 통해서 Flask를 연동하는 예제이다.

본문은 다음의 가이드에 대한 요약 및 보충 내용을 다룬다.
http://flask-docs-kr.readthedocs.org/ko/latest/deploying/mod_wsgi.html

설치

1. 아파치를 설치한다.

 --with-python=<path/python>
 --with-apxs=<path/apxs>
* apxs(APache eXtenSion tool) : 확장 모듈을 설치를 위한 도구

2. WSGI 모듈(mod_wsgi)를 설치한다.

pip install mod_wsgi

* 빌드를 위해 apxs가 있어야 한다.

3. 아파치 설정 파일(httpd.conf)에 모듈(mod_wsgi)를 추가한다.
LoadModule wsgi_module modules/mod_wsgi.so
 * mod_wsgi.so는 pip로 설치된 폴더에 원본이 있다. (링크 걸면된다.)

설정

1. 가상 호스트 연결을 통한 mod_wsgi 사용 예제

NameVirtualHost *

<VirtualHost api4u.info>
    ServerName adi4u.info

    WSGIDaemonProcess api4u user=user1 group=group1 threads=5
    WSGIScriptAlias / /var/www/api4u/api4u.wsgi

    <Directory /var/www/api4u>
        WSGIProcessGroup api4u
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

2. WSGIDaemonProcess를 위한 계정을 만든다.

groupadd group1 ; useradd -g group1 user1

* 해당 계정을 통해서 프로젝트를 생성 및 수행한다.

3. 사용할(생성한) 계정으로 가상환경을 만든다.

virtualenv -p python3.5 Pyzone

3. 가상 환경을 위한 .wsgi 예제 (/var/www/api4u/api4u.wsgi)

import sys 
sys.path.insert(0, '/var/www/api4u')

activate_this = '/home/user1/Pyzone/bin/activate_this.py'
# execfile(activate_this, dict(__file__=activate_this))
exec(open(activate_this).read(), dict(__file__=activate_this)) 

from api4u import app as application

* python 3.5에서는 execfile() 함수가 없음으로 exec() 함수를 사용한다.

SQLite3에 대한 이점 및 사용 예제

파이썬에 기본으로 탑재되어 있는 SQLite3 에 대해서 다룬다.

SQLite는 가벼운 디스크 기반의 데이터 베이스를 제공하는 C 라이브러리다.
어플리케이션 내부 데이터 저장소로 다양하게 활용되고, 사용이 간편하고 가벼워서 프로토타입용으로도 자주 쓰인다.

본문은 pandas + SQLite3에 대한 간략한 사용 예제를 담는다.

1. CSV 자료를 판다곰의 데이터프레임(DataFrame)으로 읽는다.

df = pd.read_csv('gov_loc.csv',skiprows=1,index_col=['lev1','lev2','lev3'],
                 names=['lev1','lev2','lev3','nx','ny','lon','lat'])

* 샘플 데이터는 기상청 주소/좌표 매핑 데이터를 이용했다.
lev1
lev2
lev3
nx
ny
lon
lat
서울특별시 None None 60 127 126.980008 37.563569
서울특별시 종로구 None 60 127 126.981642 37.570378
서울특별시 종로구 청운효자동 60 127 126.970652 37.584137
서울특별시 종로구 사직동 60 127 126.970956 37.573269
서울특별시 종로구 삼청동 60 127 126.983978 37.582425
서울특별시 종로구 부암동 60 127 126.966444 37.589856
...

2. 데이터프레임을 SQLite DB로 저장한다.

conn = sqlite3.connect('gov.db')
df.to_sql(name='loc_map_book',con=conn,index=True,if_exists='replace')

3. 메타 데이터를 이용해 스키마를 확인 하자.

query_ddl = 'SELECT sql FROM sqlite_master WHERE tbl_name = "loc_map_book";'
for i in pd.read_sql(query_ddl ,con=conn).get_values():
    print (i[0])
OUT>>
CREATE TABLE "loc_map_book" (
"lev1" TEXT,
  "lev2" TEXT,
  "lev3" TEXT,
  "nx" INTEGER,
  "ny" INTEGER,
  "lon" REAL,
  "lat" REAL
)
CREATE INDEX "ix_loc_map_book_lev1_lev2_lev3"ON "loc_map_book" ("lev1","lev2","lev3")

4. 쿼리 플랜을 통해서 인덱스가 잘 동작하는지 알아 보자.

query = 'explain query plan ' + \
        'select * from loc_map_book where lev1="{0}";'.format('서울특별시')
for i in conn.execute(query):
    print(i)
OUT>>
(0, 0, 0, 'SEARCH TABLE loc_map_book USING INDEX ix_loc_map_book_lev1_lev2_lev3 (lev1=?)')


DB 업무를 먼저 시작한 이유로, 사소한 데이터도 대용량 DB와 연결을 지었는데,
로컬 파일 DB를 활용하는 것은 개발에 매우 큰 이점이 있었다.
단일 파일로 관리 됨으로 프로그램 복제가 쉬웠고, DB 구성/관리 소요비용이 없었다.

참조:
파이썬에서 대용량 자료를 핸들링 하는 방법에 대한 글
 - SQLite가 생각보다 큰 자료에 대한 핸들링도 가능한 것으로 보인다.
https://www.reddit.com/r/Python/comments/3wa22v/120gb_csv_is_this_something_i_can_handle_in_python/


2015년 12월 5일 토요일

python을 위한 IDE 도구 Pycharm 소개

맥북(Mac)을 사용하고, 데이터 분석을 위해 Python을 접했다면, 보통의 경우 vim과 ipython notebook을 자주 사용한다.
Django나 Flask 같은 복잡한 (웹) 어플리케이션 개발의 길로 들어 선다면, IDE 도구가 필요하다.
* IDE (Integrated Development Environment : 통합 개발 환경 )

본문에서는 Pycharm 이라는 IDE 도구가 주는 즐거움을 소개한다.

1. xml과 xsd 사용 편의
xml 을 작성 할때, xsd를 기반으로 요소 목록 제공 및 규칙 검사를 자동 수행한다.

2. 손쉬운 virtualenv 환경 구성
python의 버전이 복잡한 경우에도 직관적으로 가상화 환경 관리를 할 수 있다.
프로젝트 별로 가상화 환경을 손쉽게 연결한다.

3. 다양한 프로젝트 지원
Flask, Django, Google Web Engine 등과 같은 프로젝트 생성시에 기본 구조를 만들어 준다.

4. 리팩토링(Refactoring) 지원
함수, 변수 같은 참조되는 객체(Object)의 이름을 일괄 변경해 준다.

5. 코드 정렬(reformat code) 기능
코드의 포맷에 따라 Beauty 코드로 자동 정렬 해준다.

6. 데이터베이스(DB) 연동 기능
다양한 DB 클라이언트 기능을 제공한다.

7. 다양한 플러그인 지원
IDE 도구 사용을 필수로 만드는 중요 요소이다.
All in one을 가능하게 하는 확장 영역이다.


에디터(Editor)와 개발자 vs 자동차와 운전자 is very similar.

스스로에게 질문해 보자.
당신은 베스트 드라이버 인가? 좋은 차를 가지고 있는가?


이 글을 본 당신은 좋은 차를 가지게 될 베스트 드라이버다.

파이썬 문서화 방법과 도구

파이썬(Python) 문서화를 위한 방법과 도구를 알아 본다.

먼저 문서화 방법이다.

다양성 보다는 간결성을 추구하는 파이썬의 철학처럼, 규칙에 따른 주석 만으로 문서화 할 수 있다.
PEP 257 ( Docstoring Convension : 문서화 규칙) 을 바탕으로 주석을 다는 좋은 습관 만으로 충분하다.

기능 상자(모듈, 함수, 클래스, 메소드)의 첫번째 문장 주석은 __doc__ 라는 특별한 속성이 된다.
이 속성을 통해서 기능별로 구조화된 문서를 자동 생성할 수 있다.

다음은 문서화 도구이다.

자동 문서화 도구로 자주 언급 되는 Pydoc과 Sphinx를 비교한다.
  • Pydoc
    • 정말 단순한 방법으로 문서화를 제공한다.
    • pydoc -b <module> 만으로 깔끔한 웹 문서를 볼 수 있다.
    • 개발 중에 바로바로 문서화 해서 보기에 최적이다.
    • 옵션이 빈약해서 문서 배포 용도로는 부족하다.
  • Sphinx
    • 상대적으로 복잡한 옵션과 방법으로 문서화를 제공한다.
    • PyPI와 같은 대부분의 문서화 페이지에서 사용된다.
    • 상세한 기능을 제공하며, 개발 후 문서화 배포에 최적이다.
    • 다양한 테마의 HTML 디자인을 제공한다.
Pydoc은 워낙 단순해서 직관적으로 사용하고, Sphinx를 통해서 문서화 하는 과정을 간략히 소개한다.

1. 문서화 폴더(Directory) 생성
sphinx-apidoc -H <project name> -A <Author> -V <version> -R <release> -F -f -o <output path> <module path>
* <output path>에 문서화 관련 파일들이 생성된다.

2. 문서화 폴더에 생성된 conf.py (환경 설정 파일 : default )을 적절하게 수정한다.
 - 보통은 sys.path.insert에 <module path>를 등록한다.
 - 소스(source) 보기를 제외 할때는 extensions에 sphinx.ext.viewcode를 제거한다. 
 - 필자가 좋아하는 테마는 sphinx_rtd_theme 이다.

3. HTML로 생성(Build) 명령이다.
make clean; make html
* conf.py 파일을 참조 해서 수행된다.


2015년 12월 2일 수요일

미들웨어 소프트웨어 RabbitMQ 요약

AMQP (Advanced Message Queuing Protocol)는 메세지 기반의 미들웨어(Middleware)를 위한 표준 어플리케이션 레이어 프로토콜이다.
RabbitMQ는 AMQP를 수행하는 오픈소스 미들웨어 소프트웨어이다.

본문은 RabbitMQ 가이드를 기반으로 AMQP의 이해와 설치 팁을 다룬다.


AMQP의 주요 요소


브로커(Broker)

생산자(Publishers/Producers)로 부터 메세지를 받아서, 소비자(Consumers/Subscriber)에게 전달 한다.
큐에서 메세지 삭제를 위해서는 다음의 두 가지 선택 사항이 있다.
 - 브로커가 어플로 메세지를 보낸 후 : 성능 이점
 - 어플에서 응답을 받은 후 : 안정성 이점
브로커로의 연결(Connection) 후 채널(Channel)을 열어 반복적인 TCP 연결을 막는다.

선언 영역

Exchange는 다음과 같은 타입을 선언할 수 있다.

Default
기본적으로 큐와 동일한 이름의 경로키(routing key)를 암묵적으로 사용한다.
Direct
경로키와 일치하는 큐로 메세지를 보낸다.
소비자가 여럿 일 경우, RR(Round Robin)과 같은 분배 알고리즘을 사용한다.
Fanout
모든 큐로 복제 메세지를 보낸다.
Topic
다양한 publish/subscribe 패턴으로 정의 가능하다.
Headers
헤더에 해당되는 큐로 메세지를 보낸다.

Queue는 다음과 같은 속성과 함께 선언될 수 있다.

Name : 큐의 이름
Durable : 브로커 재시작 시에도 살아남
Exclusive : 단지 하나의 연결만 사용됨, 연결을 닫으면 삭제
Auto-delete : 소비자가 한개도 없으면 삭제됨
* 속성은 큐가 생성되기 전 선언

수행 영역

Bind는 Exchange와 Queue를 연결한다.

Exchange가 수단(방법)이고 Queue를 목적지라고 할때, Binding은 경로를 말한다.

Consume은 다음 두가지 방법으로 수행 할 수 있다.

Push API : 등록된 소비자에게 메세지가 배송됨
Pull API : 필요할때 메세지를 당겨옴




RabbitMQ 설치 시 유의 사항


관리(management) 플러그인 설치

rabbitmq-plugins enable rabbitmq_management

관리 Web UI 접속 (기본 접속 포트 : 15672)

기본으로 제공되는 Guest 계정은 원격 접속을 허용하지 않는 이유로, rabbitmqctl (cli 관리 명령어)로 관리 계정을 만들어 접속한다.
rabbitmqctl add_user admin admin
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"