-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpython-rest-api-with-swaggerui.html
206 lines (164 loc) · 11.8 KB
/
python-rest-api-with-swaggerui.html
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
117
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
147
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
177
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
<!DOCTYPE html>
<html lang="english">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="index, follow" />
<link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700,400italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="http://olipratt.co.uk/theme/stylesheet/style.min.css">
<link rel="stylesheet" type="text/css" href="http://olipratt.co.uk/theme/pygments/monokai.min.css">
<link rel="stylesheet" type="text/css" href="http://olipratt.co.uk/theme/font-awesome/css/font-awesome.min.css">
<link href="http://olipratt.co.uk/static/custom.css" rel="stylesheet">
<link href="http://olipratt.co.uk/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Oli Pratt's Blog Atom">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<!-- Chrome, Firefox OS and Opera -->
<meta name="theme-color" content="#282828">
<!-- Windows Phone -->
<meta name="msapplication-navbutton-color" content="#282828">
<!-- iOS Safari -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<!-- Microsoft EDGE -->
<meta name="msapplication-TileColor" content="#282828">
<meta name="author" content="Oli Pratt" />
<meta name="description" content="What with REST APIs and the swagger framework for documenting and integrating them being the in-thing lately, to start getting to grips with them I wanted to see how easy it would be to create a simple one in Python with minimal code from me. Turns out it was very simple. As practice project I picked writing a really simple datastore. Choosing a Package After looking around for something that provides a SwaggerUI (demo here …" />
<meta name="keywords" content="Python, REST, Swagger, Flask-RESTPlus, microservice">
<meta property="og:site_name" content="Oli Pratt's Blog"/>
<meta property="og:title" content="Python REST API With SwaggerUI"/>
<meta property="og:description" content="What with REST APIs and the swagger framework for documenting and integrating them being the in-thing lately, to start getting to grips with them I wanted to see how easy it would be to create a simple one in Python with minimal code from me. Turns out it was very simple. As practice project I picked writing a really simple datastore. Choosing a Package After looking around for something that provides a SwaggerUI (demo here …"/>
<meta property="og:locale" content="en_GB"/>
<meta property="og:url" content="http://olipratt.co.uk/python-rest-api-with-swaggerui.html"/>
<meta property="og:type" content="article"/>
<meta property="article:published_time" content="2016-10-29 11:45:00+01:00"/>
<meta property="article:modified_time" content=""/>
<meta property="article:author" content="http://olipratt.co.uk/author/oli-pratt.html">
<meta property="article:section" content="REST"/>
<meta property="article:tag" content="Python"/>
<meta property="article:tag" content="REST"/>
<meta property="article:tag" content="Swagger"/>
<meta property="article:tag" content="Flask-RESTPlus"/>
<meta property="article:tag" content="microservice"/>
<meta property="og:image" content="http://olipratt.co.uk/static/images/site_logo.png">
<title>Oli Pratt's Blog – Python REST API With SwaggerUI</title>
</head>
<body>
<aside>
<div>
<a href="http://olipratt.co.uk">
<img src="http://olipratt.co.uk/static/images/site_logo.png" alt="Oli Pratt" title="Oli Pratt">
</a>
<h1><a href="http://olipratt.co.uk">Oli Pratt</a></h1>
<p>Software Engineer</p>
<nav>
<ul class="list">
<li><a href="http://olipratt.co.uk/pages/about-me.html#about-me">About Me</a></li>
<li><a href="https://www.metaswitch.com/" target="_blank">Metaswitch</a></li>
</ul>
</nav>
<ul class="social">
<li><a class="sc-github" href="https://github.com/olipratt" target="_blank"><i class="fa fa-github"></i></a></li>
<li><a class="sc-linkedin" href="https://www.linkedin.com/in/olipratt/" target="_blank"><i class="fa fa-linkedin"></i></a></li>
<li><a class="sc-rss" href="/feeds/all.atom.xml" target="_blank"><i class="fa fa-rss"></i></a></li>
</ul>
</div>
</aside>
<main>
<nav>
<a href="http://olipratt.co.uk"> Home
</a>
<a href="/archives.html">Archives</a>
<a href="/categories.html">Categories</a>
<a href="/tags.html">Tags</a>
<a href="http://olipratt.co.uk/feeds/all.atom.xml"> Atom
</a>
</nav>
<article class="single">
<header>
<h1 id="python-rest-api-with-swaggerui">Python REST API With SwaggerUI</h1>
<p>
Posted on Sat 29 October 2016 in <a href="http://olipratt.co.uk/category/rest.html">REST</a>
• 3 min read
</p>
</header>
<div>
<p>What with REST APIs and the <a href="http://swagger.io/">swagger</a> framework for documenting and integrating them being the in-thing lately, to start getting to grips with them I wanted to see how easy it would be to create a simple one in Python with minimal code from me. Turns out it was very simple.</p>
<p>As practice project I picked writing a really simple datastore.</p>
<h2 id="choosing-a-package">Choosing a Package</h2>
<p>After looking around for something that provides a SwaggerUI (<a href="http://petstore.swagger.io/">demo here</a> to see what this looks like) and schema, I found <a href="https://flask-restplus.readthedocs.io/en/stable/index.html">Flask-RESTPlus</a> which does this <a href="https://flask-restplus.readthedocs.io/en/stable/swagger.html#swagger-ui">really easily out of the box</a>. It also builds on top of <a href="http://flask.pocoo.org/">Flask</a> which I’ve heard good things about and wanted to try for a while - having only used <a href="http://cherrypy.org/">cherrypy</a> before myself.</p>
<p>Another thing I wanted was to be able to easily test the API, and it seemed <code>Flask</code> is really <a href="http://flask.pocoo.org/docs/0.11/testing/">easy to test</a>, and so by extension so is <code>Flask-RESTPlus</code> as it just plugs in on top. So this combo sounded like a good choice to get going.</p>
<p>I also needed some way to store the data and so looked for a really simple key-value store. A quick search gave <a href="http://tinydb.readthedocs.io/en/latest/getting-started.html">TinyDB</a> - small, easy to set up, and stores Python <code>dict</code>s directly (<a href="https://docs.python.org/3.5/library/json.html#json.loads">easily converted to</a> from the JSON used in the API).</p>
<h2 id="getting-started">Getting Started</h2>
<p>Getting something up and running was very straightforward - I followed the tutorial <a href="http://michal.karzynski.pl/blog/2016/06/19/building-beautiful-restful-apis-using-flask-swagger-ui-flask-restplus/">here</a> and wrote tests as I went.</p>
<p>That was followed by lots of tweaking/playing with the contents of the SwaggerUI page and working out how to create data models to enforce on the API, but the bulk of the work to get going was trivial.</p>
<h2 id="impressions">Impressions</h2>
<p>The SwaggerUI page is <strong>really</strong> great for exploring and documenting APIs. Often it’s hard to grasp how to integrate with some new code from reading it, but here you can actually play with the interface, press buttons to see what happens, and provide input and follow it through different API calls - really nice to use. Definitely like it and plan to use it more.</p>
<p>With a bit of reading of the <code>Flask-RESTPlus</code> docs you can edit all the fields and documentation in the Swagger UI page so you can make it as easy to use as possible - looks like it’s fully featured in that respect and was a good choice.</p>
<h2 id="gotchas">Gotchas</h2>
<p>It wasn’t entirely plain sailing though - here are the main problems I hit that it’s worth being aware of!</p>
<ul>
<li>
<p>You have to use a non-empty prefix for your API to start at (<a href="https://flask-restplus.readthedocs.io/en/stable/api.html#flask_restplus.Api"><code>prefix</code> parameter here</a>). I <a href="https://github.com/noirbizarre/flask-restplus/issues/210">raised an issue about it</a> but it didn’t garner much attention. It’s pretty minor though - I suspect any real system would not have the API exposed on <code>/</code> directly.</p>
</li>
<li>
<p>It doesn’t seem like the swagger schema is exposed anywhere over HTTP by <code>Flask-RESTPlus</code> by default. However, it’s really easy to do so, just return <code>api.__schema__</code> as the response to a <code>GET</code> request and it’s there. I ended up doing that in a separate <code>schema</code> namespace so it gets it’s own top-level section in the SwaggerUI.</p>
</li>
<li>
<p>If you use the <code>@api.expect</code> decorator to state what model the incoming data must match, <code>Flask-RESTPlus</code> won’t force incoming data to conform unless you set the <code>validate=True</code> parameter on it - seems like the wrong default to me…</p>
</li>
</ul>
<h2 id="end-result">End Result</h2>
<p>And here’s the result - <a href="https://github.com/olipratt/microstore">microstore</a> - a trivial datastore with a rest API and documented and interactive via SwaggerUI. I kept all the code <a href="https://github.com/olipratt/microstore/blob/master/microstore.py">in one file</a> to make it as simple a reference as possible.</p>
<p>I’d say it was a success, and was a fun weekend!</p>
</div>
<div class="tag-cloud">
<p>
<a href="http://olipratt.co.uk/tag/python.html">Python</a>
<a href="http://olipratt.co.uk/tag/rest.html">REST</a>
<a href="http://olipratt.co.uk/tag/swagger.html">Swagger</a>
<a href="http://olipratt.co.uk/tag/flask-restplus.html">Flask-RESTPlus</a>
<a href="http://olipratt.co.uk/tag/microservice.html">microservice</a>
</p>
</div>
<div class="neighbors">
<a class="btn float-right" href="http://olipratt.co.uk/the-cpp-short-string-optimisation.html" title="The C++ Short String Optimisation">
Next Post
<i class="fa fa-angle-right"></i>
</a>
</div>
</article>
<footer>
<p>© Oli Pratt </p>
<p> Powered by <a href="http://getpelican.com" target="_blank">Pelican</a> - <a href="https://github.com/alexandrevicenzi/flex" target="_blank">Flex</a> theme by <a href="http://alexandrevicenzi.com" target="_blank">Alexandre Vicenzi</a>
</p> </footer>
</main>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BlogPosting",
"name": "Python REST API With SwaggerUI",
"headline": "Python REST API With SwaggerUI",
"datePublished": "2016-10-29 11:45:00+01:00",
"dateModified": "2016-10-29 11:45:00+01:00",
"author": {
"@type": "Person",
"name": "Oli Pratt"
},
"publisher": {
"@type": "Organization",
"name": "Oli Pratt",
"logo": {
"@type": "ImageObject",
"url": "http://olipratt.co.uk/static/images/site_logo.png"
}
},
"image": "http://olipratt.co.uk/static/images/site_logo.png",
"mainEntityOfPage": "http://olipratt.co.uk/python-rest-api-with-swaggerui.html",
"url": "http://olipratt.co.uk/python-rest-api-with-swaggerui.html",
"description": "What with REST APIs and the swagger framework for documenting and integrating them being the in-thing lately, to start getting to grips with them I wanted to see how easy it would be to create a simple one in Python with minimal code from me. Turns out it was very simple. As practice project I picked writing a really simple datastore. Choosing a Package After looking around for something that provides a SwaggerUI (demo here …"
}
</script>
</body>
</html>