Skip to content

Feature/task12 azure function usersId #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

theKunte
Copy link
Contributor

@theKunte theKunte commented Jan 19, 2021

Task: #12

EXPECTED RESULTS FOR API ENDPOINT USERS/{userId}

HTTP request for endpoint users/userid:
Note when changing the id in the URL you will retrieve a different user.
This will show the users that are added to the DB and it is deployed to Azure Functions.

Test Function in Azure

  • Sign in to Azure.

  • Find nsc-function-team1 resource group

  • Select nsc-functionapp-team1

  • In the Navbar on th left select functions and click on HttpTriggerAPIUserId

  • Click on Code + Test on left nav bar

  • Click on function URL and test the function in the URL

  • It will return json {}

  • If it is not working on the first try wait for 30 seconds and try again
    image

  • Test: users/1

Create and deploy Azure Functions from Visual Studio Code:

  1. Create a serverless app in vscode with extensions and python:
  • Prerequisites:

    • Create or use existing Azure Subscription

    • Install software to local workstation:
      - Install the Azure Functions Core Tools in Visual Studio Code
      - Install Python and Visual Studio Code with the Azure Function extension.
      - Sign in to Azure.
      - Verify your environment:
      NOTE: Azure function only work with Python version 3.6, 3.7 and 3.8.
      Reference: https://docs.microsoft.com/en-us/azure/developer/python/tutorial-vs-code-serverless-python-01

       Verify your environment:
       `npm install -g azure-functions-core-tools` 
      
    1. Create a Python function for Azure functions:
      Reference: https://docs.microsoft.com/en-us/azure/developer/python/tutorial-vs-code-serverless-python-02
      Note: When creating a HttpTriger in Visual Studio Code open the function folder in a separate window in Visual Studio Code and create your function in there. This will help to structure your Triggers and keep files in the same folder instead of in the root folder

3. Examine the Python code files in vscode:
Reference:

4. Debug the Azure Functions Python Code locally:

Reference:

5. Deploy Azure Function in Python

Reference: https://docs.microsoft.com/en-us/azure/developer/python/tutorial-vs-code-serverless-python-05

Purpose: This feature implemented the API endpoint for getting a specific user by userId.

TEST PULL REQUEST:

Requirements to set up Azure Function and Deploy them to Azure:

  • Clone repository:
    • Install Azure Functions extension in vscode.

    • Open the functions folder separately in vscode.
      Note: if you have the root repository folder open the azure.function extension will not work.

    • Install Python version 3.8 if you haven't yet

    • Note: Azure function does not work with Python 3.9 See documentation: https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-python

    • Set up environment in vscode/ .venv

    • Sign in to Azure

    • Deploy your functions once you completed all functionality and tested it locally.
      To test it locally and Debug Functions:
      image

Azure Function Setup:

  -  Create a resource group for Azure Function
  -  Deploy your function to Azure from vscode
  -  Note: select correct Subscription

local packages to install:**

 - pip install pypyodbc
 - NOTE: you can also use pyodbc ( This example uses pypyodbc)
 - More Documentation found here: https://medium.com/globant/serverless-applications-with-azure-functions-python-and-docker-b594fb90fd4f
 - https://pypi.org/project/pypyodbc/
 -  pip install azure.function
 - Add these to the required file if they haven't been added automatically 
 - Check for ODBC Driver: 
 This PR is using ODBC Driver 17
 https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver15

Setup local.settings.json

-Access to Azure resources needed to access passwords
resource group: nsc-functions-team1

  • Verify that your local.settings.json file contains the following:

    "FUNCTIONS_WORKER_RUNTIME": "addPasswordHere"
    "ENV_DATABASE_USERNAME": "addPasswordHere"
    "ENV_DATABASE_PASSWORD": "addPasswordHere"
    "ENV_DATABASE_NAME": "addPasswordHere"
    "ENV_DATABASE_SERVER": "addPasswordHere"

Troubleshoot ODBC Driver

Reference:

DATE ACTIVITY TIME
1/9 Research Azure Function examples 60 minutes
1/10 More Research about Azure Function setup and deployment 60 minutes
1/11 Started reading about Azure Functions + Deployment 30 minutes
1/15 Testing Azure Function locally and applied new material from lecture 120 minutes
1/16 Create a resource group in azure and host all functions on one host troubleshoot a bunch! 60 minutes
1/17 connect resource group with DB and connected it correctly luckily! 60 minutes
1/17 Research Azure function implementation and troubleshoot 360 minutes
1/17 More research and troubleshooting 120 minutes
1/18 Additional coding and test function for userId 90 minutes
1/18 Add additional HTTP responses 60 minutes
1/18 Testing 30 minutes
1/18 Deploy functions locally to azure successfull 30 minutes
1/18 Small changes 30 minutes
1/18 Wrote this PR and probably have to update it again :D 45 min
1/19 Reviewed Comments and added changes 120 min
1/19 Met with some of my team to review issues with ODBC 240 min
1/20 Changed API endpoint for users/userId 220 min
1/20 Updated this Documentation 60 min

@theKunte theKunte added the Work-in-Progress Pull Request not ready for review label Jan 19, 2021
@theKunte theKunte added this to the Sprint 01 milestone Jan 19, 2021
@theKunte theKunte self-assigned this Jan 19, 2021
file is not needed
can be deleted
can be deleted
@theKunte theKunte requested a review from toddysm January 19, 2021 03:53
@theKunte theKunte added the team1 Issues for Practicum Team 1 label Jan 19, 2021
@theKunte theKunte linked an issue Jan 19, 2021 that may be closed by this pull request
@theKunte theKunte changed the title Feature/task12 azure function users Feature/task12 azure function usersId Jan 19, 2021
remove functions that are not associated with HttpTriggerAPIUsersId
remove functions that are not associated with HttpTriggerAPIUsersId
remove functions that are not associated with HttpTriggerAPIUsersId
removed .vscode files
removed .vscode files
removed .vscode files
removed .vscode files
remove files that should not be included
remove files that should not be included
remove files that should not be included
remove files that should not be included
remove files that should not be included
remove files that should not be included
@theKunte theKunte removed the Work-in-Progress Pull Request not ready for review label Jan 19, 2021
import azure.functions as func
import json


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to see some comments in this file. I think it would definitely be helpful in identifying what's going on at the different stages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add comments!

connectionString = "Driver={};Server={};Database={};Uid={};Pwd={};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;".format(
driver, db_server, db_name, db_username, db_password)

id = req.params.get('id')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this id for? Whose id is it?

Copy link
Contributor

@farhadbahrehmandhenry farhadbahrehmandhenry Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbrown51 this id is the id that gets passed as a parameter when this function gets called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the userId.
Natalia suggested renaming this "id" to "userId" for clarification. The way I have it right now makes it confusing. Will update it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I think that makes a lot of sense. Currently, it could be misinterpreted as a separate id of some kind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! good practice to keep names for the parameters same across the board. I used userId and taskId in my code

else:
try:
with pypyodbc.connect(connectionString) as conn:
return execute_query(conn, id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would make sense, instead of having "execute_query" to name the function something like "get_user_by_id"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For naming conventions, I would change it to your suggestion. Will update it!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used a generic name here, so that it could be repurposed for different methods (get, update, post, delete)

connectionString = "Driver={};Server={};Database={};Uid={};Pwd={};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;".format(
driver, db_server, db_name, db_username, db_password)

id = req.params.get('id')
Copy link
Contributor

@farhadbahrehmandhenry farhadbahrehmandhenry Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbrown51 this id is the id that gets passed as a parameter when this function gets called.

@nataliagourova
Copy link
Contributor

I tested the functionality via the test tool on Azure, works as expected. Overall, it'd be great to see more comments to help those who continue to develop the API down the road.

# https://stackoverflow.com/questions/16519385/output-pyodbc-cursor-results-as-python-dictionary/16523148#16523148
columns = [column[0] for column in cursor.description]
data = dict(zip(columns, row))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the sources I looked into mention closing the connection after you open, such as cursor.close() and conn.close()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment did not get attached to the correct line. connection needs to be closed after the query executes

Copy link
Contributor

@nataliagourova nataliagourova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline comments

Copy link
Contributor

@lbrown51 lbrown51 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks great. All my comments were addressed :)

@nataliagourova nataliagourova self-requested a review January 21, 2021 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team1 Issues for Practicum Team 1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TASK] Implement Azure Function for users/{user_id} API
5 participants