{"id":20819,"date":"2021-09-23T11:31:43","date_gmt":"2021-09-23T11:31:43","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/blog\/?p=20819"},"modified":"2025-02-14T12:02:29","modified_gmt":"2025-02-14T12:02:29","slug":"aws-dynamodb-with-flask-apis-and-boto3","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/blog\/aws-dynamodb-with-flask-apis-and-boto3","title":{"rendered":"CRUD Operations Using AWS DynamoDB with Flask APIs and Boto3"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>In this tutorial, we will build a demo application together; learn about the Flask framework, Boto3 library, REST APIs,  and AWS DynamoDB. If you are new at using <b>AWS DynamoDB with Flask APIs and Boto3<\/b>, don\u2019t worry! We are here to help you learn through this tutorial. <\/p>\n<h2>Goal: Using AWS DynamoDB with Flask APIs and Boto3<\/h2>\n<p>Before knowing how to implement CRUD operations on DynamoDB using Flask APIs, let\u2019s see the video and know what we will build.<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/367Sucfvvhg\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h2>Prerequisites<\/h2>\n<p>We assume that you have prior knowledge of the following:<\/p>\n<ul class=\"bullets text-left\">\n<li>Python3 Programming<\/li>\n<li>pip<\/li>\n<li>Flask<\/li>\n<li>AWS and IAM<\/li>\n<\/ul>\n<p>To get started with this tutorial, make sure you have the following as well:<\/p>\n<ul class=\"bullets text-left\">\n<li>DynamoDB local<\/li>\n<li>Python<\/li>\n<li>IDE<\/li>\n<\/ul>\n<h2>Technologies to use<\/h2>\n<p>We will be using the following technologies:<\/p>\n<ul class=\"bullets text-left\">\n<li>Flask<\/li>\n<li>Boto3<\/li>\n<li>DynamoDB<\/li>\n<\/ul>\n<p>Let\u2019s start the implementation of <em>AWS DynamoDB with Flask APIs and Boto3<\/em>. Here\u2019s my system setup:<\/p>\n<ul class=\"bullets text-left\">\n<li>Ubuntu 20.04 OS<\/li>\n<li>Python 3.8+<\/li>\n<li>Postman<\/li>\n<\/ul>\n<h2>Installing Flask and Boto3 using pip<\/h2>\n<p>Install the packages to build REST APIs<\/p>\n<ul class=\"bullets text-left\">\n<li>Flask<\/li>\n<li>Boto3<\/li>\n<\/ul>\n<p><b><em>An efficient way<\/em><\/b>: <em>Create a requirements.txt file and list all the packages into it. You can also declare the versions of the packages wherever necessary.<\/em><\/p>\n<pre>flask==1.1.2\r\nboto3==1.17.52<\/pre>\n<p>Use the above file to install all the listed packages with <em>pip<\/em>.<\/p>\n<pre>pip install -r requirements.txt<\/pre>\n<h2>Create new directory<\/h2>\n<p>Create a new directory and navigate to it using the below commands<\/p>\n<pre>mkdir mydynamoDBflaskproject\r\ncd mydynamoDBflaskproject<\/pre>\n<h2>Set Up AWS Credentials<\/h2>\n<p>Create a new file named <b>config.py<\/b><\/p>\n<pre>touch config.py<\/pre>\n<p><strong><em>NOTE<\/em><\/strong>&#8211; <em>it is advised to use a virtual environment and perform all the setup and installation inside it to avoid unnecessary pollution of the Operating System. However, it is not a mandatory process but a healthy practice.<\/em><\/p>\n<p>Now, include your AWS credentials in a python file named <em>config.py<\/em>:<\/p>\n<h3>\/\/ config.py<\/h3>\n<pre>AWS_ACCESS_KEY_ID = 'youraccessid'\r\nAWS_SECRET_ACCESS_KEY = 'yoursecretaccesskey'\r\nREGION_NAME = 'yourregionname'<\/pre>\n<ul class=\"bullets text-left\">\n<li>AWS_ACCESS_KEY_ID: AWS access key associated with an IAM role or user.<\/li>\n<li>AWS_SECRET_ACCESS_KEY: A secret key associated with the access key. This is essentially the \u201cpassword\u201d for the specified access key.<\/li>\n<li>REGION_NAME: The default region when creating new connections.<\/li>\n<\/ul>\n<h2>Configuration Set Up for APIs<\/h2>\n<p>Create a new file named \u201c<em>controller.py<\/em>.\u201d <\/p>\n<pre>touch controller.py<\/pre>\n<p><em><strong>NOTE<\/strong>&#8211; while executing these commands in the terminal, make sure you do it inside the virtual environment named \u201cvenv\u201d we created earlier.<\/em><\/p>\n<p>Open the file and paste the following code.<\/p>\n<h3>\/\/ controller.py<\/h3>\n<pre>from boto3 import resource\r\nimport config<\/pre>\n<p>The <strong>resource<\/strong> package provides higher-level object-oriented service access. It provides better abstraction and makes your code easier to comprehend.<\/p>\n<p>The <strong>config<\/strong> package will import all the AWS configurations that we set in the config.py file.<\/p>\n<p>Now it\u2019s time to <strong>configure settings<\/strong> for the Movie API <\/p>\n<h3>\/\/ controller.py<\/h3>\n<pre>AWS_ACCESS_KEY_ID = config.AWS_ACCESS_KEY_ID\r\nAWS_SECRET_ACCESS_KEY = config.AWS_SECRET_ACCESS_KEY\r\nREGION_NAME = config.REGION_NAME\r\n \r\nresource = resource(\r\n   'dynamodb',\r\n   aws_access_key_id     = AWS_ACCESS_KEY_ID,\r\n   aws_secret_access_key = AWS_SECRET_ACCESS_KEY,\r\n   region_name           = REGION_NAME\r\n)<\/pre>\n<h2>Create a Table using create_table()<\/h2>\n<p>As part of the next step, let&#8217;s create a function that would create a new table called <em>create_table()<\/em>.<\/p>\n<h3>\/\/ controller.py<\/h3>\n<pre>def create_table_movie():   \r\n   table = resource.create_table(\r\n       TableName = 'Movie', # Name of the table\r\n       KeySchema = [\r\n           {\r\n               'AttributeName': 'id',\r\n               'KeyType'      : 'HASH' #RANGE = sort key, HASH = partition key\r\n           }\r\n       ],\r\n       AttributeDefinitions = [\r\n           {\r\n               'AttributeName': 'id', # Name of the attribute\r\n               'AttributeType': 'N'   # N = Number (B= Binary, S = String)\r\n           }\r\n       ],\r\n       ProvisionedThroughput={\r\n           'ReadCapacityUnits'  : 10,\r\n           'WriteCapacityUnits': 10\r\n       }\r\n   )\r\n   return table<\/pre>\n<p>To access or modify the table\u2019s entries, we have to get the table using the resource.<\/p>\n<pre>MovieTable = resource.Table('Movie')<\/pre>\n<p>Once done, let\u2019s get started for CRUD operations using Flask APIs on DynamoDB.<\/p>\n<p class=\"boxed bg--secondary\" style=\"border: 1px solid #c7c7c7; box-shadow: 0 0 40px rgba(0, 0, 0, 0.2);\"><strong><em><span style=\"font-size:22px; color:#000;\">Supercharge your projects with our elite AWS developers!<\/span><br \/>\nElevate your business to new heights with cutting-edge solutions and unparalleled expertise. Let&#8217;s transform your vision into reality\u2014 <a href=\"https:\/\/www.bacancytechnology.com\/hire-aws-developers\" target=\"_blank\" rel=\"noopener\">hire AWS developers<\/a> from us today for a journey of innovation and success! <\/em><\/strong><\/p>\n<h2>CRUD Operations using AWS DynamoDB with Flask APIs and Boto3<\/h2>\n<h3><em>CREATE<\/em><\/h3>\n<p>Now, let\u2019s add a new entry in the Movie table.<\/p>\n<pre>def write_to_movie(id, title, director):\r\n   response = MovieTable.put_item(\r\n       Item = {\r\n           'id'     : id,\r\n           'title'  : title,\r\n           'director' : director,\r\n           'upvotes'  : 0\r\n       }\r\n   )\r\n return response<\/pre>\n<h3><em>READ<\/em><\/h3>\n<p>Read an entry from the Movie table.<\/p>\n<pre>def read_from_movie(id):\r\n   response = MovieTable.get_item(\r\n       Key = {\r\n           'id'     : id\r\n       },\r\n       AttributesToGet = [\r\n           'title,\u2019,\u2019\u2019 'director'\r\n   )\r\n return response<\/pre>\n<h3><em>UPDATE<\/em><\/h3>\n<p>Update an entry in the Movie table using the \u2018id\u2019 attribute.<\/p>\n<pre>def update_in_movie(id, data:dict):\r\n \r\n   response = MovieTable.update_item(\r\n       Key = {\r\n           'id': id\r\n       },\r\n       AttributeUpdates={\r\n           'title': {\r\n               'Value'  : data['title'],\r\n               'Action' : 'PUT' \r\n           },\r\n           'director': {\r\n               'Value'  : data['director'],\r\n               'Action' : 'PUT'\r\n           }\r\n       },\r\n \r\n       ReturnValues = \"UPDATED_NEW\"  # returns the new updated values\r\n   )\r\n \r\n  return response<\/pre>\n<p>Update \u2018upvotes\u2019 property for an entry.<\/p>\n<pre>def upvote_a_movie(id):\r\n \r\n   response = MovieTable.update_item(\r\n       Key = {\r\n           'id': id\r\n       },\r\n       AttributeUpdates = {\r\n           'upvotes': {\r\n               'Value'  : 1,\r\n               'Action' : 'ADD'\r\n           }\r\n       },\r\n \r\n       ReturnValues = \"UPDATED_NEW\"\r\n   )\r\n \r\n   response['Attributes']['upvotes'] = int(response['Attributes']['upvotes'])\r\n \r\n return response<\/pre>\n<h3><em>DELETE<\/em><\/h3>\n<p>Delete an entry from the Movie collection.<\/p>\n<pre>def delete_from_movie(id):\r\n \r\n   response = MovieTable.delete_item(\r\n       Key = {\r\n           'id': id\r\n       }\r\n   )\r\n \r\n return response<\/pre>\n<p>Let\u2019s create a linear flask application with APIs to perform operations on the Movie collection we will create using our <em>create_table_movie()<\/em> function.<\/p>\n<p><b>\/\/ app.py<\/b><\/p>\n<pre>import controller as dynamodb\r\n \r\n \r\n@app.route('\/')\r\ndef root_route():\r\n   dynamodb.create_table_movie()\r\n   return 'Table created'\r\n \r\n@app.route('\/movie', methods=['POST'])\r\ndef add_movie():\r\n   data = request.get_json()\r\n   response = dynamodb.write_to_movie(data['id'], data['title'], data['director'])   \r\n   if (response['ResponseMetadata']['HTTPStatusCode'] == 200):\r\n       return {\r\n           'msg': 'Add Movie successful',\r\n       }\r\n   return { \r\n       'msg': 'error occurred',\r\n       'response': response\r\n   }\r\n \r\n@app.route('\/movie\/<int:id>', methods=['GET'])\r\ndef get_movie(id):\r\n   response = dynamodb.read_from_movie(id)\r\n   if (response['ResponseMetadata']['HTTPStatusCode'] == 200):\r\n       if ('Item' in response):\r\n           return { 'Item': response['Item'] }\r\n       return { 'msg' : 'Item not found!' }\r\n   return {\r\n       'msg': 'error occurred',\r\n       'response': response\r\n   }\r\n \r\n@app.route('\/movie\/<int:id>', methods=['DELETE'])\r\ndef delete_movie(id):\r\n   response = dynamodb.delete_from_movie(id)\r\n   if (response['ResponseMetadata']['HTTPStatusCode'] == 200):\r\n       return {\r\n           'msg': 'Delete successful',\r\n       }\r\n   return { \r\n       'msg': 'error occurred',\r\n       'response': response\r\n   }\r\n \r\n@app.route('\/movie\/<int:id>', methods=['PUT'])\r\ndef update_movie(id):\r\n \r\n   data = request.get_json()\r\n   response = dynamodb.update_in_movie(id, data)\r\n   if (response['ResponseMetadata']['HTTPStatusCode'] == 200):\r\n       return {\r\n           'msg'                : update successful',\r\n           'response'           : response['ResponseMetadata'],\r\n           'ModifiedAttributes' : response['Attributes']\r\n       }\r\n   return {\r\n       'msg'      : \u2018error occurred',\r\n       'response' : response\r\n   }  \r\n \r\n@app.route('\/upvote\/movie\/<int:id>', methods=['POST'])\r\ndef upvote_movie(id):\r\n   response = dynamodb.upvote_a_movieMovie(id)\r\n   if (response['ResponseMetadata']['HTTPStatusCode'] == 200):\r\n       return {\r\n           'msg'      : 'Upvote successful',\r\n           'response' : response['ResponseMetadata'],\r\n           'Upvotes'    : response['Attributes']['upvotes']\r\n       }\r\n   return {\r\n       'msg'      : \u2018error occurred',\r\n       'response' : response\r\n  }<\/pre>\n<p>Now run the app.py file by using the following command inside the virtual environment <\/p>\n<pre>python app.py<\/pre>\n<p>The entire source code is available here: <a href=\"https:\/\/github.com\/manthantrivedi-bacancy\/flask-dynamoDB-boto3-example\" target=\"_blank\" rel=\"noopener\">flask-dynamoDB-boto3-example<\/a>. Feel free to clone the repository and play around with code.<\/p>\n<h2>Conclusion<\/h2>\n<p>I hope the tutorial for using AWS DynamoDB with Flask APIs and Boto3 was helpful, and you have developed your demo application as well. For more such tutorials, you can visit the <a href=\"https:\/\/www.bacancytechnology.com\/tutorials\/python\" target=\"_blank\" rel=\"noopener\">Python tutorials<\/a> page to explore basic and advanced knowledge. <\/p>\n<p>In case you need any further guidance or a helping hand for your Python application without wasting a second, contact Bacancy and <a href=\"https:\/\/www.bacancytechnology.com\/hire-python-developer\" target=\"_blank\" rel=\"noopener\">hire Python developer<\/a>. We have dedicated and experienced python developers who have optimum problem-solving skills.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In this tutorial, we will build a demo application together; learn about the Flask framework, Boto3 library, REST APIs, and AWS DynamoDB. If you are new at using AWS DynamoDB with Flask APIs and Boto3, don\u2019t worry! We are here to help you learn through this tutorial. Goal: Using AWS DynamoDB with Flask APIs [&hellip;]<\/p>\n","protected":false},"author":54,"featured_media":20825,"comment_status":"open","ping_status":"open","sticky":false,"template":"blog-new-template.php","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[1612],"tags":[],"coauthors":[1670],"class_list":["post-20819","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aws"],"acf":[],"modified_by":"Chandresh Patel","_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/20819","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/comments?post=20819"}],"version-history":[{"count":0,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/20819\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media\/20825"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media?parent=20819"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/categories?post=20819"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/tags?post=20819"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/coauthors?post=20819"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}