Overide a GET function using python flask - python

I am developing a Python app and using flask.
I am now writing my GET functions.
Here's how it should work:
GET http://{host_ip}:{port}/GetMessage?applicationId=1
GET http://{host_ip}:{port}/GetMessage?sessionId=aaaa
GET http://{host_ip}:{port}/GetMessage?messageId=bbbb
Here is my code:
#app.route('/GetMessage')
def GetMessage():
application_id = request.args.get('application_id')
messages = Message.query.filter_by(user_id=application_id)
return render_template('get.html', messages=messages)
#app.route('/GetMessage')
def GetMessage():
message_id = request.args.get('message_id')
messages = Message.query.filter_by(message_id=message_id)
return render_template('get.html', messages=messages)
But it sends me such an error message:
AssertionError: View function mapping is overwriting an existing endpoint function: GetMessage
what can be done?
Thanks!

def GetMessage():
messages = Message.query.all()
application_id = request.args.get('application_id')
if application_id:
messages.filter_by(user_id=application_id)
message_id = request.args.get('message_id')
if message_id:
messages = message.filter_by(message_id=message_id)
return render_template('get.html', messages=messages)

Related

How do receive stream from flask server (sent via yield) with axios (react frontend)

I'm sending the stream of data from flask server via yield. I'm able to see this stream if I go directly to api url. However I don't know how to receive it on frontend. I would appreciate the help. Here is how my backend looks like:
STREAM
`
def redis_stream():
global lock
channel = r.pubsub()
channel.subscribe('CellGridMapClose')
for msg in channel.listen():
if msg['type'] == 'message':
obj = tm.CellGridMapping()
obj.ParseFromString(msg['data'])
objects = obj.objects
movement = []
for vehicle in objects:
x, y = vehicle.pos.x, vehicle.pos.y
movement.append({'posx': x/50, 'posy': y/40})
yield bytes(json.dumps(movement), 'utf-8')
`
ROUTE
`
#app.route('/redis-stream')
def redis_data():
return Response(redis_stream(), mimetype='application/json')
`
This is how my frontend looks. I've tried many variants. This is the last one, however it's not working
FRONTEND
`
const response = await axios.get("/redis-stream", {responseType: 'arraybuffer'});;
console.log(response.data);
`

Is it possible to use Flask RestX wih Flask's 2.0+ async await?

Usage of async/await was presented in Flask 2.0. (https://flask.palletsprojects.com/en/2.0.x/async-await/)
I am using Flask-RestX so is it possible to use async/await in RestX requests handlers?
Something like:
#api.route('/try-async')
class MyResource(Resource):
#api.expect(some_schema)
async def get(self):
result = await async_function()
return result
is not working and when I try to reach this endpoint I'm getting error:
TypeError: Object of type coroutine is not JSON serializable
Is there any info on that?
Package versions:
flask==2.0.1
flask-restx==0.4.0
and I've also installed flask[async] as documentation suggests.
I've gotten around this by using an internal redirect
#api.route('/try-async')
class MyResource(Resource):
#api.expect(some_schema)
def get(self):
return redirect(url_for('.hidden_async'), code=307)
#api.route('/hidden-async', methods=['GET'])
async def hidden_async():
result = await async_function()
return result
Redirecting with code=307 will ensure any method and body are unchanged after the redirect (Link). So passing data to the async function is possible as well.
#api.route('/try-async')
class MyResource(Resource):
#api.expect(some_schema)
def post(self):
return redirect(url_for('.hidden_async'), code=307)
#api.route('/hidden-async', methods=['POST'])
async def hidden_async():
data = request.get_json()
tasks = [async_function(d) for d in data]
result = await asyncio.gather(tasks)
return result

Python-Telegram-Bot: send message through bot in different module

I'm writing a Telegram bot using the python-telegram-bot library.
The bot should send a message to the user when a new YoutubeChannel is published.
I created a telegram_bot.py in which I created a TelegramBot class.
In this class I have this function:
telegram_bot.py
def __init__(self):
self.updater = Updater(token=telegram_token, use_context=True)
self.dispatcher = self.updater.dispatcher
self.updater.start_polling()
def send_message(self, text_message, context: CallbackContext):
context.bot.send_message(
chat_id="#<<my username>>", text=text_message)
And in the main.py I have a line of code that should send the message usign the aforementioned function, like this:
main.py
from telegram_bot import TelegramBot
tg_bot = TelegramBot()
tg_bot.send_message("New video!")
But, when I run the code above, I get this error:
TypeError: send_message() missing 1 required positional argument: 'context'
But in the send_message definition I already defined the context
Solved this way:
main.py
tg_bot = TelegramBot()
tg_bot.send_message("New video!", context=tg_bot.dispatcher)

Deleting Messages in Slack

Sooo, I'm relatively new to programming, and trying to learn how to consume API's. I figured I would start out by building a Slack bot for moderation purposes since I use Slack a lot. For the most part, everything works except for when I try to delete a message. The API returns saying it can't find the message even though it is there in the channel (the slack API uses timestamps to locate said message). The timestamps match, but proclaims the message doesn't exist. Here is my code:
def __init__(self, token):
self.token = token
self.users = {}
self.channels = {}
self.slack = SlackClient(self.token)
self.as_user = True
def connect(self):
if self.slack.rtm_connect():
self.post_message('#test', "*AUTOMOD* _v0.1_")
while True:
# print(self.slack.rtm_read())
self.parse_data(self.slack.rtm_read())
time.sleep(1)
def parse_data(self, payload):
if payload:
if payload[0]['type'] == 'message':
print(("user: {} message: {} channel: {}").format(payload[0]['user'], payload[0]['text'], payload[0]['channel']))
self.handle_message(payload[0])
def handle_message(self, data):
# these users can post whatever they want.
WHITELISTED = ["U4DU2TS2F", "U3VSRJJD8", "U3WLZUTQE", "U3W1Q2ULT"]
# get userid
sent_from = (data['user'])
# ignore whitelisted
if sent_from in WHITELISTED:
return
# if message was sent from someone not in WHITELISTED, delete it
else:
print(("\n\ntimestamp of message: {}").format(data['ts']))
self.delete_message(data['channel'], data['ts'])
self.post_message(data['channel'], "```" + random.choice(dongers) + "```")
def delete_message(self, channel, timestamp):
print(("deleting message in channel '{}'...").format(channel))
print("timestamp check (just to make sure): ", timestamp)
deleted = self.slack.api_call("chat.delete",
channel=channel,
timestamp=timestamp,
as_user=self.as_user
)
if deleted.get('ok'):
print("\nsuccessfully deleted.\n")
else:
print(("\ncouldn't delete message: {}\n").format(deleted['error']))
OUTPUT
timestamp of message: 1488822718.000040
deleting message in channel: 'G4DGYCW2X'
timestamp check (just to make sure...): 1488822718.000040
couldn't delete message: message_not_found
Any ideas on what could be happening? Here is the chat.delete method for context.
EDIT:
Due #pvg's recommendation of "Minimal, Complete, and Verifiable example", I have placed the ENTIRE code from the project in a gist.
One issue might be that you appear to be passing a timestamp parameter to chat.delete, when the API method takes a ts parameter instead. (See docs)

How do I return the Instagram Realtime subscription challenge?

I'm trying to subscribe to a tag. It appears that the callback URL is being called correctly with a hub.challenge and hub.mode, and I figured out how to access the challenge using self.request.get('hub.challenge'). I thought I was just supposed to echo the challenge, but that doesn't appear to work since I receive the following errors in the GAE logs:
InstagramAPIError: (400) APISubscriptionError-Challenge verification failed. Sent "647bf6dbed31465093ee970577ce1b72", received "
647bf6dbed31465093ee970577ce1b72
".
Here is the full handler:
class InstagramHandler(BaseHandler):
def get(self):
def process_tag_update(update):
update = update
mode = self.request.get('hub.mode')
challenge = self.request.get('hub.challenge')
verify_token = self.request.get('hub.verify_token')
if challenge:
template_values = {'challenge':challenge}
path = os.path.join(os.path.dirname(__file__), '../templates/instagram.html')
html = template.render(path, template_values)
self.response.out.write(html)
else:
reactor = subscriptions.SubscriptionsReactor()
reactor.register_callback(subscriptions.SubscriptionType.TAG, process_tag_update)
x_hub_signature = self.request.headers.get('X-Hub-Signature')
raw_response = self.request.data
try:
reactor.process('INSTAGRAM_SECRET', raw_response, x_hub_signature)
except subscriptions.SubscriptionVerifyError:
logging.error('Instagram signature mismatch')
So returning it as a string worked. I should have payed closer attention to the error message, but it took a helpful person on the Python IRC to point out the extra line breaks in the message. Once I put the template files on one line, it seemed to work. I can now confirm that my app is authorized via Instagram's list subscription URL.

Categories

Resources