Google Maps API - Sign Geocode Requests with Python 3 - google-maps-api-3

I'm trying to create a script to generate signed urls using my Maps API license to geocode addresses, but I'm having trouble with my sign_url function.
import urllib
import urllib.parse
import base64
import hashlib
import hmac
import re
google_apis_url_http = 'http://maps.googleapis.com'
geocoding_endpoint_json = '/maps/api/geocode/json'
def encode_params(address, client, sensor):
return urllib.parse.urlencode({'address': address, 'client': client, 'sensor': sensor})
def sign_url(url, private_key):
decoded_key = base64.urlsafe_b64decode(private_key)
signature = hmac.new(decoded_key, url, hashlib.sha1)
encoded_signature = base64.urlsafe_b64encode(signature.digest())
return encoded_signature
with open("addresses.txt", "r") as inputFile:
inputList = inputFile.read().splitlines()
for line_address in inputList[0:1]:
comma_stripped_address = re.sub(",", "", line_address)
formatted_address = re.sub(" ", "+", comma_stripped_address)
encoded_params = encode_params(formatted_address, 'gme-********', 'false')
url_to_sign = geocoding_endpoint_json + '?' + encoded_params
print(sign_url(url_to_sign, '********'))
Here's the error I'm getting:
Traceback (most recent call last):
File "/Users/[me]/PycharmProjects/Google APIs/geocode_auth.py", line 31, in <module>
print(sign_url(url_to_sign, '********'))
File "/Users/[me]/PycharmProjects/Google APIs/geocode_auth.py", line 18, in sign_url
signature = hmac.new(decoded_key, url, hashlib.sha1)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/hmac.py", line 131, in new
return HMAC(key, msg, digestmod)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/hmac.py", line 73, in __init__
self.update(msg)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/hmac.py", line 79, in update
raise TypeError("expected bytes, but got %r" % type(msg).__name__)
TypeError: expected bytes, but got 'str'
Anyone know why this TypeError is being raised? I'm modeling the script off of a demo done in Python v2, so it's possible something broke in v3...

Related

How to deploy a FastAPI endpoint using pythonanywhere?

I have been trying to deploy EasyOCR (it's fine if it works on CPU) with FastAPI endpoints such that anyone can use it via https POST request. It runs fine on my local host but when I have been facing challenges in deploying it using pythonanywhere. I added the additional requirements like pip install easyocr, pip install python-multipart==0.0.5.
The following is my code-
import io
import logging
import re
from fastapi import FastAPI, APIRouter, Request, File, UploadFile
from fastapi.responses import FileResponse, StreamingResponse
import easyocr
import PIL
from PIL import Image, ImageOps
import numpy
app = FastAPI()
router = APIRouter()
ocr = easyocr.Reader(["en"])
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("ocr")
#app.get("/")
async def root():
return {"message": "Hello World"}
#app.post("/ocr")
async def do_ocr(request: Request, file: UploadFile = File(...)):
if file is not None:
imgFile = numpy.array(PIL.Image.open(file.file).convert("RGB"))
res = ocr.readtext(imgFile)
# return array of strings
return [item[1] for item in res]
return {"error": "missing file"}
app.include_router(router)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app)
I am getting the error in the logs-
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/somyatomar15/main.py", line 82, in <module>
uvicorn.run(app)
File "/usr/local/lib/python3.10/site-packages/uvicorn/main.py", line 463, in run
server.run()
File "/usr/local/lib/python3.10/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 633, in run_until_complete
self.run_forever()
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 600, in run_forever
self._run_once()
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 1896, in _run_once
handle._run()
File "/usr/local/lib/python3.10/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.10/site-packages/uvicorn/server.py", line 77, in serve
await self.startup(sockets=sockets)
File "/usr/local/lib/python3.10/site-packages/uvicorn/server.py", line 158, in startup
sys.exit(1)
SystemExit: 1

Strava GPX upload with python module requests is giving a ValueError - why?

I don't understand why this ValueError occurs?
Post request
import requests
headers = {'authorization': 'Bearer XXXXXXXXXXXXXXXX'}
files = [{'file': open('../poc_data/Sport-sessions/GPS-data/2012-08-09_05-32-43-UTC_55d566fa93bc7d9d1757b8e0.gpx', 'rb')}, {'data_type': 'gpx'}, {'Content-Type': 'multipart/form-data'}]
r = requests.post('https://www.strava.com/api/v3/uploads', headers=headers, files=files)
Error traceback
*Traceback (most recent call last):
File "D:/projekte/11_github/poc_runtastic/poc_code/strava_upload_activities.py", line 19, in <module>
r = requests.post('https://www.strava.com/api/v3/uploads', headers=headers, files=files)
File "E:\Python\Python38\lib\site-packages\requests\api.py", line 117, in post
return request('post', url, data=data, json=json, **kwargs)
File "E:\Python\Python38\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, *kwargs)
File "E:\Python\Python38\lib\site-packages\requests\sessions.py", line 528, in request
prep = self.prepare_request(req)
File "E:\Python\Python38\lib\site-packages\requests\sessions.py", line 456, in prepare_request
p.prepare(
File "E:\Python\Python38\lib\site-packages\requests\models.py", line 319, in prepare
self.prepare_body(data, files, json)
File "E:\Python\Python38\lib\site-packages\requests\models.py", line 512, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "E:\Python\Python38\lib\site-packages\requests\models.py", line 141, in
_encode_files
for (k, v) in files:
ValueError: not enough values to unpack (expected 2, got 1)
The reason for that effect regards to the API-design: it is expecting one explicit dictionary named headers and one named params.
In my given example above I sent only one (headers) and that explains the ValueError.
This code works:
import requests
files = {
'file': open('../poc_data/Sport-sessions/GPS-data/2012-08-09_05-32-43-UTC_55d566fa93bc7d9d1757b8e0.gpx', 'rb')
}
headers = {
'authorization': 'Bearer XXXXXXXXXXXXXXXX'
}
params = {
'data_type': 'gpx'
}
url = 'https://www.strava.com/api/v3/uploads'
r = requests.post(files=files, headers=headers, params=params, url=url)

How can I send a file using to a HTTP server and read it?

So, I created the following HTTP server tunneled via ngrok, and I am trying to send a file to the server, to then read it and display it on the web page of the server.
Here's the code for the server:
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
from pyngrok import ngrok
import time
port = os.environ.get("PORT", 80)
server_address = ("127.0.0.1", port)
class MyServer(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
def do_POST(self):
'''Reads post request body'''
self._set_headers()
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
self.wfile.write("received post request:<br>{}".format(post_body))
def do_PUT(self):
self.do_POST()
httpd = HTTPServer(server_address, MyServer)
public_url = ngrok.connect(port).public_url
print("ngrok tunnel \"{}\" -> \"http://127.0.0.1:{}\"".format(public_url, port))
try:
# Block until CTRL-C or some other terminating event
httpd.serve_forever()
except KeyboardInterrupt:
print(" Shutting down server.")
httpd.socket.close()
And I have been trying to send a file using POST as follow
>>> url = 'https://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}
>>> r = requests.post(url, files=files)
>>> r.text
I imported requests of course, and here's what I get
Exception occurred during processing of request from ('127.0.0.1', 60603)
Traceback (most recent call last):
File "C:\Program Files\Python39\lib\socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Program Files\Python39\lib\socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "C:\Program Files\Python39\lib\socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Program Files\Python39\lib\socketserver.py", line 720, in __init__
self.handle()
File "C:\Program Files\Python39\lib\http\server.py", line 427, in handle
self.handle_one_request()
File "C:\Program Files\Python39\lib\http\server.py", line 415, in handle_one_request
method()
File "C:\Users\pierr\OneDrive\Desktop\SpyWare-20210104T124335Z-001\SpyWare\Ngrok_Test.py", line 28, in do_POST
content_len = int(self.headers.getheader('content-length', 0))
AttributeError: 'HTTPMessage' object has no attribute 'getheader'
Could someone please help me fix this error ? I don't get where it comes from.
Syntax has changed. You need to use
content_len = int(self.headers.get('Content-Length'))
Instead of
content_len = int(self.headers.getheader('content-length', 0))
The rest should be the same

async with" if the event loop is running

I'm writing my first telegram bot with telepot and telethon
my main code is:
import sys
import asyncio
import random
import telepot
import telepot.aio
from telepot.aio.loop import MessageLoop
from telepot.namedtuple import ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove, ForceReply
from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton
from telepot.namedtuple import InlineQueryResultArticle, InlineQueryResultPhoto, InputTextMessageContent
async def on_chat_message(msg):
global listenFromKeyboardUsername, listenFromKeyboardPassword, listenFromKeyboardLinkGroup
content_type, chat_type, chat_id = telepot.glance(msg)
chat_id = str(chat_id)
if content_type == 'text':
name = msg["from"]["first_name"]
txt = msg['text']
# stuff..
elif userExistsInDb and userData['listenFromKeyboardLinkGroup'] and chat_id == doc.id:
group = telegramGetMessages.checkGroup(txt)
print(group)
TOKEN = "*******"
bot = telepot.aio.Bot(TOKEN)
answerer = telepot.aio.helper.Answerer(bot)
loop = asyncio.get_event_loop()
loop.create_task(MessageLoop(bot, {'chat': on_chat_message,
'callback_query': on_callback_query}).run_forever())
print('Listening ...')
loop.run_forever()
from the code above I call the checkGroup function:
def checkGroup(hash):
initClient()
global result
hash = hash.replace('https://t.me/joinchat/', '')
with TelegramClient(name, api_id, api_hash) as client:
result = client(functions.messages.CheckChatInviteRequest(hash=hash))
if isinstance(result, ChatInvite):
print('You are not inside the group')
with TelegramClient(name, api_id, api_hash) as client:
client(functions.messages.ImportChatInviteRequest(hash=hash))
result = client(functions.messages.CheckChatInviteRequest(hash=hash))
return result
where I'm getting this error:
RuntimeError: You must use "async with" if the event loop is running (i.e. you are inside an "async def")
then I edit the checkGroup function with async def checkGroup(hash): ..
but now I'm geting this error and I don't know what to do:
Task exception was never retrieved
future: <Task finished coro=<Router.route() done, defined at /home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/telepot/aio/helper.py:213> exception=NotFound('No document to update: projects/telegram-bot-4ee9f/databases/(default)/documents/users/585089661/data/groups',)>
Traceback (most recent call last):
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 57, in error_remapped_callable
return callable_(*args, **kwargs)
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/grpc/_channel.py", line 549, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/grpc/_channel.py", line 466, in _end_unary_response_blocking
raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.NOT_FOUND
details = "No document to update: projects/telegram-bot-4ee9f/databases/(default)/documents/users/585089661/data/groups"
debug_error_string = "{"created":"#1552727386.760400590","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1039,"grpc_message":"No document to update: projects/telegram-bot-4ee9f/databases/(default)/documents/users/585089661/data/groups","grpc_status":5}"
>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/telepot/aio/helper.py", line 244, in route
return await _invoke(fn, msg, *args, **kwargs)
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/telepot/aio/helper.py", line 16, in _invoke
return await fn(*args, **kwargs)
File "/home/ale/PycharmProjects/newTelegramBot/chatAsync.py", line 119, in on_chat_message
database.updateUserData(chat_id, 'groups', 'nameGroup', txt)
File "/home/ale/PycharmProjects/newTelegramBot/database.py", line 38, in updateUserData
field: key,
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/cloud/firestore_v1beta1/document.py", line 371, in update
write_results = batch.commit()
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/cloud/firestore_v1beta1/batch.py", line 148, in commit
metadata=self._client._rpc_metadata,
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/cloud/firestore_v1beta1/gapic/firestore_client.py", line 946, in commit
request, retry=retry, timeout=timeout, metadata=metadata
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/gapic_v1/method.py", line 143, in __call__
return wrapped_func(*args, **kwargs)
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/retry.py", line 270, in retry_wrapped_func
on_error=on_error,
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/retry.py", line 179, in retry_target
return target()
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/timeout.py", line 214, in func_with_timeout
return func(*args, **kwargs)
File "/home/ale/PycharmProjects/newTelegramBot/venv/lib/python3.6/site-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
six.raise_from(exceptions.from_grpc_error(exc), exc)
File "<string>", line 3, in raise_from
google.api_core.exceptions.NotFound: 404 No document to update: projects/telegram-bot-4ee9f/databases/(default)/documents/users/585089661/data/groups
/usr/lib/python3.6/asyncio/base_events.py:1441: RuntimeWarning: coroutine 'checkGroup' was never awaited
handle = None # Needed to break cycles when an exception occurs.
I'm reading around, and maybe for this problem it's better to use the delegatoBot, but I'm not really sure because I can't find great examples!
It wold be wonderfull recive a reply, If you need anything just ask!
Thankyou

Python3 - coinbase API authentication

I am trying to access my coinbase account using their API.
I am using the following code: (which is from the website https://developers.coinbase.com/docs/wallet/api-key-authentication)
import json, hmac, hashlib, time, requests
from requests.auth import AuthBase
# Before implementation, set environmental variables with the names API_KEY and API_SECRET
API_KEY = 'API_KEY'
API_SECRET = 'API_SECRET'
# Create custom authentication for Coinbase API
class CoinbaseWalletAuth(AuthBase):
def __init__(self, api_key, secret_key):
self.api_key = api_key
self.secret_key = secret_key
def __call__(self, request):
timestamp = str(int(time.time()))
message = timestamp + request.method + request.path_url + (request.body or '')
signature = hmac.new(self.secret_key, message, hashlib.sha256).hexdigest()
request.headers.update({
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': self.api_key,
})
return request
api_url = 'https://api.coinbase.com/v2/'
auth = CoinbaseWalletAuth(API_KEY, API_SECRET)
# Get current user
r = requests.get(api_url + 'user', auth=auth)
print r.json()
# {u'data': {u'username': None, u'resource': u'user', u'name': u'User'...
However I am getting the following error:
Traceback (most recent call last):
File "test1.py", line 44, in <module>
r = requests.get(api_url + 'user', auth=auth)
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\api.py", line 72, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\sessions.py", line 494, in request
prep = self.prepare_request(req)
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\sessions.py", line 437, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\models.py", line 309, in prepare
self.prepare_auth(auth, url)
File "C:\Users\lclar\virtualenv-env\lib\site-packages\requests\models.py", line 540, in prepare_auth
r = auth(self)
File "test1.py", line 29, in __call__
signature = hmac.new(self.secret_key, message, hashlib.sha256).encode("utf-8").digest()
File "C:\Users\lclar\AppData\Local\Programs\Python\Python36-32\lib\hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "C:\Users\lclar\AppData\Local\Programs\Python\Python36-32\lib\hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
Can someone please help me?
Thanks in advance.
I assuming the data type self.secret_key = secret_key is a string. For Python >= 3.4, hmac.new(key, msg=None, digestmod=''), the key must be of type bytes or bytearray per the docs: https://docs.python.org/3/library/hmac.html
Likewise to avoid the TypeError: Unicode-objects must be encoded before hashing error, do the same for the message variable as shown below:
signature = hmac.new(self.secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()

Resources