I'm makeing a simple proxy with Flask to mock the call describe_regions() of AWS.
The Flask server has de following code:
from __future__ import unicode_literals
from flask import Flask
from flask import Response
from flask import stream_with_context
# from httpretty import HTTPretty, register_uri
import httpretty
import requests
from flask import request
import time
RESPONSE = u"""<DescribeRegionsResponse xmlns="http://ec2.amazonaws.com/doc/2015-10-01/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<regionInfo>
<item>
<regionName>us-east-1</regionName>
<regionEndpoint>ec2.us-east-1.amazonaws.com</regionEndpoint>
</item>
<item>
<regionName>eu-west-1</regionName>
<regionEndpoint>ec2.eu-west-1amazonaws.com</regionEndpoint>
</item>
</regionInfo>
</DescribeRegionsResponse>"""
app = Flask(__name__)
#app.route('/<path:url>', methods=['GET', 'PUT', 'POST', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS', 'CONNECT'])
def home(url):
return Response(RESPONSE, mimetype='text/xml')
if __name__ == '__main__':
app.run(debug=True)
Then I has the following code to test it. I use Boto3 to call the API for AWS.
from boto3.session import Session
import os
credentials = {
'aws_access_key_id': 'sadasdasda',
'aws_secret_access_key': 'dasdasdasd'
}
os.environ["HTTP_PROXY"] = 'http://localhost:5000/'
os.environ["HTTPS_PROXY"] = 'http://localhost:5000/'
session_boto3 = Session(**credentials)
ec2 = session_boto3.client('ec2', 'eu-west-1', verify=False)
regions = ec2.describe_regions()
print regions
The problem is: the Flask server get the petition, but the Response doesn't like to Boto3 and I get the following traceback error:
Traceback (most recent call last):
File "/pruebas_mock/prueba.py", line 82, in <module>
regions = ec2.describe_regions()
File "/mock_aws/local/lib/python2.7/site-packages/botocore/client.py", line 228, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/client.py", line 475, in _make_api_call
operation_model, request_dict)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 117, in make_request
return self._send_request(request_dict, operation_model)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 146, in _send_request
success_response, exception):
File "/mock_aws/local/lib/python2.7/site-packages/botocore/endpoint.py", line 219, in _needs_retry
caught_exception=caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/hooks.py", line 226, in emit
return self._emit(event_name, kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/hooks.py", line 209, in _emit
response = handler(**kwargs)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 183, in __call__
if self._checker(attempts, response, caught_exception):
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 250, in __call__
caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 273, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 313, in __call__
caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 222, in __call__
return self._check_caught_exception(attempt_number, caught_exception)
File "/mock_aws/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 355, in _check_caught_exception
raise caught_exception
botocore.vendored.requests.exceptions.SSLError: [Errno 1] _ssl.c:510: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
How should I make the response with Flask?
Thanks.
By default, boto3 (and all of the other AWS SDK's) will connect to services using SSL. Your proxy Flask server does not appear to be using SSL so you can either use SSL in your proxy or tell boto3 not to use SSL for your proxy server:
ec2 = session_boto3.client('ec2', 'eu-west-1', use_ssl=False, verify=False)
The verify parameter tells boto3 not to try to validate the SSL cert but it will still try to connect via SSL. the use_ssl=False tells it to use plain HTTP to talk to your endpoint.
Related
I am getting the following error:
[ERROR] SSLError: SSL validation failed for https://data.iot.ap-northeast-2.amazonaws.com/topics/app%2Ftest%2Fresponse?qos=1 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1124)
Traceback (most recent call last):
File "/var/task/app.py", line 197, in lambda_handler
mqttcli.test('test', '11111', {}, 1, 200)
File "/opt/python/lib/python3.8/site-packages/connectors/MQTTClient.py", line 40, in test
response = self._iot_client.publish(
File "/var/task/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/task/botocore/client.py", line 662, in _make_api_call
http, parsed_response = self._make_request(
File "/var/task/botocore/client.py", line 682, in _make_request
return self._endpoint.make_request(operation_model, request_dict)
File "/var/task/botocore/endpoint.py", line 102, in make_request
return self._send_request(request_dict, operation_model)
File "/var/task/botocore/endpoint.py", line 136, in _send_request
while self._needs_retry(attempts, operation_model, request_dict,
File "/var/task/botocore/endpoint.py", line 253, in _needs_retry
responses = self._event_emitter.emit(
File "/var/task/botocore/hooks.py", line 356, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
File "/var/task/botocore/hooks.py", line 228, in emit
return self._emit(event_name, kwargs)
File "/var/task/botocore/hooks.py", line 211, in _emit
response = handler(**kwargs)
File "/var/task/botocore/retryhandler.py", line 183, in __call__
if self._checker(attempts, response, caught_exception):
File "/var/task/botocore/retryhandler.py", line 250, in __call__
should_retry = self._should_retry(attempt_number, response,
File "/var/task/botocore/retryhandler.py", line 277, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/var/task/botocore/retryhandler.py", line 316, in __call__
checker_response = checker(attempt_number, response,
File "/var/task/botocore/retryhandler.py", line 222, in __call__
return self._check_caught_exception(
File "/var/task/botocore/retryhandler.py", line 359, in _check_caught_exception
raise caught_exception
File "/var/task/botocore/endpoint.py", line 200, in _do_get_response
http_response = self._send(request)
File "/var/task/botocore/endpoint.py", line 269, in _send
return self.http_session.send(request)
File "/var/task/botocore/httpsession.py", line 281, in send
raise SSLError(endpoint_url=request.url, error=e)
This is the code that is causing this error:
_iot_client = boto3.client('iot-data',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name= REGION_NAME)
response = _iot_client.publish(
topic = "app/test/response",
qos = 1,
payload = json.dumps(
{
'msgid': msgid,
'status': status,
'data': payload
}
)
)
There is no error in S3 or other services through boto3. only iot-data.
It works without any problems when i run the .py.
but an error occurs when running after deploy to lambda.
There was no error until recently.
We also are experiencing this issue, in our case, an update in the "certifi" library (requests dependency) was causing some conflict with boto3 iot publish, rolling back the version solved the problem, although we are not entirely sure what exactly was failing.
You need to get the "Data-ATS" endpoint instead of the untrusted "Symantec" endpoint that's built-in. Try this:
import boto3
def get_aws_iot_ats_endpoint():
"""
Get the "Data-ATS" endpoint instead of the
untrusted "Symantec" endpoint that's built-in.
"""
iot_client = boto3.client(
"iot",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name= REGION_NAME,
verify=True
)
details = iot_client.describe_endpoint(endpointType="iot:Data-ATS")
host = details.get("endpointAddress")
return f"https://{host}"
IOT_DATA_ENDPOINT = get_aws_iot_ats_endpoint()
client_iot = boto3.client(
"iot-data",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name= REGION_NAME,
verify=True,
endpoint_url=IOT_DATA_ENDPOINT
)
response = client_iot.publish(
topic = "app/test/response",
qos = 1,
payload = json.dumps(
{
'msgid': msgid,
'status': status,
'data': payload
}
)
)
I had the same error.
Simply insert this at the beginning of your code:`
from botocore.exceptions import ClientError
It should work.
Best.
I am running this python code where I am trying to run a socketio flask application and passing ssl certificate files:
from flask import Flask, render_template, request, session, Markup, current_app, jsonify
from flask_socketio import emit, SocketIO
import eventlet
from flask_babel import gettext
app = Flask(__name__)
app.config['SECRET_KEY'] = '123'
app.config['FILEDIR'] = 'static/_files/'
socketio = SocketIO(app)
if __name__ == '__main__':
try:
app_host = os.environ.get('APP_HOST')
app_port = os.environ.get('APP_PORT')
eventlet.wsgi.server(eventlet.wrap_ssl(eventlet.listen((app_host, int(app_port))),certfile ='selfsigned.crt', keyfile = 'selfsigned.key',server_side = True),app)
except Exception as e:
logger.error(e)
When I run this code it throws following SSL error:
(21755) wsgi starting up on https://12.34.56.78:5000
(21755) accepted ('12.34.56.79', 50021)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 458, in fire_timers
timer()
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 58, in __call__
cb(*args, **kw)
File "/usr/local/lib/python3.6/site-packages/eventlet/greenthread.py", line 218, in main
result = function(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 781, in process_request
proto.__init__(conn_state, self)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 335, in __init__
self.handle()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 368, in handle
self.handle_one_request()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 397, in handle_one_request
self.raw_requestline = self._read_request_line()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 380, in _read_request_line
return self.rfile.readline(self.server.url_length_limit)
File "/usr/local/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 204, in recv_into
return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 225, in _base_recv
read = self.read(nbytes, buffer_)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 139, in read
super(GreenSSLSocket, self).read, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 113, in _call_trampolining
return func(*a, **kw)
File "/usr/local/lib/python3.6/ssl.py", line 871, in read
return self._sslobj.read(len, buffer)
File "/usr/local/lib/python3.6/ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:2217)
What I want is that this app should run over https connection but this error is preventing it from running. Below are my python and package version details:
python 3.6.3
eventlet==0.22.1
Flask==0.12.2
Flask-SocketIO==2.9.3
It seems that the request that has been made to the server is using http instead of https. You have to make sure that the client is also making a request using the same https protocol as the server. For example in you client code, you have to make a request to https://<server-ip> instead of http://<server-ip>
so recently I tried myself with Exchangelib, but I currently can't solve the issue. Heres my code:
from exchangelib import DELEGATE, Account, Credentials, IMPERSONATION
from exchangelib.configuration import Configuration
config = Configuration(
server='https://XXX',
credentials=Credentials(username='XXX\\XXX', password='XXX')
)
account = Account(
primary_smtp_address='mail#mail.com',
config=config,
autodiscover=False,
access_type=DELEGATE,
)
for item in account.inbox.all().order_by('-datetime_received')[:20]:
print(item.subject, item.sender, item.datetime_received)
Currently I receive the following error:
File "Project/Exchange/standardoutlook2.py", line 23, in <module>
config = Configuration(server='https://XXX', credentials=credentials)
File "Projectvenv36\lib\site-packages\exchangelib\configuration.py", line 46, in __init__
version=version
File "Projectvenv36\lib\site-packages\exchangelib\protocol.py", line 176, in __call__
protocol = super(CachingProtocol, cls).__call__(*args, **kwargs)
File "Projectvenv36\lib\site-packages\exchangelib\protocol.py", line 209, in __init__
name=self.credentials.username)
File "Projectvenv36\lib\site-packages\exchangelib\transport.py", line 149, in get_service_authtype
timeout=BaseProtocol.TIMEOUT)
File "Projectvenv36\lib\site-packages\requests\sessions.py", line 559, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "Projectvenv36\lib\site-packages\requests\sessions.py", line 512, in request
resp = self.send(prep, **send_kwargs)
File "Projectvenv36\lib\site-packages\requests\sessions.py", line 622, in send
r = adapter.send(request, **kwargs)
File "Projectvenv36\lib\site-packages\requests\adapters.py", line 412, in send
self.cert_verify(conn, request.url, verify, cert)
File "Project/Exchange/standardoutlook2.py", line 13, in cert_verify
}[urlparse(url).hostname]
KeyError: 'https'
I've added the certificate to the certificate of certifi, so when I start any request to the server outside of the code above it works well.
I am kind of new in Google APIs and I am trying to connect to Google Content API via Python. I am using a service account for that.
My script is quite easy and straightforward:
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
import httplib2
credentials = ServiceAccountCredentials.from_p12_keyfile(
'xxxxx.iam.gserviceaccount.com',
'/Users/Downloads/pkey.txt',
scopes='https://www.googleapis.com/auth/content')
http = credentials.authorize(httplib2.Http())
service = build('https://www.googleapis.com/content', 'v2')
In the authorization process I get this error:
Traceback (most recent call last):
File "/Users/PycharmProjects/authorization.py", line 22, in <module>
service = build('https://www.googleapis.com/content', 'v2')
File "build/bdist.macosx-10.11-intel/egg/oauth2client/_helpers.py", line 133, in positional_wrapper
File "build/bdist.macosx-10.11-intel/egg/googleapiclient/discovery.py", line 228, in build
File "build/bdist.macosx-10.11-intel/egg/googleapiclient/discovery.py", line 275, in _retrieve_discovery_doc
File "/Library/Python/2.7/site-packages/httplib2-0.10.3-py2.7.egg/httplib2/__init__.py", line 1659, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/Library/Python/2.7/site-packages/httplib2-0.10.3-py2.7.egg/httplib2/__init__.py", line 1399, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/Library/Python/2.7/site-packages/httplib2-0.10.3-py2.7.egg/httplib2/__init__.py", line 1319, in _conn_request
conn.connect()
File "/Library/Python/2.7/site-packages/httplib2-0.10.3-py2.7.egg/httplib2/__init__.py", line 1069, in connect
self.ssl_version, self.host)
File "/Library/Python/2.7/site-packages/httplib2-0.10.3-py2.7.egg/httplib2/__init__.py", line 97, in _ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=hostname)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 352, in wrap_socket
_context=self)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 579, in __init__
self.do_handshake()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 816, in do_handshake
match_hostname(self.getpeercert(), self.server_hostname)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 271, in match_hostname
% (hostname, ', '.join(map(repr, dnsnames))))
ssl.CertificateError: hostname 'https%3a%2f%2fwww.googleapis.com%2fcontent.googleapis.com' doesn't match either of '*.googleapis.com', '*.clients6.google.com', '*.cloudendpointsapis.com', 'cloudendpointsapis.com', 'googleapis.com'
Process finished with exit code 1
Does it have to do with my authorisation? Or I am doing something wrong?
Thanks a lot for your help!
You want to provide build() with the api_name, not a URL.
service = build('content', 'v2')
Source: https://developers.google.com/api-client-library/python/apis/
Want to use wechat sdk to create menu
WeChat.create_menu({
"button":[
{
"type":"click",
"name":"Daily Song",
"key":"V1001_TODAY_MUSIC"
},
{
"type":"click",
"name":" Artist Profile",
"key":"V1001_TODAY_SINGER"
},
{
"name":"Menu",
"sub_button":[
{
"type":"view",
"name":"Search",
"url":"http://www.soso.com/"
},
{
"type":"view",
"name":"Video",
"url":"http://v.qq.com/"
},
{
"type":"click",
"name":"Like us",
"key":"V1001_GOOD"
}]
}]
})
Currently not work because of this error:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1519, in __call__
response = self._internal_error(e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1511, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1505, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1077, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 547, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 545, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechatAPIHandler.py", line 72, in post
"key":"V1001_GOOD"
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 355, in create_menu
data=menu_data
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 949, in _post
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 907, in _request
"access_token": self.access_token,
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 849, in access_token
self.grant_token()
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 273, in grant_token
"secret": self.__appsecret,
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 935, in _get
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/wechat_sdk/basic.py", line 917, in _request
**kwargs
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/base/data/home/apps/s~project-boom/1.384461758981660124/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
SSLError: Can't connect to HTTPS URL because the SSL module is not available.
python request module is include in the app engine project. Using python 2.7. Being look for ways to solve this problem but have not find very clear way to solve the problem yet
If you're using GAE's Sockets, you can get SSL support without any hacks by simply loading the SSL library.
Simply add this to your app.yaml file:
libraries:
- name: ssl
version: latest
This is documented on Google Cloud's OpenSSL Support documentation.
This blog post details a solution. From the blog post:
The problem is GAE has a “whitelist” of select standard libraries. SSL
(_ssl, _socket) is not one of them. So, we need to tweak the sandbox
environment (dangerous) carefully. The below code uses the standard
Python socket library instead of the GAE-provided in the development
environment. Modify [or create] appengine_config.py:
import os
# Workaround the dev-environment SSL
# http://stackoverflow.com/q/16192916/893652
if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
import imp
import os.path
from google.appengine.tools.devappserver2.python import sandbox
sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
# Use the system socket.
psocket = os.path.join(os.path.dirname(os.__file__), 'socket.py')
imp.load_source('socket', psocket)
Jan Dolejsi,
If you're using GAE's Sockets, you can get SSL support without any
hacks by simply loading the SSL library.
Simply add this to your app.yaml file:
libraries:
- name: ssl
- version: latest
If you're experiencing RAND_egd error, just change "-version: latest" in your app.yaml, to "-version: 2.7"!