ruby/python จัดการ command line arguments

มี server นึง (เขียนด้วย C/C++) ในบริษัทผมที่ผมต้องใช้งาน ต้องขอข้อมูลจากมันเป็นประจำ การที่จะเอา software เต็มๆ ไปขอข้อมูลจากมันบางทีก็เป็นเรื่องยุ่งยาก เขาก็เลยมีตัว test connection (เขียนด้วย C/C++ เช่นกัน) ไว้ทดสอบขอข้อมูลจาก server ตัวนั้นเพื่อดูว่ามันได้ข้อมูลไหม หรือเราลงถูกรึเปล่า ทีนี้ไอ้ตัว simple tool ตัวนี้มันใช้ยากพอดูเลย

$> ./runaction -s <server service> -h <server IP/Host> -e <encryption ไหม ตอบได้ yes/no> -p <server port> -f <file ใส่ชื่อ item ที่จะขอ>

จะเห็นว่าชื่อ parameter มันยาก แถมผมต้อง save ชื่อ item ที่จะขอลง file ถ้าจะขอหลาย item ก็ต้องเคาะบรรดทัดไปเรื่อยๆ แบบนี้

$> cat item.txt
facebook
oracle
ibm

แล้วก็ต้องใส่ item.txt ลงไปใน -f ข้างบน แล้ว server ก็จะส่งข้อมูลของ facebook, oracle และ ibm มาให้ แถมยังต้องใส่ env variable “ACTION_PATH” ไปที่ folder ของตัว simple tool นั้นอีก

ที่นี้ผมมีเรื่องที่จะต้องเปลี่ยน item บ่อยๆ เพื่อทดสอบอะไรบางอย่าง เลยอยากจะให้ใส่ชื่อ item ลงใน command เลยไม่ต้องไปสร้าง file เอง แถมทดสอบกับ server เดียวกันซ้ำๆ ก็ใส่ค่า default ไปเลย สรุป requirement ได้ดังนี้

  • ผมใส่ชื่อ item เป็น facebook,apple,vodaphone แล้วมันไปสร้าง file ชื่อ item ให้
  • มี default host, service, port, encryption ผมไม่จำเป็นต้องใส่ถ้าต่อกับ default server แต่ถ้าผมจะต่อกับ server ตัวอื่น ก็ต้องใส่ parameter อะไรไปในรูปแบบที่ง่ายกว่านี้
  • เฉพาะ item เป็น field ที่ต้องใส่เสมอ

Continue reading “ruby/python จัดการ command line arguments”

python: สร้าง string 1 ถึง 500

ช่วงนี้มีงานที่ต้อง test api กับ dummy item ประมาณ 500 item บ่อย ซึ่งต้อง input เข้าไปเป็น string แบบ “1,2,3,4,5,6,…,499,500” (ไอ้ … คือ 7,8,9,10 ไปเรื่อยๆ จนถึง 500) จะให้เขียนมือก็กระไรอยู่ ก็เลยเขียน script ง่อยๆ มา gen แม่มซะ

",".join([str(value) for value in range(1,501)])

ซึ่งก็จะได้ผลลัพท์มาประมาณนี้

'1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,
43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,
83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,1
17,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,1
47,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,1
77,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,2
07,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,2
37,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,2
67,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,2
97,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,3
27,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,3
57,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,3
87,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,4
17,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,4
47,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,4
77,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500'

แล้วก็จะให้ print ลง file หรือ redirect ลง file ก็ได้ เพื่อเอาไอ้ string 1 ถึง 500 นี่ไปใช้ต่อ

จริงๆ จะเขียนให้ code ที่มาเรียก api gen 1 ถึง 500 นี่ก็ได้นะ แต่ว่า code บน JavaScript น่าจะหลายบรรทัดอยู่มั้ง (?)

Python: post request with json

ออกตัวล้อฟรีก่อนว่าผมเขียนภาษา dynamic อยู่ 2 ภาษาคือ พอจะเขียน python ได้บ้าง (งาน script เล็กๆ แทน shellscript หรือเขียน process log file เพื่อเสริมการทำงาน) และภาษา javascript ซึ่งใช้ทำงานจริงจังมา 2 ปี

ปลายปีที่แล้วมีงานที่ต้องลอง reproduce ปัญหาด้วยการยิง http post request ที่มี input เป็น json format เพื่อดูผลการทำงานของ server อยู่บ่อยๆ เลยต้องหาวิธียิง request แบบง่ายๆ ซึ่งคิดไว้ 3 ทางคือ

  • ใช้ jQuery.ajax เขียน ก็ใช้เวลาไม่นาน
  • ใช้ Advanced REST client plugin บน Chrome ก็ได้
  • ใช้ RESTClient ของ Firefox ก็ได้

แต่ทุกตัวต้องมาเปิด browser อะไรยุ่งยาก เลยหาวิธีเขียนบน python รันแค่ cmd แล้วรัน script ก็น่าจะได้ผลเร็วกว่าเปิด browser พวกนี้ ก็เลยไปค้นๆ google มา

วิธีแรกใช้ lib Requests

import requests
import json

payload={'service':'QUOTE','subject':'AAPL'}
url='http://1xx.xx.xxx.xxx:8080/quote'
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), headers=headers)
print r.json

สิ่งที่ผมลืมไปคือหลังๆ ผมติด json บน javascript ที่ key ไม่จำเป็นต้องเป็น string ซึ่งมันขัดกับ dictionary ของ python เลยงงๆ อยู่สักพักก็ได้ http request แบบง่ายๆ ขึ้นมา script นึง

ไอ้ script ที่แล้วใช้ 3rd party lib เลยอยากลองแบบ python lib เพียวๆ ดูบ้าง ลองค้นๆ วิธีดูสักพักก็ได้เจ้าตัวนี้มา

import urllib2
import json

payload=json.dumps({'closure':'Python test tool','service':'Chart','subject':['AAPL']})
headers = {'content-type': 'application/json'}
req = urllib2.Request(url='http://1xx.xx.xxx.xxx:8080/chart',data=payload,headers=headers)
f=urllib2.urlopen(req)
print f.read()
f.close()

จะเห็นว่า code ยุ่งยากขึ้นอย่างเห็นได้ชัด แต่ก็ค่อนข้างจะ simple ตามสไตล์ python อยู่ดี

ป.ล. ผมเคยลองหาข้อมูล python call webservice (xml, soap พวกนั้น) เพื่อใช้ทำ script test แต่พบว่ามันยากเย็นแสนเข็ญจนตัดใจไปใช้ soapui แทน