{"id":3432,"date":"2021-03-07T20:36:10","date_gmt":"2021-03-07T19:36:10","guid":{"rendered":"http:\/\/van-maanen.com\/?p=3432"},"modified":"2021-03-07T20:36:10","modified_gmt":"2021-03-07T19:36:10","slug":"server-app-for-apis","status":"publish","type":"post","link":"http:\/\/archief.van-maanen.com\/?p=3432","title":{"rendered":"Server App for APIs"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I found a brilliant script to handle API requests. I noticed three elements here: it contains a server process, it is able to receive a call and it is able to return results.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import flask\nfrom flask import request, jsonify\nimport pyodbc\nimport pandas as pd\napp = flask.Flask(<strong>name<\/strong>)\napp.config[\"DEBUG\"] = True\ndef dict_factory(cursor, row):\n  d = {}\n  for idx, col in enumerate(cursor.description):\n    d[col[0]] = row[idx]\n  return d\n@app.route('\/', methods=['GET'])\ndef home():\n  return '''Distant Reading Archive'''\n@app.route('\/api\/v1\/resources\/books\/all', methods=['GET'])\ndef api_all():\n  connStr =       pyodbc.connect('DSN=AzureSQL;UID=tomvanmaanen;PWD=****')\n  cursor = connStr.cursor()\n  data = []\n  rows = cursor.execute('SELECT * FROM books;').fetchall()\n  for row in rows:\n    data.append([x for x in row])\n  cursor.close()\n  connStr.close()\n  return jsonify(data)\n@app.errorhandler(404)\ndef page_not_found(e):\n  return \"404 The resource could not be found.\", 404\n@app.route('\/api\/v1\/resources\/books', methods=['GET'])\ndef api_filter():\n  query_parameters = request.args\n  id = query_parameters.get('id')\n  published = query_parameters.get('published')\n  author = query_parameters.get('author')\n  query = \"SELECT * FROM books WHERE\"\n  to_filter = []\n  if id:\n    query += ' id=? AND'\n    to_filter.append(id)\n  if published:\n    query += ' published=? AND'\n    to_filter.append(published)\n  if author:\n    query += ' author=? AND'\n    to_filter.append(author)\n  if not (id or published or author):\n    return page_not_found(404)\n  query = query[:-4] + ';'\n  connStr = pyodbc.connect('DSN=AzureSQL;UID=tomvanmaanen;PWD=*****')\n  cursor = connStr.cursor()\n  data = []\nrows = cursor.execute(query, to_filter).fetchall()\nfor row in rows:\n  data.append([x for x in row])\ncursor.close()\nconnStr.close()\nreturn jsonify(data)\napp.run()<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This API can be called by two different calls:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">http:\/\/127.0.0.1:5000\/api\/v1\/resources\/books?author=Connie+Willis <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">or<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"> http:\/\/127.0.0.1:5000\/api\/v1\/resources\/books\/all<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It can be see in the code what happens. If we call http:\/\/127.0.0.1:5000\/api\/v1\/resources\/books\/all, we see that a function is used that is provided after the definition of &#8220;\/api\/v1\/resources\/books\/all&#8221;. In that function, we a sql is fired that is &#8220;SELECT * FROM books;&#8221;. We see that the query results are returned as a json file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As it is a GET call, the results are simply returned to the client.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If we call &#8220;127.0.0.1:5000\/api\/v1\/resources\/books?author=Connie+Willis&#8221;, we see what happens after the definition \/api\/v1\/resources\/books, in combination with some arguments. The arguments are provided after the ? mark. We see that parameter author is used. When that parameter is used, a query is used that is formulated as &#8220;SELECT * FROM books WHERE author = Connie+Willis&#8221;<\/p>\n\n\n\n<pre id=\"block-d638e12f-e7e7-48c0-bc62-0680548a3dea\" class=\"wp-block-preformatted\"><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I found a brilliant script to handle API requests. I noticed three elements here: it contains a server process, it is able to receive a call and it is able to return results. The script: import flask from flask import request, jsonify import pyodbc import pandas as pd app = flask.Flask(name) app.config[&#8220;DEBUG&#8221;] = True def [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-3432","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"_links":{"self":[{"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=\/wp\/v2\/posts\/3432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3432"}],"version-history":[{"count":0,"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=\/wp\/v2\/posts\/3432\/revisions"}],"wp:attachment":[{"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3432"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/archief.van-maanen.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}