Forwarding a request to another API in Python (Rust) Robyn - python-3.x

I am using FastAPI to take in a JSON file which will then be the body of an API request out.. Orwell and Good so far. Now I want to apply the same but with robyn built on rust, instead of FastAPI. Not managed to get any joy with calling the API here at the point marked ??.
What things do I need to consider (documentation is sparse). Does robyn cut it alone, or am I missing something?
from robyn import Robyn, jsonify
app = Robyn(__file__)
#app.post("/yt")
async def json(request):
body = request["body"]
outurl = "https://translate.otherapi.com/translate/v1/translate"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer {0}".format(TOKEN)
}
?? response_data = await call_api(data)
return response_data['translations'][0]
app.start(port=5000)
With FastAPI:
import aiohttp
import aiofiles
import json
import requests
from fastapi import FastAPI, Header, Depends, HTTPException, Request
app = FastAPI()
async def call_api(data):
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
async with session.post(url, headers=headers, json=data) as resp:
response_data = await resp.json()
return response_data
#app.post("/yt")
async def root(request:Request):
data = await request.json()
file_path = "data.json"
await write_json_to_file(data, file_path)
data = await read_json_from_file(file_path)
response_data = await call_api(data)
return response_data['translations'][0]
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8001)

The author of Robyn here. I am unable to understand what you are trying to achieve here. However, there is one issue, request["body"] returns a byte string array at the moment.
You need to alter your code to this:
import json
#app.post("/yt")
async def json(request):
body = bytearray(request["body"]).decode("utf-8")
data = json.loads(body)
outurl = "https://translate.otherapi.com/translate/v1/translate"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer {0}".format(TOKEN)
}
response_data = await call_api(data)
return response_data['translations'][0]
This is peculiarity that I am not very fond of. We are hoping to fix this within the next few releases.
I hope this helped :D

Related

How to decode a base64 to an image discord.py and send it

So I found this API which which helps in image manipulation. It gives the result in base64 format. I searched a lot but couldn't find how exactly to decode base64 to an image. Here is the code:-
#bot.command()
async def image(ctx, method=None):
params = {'method': method, 'img1': 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png'}
header = {"Authorization": "mykey"}
async with aiohttp.ClientSession(headers=header) as session:
async with session.post(f'https://api.pgamerx.com/v5/canvas', params=params) as resp:
res = await resp.json()
data = res[0]["base64"]
print(data)
I print the data to get the base64 string and it was pretty huge and almost crashed my pc while pasting it. Any help would be appreciated.
(Note) There is no problem with the code, everything works fine
import io, base64 # Add these imports to the top of the file
#bot.command()
async def image(ctx, method=None):
params = {'method': method, 'img1': 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png'}
header = {"Authorization": "mykey"}
async with aiohttp.ClientSession(headers=header) as session:
async with session.post(f'https://api.pgamerx.com/v5/canvas', params=params) as resp:
res = await resp.json()
data = res[0]["base64"]
print(data)
file = discord.File(io.BytesIO(base64.b64decode(data)))
await ctx.send(file=file)
This uses base64.b64decode to decode the base64 encoded string, then wraps the result in a bytesio so that it can be read by discord.File

Authentification on Wootrade with python

I wanted to trade on Wootrade with some bots but I have a hard time getting the authentification right..
Here is my code:
import time
import hmac
from urllib.parse import urlencode
import requests
import hashlib, json, pprint
YOUR_API_SECRET = "SECRET"
YOUR_API_KEY = "KEY"
api_endpoint = "https://api.staging.woo.network/v1/client/info"
ts = int(time.time() * 1000)
hashedsig = hashlib.sha256(YOUR_API_SECRET.encode('utf-8'))
params = urlencode({
"signature" : hashedsig,
"timestamp" : ts,
})
hashedsig = hmac.new(YOUR_API_SECRET.encode(), params.encode('utf-8'), hashlib.sha256).hexdigest()
userdata = requests.get(api_endpoint,
params = {
"x-api-signature": hashedsig,
"x-api-timestamp": ts,
"x-api-key": YOUR_API_KEY
},
headers = {
"x-api-signature": hashedsig,
"x-api-timestamp": str(ts),
"x-api-key": YOUR_API_KEY
}
)
print(userdata.json())
and that's the error message:
{'success': False, 'code': -1002, 'message': 'invalid api key.'}
But I am pretty sure, that my api-key is right, I tried a new one and that didnt work either.
I tried to follow the instructions on the website: https://kronosresearch.github.io/wootrade-documents/#example
But I am not that familiar with hashing my authentication, because the exchanges I used before had either some examples in python or a package to download, so I am not sure, what I did wrong.
I am thankful for any help I can get!
Cheers!
You should also send your params in requests, the following code is how I make it work to get account orders:
import requests
import datetime
import time
import hmac
import hashlib
from collections import OrderedDict
class Client():
def __init__(self, api_key=None, api_secret=None):
self.api_key = api_key
self.api_secret = api_secret
self.base_api = "https://api.woo.network/v1/"
def get_signature(self, params, timestamp):
query_string = '&'.join(["{}={}".format(k, v) for k, v in params.items()]) + f"|{timestamp}"
signature = hmac.new(
self.api_secret.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def get_orders(self, symbol):
url = self.base_api + "orders/"
params = {
"symbol": symbol
}
params = OrderedDict(sorted(params.items()))
timestamp = str(int(time.time() * 1000))
signature = self.get_signature(params, timestamp)
headers = {
'Content-Type': "application/x-www-form-urlencoded",
'x-api-key': self.api_key,
'x-api-signature': signature,
'x-api-timestamp': timestamp,
'cache-control': 'no-cache'
}
resp = requests.get(url=url, params=params, headers=headers).json()
print(resp)
If you have any further questions, please join the WOOTRADE official telegram group and ask the admins~
(Please don't do any transfer if anyone ask you to do so in the group!)
Telegram: T.me/wootrade
Or you can try this python library for wootrade API
https://github.com/wanth1997/python-wootrade?fbclid=IwAR15onh2IX4KX85ahG-hJjXspFwhrTLHSNWGyW7n8c5kAw_8U4cQocbZEEc

Get content-length of FastAPI response

Im trying to get the content-length of FastAPI response on the server side for logging purpose. Is this possible? Thanks.
#app.get("/foo")
async def foo(background_tasks: BackgroundTasks):
data = {"foo": "foo"}
response_content_length = get_content_length()
background_tasks.add_task(log, response_content_length )
return data
You can create your own route by inheriting APIRoute class, now you should be able to log everything, without repeating yourself.
from fastapi import FastAPI, Request, Response, Body, BackgroundTasks, APIRouter
from fastapi.routing import APIRoute
from typing import Callable, List
class ContextIncludedRoute(APIRoute):
def get_route_handler(self) -> Callable:
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request) -> Response:
response: Response = await original_route_handler(request)
content_length = response.headers["content-length"]
print(content_length)
return response
return custom_route_handler
app = FastAPI()
router = APIRouter(route_class=ContextIncludedRoute)
#router.post("/dummy")
async def dummy():
return {"foo":"foo"}
app.include_router(router)

Python asynchronous function calls using aiohttp

I am trying to understand aiohttp a little better. Can someone check why my code is not printing the response of the request, instead it just prints the coroutine.
import asyncio
import aiohttp
import requests
async def get_event_1(session):
url = "https://stackoverflow.com/"
headers = {
'content-Type': 'application/json'
}
response = await session.request('GET', url)
return response.json()
async def get_event_2(session):
url = "https://google.com"
headers = {
'content-Type': 'application/json'
}
response = await session.request('GET', url)
return response.json()
async def main():
async with aiohttp.ClientSession() as session:
return await asyncio.gather(
get_event_1(session),
get_event_2(session)
)
loop = asyncio.get_event_loop()
x = loop.run_until_complete(main())
loop.close()
print(x)
Output:
$ python async.py
[<coroutine object ClientResponse.json at 0x10567ae60>, <coroutine object ClientResponse.json at 0x10567aef0>]
sys:1: RuntimeWarning: coroutine 'ClientResponse.json' was never awaited
How do i print the responses instead?
The error message you received is informing you that a coroutine was never awaited.
You can see from the aiohttp documentation that response.json() is a also a coroutine and therefore must be awaited. https://docs.aiohttp.org/en/stable/client_quickstart.html#json-response-content
return await response.json()

TypeError: _request() got an unexpected keyword argument 'cookies' (aiohttp)

import random
import asyncio
import json
import aiohttp
import sys
import urllib
from lxml.html.soupparser import parse
from aiohttp import ClientSession
from threading import Thread
def ttest():
async def fetch(url, session):
headers = {
'Host': 'example.com'
}
cookies2 = {
'test': 'test'
}
data = '{"test":"test"}'
async with session.post(url, data=data, headers=headers, cookies=cookies2) as response:
return await response.read()
async def bound_fetch(sem, url, session):
async with sem:
html = await fetch(url, session)
print(html)
async def run(r):
url = "https://test.com"
tasks = []
sem = asyncio.Semaphore(1000)
async with aiohttp.ClientSession() as session:
for i in range(r):
task = asyncio.ensure_future(bound_fetch(sem, url, session))
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
number = 1
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(number))
loop.run_until_complete(future)
ttest()
This is the error: TypeError: _request() got an unexpected keyword argument 'cookies'
I want use cookies like you see in the code, but i can not, can anyone help me?
The feature was added on aiohttp GitHub master but not released yet.
Please either install aiohttp from GitHub or wait for a while for aiohttp 3.5 release.
I hope to publish it in a few days.

Resources