{"id":15280,"date":"2021-05-26T16:54:21","date_gmt":"2021-05-26T20:54:21","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=15280"},"modified":"2021-06-14T06:49:58","modified_gmt":"2021-06-14T10:49:58","slug":"graphql-flask-jwt-sqlalchemy","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/graphql-flask-jwt-sqlalchemy\/","title":{"rendered":"Flask app with a GraphQL API, JWT Authentication and SQLAlchemy"},"content":{"rendered":"<p>I wrote (and open sourced) a <a href=\"https:\/\/github.com\/qxf2\/qxf2-employees\">Flask app with a GraphQL API<\/a> that was implemented using <a href=\"https:\/\/graphene-python.org\/\">Graphene<\/a>. The application is similar to the <a href=\"https:\/\/docs.graphene-python.org\/projects\/sqlalchemy\/en\/latest\/tutorial\/\">official Graphene example<\/a> but includes the following:<\/p>\n<p>1. JWT authentication<br \/>\n2. An example of filtering<br \/>\n3. A minimal amount of data for people to tinker with the app<\/p>\n<p>This article is suitable for:<br \/>\na) Testers looking to get started with writing GraphQL queries, using GraphiQL and the mod-header plugin and (optionally) Python<br \/>\nb) Developers looking for an example of a Flask app that implements a GraphQL API along with authentication<\/p>\n<p><b>Note to developers<\/b>: I am not a developer! Treat the code I have shared as a beginner-level introduction to Flask + Graphene + GraphQL filtering + SQLAlchemy + JWT authentication. The only reason I am sharing my application code is because I did not find a full working example online that showed authentication, filtering along with the data for a Flask application.<\/p>\n<hr>\n<h3>Outline of the post<\/h3>\n<p>We will be covering the following steps in this post. Developers can stop at the end of step 1. QA folks can play along through the end. As you read through this post, <span style=\"color:blue;\">commands<\/span> and <span style=\"color:blue;\">filenames<\/span> will be in <span style=\"color:blue;\">blue<\/span>.<\/p>\n<p><a href='#env_setup'>1. Environment setup<\/a><br \/>\n&nbsp;&nbsp;1a. Get code and install dependencies<br \/>\n&nbsp;&nbsp;1b. Setup the data<br \/>\n&nbsp;&nbsp;1c. Add credentials<br \/>\n&nbsp;&nbsp;1d. Start the application<\/p>\n<p><a href='#GraphQL_query_GraphiQL'>2. GraphQL query using GraphiQL<\/a><br \/>\n&nbsp;&nbsp;2a. Install ModHeader plugin<br \/>\n&nbsp;&nbsp;2b. Authentication<br \/>\n&nbsp;&nbsp;2c. Query all employees<br \/>\n&nbsp;&nbsp;2d. Query based on a field<\/p>\n<p><a href='#GraphQL_query_Python'>3. GraphQL query using Python<\/a><\/p>\n<hr>\n<h3><a id='env_setup'>1. Environment setup<\/a><\/h3>\n<p>This section will let you run the Flask app with a simple GraphQL API. The instructions here are explicit to help beginners. I assume you have git setup along with Python 3.7 (or higher) and <a href=\"https:\/\/pypi.org\/project\/virtualenv\/\">virtualenv<\/a>.<\/p>\n<h4>1a. Get code and install dependencies<\/h4>\n<p>i. Clone the repo using the command: <span style=\"color:blue;\">git clone https:\/\/github.com\/qxf2\/qxf2-employees.git<\/span>.<br \/>\nii. Once you have cloned the repo <span style=\"color:blue;\">cd qxf2-employees\/<\/span> to get into the root directory of the repository.<br \/>\niii. Next, create a virtual environment for this project with the command <span style=\"color:blue;\">virtualenv -p python3.8 venv-employee-database<\/span>.<br \/>\niv. Activate your virtual environment <span style=\"color:blue;\">source venv-employee-database\/Scripts\/activate<\/span> (Windows) or <span style=\"color:blue;\">source venv-employee-database\/bin\/activate<\/span> (*nix).<br \/>\nv. Install the dependencies using the command <span style=\"color:blue;\">pip install -r requirements.txt<\/span>. <\/p>\n<p>At this stage, you have gotten the code and setup the dependencies.<\/p>\n<h4>1b. Setup the data<\/h4>\n<p>I have shipped some data with the repository. Let us set it up in a <a href=\"https:\/\/www.sqlite.org\/index.html\">SQLite<\/a> database. To do that, create a new database using the command <span style=\"color:blue;\">sqlite3 data\/employee_database.sqlite3<\/span>. This will give you a sqlite prompt. In that prompt, enter the following commands<\/p>\n<p>i. Get ready to import csv: <span style=\"color:blue;\">.mode csv<\/span><br \/>\nii. Import the data: <span style=\"color:blue;\">.import data\/dummy_data.csv employee<\/span><br \/>\niii. Verify the data was imported right: <span style=\"color:blue;\">select * from employee;<\/span> &#8230; this step should show you two rows.<br \/>\niv. Quit <span style=\"color:blue;\">.quit<\/span><\/p>\n<p>Carefully observe the output of step iii above. It will show you that the data has two rows and several columns. We will be querying this data via the GraphQL API.<\/p>\n<p>Now, you should have a <code>data\/employee_database.sqlite3<\/code> file present with some data in it. The hardest parts of the setup are over. <\/p>\n<h4>1c. Add credentials<\/h4>\n<p>Let us add a couple of credentials. One for the app secret. Another to setup a user to query the GraphQL API.<\/p>\n<p>i. Update the file <span style=\"color:blue;\">employees\/secret.py<\/span> with any secret string you want to use.<br \/>\nii. Next, create a file called <span style=\"color:blue;\">employees\/allowed_users.py<\/span><br \/>\niii. Add one line to the file created in step ii (a Python dictionary) <span style=\"color:blue;\">USERS = {&#8220;user1&#8221;: &#8220;password1&#8221;}<\/span>.<\/p>\n<h4>1d. Start the application<\/h4>\n<p>Now, you are ready to start the application.<\/p>\n<p>i. Run the command <span style=\"color:blue;\">python run.py<\/span>.<br \/>\nii. You should see a console message letting you know that the application has started on localhost:5000.<br \/>\niii. To verify, launch your browser and visit <span style=\"color:blue;\">http:\/\/localhost:5000\/graphql<\/span>.<br \/>\niv. If all goes well, you should see the GraphiQL editor.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.03.28-PM-1024x115.png\" alt=\"graphiql editor\" width=\"900\" height=\"101\" class=\"aligncenter size-large wp-image-15293\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.03.28-PM-1024x115.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.03.28-PM-300x34.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.03.28-PM-768x86.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.03.28-PM.png 1426w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<hr>\n<h3><a id='GraphQL_query_GraphiQL'>2. GraphQL queries using GraphiQL<\/a><\/h3>\n<p>The tool you saw at the end of the setup (on \/graphql) is called GraphiQL (pronounced graphical). It is a web interface that lets you query the GraphQL API. You can think of it as the equivalent of a primitive Postman for GraphQL APIs. <\/p>\n<p><b>Note 1:<\/b> Hey, testers &#8211; your developers will give you the API being exposed and the fields that can be queried. So as you go through these examples, do not worry if you do not know where some of the syntax comes from. <\/p>\n<p><b>Note 2:<\/b> For the really curious ones, the fields exposed comes from employees\/model.py and the query names come from employees\/schema.py. For both, you will need to get rid of the underscore and use camel case. E.g.: github_id becomes githubId. <\/p>\n<h4>2a. Install ModHeader plugin<\/h4>\n<p>Our application uses JWT authentication and the token is passed via the header. So before we dive into writing queries, let us add a browser plugin that lets us modify the header. I chose the <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/modheader\/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=en\">ModHeader<\/a> extension.<\/p>\n<h4>2b. Authentication<\/h4>\n<p>Once you have the ModHeader plugin, first authenticate with the server and receive a token. To do that, in your GraphiQL editor, paste the following:<\/p>\n<pre lang=\"javascript\">\r\nmutation {\r\n    auth(username: \"user1\", password: \"password1\") {\r\n        accessToken\r\n        refreshToken\r\n        }\r\n}\r\n<\/pre>\n<p>This should return an access token as well as a refresh token. Your GraphiQL editor should look like the screenshot below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.40.46-PM-1024x258.png\" alt=\"GraphiQL JWT authenticate\" width=\"900\" height=\"227\" class=\"aligncenter size-large wp-image-15297\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.40.46-PM-1024x258.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.40.46-PM-300x76.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.40.46-PM-768x193.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.40.46-PM.png 1430w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<p>Copy the access token. Open your ModHeader extension, add a <span style=\"color:blue;\">Authorization<\/span> header and paste the strong <span style=\"color:blue;\">Bearer access_token<\/span> as the value where <span style=\"color:blue;\">access_token<\/span> is the value of your access token. Your ModHeader plugin should look something like the screenshot below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.48.06-PM.png\" alt=\"ModHeader Authorization\" width=\"624\" height=\"186\" class=\"aligncenter size-full wp-image-15300\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.48.06-PM.png 624w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.48.06-PM-300x89.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/p>\n<p>Now you are set to make queries. Our application exposes just two queries. One to query all employees. Another to query employees based on a given email or Skype id.<\/p>\n<h4>2c. Query for all employees<\/h4>\n<p>Let us query for all employees and get their email, id, join date, if they are active and their author name fields. To query all employees, use the following snippet in your GraphiQL editor<\/p>\n<pre lang=\"javascript\">\r\nquery findAllEmployees{\r\n    allEmployees{\r\n        edges{\r\n            node{\r\n                email\r\n                employeeId\r\n                dateJoined\r\n                isActive\r\n                blogAuthorName\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>One way to understand this query is that <span style=\"color:blue;\">allEmployees<\/span> is the query exposed by the GraphQL API and will usually be given to you by the developer. You are creating a named query called findAllEmployees (you can use any name here) and then within it, calling <span style=\"color:blue;\">allEmployees<\/span>. You want only some properties of the employee node. To do that you add a <span style=\"color:blue;\">node<\/span> element and list the properties of employees that you want &#8211; email, employee id, join date, etc.<\/p>\n<p>If you have setup ModHeader correctly, you should see an output similar to the screenshot below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.50.07-PM-1024x381.png\" alt=\"GraphQL all employees\" width=\"900\" height=\"335\" class=\"aligncenter size-large wp-image-15301\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.50.07-PM-1024x381.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.50.07-PM-300x112.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.50.07-PM-768x286.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-27-at-11.50.07-PM.png 1425w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/p>\n<h4>2d. Query based on a field<\/h4>\n<p>Finally, let us filter the employees table based on email and find that employee&#8217;s Skype id and GitHub id. To do that, execute the following snippet:<\/p>\n<pre lang=\"javascript\">\r\nquery FindEmployeeByEmail($email: String = \"lasker@qxf2.com\") {\r\n    findEmployee(email: $email) {\r\n        githubId\r\n        skypeId\r\n    }\r\n}\r\n<\/pre>\n<p>One way to understand this query is that <span style=\"color:blue;\">findEmployee<\/span> is the query exposed by the GraphQL API and will be usually given to you by the developer. This <span style=\"color:blue;\">findEmployee<\/span> takes one parameter called email. Since emails are unique, the API will return at most one node. You are creating a query called FindEmployeeByEmail (call it whatever you want!) that passes $email to the <span style=\"color:blue;\">findEmployee<\/span> query. You are also saying you just want the employee&#8217;s Skype and GitHub ids.<\/p>\n<p>If all goes well, you should see the following output:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-28-at-12.07.15-AM-1024x175.png\" alt=\"GraphQL filter by email\" width=\"900\" height=\"154\" class=\"aligncenter size-large wp-image-15302\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-28-at-12.07.15-AM-1024x175.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-28-at-12.07.15-AM-300x51.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-28-at-12.07.15-AM-768x132.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-28-at-12.07.15-AM.png 1425w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/> <\/p>\n<hr>\n<h3><a id='GraphQL_query_Python'>3. GraphQL query using Python<\/a><\/h3>\n<p>We can do the same things using Python and <a href=\"https:\/\/pypi.org\/project\/requests\/\">requests<\/a> too. Accessing a GraphQL API using the requests module is very similar to accessing a REST API using the requests module. We just pass the query as part of the json argument to requests.some_http_method(). I will not explain the code here since this article is already pretty long. But this is an example Python script I wrote to query all employees. Hopefully, you notice that this is just an auth step plus a GET request that passes a query parameter that looks pretty much exactly like the query you would write on a GraphiQL editor. <\/p>\n<h4>File 1: sample_gql_query.py<\/h4>\n<pre lang=\"python\">\r\n\"\"\"\r\nTest to query the Employee GraphQL endpoint\r\n\"\"\"\r\nimport requests\r\nimport json\r\nimport user_credentials as credentials\r\nBASE_URL = 'http:\/\/localhost:5000\/graphql'\r\n\r\ndef authenticate():\r\n    \"Return an authenticate code\"\r\n    query = f\"\"\"mutation {{\r\n        auth(password: \"{credentials.PASSWORD}\", username: \"{credentials.USERNAME}\") {{\r\n            accessToken\r\n            refreshToken\r\n            }}\r\n        }}\r\n    \"\"\"\r\n    response = requests.post(url = BASE_URL, json = {'query': query})\r\n\r\n    return response.json().get('data',{}).get('auth',{}).get('accessToken',None)\r\n\r\ndef test_query_all():\r\n    \"Query allEmployees\"\r\n    query = \"\"\"query\r\n    findAllEmployees{\r\n        allEmployees{\r\n            edges{\r\n                node{\r\n                    email\r\n                    employeeId\r\n                    dateJoined\r\n                    isActive\r\n                    blogAuthorName\r\n                }\r\n            }\r\n        }\r\n    }\"\"\"\r\n    access_token = authenticate()\r\n    print(f'Access token: {access_token}')\r\n    headers = {'Authorization': f'Bearer {access_token}'}\r\n    response = requests.get(url = BASE_URL, json = {'query': query}, headers =\\\r\n        headers)\r\n    all_employees = response.json().get('data', {}).get('allEmployees', {}).get('edges', [])\r\n    for employee in all_employees:\r\n        print(employee)\r\n\r\n\r\n#---START OF SCRIPT\r\nif __name__==\"__main__\":\r\n    test_query_all()\r\n<\/pre>\n<h4>File 2: user_credentials.py<\/h4>\n<p>Place this file in the same folder as File 1 (sample_gql_query.py).<\/p>\n<pre lang=\"python\">\r\nUSERNAME='user1'\r\nPASSWORD='password1'\r\n<\/pre>\n<p>Note 1: You should not be authenticating with every request. Authenticate once and the token will be valid for 30-minutes.<br \/>\nNote 2: You will decide the data structure used in File 2 (user_credentials.py) depending upon the number of users that your tests need. For only one user, what is shown here is more than enough.<\/p>\n<hr>\n<p>Hopefully you managed to follow along to the end. If you are very new to GraphQL, you are probably feeling like you did not understand head or tail of what just happened. That&#8217;s ok &#8211; what you just did now forms a solid base for you to start understanding the more theoretical introductions to GraphQL that are available on the Internet. There are also some excellent practical examples for larger datasets (e.g.: movies) that you are (hopefully!) now in a position to tackle better. Some possible next steps for you include Googling how to construct queries, understand mutations, figure out the GraphQL API by looking at code, etc.<\/p>\n<p>If you got stuck in any of the steps, post a comment below and someone from Team Qxf2 will help you out!<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>I wrote (and open sourced) a Flask app with a GraphQL API that was implemented using Graphene. The application is similar to the official Graphene example but includes the following: 1. JWT authentication 2. An example of filtering 3. A minimal amount of data for people to tinker with the app This article is suitable for: a) Testers looking to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[172,288,287],"tags":[],"class_list":["post-15280","post","type-post","status-publish","format-standard","hentry","category-flask","category-gql","category-graphql"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=15280"}],"version-history":[{"count":29,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15280\/revisions"}],"predecessor-version":[{"id":15321,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15280\/revisions\/15321"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=15280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=15280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=15280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}