Python Twisted continuous reconnect attempts - python-3.x

When trying to connect a factory I want it to periodically try to reconnect if it fails to do so. I tried it with a code looking like that:
def reconnect():
print("this sucks")
reactor.connectTCP("localhost", 6667, factory2)
factory2 = pb.PBClientFactory()
factory2.clientConnectionFailed(reconnect(), "reasons")
reactor.connectTCP("localhost", 6667, factory2)
If I run this code it prints "this sucks" just once, although calling the connectTCP method with factory2 as parameter again. How should I go about implementing the desired behavior?

clientConnectionFailed is a method that is called by Twisted on a factory when a connection attempt fails. The usage in your example is nonsensical.
See ReconnectingClientFactory for one solution:
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.internet import reactor
from yourlib import YourProtocol
factory = ReconnectingClientFactory()
factory.protocol = YourProtocol
reactor.connectTCP(host, port, factory)
reactor.run()
However, this does not combine well with PB due to the use of a custom factory class to support PB. This is just one of many reasons to avoid using PB at all.
A more recently introduced solution is ClientService:
from twisted.application.internet import ClientService
from twisted.internet.endpoints import HostnameEndpoint
from yourlib import YourFactory
factory = YourFactory()
service = ClientService(
HostnameEndpoint(reactor, host, port),
YourFactory(),
)
service.startService()
reactor.run()
Note I've skipped over correct "service" usage here for brevity; see the Twisted
service documentation for details on correct usage.

Related

Python aiosqlite override Connection with pysqlcipher3

I saw an example of peewee where pysqlcipher was used as the connector for managing a database file rather than the sqlite module. That's great and there's even an async version of peewee but I don't need (Or want) to use peewee's object model. In peewee, the connector is initialized like this:
from peewee import *
from playhouse.sqlcipher_ext import SqlCipherDatabase
db = SqlCipherDatabase(None)
class Entry(Model):
class Meta:
database = db
I want to do something similar with aiosqlite and pysqlcipher3 instead of using peewee. Maybe it can work by overriding aiosqlite.Connection but I've never done something like that before. How can I use pysqlcipher3 with aiosqlite?
aiosqlite uses the standard library sqlite3 module -- and that appears to be hardcoded here:
https://github.com/omnilib/aiosqlite/blob/master/aiosqlite/core.py
In addition they've sprinkled all kinds of sqlite3-specific type annotations all over the place, so I'm not sure whether you can even monkey-patch it without causing issues.

Run Flask on demand to visualize computed data

Using Python 3.7, I made a CLI utility which prints some results to stdout. Depending on an option the results should be visualized in a browser (single user, no sessions). Flask seems to be a good choice for this. However, this is not a standard usecase described in the docs or in tutorials.
I am looking for a best practise way to pass the data (e.g. a Python List) to the Flask app so that I can return it from view functions. Basically it would be immutable application data. The following seems to work but I don't like to use globals:
main.py:
import myapp
result = compute_stuff()
if show_in_browser:
myapp.data = result
myapp.app.run()
myapp.py:
from flask import Flask
from typing import List
app = Flask(__name__)
result: List
#app.route("/")
def home():
return f"items: {len(result)}"
Reading the Flask docs I get the impression I should use an application context. On the other hand, its lifetime does not span across requests and I would not know how to populate it. Reading other questions I might use a Flask config object because it seems to be available on every request. But this is not really about configuration. Or maybe I should use Klein, inspired by this answer?
There does not seem to be a best practice way. So I am going with a modification of my original approach:
class MyData:
pass
class MyApp(Flask):
def __init__(self) -> None:
super().__init__(__name__)
self.env = "development"
self.debug = True
def getData(self) -> MyData:
return self._my_data
def setMyData(self, my_data: MyData) -> None:
self._my_data = my_data
app = MyApp()
This way I can set the data after the app instance was already created - which is necessary to be able to use it in routing decorators defined outside of the class. It would be nice to have more encapsulation: use app methods for routing (with decorators) instead of module global functions accessing a module global app object. Apparently that is not flaskic.

How do I call this async function from Bittrex?

I had a script that I used for checking my balances in Bittrex and now I'm trying to upgrade to the WebSocket API but I'm having a hard time since there's a lot of concepts I don't understand. This is function I'm trying to call:
from signalr_aio import Connection
from base64 import b64decode
from zlib import decompress, MAX_WBITS
import hashlib
import hmac
import json
async def create_signature(api_secret, challenge):
api_sign = hmac.new(api_secret.encode(), challenge.encode(),
hashlib.sha512).hexdigest()
return api_sign
From there I need to pass api_sign to to another function. I've tried playing around with it but I can't even get print(create_signature(api_secret, challenge)) to work. The asyncio module isn't even imported either so I can't use the information I found on how async works, and I'm assuming it's not necessary to import it.
When I try calling it the way I would a regular function I get that the coroutine was never awaited
I am the author of the example you are using. If you can't figure out how the authentication is done from the example or if its beyond your current understanding, then I suggest to use either:
Async: https://github.com/slazarov/python-bittrex-websocket-aio
Non-async: https://github.com/slazarov/python-bittrex-websocket
I am the author of both libraries

jmeter: access testplan name in sampler

We are developing some test cases using JSR-223 samplers ( groovy lanquage). We have some configuration information that is loaded at run time that keys off the TestPlan name. I don't see a means for accessing the testplan or name from the sampler, or sampler result. Is there a means to do so?
Here it is:
import org.apache.jmeter.services.FileServer;
String script = FileServer.getFileServer().getScriptName();
You can do the same using __TestPlanName() function passing via "Parameters" section
References:
FileServer class JavaDoc
How to Use JMeter Functions
UPDATE
Theoretically it is possible to access JMeter Test Plan tree, but remember, every time you bypass Java limitation using Reflection somewhere somehow a kitten dies.
Example code:
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.SearchByClass;
import java.lang.reflect.Field;
import java.util.Collection;
StandardJMeterEngine engine = ctx.getEngine();
Field test = engine.getClass().getDeclaredField("test");
test.setAccessible(true);
HashTree testPlanTree = (HashTree) test.get(engine);
SearchByClass<TestPlan> testPlans = new SearchByClass<>(TestPlan.class);
testPlanTree.traverse(testPlans);
Collection<TestPlan> testPlansRes = testPlans.getSearchResults();
for (TestPlan testPlan : testPlansRes) {
log.info(testPlan.getProperty("TestElement.name").toString());
}
Demo:
You can check out How to Use BeanShell: JMeter's Favorite Built-in Component for more information on using JMeter and Java API.

RobotFramework Monitoring Thread to Trigger Teardown

I am trying to have a monitoring thread in robotframework to continuously monitor a signal and force a teardown if a certain signal is read. I have the following code.
import signal
from datetime import datetime
from robot.api import logger
from robot.libraries.BuiltIn import BuiltIn
import logging
import thread
import os
import sys
import time
def do_error_log_monitoring_new():
def _monitor_log():
time.sleep(5)
# Monitor_Some_Signal
builtin_lib.fatal_error(msg='Force Teardown')
thread_logger = logging.getLogger('root')
thread_logger.info("Started Fault Listener")
builtin_lib = BuiltIn().get_library_instance('BuiltIn', all=True)
thread.start_new_thread(_monitor_log, ())
I have builtin_lib = BuiltIn().get_library_instance('BuiltIn', all=True) with the all=True argument to return dictionary mapping of all library names to instances. However I see the following error:
AttributeError: 'dict' object has no attribute 'fatal_error'
Furthermore, removing the all=True argument allows the function to go through and fatal_error to trigger, however I notice that it does not trigger a teardown in the main thread, which is what I intend to do. Any advice on how I can trigger teardown in the main thread from the fatal_error() function in the secondary thread?
You're setting builtin_lib to a dictionary (the result of BuiltIn().get_library_instances(..., all=True). As the error message states, this dictionary does not have a fatal_error method.
Change this:
builtin_lib.fatal_error(msg='Force Teardown')
... to this:
BuiltIn().fatal_error(msg='Force Teardown')
If you only need a reference to the BuiltIn library (versus a dictionary of all libraries), you don't need to call get_library_instance at all since BuiltIn() already returns an instance of the library.

Resources