Reverse gecoding - geopy.Nominatim module throws urlopen error [SSL: UNKNOWN PROTOCOL] - ssl

I am trying to get the address details from Latitude and Longitude using geopy.Nominatim module. Am getting "<'urlopen error [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:727)>" error.
Version Details :
Python version : 2.7
geopy version : 1.23.0
geographiclib : 1.50 (Dependency with geopy)
requests : 2.25.1
chardet : 3.0.4 (Dependency with requests)
urllib3 : 1.25.10 (Dependency with requests)
idna : 2.10 (Dependency with requests)
certifi : 2020.6.20 (Dependency with requests)
Code:
=====
from geopy.geocoders.osm import Nominatim
from geopy.exc import GeocoderServiceError
def reverse(lat,long):
app = Nominatim(user_agent='reverse-geocoding')
coordinates = "{},{}".format(lat,long) # not giving the actual co-ordinates
try:
address_details = app.reverse(coordinates,language="en").raw
return address_details
except GeocoderServiceError as e1:
print (str(e1))
result = reverse(lat,long)
print(result)
================
I have used the following workarounds with the same script.Am getting "<'urlopen error [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:727)>" error
workaround 1: To use the CA bundle used by requests library:
from geopy.geocoders.osm import Nominatim
from geopy.geocoders import options
from geopy.exc import GeocoderServiceError
import ssl
import certifi
def reverse(lat,long):
ctx = ssl.create_default_context(cafile=certifi.where())
options.default_ssl_context = ctx
app = Nominatim(user_agent='reverse-geocoding')
coordinates = "{},{}".format(lat,long) # not giving the actual co-ordinates
try:
address_details = app.reverse(coordinates,language="en").raw
return address_details
except GeocoderServiceError as e1:
print (str(e1))
result = reverse(lat,long)
print(result)
Workaround 2: To disable TLS certificate verification completely:
from geopy.geocoders.osm import Nominatim
from geopy.geocoders import options
from geopy.exc import GeocoderServiceError
import ssl
def reverse(lat,long):
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
options.default_ssl_context = ctx
app = Nominatim(user_agent='reverse-geocoding')
coordinates = "{},{}".format(lat,long) # not giving the actual co-ordinates
try:
address_details = app.reverse(coordinates,language="en").raw
return address_details
except GeocoderServiceError as e1:
print (str(e1))
result = reverse(lat,long)
print(result)
Could anyone please help me to find a fix for this issue.

The error UNKNOWN PROTOCOL is in all probability due to the fact that your request is going via a proxy.
I looked into your code mentioned in Workaround 2. Please mention the proxy explicitly in your code. Try using below code lines:
ctx = ssl.create_default.context()
ctx.check_hostname = True
ctx.verify_mode = ssl.CERT_REQUIRED
options.default_ssl_context = ctx
proxies = {'https':'https://your-proxy-server.com:port'}
app = Nominatim(user_agent="your-agent", proxies=proxies, timeout=10)
This will also help you not to ignore SSL verification completely.

Related

Telegram bot Message Handler error [Local varialbe referenced before assignment]

from dotenv import load_dotenv
import os
from panda import *
from telegram.ext import *
from telegram.update import *
load_dotenv('.env')
Token =os.getenv('TOKEN')
print("The bot connected .....")
# commands handler
# start message
def start_command(update,context):
update.message.reply_text("Hello am mr panda am here to help you: ")
# help command
def help_command(update,context):
res = panda.help()
update.message.reply_text(res)
# message handler
**def message_handle(update,context):
message = str(update.message.text).lower()
respose = panda.hello(message)
update.message.reply_text(respose)**
# errror handler
def error(update,context):
print(f"Update the context error : {context.error}")
# main function
def main():
global message
updater =Updater(Token,use_context=True)
dp = updater.dispatcher
# command handlers
dp.add_handler(CommandHandler("start",start_command))
dp.add_handler(CommandHandler("help",help_command))
**# message handlers
dp.add_handler(MessageHandler(Filters.text,message_handle))**
# error handlers
dp.add_error_handler(error)
updater.start_polling()
updater.idle()
main()
This was the code Am getting error
Update the context error: local variable 'message' referenced before assignment
I think there is an error on the highlighted portions I do little searches and I referred to the documentation too I can't catch the error.
Does anyone have solution that would be great :)

Facing "IllegalLocationConstraintException" error

I am trying to create a s3-bucket using AWS SDK for Python in PyCharm and facing the following error.
"An error occurred (IllegalLocationConstraintException) when calling the CreateBucket operation: The unspecified location constraint is incompatible for the region specific endpoint this request was sent to."
Here is my code:
import os
import boto3
from botocore.exceptions import ClientError
ACCESS_KEY = 'AWS_ACCESS_KEY_ID'
SECRET_KEY = 'AWS_SECRET_ACCESS_KEY'
PRI_BUCKET_NAME = 'soundcloud2'
TRANSIENT_BUCKET_NAME = 'soundcloud3'
def main():
"""entry point"""
access = os.getenv(ACCESS_KEY)
secret = os.getenv(SECRET_KEY)
s3 = boto3.resource('s3', aws_access_key_id=access, aws_secret_access_key=secret)
create_bucket(TRANSIENT_BUCKET_NAME, s3)
def create_bucket(name, s3):
try:
bucket = s3.create_bucket(Bucket=name)
except ClientError as ce:
print('error', ce)
if __name__ == '__main__':
main()
Try modifying your code as below:
bucket = s3.create_bucket(Bucket=name,
CreateBucketConfiguration={
'LocationConstraint': 'ap-south-1'}
)
or whatever region, unless your region is in the U.S.

REST call to sslCertificate.insert fails with "The SSL certificate could not be parsed", but gcloud works fine

Here's a example program that generates the error:
import urllib3
import certifi
from google.auth.transport.urllib3 import AuthorizedHttp
from google.oauth2 import service_account
import boto3
from pprint import pprint
import json
# parameters
JSON_SERVICE_ACCOUNT_FILE = "/home/mwilbert/gcp/matt-vm-service-account.json"
SCOPES = [
'https://www.googleapis.com/auth/devstorage.read_write',
'https://www.googleapis.com/auth/compute'
]
TEST_PROJECTID = 'mwilbert-workspace'
TEST_FULLCHAIN_FILE = '/etc/letsencrypt/live/fake.mapgeo.io/fullchain.pem'
TEST_PRIVKEY_FILE = '/etc/letsencrypt/live/fake.mapgeo.io/privkey.pem'
http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs=certifi.where())
credentials = service_account.Credentials.from_service_account_file(JSON_SERVICE_ACCOUNT_FILE)
scoped_credentials = credentials.with_scopes(SCOPES)
authed_http = AuthorizedHttp(scoped_credentials,http)
requestBody = {
"name":"deleteme",
"description": "fake domain cert",
"certificate": TEST_FULLCHAIN_FILE,
"privateKey": TEST_PRIVKEY_FILE,
}
rb = json.dumps(requestBody)
url = 'https://www.googleapis.com/compute/v1/projects/%s/global/sslCertificates' % TEST_PROJECTID
r = authed_http.urlopen('POST',
url,
headers={'Content-Type': 'application/json'},
body=rb)
response = json.loads(r.data)
pprint(response)
However if I pass the same arguments to gcloud
gcloud compute ssl-certificates create deleteme
--certificate=/etc/letsencrypt/live/fake.mapgeo.io/fullchain.pem
--private-key=/etc/letsencrypt/live/fake.mapgeo.io/privkey.pem
--description="fake domain cert" --project=mwilbert-workspace
from the same terminal session the certificate is created. The certificate is in .PEM format.
Has anyone gotten this call to work? If so, any pointers?

SSL in python3 with HTTPServer

I found here a (apparently-)working HTTPS server for python 2: http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/?c=15536
I'm trying to port it in python3 but I have no good results. This is my code:
from socketserver import BaseServer
import string,cgi,time
from os import curdir, sep
from http.server import SimpleHTTPRequestHandler, HTTPServer
import ssl
import os # os. path
import socket
class SecureHTTPServer(HTTPServer):
def __init__(self, server_address, HandlerClass):
BaseServer.__init__(self, server_address, HandlerClass)
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
#server.pem's location (containing the server private key and
#the server certificate).
fpem = 'certificate1.pem'
ctx.load_verify_locations(fpem)
self.socket = ctx.wrap_socket(socket.socket(self.address_family,
self.socket_type))
self.server_bind()
self.server_activate()
class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
def setup(self):
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
def do_GET(self):
print('get recieved!');
self.send_error(404,'File Not Found: %s' % self.path)
def test(HandlerClass = SecureHTTPRequestHandler,
ServerClass = SecureHTTPServer):
server_address = ('', 1443) # (address, port)
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print ("Serving HTTPS on", sa[0], "port", sa[1], "...")
httpd.serve_forever()
if __name__ == '__main__':
test()
When I run it I get no errors, but when I connect to localhost:1443 (with https) I get no response and the print('get recieved!'); is't triggered.
I found another (simpler) solution here: http://www.piware.de/2011/01/creating-an-https-server-in-python/
This is my working porting to python3:
from http.server import HTTPServer,SimpleHTTPRequestHandler
from socketserver import BaseServer
import ssl
httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='certificate.pem', server_side=True)
httpd.serve_forever()
Since Python 3.7 ssl.wrap_socket is deprecated, use SSLContext.wrap_socket instead:
check: https://docs.python.org/3.7/library/ssl.html#ssl.wrap_socket
and since version 3.10: SSLContext without protocol argument is deprecated.
check: https://docs.python.org/3.10/library/ssl.html#ssl.SSLContext
from http.server import HTTPServer,SimpleHTTPRequestHandler
import ssl
httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
# Since version 3.10: SSLContext without protocol argument is deprecated.
# sslctx = ssl.SSLContext()
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslctx.check_hostname = False # If set to True, only the hostname that matches the certificate will be accepted
sslctx.load_cert_chain(certfile='certificate.pem', keyfile="private.pem")
httpd.socket = sslctx.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()

Twisted trial error with SSL

SSLTest.testError passes, but Trial raises an exception after tearDown. For comparison there is RegularTest.testOk that works OK.
I have not found any Twisted bug that explain this, so I assume I'm doing something wrong given how easy this is to reproduce. Any ideas?
Here's the code:
from twisted.web import resource
from twisted.internet import ssl, reactor
from twisted.web.server import Site
from twisted.web.client import Agent, WebClientContextFactory
from twisted.trial.unittest import TestCase
class DummyServer(resource.Resource):
isLeaf = True
def render(self, request):
return 'hello world'
class SSLTest(TestCase):
def setUp(self):
site = Site(DummyServer())
SSLFactory = ssl.DefaultOpenSSLContextFactory('../server.key',
'../server.crt')
port = reactor.listenSSL(0, site, contextFactory=SSLFactory)
self.port = port
self.portNumber = port._realPortNumber
def tearDown(self):
self.port.stopListening()
def testError(self):
def finished(result):
self.assertEquals(result.code, 200)
url = 'https://127.0.0.1:%s' % self.portNumber
agent = Agent(reactor, WebClientContextFactory())
d = agent.request('GET', url)
d.addCallback(finished)
return d
class RegularTest(TestCase):
def setUp(self):
site = Site(DummyServer())
port = reactor.listenTCP(0, site)
self.port = port
self.portNumber = port._realPortNumber
def tearDown(self):
self.port.stopListening()
def testOk(self):
def finished(result):
self.assertEquals(result.code, 200)
url = 'http://127.0.0.1:%s' % self.portNumber
agent = Agent(reactor,)
d = agent.request('GET', url)
d.addCallback(finished)
return d
Here's stdout:
$ trial trialerror.py
trialerror
RegularTest
testOk ... [OK]
SSLTest
testError ... [OK]
[ERROR]
===============================================================================
[ERROR]
Traceback (most recent call last):
Failure: twisted.trial.util.DirtyReactorAggregateError: Reactor was unclean.
Selectables:
<TLSMemoryBIOProtocol #0 on 51135>
trialerror.SSLTest.testError
-------------------------------------------------------------------------------
Ran 2 tests in 0.018s
FAILED (errors=1, successes=2)
Jonathan Lange wrote about this problem and its solutions. You may also want to consider not using real network connections in your unit tests. Agent already works. So do Site,
reactor.listenSSL, etc. Try to write unit tests that exercise your code and not lots and lots of code from the libraries your code depends on.