Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
»ùÓÚFlaskÉè¼ÆRESTful API
 
  7954  次浏览      32
 2017-12-29  
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚblog.miguelgrinberg.com£¬ÎÄÕ´Ӱ²×°²¿Êðµ½Éè¼Æµ½¶Ôweb·þÎñÔö¼Ó°²È«»úÖÆæ¸æ¸µÀÀ´¡£

FlaskÊÇÒ»¸öPython WEB¿ª·¢¿ò¼Ü¡£½ÓÏÂÀ´Ò»¶ÎÏÐϾʱ¼ä´òËã×öµÄ¡°Î÷×Ó¿ìѶ¡±ÏîÄ¿ÖУ¬ÎÒ´òËãÄÃËüÀ´×öRESTful API¡£ËäȻ֮ǰ¶ÔPython²¢²»Á˽⣬¶ÔFlask¸üÊÇİÉú£¬µ«°®ÕÛÌڵı¾ÐÔ´ÙʹÎÒ²»¶Ïȥѧϰ¡£ÓÚÊǽñÌì¿´blog¡¢¿´Îĵµ£¬Ð¡ÓÐÊÕ»ñ£¬ÂÔ¼ÇÒ»¶þ¡£

×¼±¸¹¤×÷

È·±£»úÆ÷ÉÏÒѾ­°²×°ÁËPython¡¢Pip¡¢VirtualenvµÈ¹¤¾ß¡£Èç¹ûĬÈϵÄPip°²×°Ô´±È½ÏÂý£¬¿ÉÒÔÓÃv2exµÄÊÔÊÔ¡£¾ßÌå·½·¨ÊÇÔÚ~/.pip/Ï´´½¨Ò»¸öÃûΪpip.confµÄÎļþ£¬ÊäÈëеÄpipÔ´¡£

[global]
index-url = http://pypi.v2ex.com/simple

°²×°Flask

ΪÁ˲»Ó°ÏìϵͳµÄPython»·¾³£¬ÎÒÃÇÓÃVirtualenvÐéÄâÒ»¸öÔËÐл·¾³£¬È»ºóÔÚ´Ë»·¾³Ï¿ª·¢Ò»¸öÃûΪtodoµÄʾÀýСӦÓ㨴¿RESTful API£¬JSON¸ñʽµÄÊý¾Ý£©¡£

cd ~/Desktop
mkdir todo-api
cd todo-api
virtualenv venv
. venv/bin/activate

´ËʱÃüÁîÐд°¿ÚÓ¦³öÏÖ(venv)mbpr2013:todo-api linkoubian$ ÕâÑùµÄÌáʾ·û£¬×¢Òâ×î×ó±ßµÄvenv±íÃ÷µ±Ç°ÔËÐеÄÊÇÐéÄâ³öÀ´µÄ»·¾³¡£¹¤×÷Íê³Éºó´òËãÍ˳övenv£¬Ö»ÐèÖ´ÐÐdeactivateÃüÁî¼´¿É¡£

ÕâʱִÐÐpip install flask±ã¿ÉÔÚvenvϰ²×°flaskÄ£¿é¡£

²âÊÔFlaskÊÇ·ñÕý³£¹¤×÷

±àдһ¸öHello World³ÌÐò£¬ÈçÏ£º

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
return "Hello, World!"

if __name__ == '__main__':
app.run(debug = True)

±£´æÎª~/Desktop/todo-api/app.py£¬Ìí¼Ó¿ÉÖ´ÐÐȨÏÞºó£¬ÇÃpython app.py¿ªÊ¼ÔËÐÐFlask¡£´Ëʱ´ò¿ªä¯ÀÀÆ÷£¬·ÃÎÊlocalhost:5000¼´¿É¿´µ½Hello, World!

¿ªÊ¼Éè¼ÆRESTful API

»ñÈ¡ËùÓеÄtasks

Ò»¸ötaskÓÉid¡¢title¡¢description¡¢doneµÈÊôÐÔ¹¹³É£¬»ñÈ¡taskÁбíµÄurl¿ÉÒÔÉè¼Æ³É/todo/tasks¡£¾ßÌå´úÂëÈçÏ£¬

from flask import Flask, jsonify

app = Flask(__name__)

tasks = [
{
'id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'id': 2,
'title': u'Learn Python',
'description': u'Need to find a good Python tutorial on the web',
'done': False
},
]

@app.route('/todo/tasks', methods = ['GET'])
def get_tasks():
return jsonify({'tasks': tasks})

if __name__ == '__main__':
app.run(debug = True)

ÒòΪFlaskÔËÐÐÔÚdebugģʽÏ»á×Ô¶¯reload£¬ËùÒÔ´úÂëдÍêºó±£´æÎļþ¼´¿É¡£

MacÉÏÓÐÒ»¿îÃûΪPawµÄHTTP Client£¬ËãÊÇÎÒ¼û¹ý¡¢ÓùýµÄ¸÷ÖÖAPI²âÊÔ¹¤¾ßÖеÄٮٮÕߣ¬Á¦¼ö¡£

´ò¿ªPaw£¬ÔÚurlÀïÊäÈëhttp://localhost:5000/todo/tasks£¬Ñ¡ÔñGET£¬ÇÃCMD+Enter¼´¿ÉÌýµ½±íʾ³É¹¦µÄÇå´àÌáʾÒô¡£Paw³ýÁËÌṩԭÉúµÄHTTPÏìÓ¦¸ñʽ£¬»¹Ìṩ¸ñʽ»¯ºóä¯ÀÀ¹¦ÄÜ£¬Ñ¡ÔñJSON¸ñʽ¼´¿É¡£

ÉÏÃæÕâ¶Î´úÂ뻹ÊDZȽÏÇåÎúºÃ¶®µÄ£¬Ê×ÏÈ´´½¨Ò»¸ötaskÊý×飬³õʼ»¯Á½¸ötask¶ÔÏó·Å½øÈ¥¡£Ö¸¶¨GET·½Ê½ÇëÇó/todo/tasks×ÊԴʱִÐÐget_tasks·½·¨£¬¾ßÌåÊǰÑÇ°Ãæ´´½¨µÄtasksÊý×éÒÔJSONµÄ¸ñʽ·µ»Ø¡£¶ø½«PythonµÄÊý×éת³ÉJSON¸ñʽÊÇͨ¹ýFlaskµÄjsonifyº¯ÊýʵÏֵġ£

¸ù¾Ýid»ñµÃÌØ¶¨task

ͨ³£ÎÒÃǽ«id·ÅÔÚURLÖУ¬È»ºó¶ÔÓ¦µÄ´¦Àíº¯Êý´ÓURLÖеõ½idÒÔ´ÓÊý¾ÝÔ´£¨´Ë´¦ÎªtaskÊý×飬´æÔÚÄÚ´æÖУ©ÖвéѯÏàÓ¦µØentity£¨´Ë´¦Îªtask£©¡£

@app.route('/todo/tasks/<int:task_id>', methods = ['GET'])
def get_task(task_id):
task = filter(lambda t: t['id'] == task_id, tasks)
if len(task) == 0:
abort(404)
return jsonify({'task': task[0]})

ΪÁËÕý³£Ê¹ÓÃabortº¯Êý£¬ÐèÒª´ÓflaskÄ£¿éimportһϡ£Í¨¹ýPaw²âÊÔhttp://localhost:5000/todo/tasks/1£¬·¢ÏÖÒ»ÇÐÕý³£¡£

·ÃÎÊhttp://localhost:5000/todo/tasks/0ʱ£¬·µ»ØÒ»¶Î³ö´íµÄHTML£¬ÕâÊÇFlask¶Ô404µÄĬÈÏ´¦Àí£¬ÎÒÃÇ¿ÉÒÔ×Ô¼º¶¨ÒåÒ»¸ö·µ»ØJSON¸ñʽµÄ´íÎóÏûÏ¢¡£

@app.errorhandler(404)
def not_found(error):
return make_response(jsonify( { 'error': 'Not found' } ), 404)

ÎÒÃÇÓÃmake_responseº¯Êý£¬½«¹¹ÔìºÃµÄJSON×÷Ϊ404´íÎóµÄÏìÓ¦£¬·µ»Ø¸ø¿Í»§¶Ë¡£

´´½¨Ò»¸ötask

URLÈÔÈ»ÓÃ/todo/tasks£¬µ«HTTP·½·¨ÎªPOST¡£¸ù¾ÝRequest¶ÔÏóÖеÄÊý¾Ý¹¹ÔìÒ»¸öеÄtask¶ÔÏ󣬲åÈëÊý¾ÝÔ´¼´¿É¡£

@app.route('/todo/tasks', methods = ['POST'])
def create_task():
if not request.json or not 'title' in request.json:
abort(400)
task = {
'id': tasks[-1]['id'] + 1,
'title': request.json['title'],
'description': request.json.get('description', ''),
'done': False
}
tasks.append(task)
return jsonify({'task': task}), 201

ÁíÍ⣬ÎÒÃÇÐèÒª¶¨ÒåÒ»¸ö400µÄ´¦ÀíÆ÷£¬ÀàËÆÓÚ404£¬

@app.errorhandler(400)
def not_found(error):
return make_response(jsonify( { 'error': 'Bad request' } ), 400)

ÔÚPawÖУ¬POSTÇëÇóhttp://localhost:5000/todo/tasks£¬Í¬Ê±HeaderÀï¼ÓÒ»¸öContent-Type£¬ÖµÎªapplication/json£¬BodyÀï¼ÓÈëÒ»¶ÎÎı¾ÄÚÈÝ{¡°title¡±: ¡°Buy a cell phone¡±}£¬ÇÃCMD+EnterÖ´ÐС£

¸ù¾ÝREST CookbookÒ»ÊéµÄ½¨Ò飬¿ÉÒÔÔÚ·µ»ØµÄÐÂÔötaskÀï¼ÓÈëÒ»¸öuri×ֶΡ£Îª´Ë£¬½¨Ò»¸öÃûΪmake_public_taskµÄº¯Êý£¬ÈçÏ£¬

def make_public_task(task):
new_task = {}
for field in task:
new_task[field] = task[field]
if field == 'id':
new_task['uri'] = url_for('get_task', task_id = task['id'], _external = True)

return new_task

ÁíÍ⣬create_taskÖиÄΪ£¬

return jsonify({'task': make_public_task(task)}), 201

get_tasksÖиÄΪ£¬

return jsonify({'tasks': map(make_public_task, tasks)})

get_taskÖиÄΪ£¬

return jsonify({'tasks': map(make_public_task, tasks)})

¸üÐÂÒ»¸ötask

ÏÔÈ»´ËʱµÄHTTP·½·¨ÎªPUT£¬ÏàÓ¦µÄurlºÍ»ñÈ¡taskÀàËÆ¡£

@app.route('/todo/tasks/<int:task_id>', methods = ['PUT'])
def update_task(task_id):
task = filter(lambda t: t['id'] == task_id, tasks)
if len(task) == 0:
abort(404)
if not request.json:
abort(400)
if 'title' in request.json and type(request.json['title']) != unicode:
abort(400)
if 'description' in request.json and type(request.json['description']) is not unicode:
abort(400)
if 'done' in request.json and type(request.json['done']) is not bool:
abort(400)
task[0]['title'] = request.json.get('title', task[0]['title'])
task[0]['description'] = request.json.get('description', task[0]['description'])
task[0]['done'] = request.json.get('done', task[0]['done'])
return jsonify( { 'task': make_public_task(task[0]) } )

ɾ³ýÒ»¸ötask

@app.route('/todo/tasks/<int:task_id>', methods = ['DELETE'])
def delete_task(task_id):
task = filter(lambda t: t['id'] == task_id, tasks)
if len(task) == 0:
abort(404)
tasks.remove(task[0])
return jsonify( { 'result': True } )

ÐÞ¸ÄPythonÔ´Îļþºó£¬Flask»áreload£¬Õ⽫µ¼ÖÂÉÏÒ»´ÎcreateµÄtask¶ªÊ§£¬ËùÒÔÖ±½Ó³¢ÊÔdelete֮ǰÔö¼ÓµÄtask¿ÉÄܻᱨ404×ÊÔ´ÕÒ²»µ½´íÎó¡£

ΪWEB·þÎñÔö¼Ó°²È«»úÖÆ

»ùÓÚFlaskµÄHTTBasicAuthÀ©Õ¹£¬¶¨ÒåÁ½¸öº¯ÊýÈçÏ£¬

auth = HTTPBasicAuth()

@auth.get_password
def get_password(username):
if username == 'linkoubian':
return '7c4a8d09ca3762af61e59520943dc26494f8941b'
return None

@auth.error_handler
def unauthorized():
return make_response(jsonify( { 'error': 'Unauthorized access' } ), 401)

ÆäÖÐget_password·½·¨ÊÇ·µ»ØÖ¸¶¨Óû§µÄÃÜÂëÐÅÏ¢£¨Í¨³£ÊÇ´ÓÊý¾Ý¿âÓû§±í²éѯµÃµ½£©£¬µ±´Ë´¦·µ»ØµÄÖµºÍ¿Í»§¶Ë´«µÝµÄֵƥÅäʱ£¨Æ¥Åä¹ý³ÌÓÉHTTPBasicAuthÍê³É£©³É¹¦£¬·ñÔòÖ´ÐÐerror_handler·µ»Ø´íÎóÐÅÏ¢¡£

¶¨ÒåÍêУÑéÏà¹ØµÄ´úÂ룬»¹Ð轫УÑéÂß¼­Ó¦Óõ½ÐèҪУÑéµÄWEB·þÎñ¡£±ÈÈ磬ϣÍûÖ»ÓÐÊÚȨÓû§²Å¿ÉÒÔÐ޸Ļòɾ³ýtask£¬Ôò¿ÉÒÔÔÚupdate_task¼°delete_task·½·¨ÉÏÃæ¼ÓÉÏ@auth.login_required¼´¿É¡£

´ËʱÔÚPawÖÐÐèÌí¼ÓAuthorizationÍ·£¬ÖµÎªHTTP Basic Auth£¬ÔÚusername¼°passwordÎı¾¿òÖзֲ¼ÊäÈëÐÅÏ¢£¬ÇÃCMD+Enter½øÐвâÊÔ¡£

   
7954 ´Îä¯ÀÀ       32
Ïà¹ØÎÄÕÂ

ÆóÒµ¼Ü¹¹¡¢TOGAFÓëArchiMate¸ÅÀÀ
¼Ü¹¹Ê¦Ö®Â·-ÈçºÎ×öºÃÒµÎñ½¨Ä££¿
´óÐÍÍøÕ¾µçÉÌÍøÕ¾¼Ü¹¹°¸ÀýºÍ¼¼Êõ¼Ü¹¹µÄʾÀý
ÍêÕûµÄArchimateÊÓµãÖ¸ÄÏ£¨°üÀ¨Ê¾Àý£©
Ïà¹ØÎĵµ

Êý¾ÝÖÐ̨¼¼Êõ¼Ü¹¹·½·¨ÂÛÓëʵ¼ù
ÊÊÓÃArchiMate¡¢EA ºÍ iSpace½øÐÐÆóÒµ¼Ü¹¹½¨Ä£
ZachmanÆóÒµ¼Ü¹¹¿ò¼Ü¼ò½é
ÆóÒµ¼Ü¹¹ÈÃSOAÂ䵨
Ïà¹Ø¿Î³Ì

ÔÆÆ½Ì¨Óë΢·þÎñ¼Ü¹¹Éè¼Æ
ÖÐ̨սÂÔ¡¢ÖÐ̨½¨ÉèÓëÊý×ÖÉÌÒµ
ÒÚ¼¶Óû§¸ß²¢·¢¡¢¸ß¿ÉÓÃϵͳ¼Ü¹¹
¸ß¿ÉÓ÷ֲ¼Ê½¼Ü¹¹Éè¼ÆÓëʵ¼ù