How to locally test a dockerized app connected with AWS lambda - python

Sorry Docker starter question here.
I'm currently trying to build an app with Python using FastApi and dockerize it. When it's dockerized I will connect it to an AWS Lambda. The problem is, how can I test my Lambda before deploying it to ECR?
I already tried to use the local Lambda invoke with: localhost:9000/2015-03-31/functions/function/invocations and create a post request reading a file:
{
"resource": "/",
"path": "/upload/",
"httpMethod": "POST",
"requestContext": {},
"multiValueQueryStringParameters": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json" },
"body": { "filename": "image.jpg" },
"files": { "upload": "image.jpg" }
}
I don't get it to work...
Code:
#app.post("/upload/")
async def upload_image(request: Request):
print(request)
print(await request.json())
print(await request.body())
return {"received_request_body": request.json()}
handler = Mangum(app)

Does your container image include the runtime interface emulator (RIE)? Did you build and run the container image? Take a read through the following reference:
https://docs.aws.amazon.com/lambda/latest/dg/images-test.html
You might also check out AWS SAM CLI, which offers a nice workflow for local build and test of Lambda functions.
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html

I am not sure about your complete infra.But based on the above given limited information I am trying to answer.
You can test lambda independently with test events.You can do this from either AWS console or from cli (aws lambda invoke).
Reference:
https://docs.aws.amazon.com/lambda/latest/dg/testing-functions.html
But if you want to test it with api then use api gateway along with your lambda which will expose it as an endpoint.Then you can test your lambda which ever way you are comfortable(like curl command/postman etc..)
Reference
Api Gateway with lambda
Navigation for test event from Lambda console
Test event for Lambda screenshot

Related

Flasgger does not load when hostname has a path

I have a Flask application and I've integrated Flasgger for documentation. When I run my app locally, I can access swagger at http://127.0.0.1:5000/apidocs. But when it's deployed to our dev environment, the hostname is https://services.company.com/my-flask-app. And when I add /apidocs at the end of that URL, swagger does not load.
This is how I've configured swagger:
swagger_config = {
"headers": [],
"specs": [
{
"endpoint": "APISpecification",
"route": "/APISpecification",
"rule_filter": lambda rule: True, # all in
"model_filter": lambda tag: True, # all in
}
],
"static_url_path": "/flasgger_static",
"specs_route": "/apidocs/",
"url_prefix": "/my-flask-app", # TODO - redo this for INT deployment
}
When I run this, on my local I can access swagger at http://127.0.0.1:5000/my-flask-app/apidocs/#/, but I think on my dev environment it'd probably be accessible at https://services.company.com/my-flask-app/my-flask-app/api-docs. When I check the console, Flasgger tries to get the css from https://services.company.com/ not https://services.company.com/my-flask-app
Any ideas on how I can resolve this?

Azure functions app keeps returning 401 unauthorized

I have created an Azure Function base on a custom image (docker) using VS Code.
I used the deployment feature of VS code to deploy it to azure and everything was fine.
My function.json file specifies anonymous auth level:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
Why an I still getting the 401 unauthorized error?
Thanks
Amit
I changed my authLevel from function to anonymous and it finally worked!
Below methods can fix 4XX errors in our function app:
Make sure you add all the values from Local.Settings.json file to Application settings (FunctionApp -> Configuration -> Application Settings)
Check for CORS in your function app. Try adding “*” and saving it.. reload the function app and try to run it.
(Any request made against a storage resource when CORS is enabled must either have a valid authorization header or must be made against a public resource.)
When you make your request to your function, you may need to pass an authorization header with key 'x-functions-key' and value equal to either your default key for all functions (Function App > App Keys > default in the Azure portal) or a key specific to that function (Function App > Functions > [specific function] > Function Keys > default in Azure Portal).

Creating rest api with get method using AWS amplify, with a python lambda function

Is there a way to set up a rest api using a python lambda function with a get method that uses query parameters by using the amplify CLI or editing the code?
I know this can be done through the AWS Management Console, but was hoping for a more code-oriented solution. Below is the sample lambda I'm trying to use and a simple example of how I would like to get different api responses (length of dummy text string) based on the get method called by the api using something like "curl https://......../myapi?length=4"
import json
def handler(event, context):
print('received event:')
str_len = event['queryStringParameters']['length']
body = {
"message" : "DUMMY TEST"[1:str_len]
}
response = {
"statusCode" : 200,
"body" : json.dumps(body),
"headers" : {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
}
}
return response

How to setup AWS SAM local debugging with Python on Visual Studio Code?

I was trying to use the debugging function for lambda (python) in Visaul Studio Code. I was following the instructions on AWS Docs, but I could not trigger the python applicaion in debug mode.
Please kindly see if you know the issue and if I have setup anything incorrectly, thanks.
Reference:
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-debugging.html
Observation
Start application
Seems application was not started on the debug port specified?
Request call
The endpoint could not be reached and python application was not entered
If accessed through port 3000, application could complete successfully
Setup performed
Initialize the project and install ptvsd as instructed
Enable ptvsd on the python code
Add launch configuration
Project structure
Python source
This is basically just the offical helloworld sample for python
import json
# import requests
import ptvsd
# Enable ptvsd on 0.0.0.0 address and on port 5890 that we'll connect later with our IDE
ptvsd.enable_attach(address=('localhost', 5890), redirect_output=True)
ptvsd.wait_for_attach()
def lambda_handler(event, context):
"""Sample pure Lambda function
Parameters
----------
event: dict, required
API Gateway Lambda Proxy Input Format
Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
context: object, required
Lambda Context runtime methods and attributes
Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
Returns
------
API Gateway Lambda Proxy Output Format: dict
Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
"""
# try:
# ip = requests.get("http://checkip.amazonaws.com/")
# except requests.RequestException as e:
# # Send some context about this error to Lambda Logs
# print(e)
# raise e
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
# "location": ip.text.replace("\n", "")
}),
}
Launch configuration
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "SAM CLI Python Hello World",
"type": "python",
"request": "attach",
"port": 5890,
"host": "localhost",
"pathMappings": [
{
"localRoot": "${workspaceFolder}/hello_world/build",
"remoteRoot": "/var/task"
}
]
}
]
}
It seems I was editing the python file at "python-debugging/hello_world/build" following the guideline of the doc (there is a step in the doc which asks you to copy the python file to "python-debugging/hello_world/build").
But then when you run "sam local start-api", it actually runs the python file at the location specifed by the CloudFormation template (tempalted.yaml), which is at "python-debugging/hello_world" (check the "CodeUri" property).
When I moved all the libriaries to the same folder as the python file it works.
So I suppose you have to make sure which python (or lambda) script you are running, and ensure the libraries are together with the python script (if you are not using layers).
Folder structure
Entering debugging mode in Visual studio code
Step 1: Invoke and start up the local API gateway
Server
Step 2: Send a test request
Client
Step 3: Request received, lambda triggered, pending activating debug mode in Visual Studio Code
Server
Step 4: Lambda function triggered, entering debug mode in Visual Studio Code
In the IDE, open the "Run" perspective, select the launch config for this file ("SAM CLI Python Hello World"). Start the debug.
Step 5: Step through the function, return response
Server
Client

How can I create and manage a Lambda Function from Python Script?

I would like to manage my AWS Lambda Functions from Python script, without having to use the AWS Website Console. The idea is to be able to quickly recreate/migrate/setup my applications objects (tables, functions etc.) into a new AWS Cloud Account or Region.
It is easy to do this with DynamoDB tables, for instance:
import boto3
resource = boto3.resource(service_name='dynamodb', region_name='region', ...)
resource.create_table(
TableName='table_name',
KeySchema=[...],
AttributeDefinitions={...},
ProvisionedThroughput={...}
)
Done! I just created a new DynamoDB table from Python Script. How can I do the same for Lambda Functions? Say... create a new function, configure ‘Function Name’ and ‘Runtime’, maybe set up a ‘Role’ and upload a script from file. That’d be really helpful.
Thanks in advance.
To create lambda function using boto3, you can use create_function.
The AWS docs also provide an example of how to use the create_function:
response = client.create_function(
Code={
'S3Bucket': 'my-bucket-1xpuxmplzrlbh',
'S3Key': 'function.zip',
},
Description='Process image objects from Amazon S3.',
Environment={
'Variables': {
'BUCKET': 'my-bucket-1xpuxmplzrlbh',
'PREFIX': 'inbound',
},
},
FunctionName='my-function',
Handler='index.handler',
KMSKeyArn='arn:aws:kms:us-west-2:123456789012:key/b0844d6c-xmpl-4463-97a4-d49f50839966',
MemorySize=256,
Publish=True,
Role='arn:aws:iam::123456789012:role/lambda-role',
Runtime='nodejs12.x',
Tags={
'DEPARTMENT': 'Assets',
},
Timeout=15,
TracingConfig={
'Mode': 'Active',
},
)
print(response)

Categories

Resources