Skip to content

Instantly share code, notes, and snippets.

@marcogrcr
Last active April 19, 2024 03:03
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marcogrcr/6f0645b20847be4ef9cd6742427fc97b to your computer and use it in GitHub Desktop.
Save marcogrcr/6f0645b20847be4ef9cd6742427fc97b to your computer and use it in GitHub Desktop.
Send request with SigV4 in python using boto3
from boto3.session import Session
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.credentials import Credentials
from http.client import HTTPConnection, HTTPSConnection
import json
import os
from urllib.parse import urlparse
def sigv4_request(
url,
method='GET',
body=None,
params=None,
headers=None,
service='execute-api',
region=os.environ['AWS_REGION'],
credentials=Session().get_credentials().get_frozen_credentials()
):
"""Sends an HTTP request signed with SigV4
Args:
url: The request URL (e.g. 'https://www.example.com').
method: The request method (e.g. 'GET', 'POST', 'PUT', 'DELETE'). Defaults to 'GET'.
body: The request body (e.g. json.dumps({ 'foo': 'bar' })). Defaults to None.
params: The request query params (e.g. { 'foo': 'bar' }). Defaults to None.
headers: The request headers (e.g. { 'content-type': 'application/json' }). Defaults to None.
service: The AWS service name. Defaults to 'execute-api'.
region: The AWS region id. Defaults to the env var 'AWS_REGION'.
credentials: The AWS credentials. Defaults to the current boto3 session's credentials.
Returns:
The HTTP response
"""
# sign request
req = AWSRequest(
method=method,
url=url,
data=body,
params=params,
headers=headers
)
SigV4Auth(credentials, service, region).add_auth(req)
req = req.prepare()
# parse URL
u = urlparse(req.url)
path_and_query = u.path if u.query is None else u.path + '?' + u.query
# send request
cnn = HTTPSConnection(u.hostname) if u.scheme == 'https' else HTTPConnection(u.hostname)
cnn.request(
req.method,
path_and_query,
headers=req.headers,
body=req.body
)
return cnn.getresponse()
def __init__():
# send request
response = sigv4_request(
'https://www.example.com',
method='POST',
headers={
'content-type': 'application/json',
},
body=json.dumps({
'foo': 'bar'
}),
region='us-west-2',
credentials=Credentials(
'ACCESS_KEY_ID',
'SECRET_ACCESS_KEY',
'SESSION_TOKEN'
)
)
# do something with response
print(response.status)
print(json.loads(response.read().decode()))
from boto3.session import Session
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.credentials import Credentials
import json
import os
from requests import request
def sigv4_request(
url,
method='GET',
body=None,
params=None,
headers=None,
service='execute-api',
region=os.environ['AWS_REGION'],
credentials=Session().get_credentials().get_frozen_credentials()
):
"""Sends an HTTP request signed with SigV4
Args:
url: The request URL (e.g. 'https://www.example.com').
method: The request method (e.g. 'GET', 'POST', 'PUT', 'DELETE'). Defaults to 'GET'.
body: The request body (e.g. json.dumps({ 'foo': 'bar' })). Defaults to None.
params: The request query params (e.g. { 'foo': 'bar' }). Defaults to None.
headers: The request headers (e.g. { 'content-type': 'application/json' }). Defaults to None.
service: The AWS service name. Defaults to 'execute-api'.
region: The AWS region id. Defaults to the env var 'AWS_REGION'.
credentials: The AWS credentials. Defaults to the current boto3 session's credentials.
Returns:
The HTTP response
"""
# sign request
req = AWSRequest(
method=method,
url=url,
data=body,
params=params,
headers=headers
)
SigV4Auth(credentials, service, region).add_auth(req)
req = req.prepare()
# send request
return request(
method=req.method,
url=req.url,
headers=req.headers,
data=req.body
)
def __init__():
# send request
response = sigv4_request(
'https://www.example.com',
method='POST',
headers={
'content-type': 'application/json',
},
body=json.dumps({
'foo': 'bar'
}),
# In Lambda functions, you can omit 'region' and 'credentials' to use the Lambda's region and credentials
)
# do something with response
print(response.status_code)
print(response.json())
@0xAPPA
Copy link

0xAPPA commented Sep 6, 2023

lifesaver, thanks for sharing

@Nirmazaki
Copy link

thank you so much!!!
you saved my soul!

@geraldstanje
Copy link

geraldstanje commented Mar 30, 2024

hi can i use that to send an inference request to aws sagemaker?

@marcogrcr
Copy link
Author

marcogrcr commented Apr 3, 2024

@geraldstanje Hello, I haven't tested this code with sagemaker. In theory, as long as the endpoint is protected with SigV4 it should work. You'll have to test it yourself though.

@geraldstanje
Copy link

dont you need a aws_key_id and aws_session for that?

@marcogrcr
Copy link
Author

@geraldstanje Yes, see here.

@geraldstanje
Copy link

i will test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment