태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'웹'에 해당되는 글 5건

  1. 2012.08.02 도깨비: 요청/응답 json 포맷 사용 + mongodb 저장소 붙이기 (6)
  2. 2007.08.17 Ruby on Rails - Controller의 단위 (5)
  3. 2007.07.02 실명인증 (5)
  4. 2007.06.08 지름: Ferret short cuts (O'reilly), PDF
  5. 2007.03.15 Playtalk

도깨비: 요청/응답 json 포맷 사용 + mongodb 저장소 붙이기

Daily life/Hard study 2012. 8. 2. 22:20

지난번에 작업 - http://blog.dgoon.net/449 - 하다 말았던 부분을 이어서 한다. 도깨비에 추가로 할 작업은 다음 두가지이다.

1. 일단 요청/응답 포맷을 json으로 바꾼다.
2. persistent layer를 붙인다(mongodb?)

-----
query string 이나 parameter 는 버린다.
POST 로 요청을 받고 -> Content-type 이 application/json 인지 확인하고 -> body 를 읽어서 json.loads 를 한다.
요청이 가져야 하는 값들은 여기서 나오는 json 에 모두 포함되어 있어야 한다. 몇 가지 사소한 것들을 적어둔다.

a. 요청 타입(POST/GET)은 지난번에 @require_http_methods("POST") 로 강제했다
b. content-type은 request.META.get('CONTENT-TYPE') 에 들어있다.
c. body는 request.read() 를 하면 나온다

필수 데이터가 들어있는지 확인하는 코드(check_required)와 content-type을 확인하는 코드(check-content-type)을 함수로 분리하면 더미 로직은 get/put 둘 모두,

        check_content_type(request, "application/json")
        body = request.read()
        req_dict = simplejson.loads(body)
        check_required(GET_REQUIRED_FIELDS, req_dict.keys())
        print req_dict


이 정도로 간단해진다. 조건이 맞지 않는 경우 check_required, check_content_type 함수들은 직접 예외를 생성해서 던진다. 테스트 요청을 날리던 get.py, put.py 에서는 content-type 만 application/json 으로 바꾸고, urlencode 하던 부분을 simplejson.dumps 로만 바꾸면 된다.

{'app_key': 'deadbeef', 'condition': {}}
[02/Aug/2012 21:06:05] "POST /api/v1/get/ HTTP/1.1" 200 2
{'content': 'THIS_IS_CONTENT', 'tag_list': ['tag1', 'tag2', 'tag3'], 'meta': {}, 'app_key': 'deadbeef'}
[02/Aug/2012 21:06:16] "POST /api/v1/put/ HTTP/1.1" 200 2

이전보다 코드도 짧아지고, tag_list 도 리스트로 제대로 들어온다. 에잉 훨 낫네.

-----
persistent layer를 붙인다. 전에 튜토리얼을 따라가본 몽고디비를 쓰고 싶다. 그때는 c++ 클라이언트였는데, 파이썬이라고 뭐 딱히 다르진 않지 싶다. 더 쉽겠지...

http://www.mongodb.org/display/DOCS/Drivers -> http://www.mongodb.org/display/DOCS/Python+Language+Center

여기서 찾아보면 몇 가지 라이브러리가 있다. PyMongo 를 선택. 일단 언제나처럼 pip,easy_install,apt-get 순서로 패키지가 있나 뒤져본다.

sudo pip install pymongo

빙고. 파이썬 쉘 띄워서 import pymongo 해보니 뭔가 임포트 된다. 이걸 쓰면 되겠다.

http://api.mongodb.org/python/current/tutorial.html

여기 튜토리얼이니 잠깐 읽어보면 어렵지 않아요~ 지난번에 삽질하면서 katy 에 몽고디비 설치는 해 두었으니 그대로 활용하자. db=tokebi, collection=twit 으로 간다. store_mongodb.py 를 만들고, MongoStore 클래스에 몽고디비 접근 구현 코드를 둔다. 인터페이스는 mongo_store.get/put 이며 api_get, api_put 이 받은 요청을 거의 그대로 받는다.


api_get:
        app_key, condition = get_items(req_dict, GET_REQUIRED_FIELDS)             
        store = MongoStore('twit')
        retrieved = store.get(app_key, condition)

api_put:
        app_key, content, tag_list, meta = get_items(req_dict, PUT_REQUIRED_FIELDS)
        store = MongoStore('twit')
        ack = store.put(app_key, content, tag_list, meta)

api_get, api_put 에 각각 위의 코드가 추가되었다. 테스트 요청을 날려보면서 디버깅을 좀 해야 했는데, python get.py localhost 2223 > ~/public_html/get_error.html 등으로 저장한 뒤에 브라우저로 열어보면 좀 쉽다. 몽고디비에 쓰고 읽을 때 필요한 자료구조는 뭘까 하고 튜토리얼을 봤더니,

In PyMongo we use dictionaries to represent documents. ...

저장 단위가 파이썬 맵이므로 구현은 아주 간단하다. 심지어 문서를 꺼내오는 조건도 사전이므로,몽고디비 접근은 거의 자명하다.

#-*- encoding: utf-8 -*-from pymongo import Connection
CONN = Connection()

def doc2dict(d):
    ret = dict(d)
    ret['_id'] = str(ret['_id'])
    return ret

class MongoStore(object):
    def __init__(self, collection):
        self.collection = CONN.tokebi[collection]

    def get(self, app_key, condition):
        cond = condition.copy()
        cond['app_key'] = app_key
        return map(doc2dict, self.collection.find(condition))

    def put(self, app_key, content, tag_list, meta):
        doc = {
            'app_key': app_key,
            'content': content,
            'tag_list': tag_list,
            'meta': meta,
        }
        return self.collection.insert(doc)


api_get, api_put 에서 응답을 적절히 json 포맷으로 만들어 준다면 테스트 요청을 날리는 get.py 에서는 여러개의 문서 리스트를 응답으로 얻게 된다. 받은 결과를 화면에 찍어보면,

dgoon@katy:~/works/tokebi/sample_query$ python get.py localhost 2223
{'Content-type': 'application/json', 'Accept': 'text/plain'}
{'condition': {}, 'app_key': 'deadbeef'}
0
        content THIS_IS_CONTENT
        _id 501a74c272653e2217c9b255
        meta {}
        app_key deadbeef
        tag_list ['tag1', 'tag2', 'tag3']
1
        content THIS_IS_CONTENT
        _id 501a74d472653e222068f2b8
        meta {}
        app_key deadbeef
        tag_list ['tag1', 'tag2', 'tag3']
2
        content 두만강푸른물에
        _id 501a750372653e222068f2b9
        meta {}
        app_key deadbeef
        tag_list [u'\uac15\uc0b0\uc5d0', u'\ub178\ub798']
3
        content 티비유치원 하나둘셋
        _id 501a768072653e225e6cb3c1
        meta {}
        app_key deadbeef
        tag_list ['hana', 'dul', 'set']


이렇게 확인할 수 있다. 한글도 잘 들어가는 것을 확인할 수 있다. 2번 문서의 tag_list에 들어있는 것은,

>>> for k in [u'\uac15\uc0b0\uc5d0', u'\ub178\ub798']:
...     print k
...
강산에
노래

이렇게 유효한 한글이다. PyMongo 튜토리얼에서 설명되어 있는데 - BSON strings are UTF-8 encoded 라고 한다. Unicode문자열은 encode 되어 저장된다고. 그리고 simplejson 으로 직렬화 할때는 다시 유니코드가 되어서 응답을 받은 쪽에서는 한글이 모두 유니코드로 떨어지게 된다. 나중에 좀 헷갈릴 것 같다.


-> http://git.dgoon.net/?p=tokebi.git;a=commit;h=da49398646c0812a0d33d71cbec23e5052f5ca09


-----

추가적으로 해야 하는 작업은 ... 잊고 있었는데, 나 말고 다른 사람도 이걸 쓰게 하려면


1. user_id 같은걸 넣어야 하고,


최신 엔트리를 가져오려면,


2. created_at 이 필요하고,


사람을 가리거나 정렬이 필요하니


3. 적절한 인덱스 가 필요하다.


다음 작업은 이상 3개가 되겠다.

Trackbacks 0 : Comments 6
  1. Favicon of http://ub.cheapshoesel.com/ nike shoes 2013.04.08 05:44 Modify/Delete Reply

    우리가 어디에 있는가가 중요한 것이 아니라 어디로 가야 하느냐가 중요한것이다

  2. Favicon of http://ntu.contact-hotel.com/longchamp.php sac longchamp 2013.04.13 20:52 Modify/Delete Reply

    매우 지원, 아주 좋아, http://ntu.4dmv.com/montblanc.php mont blanc pens.

  3. Favicon of http://www.todsoutletonlinexx.com/ tods shoes 2013.04.23 18:22 Modify/Delete Reply

    당신은 내가사랑할 만한 사람이 아니예요,사랑하지 않으면 안될 사람이예요.

  4. Favicon of http://frk.hairstraightenernx.com ghd straightener 2013.04.29 03:30 Modify/Delete Reply

    좋으면 좋고 싫으면 싫은 거지, 뭐가 이렇게 어렵고 복잡하냐구

  5. Favicon of http://frk.shoesxstorex.com/ jordan 18 2013.04.29 08:16 Modify/Delete Reply

    좋으면 좋고 싫으면 싫은 거지, 뭐가 이렇게 어렵고 복잡하냐구

  6. Favicon of http://2962sacresgion511.com/ChicagoBlackhawksjersey.php Chicago Blackhawks Jersey 2013.07.15 18:36 Modify/Delete Reply

    태양이 바다에 미광을 비추면,나는 너를 생각한다.

Write a comment


Ruby on Rails - Controller의 단위

Tech 2007. 8. 17. 02:45
연관된 이전 글

이전에 모델(테이블?)에 대한 CRUD인터페이스를 기반으로 하는 Model-Wrapper스러운 컨트롤러에 대해 이건 아니야! 라면서 툴툴거린 적이 있다. 컨트롤러는 어떤 단위로 만들어져야 하는가. user라는 모델과 user 라는 컨트롤러가 있어서 가입/로그인/정보수정/개인화페이지 등 user 모델이 주가 되는 페이지는 모두 user 컨트롤러에 붙는 것인가? 왠지 이건 아닌 것 같다... 컨트롤러는 서비스의 구조다.

만들려는 웹 서비스의 사이트맵을 한번 그려보자. 트리 구조로 그리면서 가능한한 모든 페이지를 다 포함시키자. 웹 페이지가 될 녀석들은 가능한 한 Leaf node로 내린다. 그려놓고 보면 흐름이 있거나, 밀접하게 연관되어 있는 페이지들을 묶어 서브 트리를 구성할 수 있다. 이 서브트리의 루트는 자기 아래쪽에 있는 있는 페이지들에 대해 일종의 초기화면 역할을 할 수 있는 녀석이니 적당한 녀석을 골라 올리거나 아니면 새로 만든다. 자, 이런 식으로 트리 구조가 다 그려졌으면 초기화면인 Root node와 액션과 1:1 로 연결될 Leaf node를 제외하고 나서 나머지 node를 가지고 컨트롤러를 찍자. 찍은 녀석이 웹 페이지를 가진다면 그것이 컨트롤러의 index가 되고, 웹 페이지를 가지지 않아도 Leaf가 아닌 이상 상관은 없다. 어느 정도 Depth에 있는 노드를 컨트롤러로 정할지는 만들 웹 서비스에 따라 그때그때 다를 수 있다. 나름대로 정한 규칙이 있다면,

컨트롤러는 다른 컨트롤러를 부모나 자식으로 가지지 않는다.
컨트롤러는 자신을 루트로 하는 서브트리의 노드들(만)을 액션으로 가진다.
컨트롤러와 Leaf node 사이에 있는 Node는 서브트리에 있는 액션들의 이름에 Prefix가 된다.

정도가 되겠다. 꽤 쓸만한 방법인듯 하다. 너무 직관에만 의존하면 위험하니 적절한 참고나 가이드라인 정도로 삼으면 괜찮을 듯 하다.

실례로 사용할 만한 그림을 그려놓고 싶지만, 너무 귀찮으므로 나중에 포스팅하고 링크로 연결시켜 놓겠다.

'Tech' 카테고리의 다른 글

sena, the most powerful machine in the universe!  (6) 2007.08.31
svn relocate/tunneling  (0) 2007.08.31
Ruby on Rails - Controller의 단위  (5) 2007.08.17
실명인증  (5) 2007.07.02
지름: Ferret short cuts (O'reilly), PDF  (0) 2007.06.08
Web - 데이터를 어디에 저장하지?  (2) 2007.05.02
Trackbacks 0 : Comments 5
  1. Favicon of http://www.iwonny.net 워니 2007.08.17 09:02 Modify/Delete Reply

    그림그림!!! ㅎㅎ
    좋은글 감사합니다~ 다음 포스팅 열심히 기다릴게요 ㅋㅋ

  2. 얼음공주 2007.08.21 15:17 Modify/Delete Reply

    블로그 구경잘 하였습니다. 블로그에 필요한 동영상, boom4u.net 도 구경 오세요~~

  3. Favicon of http://24337.ccgenevois.com/clfrance.php christian louboutin 2013.07.11 09:25 Modify/Delete Reply

    희미한 달빛이 샘물 위에 떠있으면,나는 너를 생각한다.

Write a comment


실명인증

Tech 2007. 7. 2. 00:00

음... 어떻게 하는걸까 궁금했었는데, 의외로 쉽다.

1. 한국신용평가정보(혹은 비슷한 일을 해주는 다른 업체)와 계약을 한다
2. 뭔가와 아이디/비번을 받는다
3. 뭔가에는 ExecutableBinary가 있을텐데, 설명서를 보고 적당히 인자를 넣는다.
4. 리턴값 혹은 Stdout 으로 나오는 값을 보고 결과를 안다.
5. 4번을 Server-side code 에서 한다.

... 쉽다. 실제로 코드 만지는 짓은 30분정도면 된다. 물론, 어따가 껴 넣는냐에 따라 삽이 좀 달라지지만... 나는 OpenAPI같은 방식일거라고 생각했는데, 어째 약간 아쉬움도...

주의 - 한국신용평가정보는 확인했고, 다른 곳들도 마찬가지라고 생각된다. 이름을 한글로 주는데 utf-8 으로 넣으면 당연히 안된다. ... utf-8 따위 신경썼을리가 없... 그냥 euc-kr 로 하자. 나는 Ruby on rails에서 작업을 해서

require 'iconv'
converter = Iconv.new('euc-kr', 'utf-8')
name = converter original_name
...

정도로 처리했다. (Thx to only2sea) 여튼, 만들던 서비스에 실명인증 부분을 대강 때려넣었는데(다듬는건 다른사람 시켜야지 쿄쿄쿄) 꽤 신기하다. ... 히히~



P.S. 실명인증 한번 하는데 20원씩 떨어진다. 덜덜덜... -0-

'Tech' 카테고리의 다른 글

svn relocate/tunneling  (0) 2007.08.31
Ruby on Rails - Controller의 단위  (5) 2007.08.17
실명인증  (5) 2007.07.02
지름: Ferret short cuts (O'reilly), PDF  (0) 2007.06.08
Web - 데이터를 어디에 저장하지?  (2) 2007.05.02
Ruby On Rails - Scaffold의 함정  (2) 2007.04.18
Trackbacks 0 : Comments 5
  1. Favicon of http://etnalry.tistory.com etnalry 2007.07.02 16:05 신고 Modify/Delete Reply

    첫 한 줄에서 '밥 로스'가 느껴지는 이유는 뭘까..
    "참 쉽죠?" ㅋㅋ

  2. 이이이 2007.07.26 22:43 Modify/Delete Reply

    ㅋㅋㅋ

  3. Favicon of http://ad.coachfactoryoutletsv.com/ coach factory outlet 2013.04.01 22:03 Modify/Delete Reply

    아름다운 여자가 해바라기하는 걸 좋아해요

Write a comment


지름: Ferret short cuts (O'reilly), PDF

Tech 2007. 6. 8. 11:39
사용자 삽입 이미지

US 9.99$

91쪽짜리 가벼운 책. Ferret자체를 원하는 것은 아니고, 이 바닥에선 뭐뭐뭐를 하고 있는지 개념을 잡기 위해 샀다.

다 읽는데 두시간이 안걸릴듯.

지금 갈피를 못잡고 있는데, 정신차리는데 약간이나마 도움이 될 냉수 한잔이 되었으면 좋겠다.





'Tech' 카테고리의 다른 글

Ruby on Rails - Controller의 단위  (5) 2007.08.17
실명인증  (5) 2007.07.02
지름: Ferret short cuts (O'reilly), PDF  (0) 2007.06.08
Web - 데이터를 어디에 저장하지?  (2) 2007.05.02
Ruby On Rails - Scaffold의 함정  (2) 2007.04.18
Javascript - folding  (2) 2007.04.16
tags : ferret, PDF, Ruby, 검색,
Trackbacks 0 : Comments 0

Write a comment


Playtalk

Daily life 2007. 3. 15. 10:26
Me2day 를 써보고 싶어 써보고 싶어! 하다가 결국 초대장을 구하지 못하고 "멀까? 멀까?" 궁금해만 하다가, 비슷한(초점을 다르다고들 하지만) 다른 서비스가 있다는 소문을 듣고 후다닥~

음, 친구들이랑 이야기하면서 나왔던 아이디어들이 구현이 되어 널리 쓰이고 있다. 후덜덜 ... -0- 핸드폰을 통해 단문에 익숙해지고 나서, 이제는 웹으로 왔다 ! 라는 느낌.  폰을 통한 문자는 1:1 이지만, 웹에서의 단문은 n:n 이다. 정말 시장바닥처럼 많은 사람이 우르르 모여 왁자지껄하게 떠들어대는 느낌... 온라인 게임보다 훨씬 재밌다.

잇힝~ 내 플레이톡을 옆에 달아바씸!


'Daily life' 카테고리의 다른 글

지름신 강림(준비)  (2) 2007.03.20
Fantasy life!  (0) 2007.03.16
전입신고  (1) 2007.03.16
Playtalk  (0) 2007.03.15
드림걸스 OST  (1) 2007.03.14
Open!  (1) 2007.03.14
Trackbacks 0 : Comments 0

Write a comment