I am calling REST API Post method using AWS Lambda function. But the basic authentication failed. same code worked fine on pycharm. Could anyone pleasehelp.
Please find below sample code
***import json
import os
import sys
import logging
import argparse
import re
import requests
import pandas as pd
import boto3
import datetime
import time
import json
import base64
import xml.etree.ElementTree as ET
def lambda_handler(event, context):
head = {
'Content-Type': 'application/xml',
'Authorization': 'c2Vn6Z1oxK3R3Q18='
}
body = f"""<?xml version='1.0' encoding='UTF-8' ?>
<ServiceRequest>
<filters>
</filters>
<preferences>
<startFromOffset>1</startFromOffset>
<limitResults>1</limitResults>
</preferences>
</ServiceRequest>"""
request_URL='https:'
response = requests.post(request_URL, headers=head, data=body)
print(response.text)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}***
Getting below output
<?xml version="1.0" encoding="UTF-8"?>
<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https:">
<responseCode>INVALID_CREDENTIALS</responseCode>
<responseErrorDetails>
<errorMessage>HTTP BASIC AUTH header is malformed.</errorMessage>
</responseErrorDetails>
</ServiceResponse>
Same code gives xml response as output when i executed on Pycharm.
Your Authorisation header should be something like
'Authorization': 'Basic c2Vn6Z1oxK3R3Q18='
Related
I have tried several things but I am not able to figure this one out. I have a back-end flask app and a front-end client written in Angular. When I submit my register user form I get a cors error. I have read the documentation for flask_cors and have tried to get it to work but I still get the same error below:
Access to XMLHttpRequest at 'http://localhost:5000/v1/auth/register' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Here is my app.py from the flask app.
Any help is greatly appreciated!
import os, sys
from flask import Flask
import pathlib
from flask_cors import CORS
from flask_restplus import Api, Resource, fields
from werkzeug.middleware.proxy_fix import ProxyFix
import coloredlogs, logging as log
coloredlogs.install()
from main.apis.user import api as User
from main.apis.auth import api as Auth
from main import create_app
from flask_pymongo import PyMongo
# Init app
app = Flask(__name__)
#cors = CORS(app, resources={r"*": {"origins": "*"}})
CORS(app, origins="http://localhost:4200", allow_headers=[
"Content-Type", "Authorization", "Access-Control-Allow-Credentials","Access-Control-Allow-Origin"],
supports_credentials=True, intercept_exceptions=False)
authorizations = {
'token': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
}
config_name = os.getenv('FLASK_CONFIG')
app = create_app(config_name)
api = Api(app, authorizations=authorizations, version='1.0', title='API docs',
description='A simple REST API with JWT authentication.',
doc='/docs'
)
app.config['jwt']._set_error_handler_callbacks(api)
app.config['ROOT_DIR'] = pathlib.Path(__file__).parent.absolute()
# #app.before_first_request
# this function is to init the db and realted models
# def create_tables():
# print("Before first statement")
# db.create_all()
# Endpoints
api.add_namespace(Auth, path='/v1')
api.add_namespace(User, path='/v1')
# Run Server
if __name__ == '__main__':
app.run()
adding this seemed to fix my issue.
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
return response
Looks like in your code you are creating app = Flask(__name__), applying the CORS to that variable and then over writing app by using app = create_app(config_name) a few lines later. So that causes your CORS setup on the first app to be lost.
I am using AWS CodeStar (Lambda + API Gateway) to build my serverless API. My lambda function works well in the Lambda console but strangely throws this error when I run the code on AWS CodeStar:
"message": "Internal server error"
Kindly help me with this issue.
import json
import os
import bz2
import pprint
import hashlib
import sqlite3
import re
from collections import namedtuple
from gzip import GzipFile
from io import BytesIO
from botocore.vendored import requests
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def handler(event, context):
logger.info('## ENVIRONMENT VARIABLES')
logger.info(os.environ)
logger.info('## EVENT')
logger.info(event)
n = get_package_list()
n1 = str(n)
dat = {"total_pack":n1}
return {'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps(dat)
}
def get_package_list():
url = "http://amazonlinux.us-east-2.amazonaws.com/2/core/2.0/x86_64/c60ceaf6dfa3bc10e730c9e803b51543250c8a12bb009af00e527a598394cd5e/repodata/primary.sqlite.gz"
db_filename = "dbfile"
resp = requests.get(url, stream=True)
remote_data = resp.raw.read()
cached_fh = BytesIO(remote_data)
compressed_fh = GzipFile(fileobj=cached_fh)
with open(os.path.join('/tmp',db_filename), "wb") as local_fh:
local_fh.write(compressed_fh.read())
package_obj_list = []
db = sqlite3.connect(os.path.join('/tmp',db_filename))
c = db.cursor()
c.execute('SELECT name FROM packages')
for package in c.fetchall():
package_obj_list.append(package)
no_of_packages = len(package_obj_list)
return no_of_packages
Expected Result: should return an Integer (no_of_packages).
I am pretty new to AWS Lambda i have a python code which has a post method for making an external API call,
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
r = request.post(url,headers=headers)
I tried putting it into a AWS Lamda call i tried like this below but it didn't get worked out
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
def lambda_handler(event, context):
response = requests.request("POST", url, headers=headers)
return response
But i am not getting in any response if i am running from local machine i am getting the output.Please help me how can i make a post call from AWS Lamda
I could get HTTP Basic Authentication to work using requests:
import requests
request = requests.post(url, auth=(user, pass), data={'a':'whatever'})
And also using urllib2 and urllib:
import urllib2, urllib
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, user, pass)
auth_handler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
content = urllib2.urlopen(url, urllib.urlencode({'a': 'whatever'}))
The problem is I get an unauthorized error when I try the same thing with mechanize:
import mechanize, urllib
from base64 import b64encode
browser = mechanize.Browser()
b64login = b64encode('%s:%s' % (user, pass))
browser.addheaders.append(('Authorization', 'Basic %s' % b64login ))
request = mechanize.Request(url)
response = mechanize.urlopen(request, data=urllib.urlencode({'a':'whatever}))
error:
HTTPError: HTTP Error 401: UNAUTHORIZED
The code I tried with mechanize could be trying to authenticate in a different way than the other two code snippets. So the question is how could the same authentication process be achieved in mechanize.
I am using python 2.7.12
The header should have been added to the request instead of the browser. In fact the browser variable isn't even needed.
import mechanize, urllib
from base64 import b64encode
b64login = b64encode('%s:%s' % (user, pass))
request = mechanize.Request(url)
request.add_header('Authorization', 'Basic %s' % b64login )
response = mechanize.urlopen(request, data=urllib.urlencode({'a':'whatever'}))
I am new to google python api client.I am learning from https://developers.google.com/api-client-library/python/start/get_started.I want to make an api which converts python object into JSON data and sends to a servlet.
The python code of file api.py:
import os
import urllib2
import httplib2
import json
import requests
from apiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run_flow
from oauth2client.file import Storage
from oauth2client import tools
api_version='1'
_file_="D:\API"
CLIENT_SECRETS = os.path.join(os.path.dirname(_file_))
flow=flow_from_clientsecrets(CLIENT_SECRETS,
scope=[
'https://www.googleapis.com/auth/devstorage.full_control',
],
http = httplib2.Http()
auth_http = credentials.authorize(http)
service=build('SendNotif',api_version,http=http)
req = urllib2.Request('http://example/notify')
req.add_header('Content-Type', 'application/json')
data={"message":"Hello User you are notified"}
data_json = json.dumps(data)
response = urllib2.urlopen(req, json.dumps(data))
The error shown is:
D:\API>python api.py
File "api.py", line 25
auth_http = credentials.authorize(http)
^
SyntaxError: invalid syntax
please do help in correcting me..
thanks in advance....
You're missing a closing parenthesis for this line:
flow=flow_from_clientsecrets(CLIENT_SECRETS,