{"id":5784,"date":"2018-01-07T17:46:50","date_gmt":"2018-01-07T17:46:50","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=5784"},"modified":"2018-04-02T13:53:16","modified_gmt":"2018-04-02T13:53:16","slug":"python-rest-service-using-bottle","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/python-rest-service-using-bottle\/","title":{"rendered":"Python REST service using Bottle"},"content":{"rendered":"<p>From the command line\/terminal run <\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\npip install bottle\r\n<\/pre>\n<p>Bottle supports a style of defining routes to functions using decorators, for example<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nfrom bottle import route, run\r\n\r\n@route('\/&lt;name&gt;')\r\ndef index(name):\r\n    return f&quot;Hello {name}&quot;\r\n\r\nrun(host='localhost', port=8080)\r\n<\/pre>\n<p><strong>HTTP Method(s)<\/strong><\/p>\n<p>By default a <em>@route<\/em> will respond to a GET HTTP method, but we can change to POST or be more explicit using the following<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n@route('\/&lt;name&gt;', method='GET')\r\n# or\r\n@get('\/&lt;name&gt;')\r\n# or POST\r\n@route('\/&lt;name&gt;', method='POST')\r\n# or\r\n@post('\/&lt;name&gt;')\r\n<\/pre>\n<p>We can combine the methods using the following<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n@route('\/&lt;name&gt;', method=&#x5B;'GET', 'POST'])\r\n<\/pre>\n<p>and then within the actual function we can use the <em>request<\/em> class like this<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n@route('\/&lt;name&gt;', method=&#x5B;'GET', 'POST'])\r\ndef index(name):\r\n    if request.method == 'POST':\r\n       return f&quot;POST {name}&quot;\r\n    elif request.method == 'GET':\r\n       return f&quot;GET {name}&quot;\r\n\r\n    return &quot;Unexpected&quot;\r\n<\/pre>\n<p>We can also declare multiple routes to a function like this<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n@route('\/', method=&#x5B;'GET', 'POST'])\r\n@route('\/&lt;name&gt;', method=&#x5B;'GET', 'POST'])\r\ndef index(name = None):\r\n    if request.method == 'POST':\r\n       return f&quot;POST {name}&quot;\r\n    else request.method == 'GET':\r\n       return f&quot;GET {name}&quot;\r\n\r\n    return &quot;Unexpected&quot;\r\n<\/pre>\n<p><strong>How about some JSON<\/strong><\/p>\n<p>Obviously JSON is the current &#8220;in vogue&#8221; format for transferring data. To return JSON instead of a simple string we can use jsonpickle, start off by installing the library using<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\npip install jsonpickle\r\n<\/pre>\n<p>We&#8217;ll add an example class for our result<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nclass Person:\r\n    def __init__(self):\r\n        self.firstName = &quot;Eddie&quot;\r\n        self.lastName = &quot;Van Halen&quot;\r\n<\/pre>\n<p>and our code (and additional imports) looks like this<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nimport jsonpickle\r\n\r\n@get('\/&lt;name&gt;')\r\ndef index(name):\r\n    person = Person()\r\n    return jsonpickle.encode(person, unpicklable=False)\r\n<\/pre>\n<p>The <em>unpicklable=False<\/em> turns off the pickle additional information to our JSON.<\/p>\n<p><strong>Errors<\/strong><\/p>\n<p>We can also supply web pages, data etc. based upon HTTP errors, such as 404 errors. Assuming we changed out @get (above) to <\/p>\n<p>@get(&#8216;\/name\/&lt;name&gt;&#8217;)<\/p>\n<p>now URL&#8217;s such as http:\/\/localhost:8080\/PutridParrot will fail to find a matching route and if we supply an error handler for a 404 then we can return some other data, i.e.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n@error(404)\r\ndef error404(error):\r\n    return &quot;Got a 404!&quot;\r\n<\/pre>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"http:\/\/bottlepy.org\/docs\/dev\/\" rel=\"noopener\" target=\"_blank\">Bottle: Python Web Framework<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>From the command line\/terminal run pip install bottle Bottle supports a style of defining routes to functions using decorators, for example from bottle import route, run @route(&#8216;\/&lt;name&gt;&#8217;) def index(name): return f&quot;Hello {name}&quot; run(host=&#8217;localhost&#8217;, port=8080) HTTP Method(s) By default a @route will respond to a GET HTTP method, but we can change to POST or be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[195],"tags":[],"class_list":["post-5784","post","type-post","status-publish","format-standard","hentry","category-python"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5784","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=5784"}],"version-history":[{"count":9,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5784\/revisions"}],"predecessor-version":[{"id":6122,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/5784\/revisions\/6122"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=5784"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=5784"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=5784"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}