Can a python async http transfer by easily added to an existing code base? - python-asyncio

I'm writing a Fusion 360 python add-in, which is an event-driven way to extent their product (their code calls my functions that hooked in to their events).
Inside my code, I would like to send a single HTTP GET (or POST) request to a remote server without making the user wait (e.g. if they're offline, I want no delay - it just needs to fail silently).
There are many dozens of async examples around, but all of them appear to require that you're running a "normal" program, and that every part of the program is async to start with (i.e. I can't find any examples of a regular program, with an async bit added).
I'm new to python, and the async Doc is drowning me :-(
That said - I do kinda know what I'm doing in other languages, and I understand how processes work (not so much threads though).
I did manage to partly "solve" my own question with this:
subprocess.Popen([get_exec(),os.path.join(prog_folder,"send_data.py"),str(VERSION)])
and a second script - except that pops open an ugly black "DOS" box which hangs around until the transfer completes and looks highly unprofessional. All attempts at avoiding the black box failed (I do not get the luxury of specifying my user's environment, and there is no "windows UI build" python version shipped that works.)
So basically - two questions
a) is it even possible for an event-driven python function to even "spawn" a thread at all? Perhaps imagine it this way: you've written a python module, and any caller can call a function in your module, which returns immediately, but your function then continues to do work for another minute in parallel - but crucially - the caller does not need to do anything special.
b) assuming it more-or-less is possible - can anyone give me a hint or a pointer to an example or something might might give me a clue where to start?
Python 3.7.6+ is my minimum environment.
My main problem (pardon the pun) is that all examples I can find do this:
loop.run_until_complete(asyncio.wait(print_http_headers(url)))
or this:
asyncio.run(main())
both of which block. Even the asyncio doc's "hello world" example is non-async as well (if only they had printed "world" first (after a 1s delay) and then printed "hello" second with no delay - that would have solved everything!!!)
All other suggestions gratefully received (there's bound to be an "outside the box" alternative I've not realized yet I expect - so long as the box isn't black and in-your-face that is :-)

Thanks! #user4815162342 - that totally did the trick!!
import _thread, time, socket
def YoBlably(stuff):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("example.com", 80))
sent=s.send(b'GET /my_path/check_update.asp?u=u1.20200505&v=1.20200503&a=_aft&p=my_prog HTTP/1.1\x0d\x0aHost: example.com\x0d\x0aAccept-Encoding: identity\x0d\x0aUser-Agent: Python\x0d\x0aConnection: close\x0d\x0a\x0d\x0a')
if sent==0:
print("s Problem")
chunk = s.recv(1024000)
if chunk == b'':
print("r Problem")
print('got {}.'.format(chunk))
s.close()
print("Starting in 1s...");
time.sleep(1)
_thread.start_new_thread(YoBlably, ('foo',))
print("Started...");
for i in range(0,6):
time.sleep(1)
print('{}...'.format(i))
print("The end...");
outputs:-
$ python pythreadsock.py
Starting in 1s...
Started...
got b'HTTP/1.1 200 OK\r\nDate: Wed, 20 May 2020 01:47:28 GMT\r\nServer: Apache/2.0.52\r\nExpires: Sun, 17 May 2020 23:58:28 GMT\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nContent-Length: 35\r\nConnection: close\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n{"current_version_xyz":1.20200502}\n'.
0...
1...
2...
3...
4...
5...
The end...

Related

Is there any reason to do xflush and xsync consecutively?

I'm looking through the source code of an x11 background manager, and I found these two lines towards the end of the code (# line 585):
XFlush(display);
XSync(display, false);
I'm confused, because these two lines do the same thing twice, except for the fact that it waits the second time.
The program also isn't multithreaded/asynchronous, so that means that there isn't any other process that could possibly terminate when it flushes the first time (setting aside that that is also a very bad way of communication).
Was the developer slightly tunnel-visioned or is there some reason to both being here?

System log in Ruby?

I made a bot in ruby, which plays a small online game. It was able to reach the final level and kill the final boss there. As the game ends there, my program reaches an unknown state and I receive an exception. However, I need some information from that battle (i.e. the final html pages). I can start all over again, but it takes around 10 hours until it reaches the final boss.
My question is: Is there some kind of a system log in Ruby, where I can see (interpolated, like bash invoked with -x option) the last few executed commands? I know that Ruby has such classes, but I haven't used them in my code, so I would like to know if there is something more general.
There's a Logger class in the std lib:
http://www.ruby-doc.org/stdlib-2.0.0/libdoc/logger/rdoc/Logger.html
But you'd need to have used it to begin with in order to get the log.
You should use set_trace_func.
http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-set_trace_func

How to check Matplotlib's speed in Xcode and increase performance?

I'm running into some considerable speed bottlenecks with a Python-Matplotlib-Xcode combination. I know some immediate responses will probably ask "Why are you doing python stuff in Xcode, just man up and use vim" --> I like the organizing ability and the built in version control, it makes elements of my work easier to deal with.
Getting python to run in xcode in the first place was a bit more tricky than I had hoped, but its possible. Now I have the following scenario:
A master file, 'main.py' does all the import stuff for me and sets up some universal formatting to make all the figures (for eventual inclusion in my PhD thesis) nice and uniform. Afterwards it runs a series of execfile commands to generate whichever graphics I need. Two things I can think of right off the bat:
1) at the very beginning of main.py after I import all the normal python stuff you tend to need, I call a system script which checks whether a certain filesystem is mounted. I keep all my climate model data on there since my local hard drive is too small to deal with all of it at once. Python pauses itself and waits for the system to do its thing, but once the filesystem has been found, it keeps going. Usually this only needs to happen once in the morning when I get to work, or if the VPN server kicked me off for whatever reason. (Side question, it'd be cool to know if theres a trick to automate an VPN login to reconnect as soon as it notices its not connected)
2) I'm not sure how much xcode is using on its own. running the same program from terminal is (somewhat) faster. I've tried to be memory conscience and turn off stuff I don't need while running the python/xcode combination.
Also, python launches a little window whenever I call plt.show(), this in itself takes time, I've considered just saving them as quick png files and opening them with some other viewer, although I guess that would also have to somehow take time to open up. Given how often these graphics change as I add model runs or think of nicer ways of displaying the data, it'd be nice to not waste something on the order of 15 to 30 minutes (possibly more) out of the entire day twiddling my thumbs and waiting for a window to pop up.
Benchmark it!
import datetime
start = datetime.datetime.now()
# your plotting code
td = datetime.datetime.now() - start
print td.total_seconds() # requires python version >= 2.7
Run it in xcode and from the command line, see what the difference is.

how to produce delay in ruby

How to produce delay in ruby?
I used sleep statement but it didn't give me what I want.
puts "amit"
sleep(10)
puts "scj"
I want it to first print amit, then a delay of 10 seconds, then print scj.
But in above case what happens is it will pause for 10 seconds and then it will print amit and scj together. I don't want that.
I hope you got what I want to say.
I can't reproduce this. From a console, this does exactly what you'd expect:
puts "amit"
sleep 10
puts "scj"
(Ruby 1.8.6 on Linux)
Can you provide a similar short but complete example which doesn't do what you want - or explain your context more?
If you're writing a web application, then the browser may well only see any data once the whole response has been written - that would explain what you're seeing. If that's the case, you'll need a different approach which would allow the initial response to be written first, and then make the browser make another request. The delay could be at the server or the client, depending no the scenario.
Call $stdout.flush before the call to sleep. The output is probably buffered (although usually output is only line-buffered so puts, which produces a newline, should work without flushing, but apparently that's not true for your terminal).

How to do pings in a rubyqt application so the GUI doesn't freeze?

I am writing an application, which shall work with networks.
As a GUI I am using rubyqt.
To determine if a Server is up I have to ping it (with net/ping).
But I ran in to a problem. If the server is down,
the GUI freezes for the timeout, even if I put the code in a Thread or IO.popen loop eg.
Thread.new('switch') do
if Net::PingExternal.new("195.168.255.244",timeout=0.9).ping then
down = false
else
down = true
end
end
will freeze for 0.9 seconds. As the QtThreads are not yet working with rubyqt,
does somebody have an idea to make the GUI don't freeze (apart from reducing the timeout)?
I was thinking about putting the pinging-part in an external program, which writes the status (up/down) in a file, which the actual program then reads, but this solution seems to be a bit clumsy.
Have you considered abstracting that operation from the request altogether? If you move the costly operation to an external library you could easily queue it up and execute it using something like delayed_job (http://github.com/tobi/delayed_job/tree/master) which would remove the risk of it halting the request at all.
Maybe this is what you are looking for...?

Resources