I am rewriting my discord bot wrapper to update it and make it more asynchronous, its been almost two years since I made it, I am using discord.py 2.0.0 I was using 1.6 i believe.
My main file is Helix.py:
"""
asynchronous Helix Bot Wrapper class
"""
### Imports ###
import os
import colorlog
import datetime
import discord
import sys
import helix_bot.bot.utility.config as cfg
import logging
from datetime import datetime
from discord.ext import commands
from sqlalchemy_utils import database_exists, create_database
## Logging set up and format with colorlog
log = logging.getLogger("HELIX_BOT")
# Change recursion limit to avoid errors
sys.setrecursionlimit(100000)
### HELIX BOT CLASS ###
class Helix(commands.AutoShardedBot):
def __init__(self, config=None):
# Set config
self.aio_session = None
if config is None:
config = cfg.ConfigDefaults.Config_file
self.description = """
Helix - A Custom Bot for SinLess Games Official Discord Server and more!
"""
self.config = cfg.Config(config)
#####################################
### SETUP VARIABLES FOR HELIX ###
#####################################
### GENERAL VARIABLES ###
self.Version = self.config.version
self.owner_id = self.config.owner_id
self.owner = self.config.owner
### DISCORD VARIABLES ###
self.TOKEN = self.config.login_token
self.applicationID = self.config.applicationID
self.invite_url = self.config.InviteURL
self.PublicKey = self.config.PublicKey
self.ClientID = self.config.ClientID
self.ClientSecret = self.config.ClientSecret
self.Prefix = self.config.prefix
### SQL VARIABLES ###
self.sql_host = self.config.sql_host
self.sql_user = self.config.sql_user
self.sql_pass = self.config.sql_passwd
self.sql_ddb = self.config.sql_ddb
self.Model_Version = self.config.model_version
self.db_connect = f'mysql+pymysql://{self.sql_user}:{self.sql_pass}#{self.sql_host}/{self.sql_ddb}'
### DEBUG VARIABLES ###
self.debug_level = self.config.debug_level
self.show_config = self.config.Show_Config
self.log_channel = self.config.Log_Channel
### SPOTIFY VARIABLES ###
self.spotify_client_id = self.config.spotify_client_id
self.spotify_client_secret = self.config.spotify_client_secret
### PERMISSIONS ###
self.dev_ids = self.config.devids
self.bot_exception_ids = self.config.bot_exception_ids
########################
### LOGGING SETTINGS ###
########################
### SET LOG LEVEL ###
self.debug_level = 'DEBUG'
log.setLevel(self.debug_level)
self.log_file = 'logs/helix.log'
### CREATE HANDLER ###
self.helix_h = logging.FileHandler(self.log_file)
self.helix_h.setLevel(self.debug_level)
### CONSOLE HANDLER ###
CH = logging.StreamHandler()
CH.setLevel(self.debug_level)
### FORMATTER ###
self.formatter = colorlog.ColoredFormatter(
"%(log_color)s[%(asctime)s] [%(levelname)s] %(message)s",
datefmt=None,
reset=True,
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'bold_red',
'EVERYTHING': 'white',
'NOISY': 'white',
'FFMPEG': 'bold_purple',
'VOICEDEBUG': 'purple',
},
secondary_log_colors={},
style='%'
)
self.helix_h.setFormatter(self.formatter)
CH.setFormatter(self.formatter)
log.addHandler(self.helix_h)
log.addHandler(CH)
log.info("Logging set up")
intents = discord.Intents.all()
log.info("Intents set up")
log.debug("Intents: {}".format(intents))
### LOAD BOT ###
super().__init__(
command_prefix=self.Prefix,
intents=intents,
description=self.description,
case_insensitive=True,
start_time=datetime.utcnow(),
)
### Remove help command ###
super().remove_command('help')
### Build Database ###
self.build_database()
def build_database(self):
if not database_exists(self.db_connect):
log.info("Creating database...")
create_database(self.db_connect)
log.info("Database created")
else:
log.info("Database already exists")
### RUN Helix Bot Async ###
async def run(self, **kwargs):
log.info("Starting Helix...")
try:
await self.login(self.TOKEN)
except Exception as e:
log.error(f'{type(e).__name__} - {e}')
log.info("Helix Logged in as {}#{}".format(self.user.name, self.user.discriminator))
log.info("Waiting {}#{} for to be Ready...".format(self.user.name, self.user.discriminator))
try:
await self.wait_until_ready()
except Exception as e:
log.error(f'{type(e).__name__} - {e}')
log.info("{}#{} is ready".format(self.user.name, self.user.discriminator))
try:
await self.change_presence(activity=discord.Game(name="Helix"))
except Exception as e:
log.error(f'{type(e).__name__} - {e}')
log.info("{}#{} is ready!".format(self.user.name, self.user.discriminator))
try:
await self.load_extensions()
except Exception as e:
log.error(f'{type(e).__name__} - {e}')
log.info("{}#{}is loaded!".format(self.user.name, self.user.discriminator))
### LOAD_EXTENSIONS Async ###
async def load_extensions(self):
for filename in os.listdir('./bot/cogs'):
if filename.endswith('.py'):
log.info("Loading {}...".format(filename))
self.load_extension(f'bot.cogs.{filename[:-3]}')
log.info("Loaded Cog {}".format(filename))
### command to unload a cog ###
#commands.command(name='unload', aliases=['unload_cog'])
#commands.is_owner()
async def unload_cog(self, ctx, *, cog: str):
"""Unloads a cog"""
try:
await self.unload_extension(cog)
await ctx.send(f'Unloaded {cog}')
except Exception as e:
await ctx.send(f'{type(e).__name__} - {e}')
### command to reload a cog ###
#commands.command(name='reload', aliases=['reload_cog'])
#commands.is_owner()
async def reload_cog(self, ctx, *, cog: str):
"""Reloads a cog"""
try:
await self.unload_extension(cog)
self.load_extension(cog)
await ctx.send(f'Reloaded {cog}')
except Exception as e:
await ctx.send(f'{type(e).__name__} - {e}')
### LOAD_EXTENSION ###
def load_extension(self, extension, **kwargs):
try:
self.load_extension(extension)
except Exception as e:
log.error(f'{type(e).__name__} - {e}')
and the file i use to run it is :
import threading
import asyncio
from bot.helix import Helix
async def main():
bot = Helix()
await bot.run()
if __name__ == '__main__':
threading.Thread(target=asyncio.run(main())).start()
My main question is even after 2 hours of letting it run, it never reaches ready status that last thing it will say is waiting for helix to be ready.
I have looked around and ready that it does take 75% longer to ready, according to the official documentation. But 2 hours and still nor ready. Dis I do something wrong or what is my problem. I have searched through what i could, and as far as i know it should work. Though i will continue to look.
The client will never properly become ready because you need to connect AND login. You can also simply use the [Client].start instead.
From the docs here:
await login(token)
Logs in the client with the specified credentials and calls the setup_hook().
await connect(*, reconnect=True)
Creates a websocket connection and lets the websocket listen to messages from Discord. This is a loop that runs the entire event system and miscellaneous aspects of the library. Control is not resumed until the WebSocket connection is terminated.
Using start will properly start the bot.
await start(token, *, reconnect=True)
A shorthand coroutine for login() + connect().
Related
I am trying to measure Bluetooth signal strength using winrt APi in python using winsdk. My workflow is to measure Bluetooth Signal strength of a device that is already connected with my Windows machine. I followed the guideline from Pywinrt documentation found here:
Here is my code snippet:
import asyncio
import winsdk.windows.devices.enumeration as e
import winsdk.windows.devices.bluetooth as bl
async def scan():
sig_strength = "System.Devices.Aep.SignalStrength"
additionalProperties = [sig_strength]
watcher = e.DeviceInformation.create_watcher(bl.BluetoothDevice.get_device_selector(), additionalProperties)
received_queue = asyncio.Queue()
def added_w(device_watcher, device_info_update):
if(device_info_update.name == "my_device"):
print("found!")
for value, key in enumerate(device_info_update.properties):
if key == "System.Devices.Aep.SignalStrength":
print("signal strength: {}".format(value) )
def updated_w(device_watcher, device_info_update):
print("update for {} with kind {}".format(device_info_update.id, device_info_update.kind))
def removed_w(device_watcher, device_info_update):
pass
def stopped_w(device_watcher, device_info_update):
pass
received_token = watcher.add_added(
lambda s, e: event_loop.call_soon_threadsafe(added_w, s, e)
)
updated_token = watcher.add_updated(
lambda s, e: event_loop.call_soon_threadsafe(updated_w, s, e)
)
removed_token = watcher.add_removed(
lambda s, e: event_loop.call_soon_threadsafe(removed_w, s, e)
)
event_loop = asyncio.get_running_loop()
stopped_future = event_loop.create_future()
def handle_stopped(sender, event_args):
stopped_future.set_result(event_args)
try:
print("scanning...")
watcher.start()
# this is the consumer for the received event queue
async def print_received():
while True:
event_args = await received_queue.get()
print(
"received:",
event_args.bluetooth_address.to_bytes(6, "big").hex(":"),
event_args.raw_signal_strength_in_d_bm, "dBm",
)
printer_task = asyncio.create_task(print_received())
# since the print task is an infinite loop, we have to cancel it when we don't need it anymore
stopped_future.add_done_callback(printer_task.cancel)
# scan for 30 seconds or until an unexpected stopped event (due to error)
done, pending = await asyncio.wait(
[stopped_future, printer_task], timeout=30, return_when=asyncio.FIRST_COMPLETED
)
if stopped_future in done:
print("unexpected stopped event", stopped_future.result().error)
else:
print("stopping...")
watcher.stop()
await stopped_future
finally:
# event handler are removed in a finally block to ensure we don't leak
watcher.remove_received(received_token)
watcher.remove_stopped(handle_stopped)
asyncio.run(scan())
However, I only get a fixed RSSI value 8 in my print in added_w function.
Any help on potential solution would be greatly appreciated!
I would like to serve both gRPC and HTTP in my flow, but the flow description only allows a single value in the protocol parameter. Is it possible to add both? If not, do i have to deploy two flows or is there a better workaround?
The documentation doesn't mention if i can have two gateways from what i can see?
f = Flow(protocol='grpc', port=12345).add(uses=FooExecutor)
with f:
client = Client(port=12345)
docs = client.post(on='/')
print(docs.texts)
Unfortunately by default, no.
But you can develop your own custom gateway that enables both protocols at the same time.
A sample custom gateway looks like the following (borrowed from here)
import grpc
from grpc_health.v1 import health, health_pb2, health_pb2_grpc
from grpc_reflection.v1alpha import reflection
from pydantic import BaseModel
from uvicorn import Config, Server
from jina import Gateway, __default_host__
from jina.proto import jina_pb2, jina_pb2_grpc
class DummyResponseModel(BaseModel):
protocol: str
class MultiProtocolGateway(Gateway):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.http_port = self.ports[0]
self.grpc_port = self.ports[1]
self.health_servicer = health.HealthServicer(experimental_non_blocking=True)
async def _setup_http_server(self):
from fastapi import FastAPI
app = FastAPI(
title='HTTP Server',
)
#app.get(path='/', response_model=DummyResponseModel)
def _get_response():
return {'protocol': 'http'}
self.http_server = Server(
Config(app, host=__default_host__, port=self.http_port)
)
async def _setup_grpc_server(self):
self.grpc_server = grpc.aio.server()
jina_pb2_grpc.add_JinaRPCServicer_to_server(
self.streamer._streamer, self.grpc_server
)
service_names = (
jina_pb2.DESCRIPTOR.services_by_name['JinaRPC'].full_name,
reflection.SERVICE_NAME,
)
# Mark all services as healthy.
health_pb2_grpc.add_HealthServicer_to_server(
self.health_servicer, self.grpc_server
)
for service in service_names:
self.health_servicer.set(service, health_pb2.HealthCheckResponse.SERVING)
reflection.enable_server_reflection(service_names, self.grpc_server)
self.grpc_server.add_insecure_port(f'{__default_host__}:{self.grpc_port}')
await self.grpc_server.start()
async def setup_server(self):
await self._setup_http_server()
await self._setup_grpc_server()
async def run_server(self):
await self.http_server.serve()
await self.grpc_server.wait_for_termination()
async def shutdown(self):
self.http_server.should_exit = True
await self.grpc_server.stop(0)
await self.http_server.shutdown()
self.health_servicer.enter_graceful_shutdown()
#property
def _should_exit(self) -> bool:
return self.http_server.should_exit
And you can access it in the following way:
from xxx import MultiProtocolGateway
from xxx import MyExecutor
from jina import Flow, Client, DocumentArray
http_port = 51000
grpc_port = 52000
flow = Flow().config_gateway(
uses=MultiProtocolGateway,
port=[http_port, grpc_port],
protocol=['http', 'grpc'],
).add(MyExecutor)
with flow:
c1 = Client(host='http://0.0.0.0:51000)
c1.post(on='/', inputs=DocumentArray().empty(5))
c2 = Client(host='grpc://0.0.0.0:52000)
c2.post(on='/', inputs=DocumentArray().empty(5))
async def simultaneous_chunked_download(urls_paths, label):
timeout = ClientTimeout(total=60000)
sem = asyncio.Semaphore(5)
async with aiohttp.ClientSession(timeout=timeout, connector=aiohttp.TCPConnector(verify_ssl=False)) as cs:
async def _fetch(r, path):
async with sem:
async with aiofiles.open(path, "wb") as f:
async for chunk in r.content.iter_any():
if not chunk:
break
size = await f.write(chunk)
if not indeterminate:
bar._done += size
bar.show(bar._done)
if indeterminate:
bar._done += 1
bar.show(bar._done)
indeterminate = False
total_length = 0
tasks = []
for url, path in urls_paths.items():
r = await cs.get(url)
if not indeterminate:
try:
total_length += r.content_length
except Exception:
indeterminate = True
tasks.append(_fetch(r, path))
verbose_print(f"url: {url},\npath: {path}\n\n")
if not indeterminate:
bar = progress.Bar(
expected_size=total_length, label=label, width=28, hide=False
)
else:
bar = progress.Bar(
expected_size=len(tasks), label=label, width=28, hide=False
)
logger._pause_file_output = True
bar.show(0)
bar._done = 0
await asyncio.gather(*tasks)
logger._pause_file_output = False
bar.done()
The function I have above is for downloading a dictionary of urls asynchronously and then printing out a progress bar. An example of its usage:
The code itself runs perfectly fine, however i keep getting these errors:
Whilst benign, they are an eyesore and could point towards my lack of knowledge on both http and asynchronous code, so i would rather try and get it fixed. However im at a loss on where or what is causing it, especially as i like i said the code runs perfectly fine regardless.
If you would like a more practical hands on attempt at recreating this the full code is on my github repo on the dev branch: https://github.com/ohitstom/spicetify-easyinstall/tree/dev
Most of the program can be disregarding if you are testing this out, just press the install button and the problematic code will show itself towards the end.
Bare in mind this is a spotify themer so if you have spotify/spicetify installed you will want to use a vm.
FIXED!:
# Create App
globals.app = QtWidgets.QApplication(sys.argv)
globals.app.setStyleSheet(gui.QSS)
# Configure asyncio loop to work with PyQt5
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
loop = QEventLoop(globals.app)
asyncio.set_event_loop(loop)
# Setup GUI
globals.gui = gui.MainWindow()
globals.gui.show()
# Set off loop
with loop:
sys.exit(loop.run_until_complete(globals.gui.exit_request.wait()))
class MainWindow(QuickWidget):
def __init__(self):
super().__init__(
name="main_window",
...etc
)
self.exit_request = asyncio.Event()
......etc
def closeEvent(self, *args):
self.exit_request.set()
Asyncio and aiohttp have some problems when running a lot of tasks concurrently on Windows, I've been having a lot of problems with it lately.
There are some workarounds available, the ones I use most are:
# set this before your event loop initialization or main function
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
Or:
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
loop.run_until_complete(your_main())
I am trying to build a telegram bot to play games for my son.
Basically, I want to get a response from the bot by using a command handler.
when I request a command handler it should give me a random response from 2 different lists.
The game is predicting food dish name like "apple pie", apple will be in list 1 and pie will be in list 2
and the bot should get different values from the list and give a response as one message via command handler.
Will appreciate your guidance/help
Below is the python code:
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from telegram import error, update
import sys
import os
import random
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
def start(update, context):
"""Send a message when the command /start is issued."""
update.message.reply_text('Hello, play games!')
def shuffle2d(arr2d, rand_list=random):
"""Shuffes entries of 2-d array arr2d, preserving shape."""
reshape = []
data = []
iend = 0
for row in arr2d:
data.extend(row)
istart, iend = iend, iend+len(row)
reshape.append((istart, iend))
rand_list.shuffle(data)
return [data[istart:iend] for (istart,iend) in reshape]
def show(arr2d):
"""Shows rows of matrix (of strings) as space-separated rows."""
show ("\n".join(" ".join(row) for row in arr2d))
A = A.rand_list['APPLE, PUMKIN, STRAWBERRY, BANANA,CHOCOLATE']
B = B.rand_list['PIE, ICE-CREAM, CAKE,SHAKE']
arr2d = []
arr2d.append([A+(j) for j in range(1,B+1)])
show(shuffle2d(arr2d))
print(show)
return show
def play(update, context):
"""Send a message when the command /play is issued."""
update.message.reply_text(shuffle2d)
def main():
"""Start the bot."""
# Create the Updater and pass it your bot's token.
# Make sure to set use_context=True to use the new context based callbacks
# Post version 12 this will no longer be necessary
updater = Updater("1XXXXXXX:XXXXXXXXXXXXXXXXXXY", use_context=True)
# Get the dispatcher to register handlers
dp = updater.dispatcher
# on different commands - answer in Telegram
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("play", play))
# on noncommand i.e message - echo the message on Telegram
dp.add_handler(MessageHandler(Filters.text, play))
# Start the Bot
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()
In this code you use a function called shuffleDish() that creates a string containing two random words chosen from separated list and it's called from the commandhandler "play"
from telegram.ext import Updater, CommandHandler
from telegram import error, update
import random
import logging
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def shuffleDish():
A = ['APPLE', 'PUMKIN', 'STRAWBERRY', 'BANANA', 'CHOCOLATE']
B = ['PIE', 'ICE-CREAM', 'CAKE', 'SHAKE']
dish = random.choice(A)+" "+random.choice(B)
return dish
def play(update, context):
update.message.reply_text(shuffleDish())
def error(update, context):
logger.warning('Update "%s" caused error "%s"', update, context.error)
def main():
updater = Updater(tgtoken, use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler("play", play))
dp.add_error_handler(error)
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
I am struggling to solve my issue, hope anyone from the community can help me here.
Our requirement is locked and can't be changed as the producer publishing the queues is controlled by a different team.
Producer which is written in JAVA declares three queues (TASK, RESPONSE, TASK_RESPONSE) and listens on them with the help of spring framework.
A hashmap is sent to the TASK and TASK_RESPONSE queue from the java AMQP client (Producer).
We need to consume these hashmaps and send the responses as follows.
If the queue TASK is processed, the response needs to be sent on RESPONSE queue incrementally.
If the queue TASK_RESPONSE is processed, the response needs to be sent on TASK_RESPONSE queue incrementally (RPC mode).
Now, we need to consume and publish this in python since we need to do some background processing on the tasks.
I tried to work with celery and dramatiq, but was not able to figure out how it can be done with them, so I tried writing myself (with the help of tutorials available online)
Problem is, I am able to consume the messages but not able to reply_to the RESPONSE queue. Here is my code.
from collections import OrderedDict
from concurrent.futures import ThreadPoolExecutor
import pika
import datetime
import logging
import json
from logging import StreamHandler
from time import sleep
from random import randint
from pika import SelectConnection
from settings import *
logging.basicConfig(handlers=[StreamHandler()], level=logging.INFO, format=logging.BASIC_FORMAT)
_logger = logging.getLogger(__name__)
class QueueConsumer(object):
"""The consumer class to manage connections to the AMQP server/queue"""
def __init__(self, queue, logger, parameters, thread_id=0):
self.channel = None
self.connection = None
self.queue_name_task = queue['task']
self.queue_name_response = queue['response']
self.logger = logger
self.consumer_id = 'Consumer Thread: %d' % (thread_id,)
self.parameters = pika.ConnectionParameters(**parameters)
def consume(self):
try:
self.connection = SelectConnection(parameters=self.parameters, on_open_callback=self._on_connected)
self.connection.ioloop.start()
except Exception as e:
self.logger.error('{} {}'.format(self.consumer_id, str(e)))
self.connection.close()
self.connection.ioloop.start()
def _on_connected(self, connection):
connection.channel(on_open_callback=self._on_channel_open)
def _on_channel_open(self, channel):
self.channel = channel
try:
# Declare Task Queue
self.channel.queue_declare(queue=self.queue_name_task,
exclusive=False,
durable=True,
auto_delete=False,
callback=self._on_queue_declared)
self.logger.info("{} Opened Channel....".format(self.consumer_id))
# Declare Task Response Queue
self.channel.queue_declare(queue=self.queue_name_response,
exclusive=False,
durable=True,
auto_delete=False)
self.logger.info("{} Opened Channel....".format(self.consumer_id))
except Exception as e:
self.logger.error('{} {}'.format(self.consumer_id, str(e)))
def _on_queue_declared(self, frame):
self.logger.debug('{} ... declaring queue'.format(self.consumer_id))
self.channel.basic_qos(prefetch_count=1)
try:
self.channel.basic_consume(queue=self.queue_name_task,
on_message_callback=self.handle_delivery,
auto_ack=True)
self.logger.info("{} Declared queue...".format(self.consumer_id))
except Exception as e:
self.logger.error('{} crashing:--> {}'.format(self.consumer_id, str(e)))
def handle_delivery(self, channel, method, header, body):
try:
start_time = datetime.datetime.now()
_logger.info("Received...")
_logger.info("Content: %s" % body)
req = json.loads(self.decode(body))
# Do something
sleep(randint(10, 20))
time_taken = datetime.datetime.now() - start_time
log_msg = "[{}] Time Taken: {}.{}".format(req['bar']['baz'], time_taken.seconds, time_taken.microseconds)
_logger.info(log_msg)
# Publish the result to another queue.
try:
self.channel.basic_publish(exchange='',
routing_key=self.queue_name_response,
properties=pika.BasicProperties(),
body=log_msg)
_logger.info("Message Published...\t(%s)" % self.queue_name_response)
except Exception as e:
self.logger.error('{} Message publishing failed:--> {}'.format(self.consumer_id, str(e)))
except Exception as err:
_logger.exception(err)
def decode(self, body):
try:
_body = body.decode('utf-8')
except AttributeError:
_body = body
return _body
if __name__ == "__main__":
pika_parameters = OrderedDict([
('host', TF_BROKER_HOST),
('port', TF_BROKER_PORT),
('virtual_host', TF_BROKER_VHOST)
])
queue = {'task': TF_IAAS_TASK_QUEUE, 'response': TF_IAAS_REPLY_QUEUE}
try:
with ThreadPoolExecutor(max_workers=TF_IAAS_THREAD_SIZE, thread_name_prefix=TF_IAAS_THREAD_PREFIX) as executor:
start = 1
for thread_id in range(start, (TF_IAAS_THREAD_SIZE + start)):
executor.submit(QueueConsumer(queue, _logger, pika_parameters, thread_id).consume)
except Exception as err:
_logger.exception(err)
Publish Messages On RabbitMQ
import pika
import json
import random
import datetime
from faker import Faker
from random import randint
fake = Faker('en_US')
if __name__ == '__main__':
try:
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='tf_task', durable=True)
started_at = datetime.datetime.now()
properties = pika.BasicProperties(delivery_mode=2)
for i in range(0, 10000):
body = {
'foo': randint(i, i+100),
'bar': {
'baz': fake.name(),
'poo': float(random.randrange(155+i, 389+i))/100
}
}
channel.basic_publish(exchange='',
routing_key='tf_task',
body=json.dumps(body),
properties=properties)
if i%10000 == 0:
duration = datetime.datetime.now() - started_at
print(i, duration.total_seconds())
print(" [x] Sent 'Hello World!'")
connection.close()
now = datetime.datetime.now()
duration = now - started_at
print(duration.total_seconds())
except Exception as e:
print(e)