Spring boot and python ends issue aio_pika - python

hi there am using spring boot to consume messages and expecting to receive the response at the python script where I publish the message
everything works fine and when am publishing the message the spring boot is able to consume the message
but with the python code am receiving the same request as body
import aio_pika
import asyncio
import json
from aio_pika import Message
from messaging import face_recognition_request_owner, face_recognition_exchange, face_recognition_request_owner_queue
async def process_message(message: aio_pika.IncomingMessage):
async with message.process():
print(message.info())
print(message.body)
await asyncio.sleep(1)
async def got_message(message: aio_pika.IncomingMessage):
with message.process():
print(message.body.decode())
async def main(loop):
connection = await aio_pika.connect_robust(
"amqp://guest:guest#127.0.0.1/", loop=loop
)
queue_name = face_recognition_request_owner_queue
main_exchange = face_recognition_exchange
routing_key = face_recognition_request_owner
# Creating channel
channel = await connection.channel()
# Declaring exchange
exchange = await channel.declare_exchange(
name=main_exchange,
type="direct",
auto_delete=False,
durable=False,
)
# Maximum message count which will be
# processing at the same time.
await channel.set_qos(prefetch_count=100)
# Declaring queue
queue = await channel.declare_queue(queue_name, auto_delete=False)
# Binding queue
await queue.bind(exchange, routing_key)
await exchange.publish(
Message(
bytes(json.dumps({'userId': "e4271f86-b933-465e-ae3f-f0b93335c773"}), "utf-8"),
content_type="application/json",
),
routing_key
)
await queue.consume(process_message)
return connection
if __name__ == "__main__":
loop = asyncio.get_event_loop()
connection = loop.run_until_complete(main(loop))
try:
loop.run_forever()
finally:
loop.run_until_complete(connection.close())
the spring code is :
#RabbitListener(queues = BackendCodes.LOAD_OWNER_QUEUE)
public Users loadOwner(FetchOwnerRequest fetchOwnerRequest) {
LOGGER.info("message: {}", fetchOwnerRequest.getUserId());
LOGGER.info("Processed and returned message");
return usersService.loadByOwnerId(fetchOwnerRequest.getUserId());
}
am getting this response
{'body_size': 50, 'headers': {}, 'content_type': 'application/json', 'content_encoding': '', 'delivery_mode': 1, 'priority': 0, 'correlation_id': None, 'reply_to': None, 'expiration': None, 'message_id': '932b3e80e2ff6df9b5408b8f6d788f1b', 'timestamp': None, 'type': 'None', 'user_id': None, 'app_id': None, 'cluster_id': '', 'consumer_tag': 'ctag1.b7b5aa77e52adde6ee9cfeb6135e9fac', 'delivery_tag': 2, 'exchange': 'face-recognition:exchange', 'redelivered': True, 'routing_key': 'face-recognition.requestOwner'}
b'{"userId": "e4271f86-b933-465e-ae3f-f0b93335c773"}'
thanks for helping

Related

Warning discord.getaway "discord.gateway: Shard ID None heartbeat blocked for more than 10 seconds."

I tried to write a Discord bot that forwards messages from one server to another. But I get a warning that disconnects my connection to the discord gateway. I read that it is possible because of tyme.slep(), but without it, the connection is always interrupted. As I understand it, DDOS protection is activated due to a large number of requests.
import asyncio
import websocket
import json
from threading import Thread
import discord
import requests
from io import BytesIO
import time
from discord.ext import tasks
# Bot
bot_token = "anything"
user_token = "anything"
client = discord.Client(intents=discord.Intents.default())
# Channels list
f = open('channels.txt', 'r')
channels_file = f.read()
channels_array = channels_file.strip().split('\n')
# Connect func
def send_json_request(ws, request):
ws.send(json.dumps(request))
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
#WebSoket
def on_closed(ws):
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
ws = websocket.WebSocket(on_close=on_closed)
ws.connect("wss://gateway.discord.gg/?v=6&encording=json")
def receive_json_response(ws):
response = ws.recv()
if response:
return json.loads(response)
def get_attachment_media(media):
media_array = []
for i in media:
response = requests.get(i['url'])
im = BytesIO(response.content)
print(im)
media_array.append(discord.File(im))
return media_array
def get_channel(id):
for i in channels_array:
if i == id:
return True
return False
#Heartbeat
def heartbeat(interval):
print("Heartbeat begin")
while True:
time.sleep(interval)
heartbeatJSON = {
"op": 1,
"d": "null"
}
send_json_request(ws, heartbeatJSON)
print("Heartbeat sent")
#tasks.loop(seconds=0.5)
async def main():
channel = client.get_channel(anything)
event = receive_json_response(ws)
try:
if event['d']['author']['id'] == 'anything':
return
id_channel = event['d']['channel_id']
id_guild = event['d']['guild_id']
if get_channel(id_channel):
content = event['d']['content']
attachment_media = get_attachment_media(event['d']['attachments'])
await channel.send(content, files=attachment_media)
op_code = event('op')
if op_code == 11:
print('Heartbeat recieved')
except:
pass
#client.event
async def on_ready():
event = receive_json_response(ws)
heartbeat_interval = event['d']['heartbeat_interval'] / 1000
send_json_request(ws, {
"op": 2,
"d": {
"token": user_token,
"properties": {
"$os": 'linux',
"$browser": 'chrome',
"$device": 'pc'
}
}
})
main.start()
asyncio.run(heartbeat(heartbeat_interval))
client.run(bot_token)
I recommend you to check this answer and adjust it to your code.
However, if you are just trying to make your bot copy the contenet of the messages sent in one server and sending to another one, you can do it in a easier way using the on_message() event. This is the entire code, which should also prevent any warning (unless the bot tries to send too many messages in a short period of time):
import discord
intents = discord.Intents.default()
intents.message_content = True # You are missing the message_content intent! (needed to read the content of the guild's messages)
client = discord.Client(intents=intents)
TOKEN = "Your Token"
guild_id = 123456789 # The guild you want your bot to send the messages to
channel_id = 987654321 # The channel of the guild you want your bot to send the messages to
guild = None
channel = None
#client.event
async def on_ready():
global guild, channel, guild_id, channel_id
await client.wait_until_ready()
guild = client.get_guild(guild_id)
channel = guild.get_channel(channel_id)
print("Logged")
#client.event
async def on_message(message : discord.Message):
if message.author == client.user: # You don't want to send the own bot messages
return
if message.guild.id == guild_id: # You don't want to send the messages from the own guild your bot is sending the messages to
return
await channel.send(f"{message.author}: {message.content}") # Add attachments if you want
client.run(TOKEN)

Django Channels sending multiple messages to same channel

Referring to documentation here
I'm sending messages to the single fetched channel_name
I'm able to successfully send messages to the specific channel
Issues I'm facing
On the channels it's sending messages multiple times
For Example -
When I send first message, I receive 1 time.
On second message, I'm getting same messages twice.
On third message, I'm geting same message 3 times.
and so on...
class ChatConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.user_id = self.scope['url_route']['kwargs']['user_id']
await self.save_user_channel()
await self.accept()
async def disconnect(self, close_code):
await self.disconnect()
async def receive_json(self, text_data=None, byte_data=None):
message = text_data['message']
to_user = text_data['to_user']
to_user_channel, to_user_id = await self.get_user_channel(to_user)
channel_layer = get_channel_layer()
await channel_layer.send(
str(to_user_channel), {
'type': 'send.message',
'from_user': self.user_id,
'to_user': str(to_user_id),
'message': message,
}
)
await channel_layer.send(
str(self.channel_name), {
'type': 'send.message',
'from_user': self.user_id,
'to_user': str(to_user_id),
'message': message,
}
)
async def send_message(self, event):
from_user = event['from_user']
to_user = event['to_user']
message = event['message']
await self.send(text_data=json.dumps({
'from_user': from_user,
'to_user': to_user,
'message': message,
}))
#database_sync_to_async
def get_user_channel(self, to_user):
try:
self.send_user_channel = ChatParticipantsChannel.objects.filter(
user=to_user).latest('id')
channel_name = self.send_user_channel
user_id = self.send_user_channel.user.user_uid
except Exception as e:
self.send_user_channel = None
channel_name = None
return channel_name, user_id
#database_sync_to_async
def save_user_channel(self):
self.user = User.objects.get(user_uid=self.user_id)
ChatParticipantsChannel.objects.create(
user=self.user,
channel=self.channel_name
)
#database_sync_to_async
def delete_user_channel(self):
ChatParticipantsChannel.objects.filter(user=self.user).delete()

how to delete a previous message if we get new message in django channels

I want to broadcast the only latest message of Django-channel layer in a specific room. Right now I have created specific room names for specific users. Now I just want to send them only latest message or note, I don't want to show all the previous messages. Right now all the previous message are showing to user side.
# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ProjectConsumer(AsyncWebsocketConsumer):
async def connect(self):
parameter = self.scope['url_route']['kwargs']["project_key"]
print("url_parameter ",parameter)
self.room_name = parameter
# Join room group
await self.channel_layer.group_add(
self.room_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_name,
self.channel_name
)
# Receive message from WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
instance_user = text_data_json['instance_user']
sender = text_data_json['sender']
receiver = text_data_json['receiver']
message = text_data_json['message']
object = {
'sender':sender,
'receiver':receiver,
'message':message,
}
# Send message to room group
await self.channel_layer.group_send(
self.room_name,
{
'type': 'sent', #function name as an event type
'object': object #function parameters as an event object
}
)
# Receive message from room group
async def sent(self, event):
sender = event['object']["sender"]
receiver = event['object']["receiver"]
message = event['object']["message"]
# Send message to WebSocket
await self.send(text_data=json.dumps({
'sender':sender,
'receiver':receiver,
'message':message,
}))
Channel_layer broadcasts only the available message, you are probably appending the message to a DOM element in your front-end

How to Index Websocket Data Stream

I've successfully connected to the Bitstamp websocket and I am now attempting to index the data stream that I receive. Specifically, I want to save bids[0][0] into a best_price variable:
{'data': {'timestamp': '1615553987', 'microtimestamp': '1615553987492634', 'bids': [['56355.57', '0.09439734'], ['56347.20', '0.03743896'], ['56346.03', '0.47172493']....etc
The problem is that I get a "subscription succeeded" message when I first connect:
{'event': 'bts:subscription_succeeded', 'channel': 'order_book_btcusd', 'data': {}}
This means I get the following error, because I cannot index the None returned from the empty data steam:
IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed
Here is my code
import asyncio
import websockets
import json
import numpy as np
def error_handler(err):
pass
def handler(msg):
pass
async def bitstamp_connect(callback):
uri = "wss://ws.bitstamp.net/"
subscription = {
"event": "bts:subscribe",
"data": {
"channel": "order_book_btcusd"
}
}
async with websockets.connect(uri) as websocket:
await websocket.send(json.dumps(subscription))
while True:
msg = json.loads(await websocket.recv())
bids = np.array(msg['data'].get('bids'))
#print(bids)
print(bids[0][0])
asyncio.get_event_loop().run_until_complete(bitstamp_connect(handler))
The problem can be easily solved by simply adding an if statement checking if the message received was a 'subscription successful' message or a 'data' message. Change your while loop to the following:
while True:
msg = json.loads(await websocket.recv())
# Check what type of message we received
if msg['event'] == 'data':
bids = np.array(msg['data'].get('bids'))
print(bids[0][0])
elif msg['event'] == 'bts:subscription_succeeded':
# You can put code here if you want to do something when first subscribing
pass

Why is my websocket request "unauthorized" only when written in OOP, when the same works perfectly when written with just functions?

I'm writing a Python program that does some trading automation. The API I work with is from Deribit, whose preferred transport mechanism is Websocket. I'm a complete newbie to Python's websockets and asyncio modules.
Here's the code I first wrote for authenticating my client and then sending a separate private message to get an order position from the account, written only with functions and no classes:
import asyncio
import websockets
import json
CL_ID = 'qxv0EeAu'
CL_SECRET = 't24F49ocH1_qFawiKnEyqlWF5D-haABb31O8xCQhySg'
REQ_URL = 'wss://test.deribit.com/ws/api/v2'
acc_token = ''
msg = {
"jsonrpc": "2.0",
"id": 1,
"params": {}
}
async def auth_api():
global msg
global acc_token
msg["method"] = "public/auth"
msg["params"] = {
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET,
"scope": "session:test"
}
async with websockets.connect(REQ_URL) as websocket:
await websocket.send(json.dumps(msg))
while websocket.open:
response = await websocket.recv()
response_json = json.loads(response)
acc_token = response_json["result"]["access_token"]
return
async def get_position(websocket, instrument):
global msg
global acc_token
msg["id"] += 1
msg["method"] = "private/get_position"
msg["params"] = {
"access_token": acc_token,
"instrument_name": instrument
}
await websocket.send(json.dumps(msg))
while websocket.open:
response = await websocket.recv()
return response
async def main():
global msg
await auth_api()
async with websockets.connect(REQ_URL) as websocket:
response = await get_position(websocket, "BTC-PERPETUAL")
print(response)
asyncio.get_event_loop().run_until_complete(main())
It works perfectly fine. Here's my result:
{"jsonrpc":"2.0","id":2,"result":{"total_profit_loss":0.000209124,"size_currency":-0.017402402,"size":-150.0,"settlement_price":8649.9,"realized_profit_loss":2.67e-7,"open_orders_margin":0.0,"mark_price":8619.5,"maintenance_margin":0.000100079,"leverage":100,"kind":"future","instrument_name":"BTC-PERPETUAL","initial_margin":0.000174039,"index_price":8619.45,"floating_profit_loss":0.000061161,"estimated_liquidation_price":-14.95,"direction":"sell","delta":-0.017402402,"average_price":8724.34},"usIn":1573756522511975,"usOut":1573756522512240,"usDiff":265,"testnet":true}
I decided to rewrite it the OOP way, and here's the class I created (the file is named "Call_Deribit"):
import asyncio, websockets, json
class WSClient():
def __init__(self, key=None, secret=None, url=None):
self.api_key = key
self.api_secret = secret
self.msg = {
"jsonrpc": "2.0",
"id": 0
}
if url:
self.host = url
else:
self.host = 'wss://test.deribit.com/ws/api/v2'
async def call_api(self, msg):
async with websockets.connect(self.host) as websocket:
print("Connected to URL:", self.host)
try:
await websocket.send(msg)
while websocket.open:
response = await websocket.recv()
response_json = json.loads(response)
return response_json
except Exception as e:
return e
def request(self, method, params, session=None):
msg = self.msg
msg["id"] += 1
msg["method"] = method
msg["params"] = params
if session != None:
msg["params"]["scope": "session:{}".format(session)]
return asyncio.get_event_loop().run_until_complete(self.call_api(json.dumps(msg)))
def get_order_book(self, instrument):
method = "public/get_order_book"
params = {
"instrument_name": instrument
}
return self.request(method, params)
And here's the main file I'm accessing the class from and where I make all the requests:
import json, asyncio, websockets
from Call_Deribit import WSClient
CL_ID = 'qxv0EeAu'
CL_SECRET = 't24F49ocH1_qFawiKnEyqlWF5D-haABb31O8xCQhySg'
REQ_URL = 'wss://test.deribit.com/ws/api/v2'
method_auth = "public/auth"
params_auth = {
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET
}
main_client = WSClient(key=CL_ID, secret=CL_SECRET, url=REQ_URL)
auth_response = main_client.request(method_auth, params_auth)
acc_token = auth_response["result"]["access_token"]
method_pos = "private/get_position"
params_pos = {
"access_token": acc_token,
"instrument_name": "BTC-PERPETUAL"
}
position = main_client.request(method_pos, params_pos)
print(position)
The first request for authentication is working this time, and I'm able to extract the access token as well, but the second private/get_position message is, for whatever reason, returning an unauthorized error.
{'jsonrpc': '2.0', 'id': 1, 'error': {'message': 'unauthorized', 'code': 13009}, 'testnet': True, 'usIn': 1573756936534405, 'usOut': 1573756936534629, 'usDiff': 224}
I've spent hours on it, and I seem to be doing exactly the same thing in the OOP version as I did on the original one. My familiarity with OOP and its concepts (such as inheritance) is limited, so I'd like to know what I'm missing here, and why my code isn't working in the OOP version, despite following the same exact workflow as in the original version.
Here's the documentation for the Deribit API: https://docs.deribit.com/v2/?python#json-rpc
Any help would be greatly appreciated.
Adding the scope under params_auth in the main file works:
params_auth = {
"grant_type": "client_credentials",
"client_id": CL_ID,
"client_secret": CL_SECRET,
"scope": "session:test"
}

Categories