Talk given to full stack cohort at Galvanize/Boulder on December 20, 2016 about building APIs with Python / Flask.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gSchoolWinter16_PythonFlaskApp.md 7.5 KiB

пре 8 година
пре 8 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # Your first Python API server
  2. In this tutorial you will learn how to make a simple HTTP/REST API in Python 2.7 (or 3.5). When you're done you will know about:
  3. * how to install/verify your Python installation
  4. * how to do a basic package installation with `pip`, [Python's package manager](https://en.wikipedia.org/wiki/Pip_(Python))
  5. * a few common Python data structures (notably Python objects, dictionaries, tuples, lists)
  6. * how to use the [`json` module](https://docs.python.org/2/library/json.html) in Python
  7. * how to install the [Flask microframework](http://flask.pocoo.org/) for Python
  8. * how to build and run a basic API in Flask
  9. #### ADDITIONAL RESOURCES
  10. ## STEP 1: Environment check
  11. You will minimally need Python 2.7.1x for this tutorial. Most if not all of the code will work in 3.5.x as well, so feel free to use that moving forward.
  12. ### CHECK YOUR VERSION OF PYTHON
  13. 1. open terminal and type `python -V`
  14. ```
  15. $ python -V
  16. Python 2.7.12 :: Anaconda 4.2.0 (64-bit)
  17. ```
  18. 2. execute `pip install flask`
  19. * if you need to know more about `pip`, please [read more on it](http://www.pythonforbeginners.com/basics/python-pip-usage/)
  20. 3. check to see if you have json installed
  21. ```
  22. $ python
  23. Python 2.7.12 |Anaconda 4.2.0 (64-bit)| (default, Jun 29 2016, 11:07:13) [MSC v.1500 64 bit (AMD64)] on win32
  24. Type "help", "copyright", "credits" or "license" for more information.
  25. Anaconda is brought to you by Continuum Analytics.
  26. Please check out: http://continuum.io/thanks and https://anaconda.org
  27. >>> import json
  28. >>> exit()
  29. ```
  30. * **If this returns an error please execute `pip install json`.**
  31. ## Step 2: Build Your First Example App
  32. We're now going to build our first functional app. It isn't going to do anything yet -- we just want to make sure that we can see that everything is looking good in out environment.
  33. 1. Open your favorite editor and **create the file `app.py`**.
  34. 2. Write the following code in your file and **save it**:
  35. ```python
  36. # -*- coding: utf-8 -*-
  37. from flask import Flask
  38. app = Flask(__name__)
  39. if __name__ == "__main__":
  40. app.run()
  41. ```
  42. 3. Go to your command line and type:
  43. ```bash
  44. $ python app.py
  45. ```
  46. You should see the following:
  47. ```
  48. * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
  49. ```
  50. 4. Hooray! You have your first Flask app, test it by opening your browser and pointing it to [localhost:5000](http://localhost:5000) (**except if** you don't see that last line `* Running ...`, then something is really wrong!)
  51. 1. **NOTE:** You haven't implemented any endpoints/routes, so you should get HTTP/404 when you hit [localhost:5000](http://localhost:5000). This is the correct behavior.
  52. 2. The default port is `5000`, which can be changed later
  53. ## Step 3: Let's dissect what is going on ...
  54. line by line now ...
  55. ```python
  56. from flask import Flask
  57. ```
  58. This is a required import to get any basic Flask app running ... don't forget it, and don't linger on it.
  59. ```python
  60. app = Flask(__name__)
  61. ```
  62. This variable is necessary to initialize the Flask app -- it is the [Application Object](http://flask.pocoo.org/docs/0.11/api/#application-object). We're giving the name `__name__` because we are running this application as a standalone in a single file (`app.py`). You can read more about how Python handles application and module name spaces, but if a file you create is run from the command line, you it's application `__name__` attribute will be set to `__main__` (unless overridden by the developer, but that is not a typical move in Python, so don't go playing footsy with it until you know why you might want to do so!)
  63. ```python
  64. if __name__ == "__main__":
  65. app.run()
  66. ```
  67. This last bit of code tells Python that if this file is run from the command line (as opposed to being imported as a module), then execute the Flask application method [`run()`](http://flask.pocoo.org/docs/0.11/api/#flask.Flask.run), which starts the HTTP server (read [the docs carefully if you're deploying](http://flask.pocoo.org/docs/0.11/deploying/#deployment) in a production environment).
  68. ## Step 3a: Let's make a few quick changes
  69. ### Change the port
  70. Let's change the port to something like `5200` using the `port` parameter if the `Flask.run()` method like this:
  71. ```python
  72. if __name__ == "__main__":
  73. app.run(port=5200)
  74. ```
  75. ### Change the host ipaddress
  76. The default parameter for the `run()` method is indeed the IP of your running server (which defaults to `127.0.0.1`). You can set it to your fixed IP or use `0.0.0.0` to make it externally available.
  77. Let's put your fixed/assigned/DHCP address in first (remember this _may_ change depending on what network you are on):
  78. * Get the IP of your machine with `ifconfig` (on \*X) or `ipconfig` on (Win\*):
  79. ```bash
  80. $ ifconfig
  81. ```
  82. and make the change accordingly:
  83. ```python
  84. if __name__ == "__main__":
  85. app.run(_your_ip_address_, port=5200)
  86. ```
  87. ### Set DEBUG mode ON
  88. Finally, let's make sure we run in debug mode so if anything crazy happens, we can find out what ... using the `debug` parameter makes that a snap ...
  89. And now update your `app.run()` accordingly:
  90. ```python
  91. app.run(_your_ip_address_, port=5200, debug=True)
  92. ```
  93. With this, others will be able to see your server (on the same network) and you will be able to make changes to your code and **dynamically update your code without stopping and starting the server**.
  94. ## Step 4: Let's make a route
  95. In our final step, we're going to implement something interesting (well sort of anyway). Let's say we have an application which will respond to `/status` by returning the following json:
  96. ### INGREDIENT A: Some JSON response spec
  97. ```json
  98. {
  99. "appname": "My awesome app",
  100. "version": "0.1",
  101. "creator": "BigBird007"
  102. }
  103. ```
  104. Because Python dictionaries are *very* similar to JSON objects, we can specify the above JSON like this in Python:
  105. ```python
  106. data = {
  107. "appname": "My awesome app",
  108. "version": "0.1",
  109. "creator": "BigBird007"
  110. }
  111. ```
  112. To convert this Python dictionary to JSON so we can return it over the wire, we use the `json` library. The two methods you should just remember are `json.dumps(a_python_object)` and `json.loads(a_json_string)` ... these two methods allow you to go back and forth from Python a JSON string (`dumps`) and from a JSON object to a Python object (`loads`) so
  113. ### INGREDIENT B: A `/status` route and handler
  114. The syntax for specifying a route is
  115. ```python
  116. @app.route("your/route/here")
  117. def the_handler_for_the_route():
  118. # your awesome implementation here
  119. # return some cool JSON usually ...
  120. return
  121. ```
  122. This pattern will be used over and over in your code, study it and remember it. To learn how to use this pattern to specify things like your `GET` or `POST` handlers, read the docs further here: http://flask.pocoo.org/docs/0.11/api/#flask.Flask.route and here: http://flask.pocoo.org/docs/0.11/api/#url-route-registrations. Everything you'd want to know will be there (including handling variable parts of your route, defaults, method handling, etc.).
  123. Let's finish off our `/status` route ... make sure you place the route somewhere before the `if __name__ ...` line of code:
  124. ```python
  125. @app.route("/status")
  126. def status_endpoint():
  127. data = {
  128. "appname": "My awesome app",
  129. "version": "0.1",
  130. "creator": "BigBird007"
  131. }
  132. return json.dumps(data)
  133. ```
  134. Your final code should look like something like the sample file provided in [app.py](./app.py).
  135. ```python
  136. %pastebin -d "v0.1 gSchool Talk" gSchoolWinter16_PythonFlaskApp.md
  137. ```
  138. u'https://gist.github.com/8c90a3673f6e44ac30f2891155f4f74c'