Accessing data POST'd to a python AWS Lambda Function URL - aws-lambda

I'm attempting to invoke an AWS Lambda Function URL in Python. Using their example lambda code as follows the value for action is always returning null. How do I access the value in the json data I POST to the Function URL?
Lambda Code (taken from here):
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
result = None
action = event.get('action')
if action == 'increment':
result = event.get('number', 0) + 1
logger.info('Calculated result of %s', result)
else:
logger.error("%s is not a valid action.", action)
response = {'result': result}
return response
Invoking using a Function URL
curl -X POST 'https://[redacted].lambda-url.eu-west-1.on.aws/' -d '{"action":"increment","number": 3}'
Result:
{"result":null}
Problem:
How do I reference the value of 'action' correctly to produce the result?

Out of interest, this is how I adapted the AWS sample code to parse the required fields
import logging
import json
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
message = json.loads(event['body'])
result = None
action = message['action']
if action == 'increment':
result = message['number'] + 1
logger.info('Calculated result of %s', result)
else:
logger.error("%s is not a valid action.", action)
response = {'result': result}
return response

Related

My function does not execute when using await in a async function pyscript

I try to fetch data from my api in python using pyscript. Following the pyscript documentation I use the async keyword on my main function and use asyncio.ensure_future to execute it, everything before the first await work but not the await keyword and any other line of code after it.
This is my code:
async def request(url: str,
method: str = "GET",
body: Optional[str] = None,
headers: Optional[dict[str, str]] = None,
**fetch_kwargs: Any) -> FetchResponse:
kwargs = {
"method": method,
"mode": "no-cors"
} # CORS: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
if body and method not in ["GET", "HEAD"]:
kwargs["body"] = body
if headers:
kwargs["headers"] = headers
kwargs.update(fetch_kwargs)
response = await pyfetch(url, **kwargs)
return response
async def get_barycenter(
filename: str,
base_url: str = "http://localhost:8001") -> dict[str, Any] | None:
headers = {"Content-type": "application/json"}
response = await request(f"{base_url}/barycenter/?image_name={filename}",
headers=headers)
body = await response.json()
if body.status != 200:
return None
return body.msg
async def main():
print('start')
test = await get_barycenter("img.jpg")
print(test)
print("end")
asyncio.ensure_future(main())
The result is only the print of start and nothing else no print of test are even "end".
I tested the API the data is visible in Insomnia and I set up correctly the cors Policy.
Part of the issue here is an existing issue in PyScript where exceptions raised in Coroutines aren't displayed on the page. To help with this for now, I would recommend adding the following snippet before your request function:
import js
def handler(loop, context):
js.console.error(context.message)
raise(context.exception)
pyscript.loop.set_exception_handler(handler)
This way, exceptions raised in coroutines are displayed in the browser's console log.
What the root issue of the the fetch request is I couldn't say, but at least this will get errors displaying and help you troubleshoot. For example, when I run your code, I see:
GET http://localhost:8001/barycenter/?image_name=img.jpg net::ERR_CONNECTION_REFUSED
Since I don't have a local server running - hopefully the errors that appear for you are more helpful.

Downloading File in Parallelwith Asyncio

I trying to pull Avro files from an API link while using Asyncio. Currently it just returns nothing if the link is to an avro file - while all my other API calls which pull json data work. What am I missing?
credentials = {'authorization': XXXXX}
async def get_data(link, session,creds)-> None:
async with session.get(url, url=link, headers=credential) as res:
content = await res.read()
r = await session.request('GET', url=str(link), headers=creds)
data = await r
return
async def data_distributor_function(credential)-> None:
async with aiohttp.ClientSession() as session:
link_list = ["https://.....","https://.....","https://.....","https://.....","https://....."]
tasks = []
for link in link_list:
tasks.append(wait_for(get_data( link=link, session=session,creds=credential),timeout=10))
results = await asyncio.gather(*tasks, return_exceptions=True)
return
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
data = asyncio.run(data_distributor_function(credential),debug=True)
If I don't do the API call in asyncio, I can just use a standard request and it works (it's just slow).
reply = requests.request("GET", link, credentials)

Python Asyncio: Am I Awaiting too much?

I've been grokking some of my sample async code and I'm struggling to understand the flow of the data and how often I find myself awaiting.
Am I using await correctly? Also - are my output types correct? I'd imagine some these should be outputting coroutines (but my Pyright/Pylance type hinting keeps telling me that's wrong...)
The functions that require inspection are governed requests, send, governed_send, and governed_sendall. Maybe I'm not understanding what await is doing completely - and how this interacts with function scopes.
The code works correctly; I'd like to understand why and whether I can optimize out some of these awaits or if that's unnecessary.
import time
import asyncio
import httpx
from typing import Any, Callable, Coroutine, Dict, List
from rich import print
class GovernedClient:
def __init__(self):
self.client = httpx.AsyncClient()
self.loop = asyncio.get_event_loop()
self.semaphore = asyncio.BoundedSemaphore(4)
def __del__(self) -> None:
# Define a destructor that closes the client and the loop.
async def close(self: GovernedClient) -> None:
# An async function is required to await aclose
await self.client.aclose()
self.loop.run_until_complete(close(self))
self.loop.close()
def govern_requests(fn: Callable) -> Callable:
# govern_requests applies semaphore locking to a given callable.
async def call(self, *args, **kwargs):
async with self.semaphore:
return await fn(self, *args, **kwargs)
return call
async def send(self, method: str, url: str) -> httpx.Response:
# A single send.
request = httpx.Request(method, url, headers={'accept': 'application/json'})
return await self.client.send(request)
#govern_requests
async def governed_send(self, method: str, url: str) -> httpx.Response:
# Applies semaphore locking via decorator.
return await self.send(method, url)
def governed_sendall(self, urls: List[str]) -> List[httpx.Response]:
async def goverened_sendall(urls: List[str]) -> List[httpx.Response]:
start = time.time()
awaitables = [self.governed_send('GET', url) for url in urls]
responses = []
for response in asyncio.as_completed(awaitables):
responses.append(await response)
print('Total time: ', int(1000 * (time.time() - start)))
return responses
return self.loop.run_until_complete(goverened_sendall(urls))
if __name__ == '__main__':
URL = 'https://www.icanhazdadjoke.com'
bc = GovernedClient()
urls = [URL for url in range(20)]
responses = bc.governed_sendall(urls)
for response in responses:
print(response.json())
You know that async is a function that will not block the code. Right?
You know that await is an async function caller that when called it will not block the code. Right?
So There's no using too much async/await because if you using it it will not blocking your code unlike def and functioname().
I guess you may understand.
Happy day!

Passing pk in a get request function

I am new to Django so I figure this question could be a bit stupid.I have an api endpoint that returns a list of Doctors(and their details) and another that returns one doctor(and his details)-this is the call am trying to make.I think the issue I am having is with how to ref the pk in the request url.
As it is, when I test on postman I get the error {
"errors": "JSONDecodeError('Expecting value: line 1 column 1 (char 0)',)",
"status": "error"
}
I am almost certain the issue is in api_services.py.I really hope someone can just point it out to me.
views.py
`class FinanceDoctorsView(GenericAPIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
#classmethod
#encryption_check
def get(self, request, *args, **kwargs):
response = {}
pk = kwargs.get("pk")
try:
result = {}
auth = cc_authenticate()
res = getDoctorInfo(auth["key"], pk)
result = res
return Response(result, status=status.HTTP_200_OK)
except Exception as e:
error = getattr(e, "message", repr(e))
result["errors"] = error
result["status"] = "error"
return Response(result, status=status.HTTP_400_BAD_REQUEST)`
api_services.py
import requests
def getDoctorInfo(auth, params):
print("getting doctorInfo from Callcenter")
try:
headers = {
"Authorization": f'Token {auth}'
}
url = f'{CC_URL}/finance/doctor-info/<int:pk>'
res = requests.get(url, headers=headers)
print("returning doctorInfo response", res.status_code)
return res.json()
except ConnectionError as err:
print("connection exception occurred")
print(err)
return err
urls.py
path(
"doctor-info/<int:pk>", views.FinanceDoctorsView.as_view(), name="doctor_info"
),
I think in the api service file, you have made a typo
url = f'{CC_URL}/finance/doctor-info/<int:pk>'
Should had be
# as in the function you have defined params,
# and I think it could have been renamed as pk
url = f'{CC_URL}/finance/doctor-info/{params}'

Python Socket.io event handling

I'm a complete beginner when it comes to socket, so please bear with me if the question seems too trivial for you.
The following is a code that i found on GitLab and I'm trying to understand
import os
import logging
import uuid
import socketio
from aiohttp import web
import sys
sys.path.append('.')
logging.basicConfig(level=logging.WARN,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M')
# Home page
async def index(request):
index_file = open('examples/rasa_demo/templates/index.html')
return web.Response(body=index_file.read().encode('utf-8'), headers={'content-type': 'text/html'})
# Action endpoint
async def webhook(request):
"""Webhook to retrieve action calls."""
action_call = await request.json()
try:
response = await executor.run(action_call)
except ActionExecutionRejection as e:
logger.error(str(e))
response = {"error": str(e), "action_name": e.action_name}
response.status_code = 400
return response
return web.json_response(response)
# Web app routing
app = web.Application()
app.add_routes([
web.get('/', index),
web.post('/webhook', webhook),
web.static('/static', 'examples/rasa_demo/static')
])
# Instantiate all bot agents
bots = BotFactory.createAll()
# Websocket through SocketIO with support for regular HTTP endpoints
sio = socketio.AsyncServer(async_mode='aiohttp', cors_allowed_origins='*')
sio.attach(app)
#sio.on('session_request')
async def on_session_request(sid, data):
if data is None:
data = {}
if 'session_id' not in data or data['session_id'] is None:
data['session_id'] = uuid.uuid4().hex
await sio.emit('session_confirm', data['session_id'])
#sio.on('user_uttered')
async def on_user_uttered(sid, message):
custom_data = message.get('customData', {})
lang = custom_data.get('lang', 'en')
user_message = message.get('message', '')
bot_responses = await bots[lang].handle_text(user_message) #await BotFactory.getOrCreate(lang).handle_text(user_message)
for bot_response in bot_responses:
json = __parse_bot_response(bot_response)
await sio.emit('bot_uttered', json, room=sid)
What I'm trying to understand is how do the event handlers catch or events like 'session_request' or'user_uttered' when they were never emitted.
Thank you.

Resources