This is a bit complicated, but i will try my best to explain what I need.
I have transaction data from a blockchain. Each transaction (hash) shows the process of swapping token A for token B. Instead of a clean two-way transaction (I send 3 A tokens to an exchange and I receive 3.2 B tokens from an exchange), decentralized exchanges send multiple transactions to different "routers" to complete a transaction. So that means, even if I send 5 A tokens to an exchange to get B tokens, a lot of things can happen during the process.
My dataframe is the following. Here, the decentralized exchange is 0xdef171fe48cf0115b1d80b88dc8eab59176fee57, and one must interact with this specific address to exchange A tokens for B tokens (or vice versa). Here, a sender will exchange ETH for stETH (or the other way around). I marked the transaction initiator in *. If I am sending stETH to receive ETH, there will be 0 in the transaction. If there is no 0 in the transaction (sending ETH to receive stETH), the transaction initiator is whoever that is sending ETH to 0xdef171fe48cf0115b1d80b88dc8eab59176fee57. I can follow the fund flows but I need a way to extract meaningful lines from each transaction.
transaction_hash block_timestamp from_address to_address value data token_address
5415557 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 *0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
5541706 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xef13101c5bbd737cfb2bf00bbd38c626ad6952f7 941057674498136.0 trace ETH
3548670 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 *0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 9.811764490425307e+16 trace ETH
5410345 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 9.90587025787512e+16 trace ETH
101417 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 *0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1.0098718719397725e+17 transfer stETH
628106 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0 1.0098718719397725e+17 transfer stETH
4153539 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 *0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
4417935 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xef13101c5bbd737cfb2bf00bbd38c626ad6952f7 7964782413657482.0 trace ETH
2231738 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 *0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0 8.304333663923933e+17 trace ETH
1927591 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0xf9234cb08edb93c0d4a4d4c70cc3ffd070e78e07 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 8.383981488060508e+17 trace ETH
195588 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 *0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 8.646723368253125e+17 transfer stETH
632414 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x4028daac072e492d34a3afdbef0ba7e35d8b55c4 8.646723368253125e+17 transfer stETH
4167634 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 *0x3826997debdf2da84150bb469e105a3185b768dc 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
3311860 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xef13101c5bbd737cfb2bf00bbd38c626ad6952f7 4888022461360245.0 trace ETH
24307 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 *0x3826997debdf2da84150bb469e105a3185b768dc 5.096406576818235e+17 trace ETH
832982 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 5.145286801431837e+17 trace ETH
76680 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 *0x3826997debdf2da84150bb469e105a3185b768dc 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 5.1552312133280275e+17 transfer stETH
627656 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x4028daac072e492d34a3afdbef0ba7e35d8b55c4 5.1552312133280275e+17 transfer stETH
1024024 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 *0xdf7bdb2d8e3c2c39b9367d887d497d450ad1c597 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1e+16 trace ETH
1550939 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x4ff0dec5f9a763aa1e5c2a962aa6f4edfee4f9ea 1e+16 trace ETH
3015729 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 1e+16 trace ETH
507394 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 0x4028daac072e492d34a3afdbef0ba7e35d8b55c4 *0xdf7bdb2d8e3c2c39b9367d887d497d450ad1c597 9991510671248444.0 transfer stETH
1366691 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xdc24316b9ae028f1497c275eb9192a3ea0f67022 1.985e+19 trace ETH
2718318 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x6e8b66cc92fcd7fe1332664182beb1161dbfc82d 1.985e+19 trace ETH
3231318 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 *0xdc2276c7430fe326b578c31ecc395964cf32ebd5 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1.985e+19 trace ETH
615668 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdc24316b9ae028f1497c275eb9192a3ea0f67022 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 2.0016204373932466e+19 transfer stETH
632154 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 *0xdc2276c7430fe326b578c31ecc395964cf32ebd5 2.0016204373932466e+19 transfer stETH
So I want to extract rows with the sender, the ETH amount, and the stETH amount in return (or vice versa)
Ideally,
transaction_hash block_timestamp from_address to_address value data token_address
5415557 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
3548670 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 9.811764490425307e+16 trace ETH
101417 0x0022141a9433660d7ef85e803ee6e96308528c23c86cae6de6ed02cbe1c2b3fb 2022-11-26 01:44:59+00:00 0x2df07a8cdf9a3e1ec55110abfe974870459e3c58 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1.0098718719397725e+17 transfer stETH
4153539 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
2231738 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0 8.304333663923933e+17 trace ETH
195588 0x002369d61019cff19509aaab55a8db70ea4c939de5256f07fdebba5818678176 2022-07-10 18:06:19+00:00 0x7ca2f6d4df00fd8f8b412388ebb180cc6c1cbba0* 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 8.646723368253125e+17 transfer stETH
4167634 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0x3826997debdf2da84150bb469e105a3185b768dc 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0.0 trace ETH
24307 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0x3826997debdf2da84150bb469e105a3185b768dc 5.096406576818235e+17 trace ETH
76680 0x00264d1d0bac183705299d25459bdd17e87cf869c148dd85b5456cd73e47ae40 2023-01-27 22:43:47+00:00 0x3826997debdf2da84150bb469e105a3185b768dc 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 5.1552312133280275e+17 transfer stETH
1024024 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 0xdf7bdb2d8e3c2c39b9367d887d497d450ad1c597 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1e+16 trace ETH
507394 0x0028728254d13d30f2fb41ad4584c23c141cd1c9163634e8eaec5767ee38b7b5 2022-10-29 18:08:35+00:00 0x4028daac072e492d34a3afdbef0ba7e35d8b55c4 0xdf7bdb2d8e3c2c39b9367d887d497d450ad1c597 9991510671248444.0 transfer stETH
3231318 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdc2276c7430fe326b578c31ecc395964cf32ebd5 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 1.985e+19 trace ETH
632154 0x003636cc9f43470d67780144d17848a940a88462eb0f8bed0475a322941b42c9 2022-09-19 20:15:35+00:00 0xdef171fe48cf0115b1d80b88dc8eab59176fee57 0xdc2276c7430fe326b578c31ecc395964cf32ebd5 2.0016204373932466e+19 transfer stETH
This seems like a very complicated task, but any help will be very appreciated.
Related
I have the following list:
['2022-04-07 16:42:26,469 20.1.Starting all probes', '2022-04-07 16:42:26,469 20.1.: Pinging 192.168.255.68 started', '2022-04-07 16:42:26,472 20.2.Username, password not present, starting probes', '2022-04-07 16:42:26,472 20.2.: Pinging 192.168.254.108 started', '2022-04-07 16:42:29,817 20.1.: Pinging 192.168.255.68 succeeded', '2022-04-07 16:42:29,819 20.1.: SSH log for 192.168.255.68', '2022-04-07 16:42:29,820 20.2.: Pinging 192.168.254.108 succeeded', '2022-04-07 16:42:29,822 20.2.All probes finished', '2022-04-07 16:42:34,938 20.1.: Successfully connected to 192.168.255.68', '2022-04-07 16:42:35,629 20.1.: Interactive SSH session established', '2022-04-07 16:42:35,629 20.1.All probes finished']
When displaying it with for loop I'll get:
2022-04-07 16:42:26,469 20.1.Starting all probes
2022-04-07 16:42:26,469 20.1.: Pinging 192.168.255.68 started
2022-04-07 16:42:26,472 20.2.Username, password not present, starting probes
2022-04-07 16:42:26,472 20.2.: Pinging 192.168.254.108 started
2022-04-07 16:42:29,817 20.1.: Pinging 192.168.255.68 succeeded
2022-04-07 16:42:29,819 20.1.: SSH log for 192.168.255.68
2022-04-07 16:42:29,820 20.2.: Pinging 192.168.254.108 succeeded
2022-04-07 16:42:29,822 20.2.All probes finished
2022-04-07 16:42:34,938 20.1.: Successfully connected to 192.168.255.68
2022-04-07 16:42:35,629 20.1.: Interactive SSH session established
2022-04-07 16:42:35,629 20.1.All probes finished
How can I order it based on the number that follows "20", using sort() or something else to have it sorted based that number and then the date like usual:
2022-04-07 16:42:26,469 20.1.Starting all probes
2022-04-07 16:42:26,469 20.1.: Pinging 192.168.255.68 started
2022-04-07 16:42:29,817 20.1.: Pinging 192.168.255.68 succeeded
2022-04-07 16:42:29,819 20.1.: SSH log for 192.168.255.68
2022-04-07 16:42:34,938 20.1.: Successfully connected to 192.168.255.68
2022-04-07 16:42:35,629 20.1.: Interactive SSH session established
2022-04-07 16:42:35,629 20.1.All probes finished
2022-04-07 16:42:26,472 20.2.Username, password not present, starting probes
2022-04-07 16:42:26,472 20.2.: Pinging 192.168.254.108 started
2022-04-07 16:42:29,820 20.2.: Pinging 192.168.254.108 succeeded
2022-04-07 16:42:29,822 20.2.All probes finished
You can use sorted with a regex as custom key. Assuming l the input list:
import re
sorted(l, key=lambda s: re.findall(r' 20\.\d+', s))
Alternatively, using the . as delimiter to split:
sorted(l, key=lambda s: s.split('.')[1])
Output:
['2022-04-07 16:42:26,469 20.1.Starting all probes',
'2022-04-07 16:42:26,469 20.1.: Pinging 192.168.255.68 started',
'2022-04-07 16:42:29,817 20.1.: Pinging 192.168.255.68 succeeded',
'2022-04-07 16:42:29,819 20.1.: SSH log for 192.168.255.68',
'2022-04-07 16:42:34,938 20.1.: Successfully connected to 192.168.255.68',
'2022-04-07 16:42:35,629 20.1.: Interactive SSH session established',
'2022-04-07 16:42:35,629 20.1.All probes finished',
'2022-04-07 16:42:26,472 20.2.Username, password not present, starting probes',
'2022-04-07 16:42:26,472 20.2.: Pinging 192.168.254.108 started',
'2022-04-07 16:42:29,820 20.2.: Pinging 192.168.254.108 succeeded',
'2022-04-07 16:42:29,822 20.2.All probes finished']
import re
def sort_list(lst):
lst_n = []
for text in lst:
n = re.search('\d{3} \d{2}.(.+?).*', text).group(1)
lst_n.append((text, n))
text_n_sorted = sorted(lst_n, key=lambda x: x[1])
sorted_text = []
for text, n in text_n_sorted:
sorted_text.append(text)
return sorted_text
I have a problem with communication via Modbus RTU. First of all sorry for my English ;):
I'm using RS485 Pi SN65HVD72 to connect with MultiCONT PRD-28-2. I made everything like is in this instruction: https://www.abelectronics.co.uk/kb/article/1035/raspberry-pi-3-serial-port-usage
config.txt changes:
toverlay=pi3-miniuart-bt
enable_uart=1
After this steps the config of my /dev looks like this:
lrwxrwxrwx 1 root root 7 gru 30 15:03 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 gru 30 15:03 serial1 -> ttyS0
In MultiCONT PRD-28-2 I change RS485 options to:
Protocol: Modbus
Parity: ODD
Stop bit: 1 bit
Python code:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
#multicont = ModbusClient(method='rtu',port='/dev/serial0',stopbits=1,bytsize=8,parity='N',baudrate=9600,timeout=1,strict=False)
multicont = ModbusClient(method='rtu',port='/dev/serial0',stopbits=1,bytsize=8,parity='O',baudrate=9600,timeout=1,strict=False)
connection = multicont.connect()
print(connection)
value = multicont.read_coils(1,15,unit=1)
log.debug(value)
Error message:
Modbus Error: [Input/Output] Modbus Error: [Invalid Message]
Incomplete message received, expected at least 2 bytes (0 received)
Logs:
2020-12-30 16:24:51,992 MainThread DEBUG transaction :118
Current transaction state - IDLE 2020-12-30 16:24:51,992
MainThread DEBUG transaction :123 Running transaction
1 2020-12-30 16:24:51,992 MainThread DEBUG transaction
:230 SEND: 0x1 0x1 0x0 0x1 0x0 0xf 0x2d 0xce 2020-12-30
16:24:51,993 MainThread DEBUG sync :75 New
Transaction state 'SENDING' 2020-12-30 16:24:51,993 MainThread
DEBUG transaction :239 Changing transaction state from
'SENDING' to 'WAITING FOR REPLY' 2020-12-30 16:24:52,995
MainThread DEBUG transaction :253 Transaction failed.
(Modbus Error: [Invalid Message] Incomplete message received, expected
at least 2 bytes (0 received)) 2020-12-30 16:24:52,995
MainThread DEBUG rtu_framer :241 Frame - [b''] not
ready 2020-12-30 16:24:52,996 MainThread DEBUG
transaction :409 Getting transaction 1 2020-12-30
16:24:52,996 MainThread DEBUG transaction :204
Changing transaction state from 'PROCESSING REPLY' to
'TRANSACTION_COMPLETE' 2020-12-30 16:24:52,996 MainThread
DEBUG communication :20 Modbus Error: [Input/Output] Modbus
Error: [Invalid Message] Incomplete message received, expected at
least 2 bytes (0 received)
PyModbus is not receiving a response.
If you have access to an oscilloscope, this is the moment to use it. There are soooo many things that can go wrong with Modbus-RTU.
Make sure you know what you are doing with the electrical wiring, familiarize yourself with RS485 biasing and termination.
Possible causes:
request sent to wrong serial device/interface
device uses different baudrate or serial settings
device can hear you allright but has a different slave ID configured, so it doesn't respond
wrong wiring, grounding issues
RS485 electrical problems, most notably the master must be biasing the bus, usually via a resistor that you have to solder/enable
Bus termination resistors are required for correct voltage levels (sometimes they are already built-in, more often you need to enable them, with some luck may work without)
Master still driving the RS485 bus while the slave is responding. (If you do not have a dedicated RS485 driver, the bus may end up being asserted/deasserted by unreliable software timers. Some devices allow you to configure a response delay as a workaround.)
Master not driving the bus at all. (Working in RS232 mode instead of RS485 mode.)
Also, Linux might have ttyAMA0 configured as a serial console for boot/kernel messages. (This is unlikely to cause your current problem, just something else to watch out for.)
Final piece of advice: if you have the option to use Modbus-TCP instead of Modbus-RTU, do that instead. This replaces all the RS485 electrical headaches which IP-configuration headaches, for which you can use over-the-counter medication.
I tried pywinusb, wmic, msiout all are unable to read the device serial number.
msiout results
Name [00000014] Apple Mobile Device Ethernet
Adapter Type Ethernet 802.3
Product Type Apple Mobile Device Ethernet
Installed Yes
PNP Device ID USB\VID_05AC&PID_12AX&MI_02\6&30B6FDC3&1&XXXX
Last Reset 19-11-2020 07:21
Index 14
Service Name Netaapl
IP Address 172.XX.XX.X, fe80::f903:XXXX:XXXX:XXXX, 2401:4900:195b:XXXX:XXXX:XXXX:XXXX:XXXX, 2401:4900:195b:f4e4:f903:XXXX:XXXX:XXXX
IP Subnet 255.XXX.XXX.XXX, 64, 128, 64
Default IP Gateway 172.XX.XX.X, fe80::XX:d1e9:XXXX:XXXX
DHCP Enabled Yes
DHCP Server 172.XX.XX.X
DHCP Lease Expires 10-12-2020 07:54
DHCP Lease Obtained 09-12-2020 08:08
MAC Address 72:70:XX:XX:XX:XX
Driver C:\WINDOWS\SYSTEM32\DRIVERS\NETAAPL64.SYS (1.8.5.1, 22.50 KB (23,040 bytes), 06-05-2020 13:05)
How to extract this serial number?
Device Properties (sorry for not taking a screenshot)
EDIT: This issue resolved itself as mysteriously as it began. Simply hoping it doesn't crop up again in the future.
I have a small python script that emails out a comic strip once a day to a handful of email addresses. Recently, one person on my list told me that the images are no longer displayed. I got the source of the email from her Gmail account, and for some reason the base-64 encoded section for the image in blank.
I have no idea why this is happening, and why it's happening to only one person. I get an SPF soft-fail in the Gmail headers, but I doubt that's causing it (that should happen to all the Gmail users on my list.) I don't even know what to Google to start troubleshooting this issue.
Faulty Email Source {censored items in curly braces}:
Delivered-To: {recipient}#gmail.com
Received: by 2002:ac2:555e:0:0:0:0:0 with SMTP id l30csp2647742lfk;
Sun, 22 Mar 2020 02:12:09 -0700 (PDT)
X-Google-Smtp-Source: ADFU+vt1SopHnbnPh0tuHjbA/v3RMASeIKMyk35ZdIXqQHBr2LmtG11vVo6cI8XXxUf/emCJQjqb
X-Received: by 2002:a92:25d6:: with SMTP id l205mr14876228ill.35.1584868329096;
Sun, 22 Mar 2020 02:12:09 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1584868329; cv=none;
d=google.com; s=arc-20160816;
b=o1VVDgxlMMWGRPy041qJS6LfA1LWjEB6+cbp768sLmMaOk7Q+qbCpAg0Mydf3pg/yu
N3Nfh0Zv7vUdS6sapH0LzmcCG6YVBC/fkGboFuUeVJgVw24CcY8e1ofkMmIkWardIQie
bNfAnebSMmIhmZ6UTrR79ggRhUglFx6EdAzNYdmpyRCxewK3/SN5JjdfW6KUQsgjQXU5
PvJQEZZrt07eKjzq2kpNVobWBj8rOvVGpYc+fqNDOircTIF5ZTI3JIbCEkNvvEyAmZOW
AK68xVtSpaYfInnJ0++dPkS9DhuH777f/yMz6Z0X26MjnoxiIovyYSNPfzZLdjpnC/CI
G4nQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
h=date:message-id:to:from:subject:mime-version;
bh=nXPNVg7/Z2G2UDLCbHAibUHl0oCh4sJ6yhHsm9HpP+Y=;
b=Vl5At9J4nLzeREzg93sHypB2XO/vbNHAtRj4apOzQZHLg0XbjD3Hxv6t9+yzFn8thS
pFnPRPCOOgyY+mp+8hTQrT5TaIlEcNC9Ay1x25X27wqcr0iBjw9xpTvjvFo1pX7jNK7E
DvUZpdSoSmas32U0zT8DH1+jX5zX/8Ydr7aTOkVLPX6umVuyl2RNlW+mLZrPnCMkiH0Z
jeTc88LMiczwsVwo2qsoKPDjFah+xTD7J+zqnuHr6IuMS3+s9t7dy4sbKRwlcxP4n2z4
ZXjJbQpEEfOec36EF89By4ZHNHxLmDx/DZvPA5nv10emet1Omki9w2HF3hcaAijZDL2l
jb1g==
ARC-Authentication-Results: i=1; mx.google.com;
spf=softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) smtp.mailfrom={sender}#{my-domain}
Return-Path: <{sender}#{my-domain}>
Received: from {my-domain} ([{my-ip-address}])
by mx.google.com with ESMTP id 141si8443110ile.78.2020.03.22.02.12.03
for <{recipient}#gmail.com>;
Sun, 22 Mar 2020 02:12:09 -0700 (PDT)
Received-SPF: softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) client-ip={my-ip-address};
Authentication-Results: mx.google.com;
spf=softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) smtp.mailfrom={sender}#{my-domain}
Received: from {my-domain} (localhost [IPv6:::1]) by {my-domain} (Postfix) with SMTP id BEFC13C00DD for <{recipient}#gmail.com>; Sun, 22 Mar 2020 05:12:02 -0400 (EDT)
Content-Type: multipart/related; boundary="===============0513549325=="
MIME-Version: 1.0
Subject: Calvin and Hobbes of the day
From: {sender}#{my-domain}
To: {recipient}#gmail.com
Message-Id: <20200322091202.BEFC13C00DD#{my-domain}>
Date: Sun, 22 Mar 2020 05:12:02 -0400 (EDT)
--===============0513549325==
Content-Type: multipart/alternative; boundary="===============1139914447=="
MIME-Version: 1.0
--===============1139914447==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Calvin and Hobbes of the day email. Image not displayed for techical reasons. To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.
--===============1139914447==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
<img src="cid:30cbc076bf26fa38547141665a3874fc0bdc91b550d5b9523fbf033cd64d0d8b"><p>This Calvin and Hobbes was originally published on Tuesday, March 22, 1994. Enjoy!</p><p style="font-family:serif;text-size:9pt;">To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.</p>
--===============1139914447==--
--===============0513549325==
Content-Type: image/gif
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-ID: <30cbc076bf26fa38547141665a3874fc0bdc91b550d5b9523fbf033cd64d0d8b>
--===============0513549325==--
Example of an email that displayed properly (also sent to a Gmail account):
Delivered-To: {recipient2}#gmail.com
Received: by 2002:ac0:945c:0:0:0:0:0 with SMTP id j28csp4283482imj;
Sun, 22 Mar 2020 02:12:06 -0700 (PDT)
X-Google-Smtp-Source: ADFU+vsBj6iMIZiI5aEUI+EaVIoyR/pGQUdx46SNDNiosv8OoI8WLTCvAYmWxdVSsUEGEThEY3kc
X-Received: by 2002:a92:4090:: with SMTP id d16mr1882262ill.200.1584868326631;
Sun, 22 Mar 2020 02:12:06 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1584868326; cv=none;
d=google.com; s=arc-20160816;
b=o85d2nyxnlrJBxjPjbEIK+iBEUzip5+8qaw3AP2sf1oWPSHGUjyKSJMM9ya0nTgByo
wn+hN60zGz/y23w7k6yp3V0gy94rP+qiMRn87bgahsdF6SOH6n2gDn1aYPFNZPCLRrgU
UI+a3aX/qdDtw03LL8A9mj+v+TCvEyntddxWjiU2UHuXT88GLOPAwmt0PwH/wQp52nRV
V4jnKFbGQU7A2FkzJccW1T6GgzoXejmXOcHi4z7emm4TGHNv4FxlPl/bna2X8dFo+8N5
mHh7+ADWyy9wHATPJqPEtTXuBoE8Bri9n20IMKaPWKzpoasb5bFV14kA+cRkh/CckHr7
3Vxw==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
h=date:message-id:to:from:subject:mime-version;
bh=tcCxyEZafImccO+owloPVRqzcCuM+m7me+VxZuISjGU=;
b=e5DjPTX5Ia11uM7bKBRA+vGqkGlsYdJuv6Mxio7xhRtcxqBxxxyIZ80ludnCvWR/j8
/B1qmGG6ZynxVlv7GTPOF4yP6qWhE2sycKf3yQ5MYZXLFmZMRSW0kcj/fjoKvd3BOOBV
8DlZUNVvfNujZpm+7sdNHhT+xAU8EY1+9+b3R6GDEyDJzKrIgXclX9yVHsH91DDa5AC8
WOUBH4ZrOZ0Zn5bvpSLOomqhGI4J2gZeb41zj8RjjuwPOE9LR5fmDCxNn+ajeBAbnJPG
Ihl3jkrnuiJWcigsn38ctPw6inWglsK3dxKBTeXbrWHHeRtu9kHZnL1l9vpl93BM/LN9
6jgQ==
ARC-Authentication-Results: i=1; mx.google.com;
spf=softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) smtp.mailfrom={sender}#{my-domain}
Return-Path: <{sender}#{my-domain}>
Received: from {my-domain} ([{my-ip-address}])
by mx.google.com with ESMTP id k2si9367254jap.23.2020.03.22.02.12.03
for <{recipient2}#gmail.com>;
Sun, 22 Mar 2020 02:12:06 -0700 (PDT)
Received-SPF: softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) client-ip={my-ip-address};
Authentication-Results: mx.google.com;
spf=softfail (google.com: domain of transitioning {sender}#{my-domain} does not designate {my-ip-address} as permitted sender) smtp.mailfrom={sender}#{my-domain}
Received: from {my-domain} (localhost [IPv6:::1])
by {my-domain} (Postfix) with SMTP id 98FA73C00A7
for <{recipient2}#gmail.com>; Sun, 22 Mar 2020 05:12:02 -0400 (EDT)
Content-Type: multipart/related; boundary="===============1535165371=="
MIME-Version: 1.0
Subject: Calvin and Hobbes of the day
From: {sender}#{my-domain}
To: {recipient2}#gmail.com
Message-Id: <20200322091202.98FA73C00A7#{my-domain}>
Date: Sun, 22 Mar 2020 05:12:02 -0400 (EDT)
This is a multi-part message in MIME format.
--===============1535165371==
Content-Type: multipart/alternative; boundary="===============1545014324=="
MIME-Version: 1.0
--===============1545014324==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Calvin and Hobbes of the day email. Image not displayed for techical reasons. To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.
--===============1545014324==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
<img src="cid:30cbc076bf26fa38547141665a3874fc0bdc91b550d5b9523fbf033cd64d0d8b"><p>This Calvin and Hobbes was originally published on Tuesday, March 22, 1994. Enjoy!</p><p style="font-family:serif;text-size:9pt;">To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.</p>
--===============1545014324==--
--===============1535165371==
Content-Type: image/gif
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-ID: <30cbc076bf26fa38547141665a3874fc0bdc91b550d5b9523fbf033cd64d0d8b>
R0lGODlhhAMgAfcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4O
Dg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEh
ISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0
NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdH
R0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpa
WltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1t
{ ... snipped 1462 lines worth of base-64 encoded data ... }
/pQ29JRRfUNJrQ5VOZVPzEP3CAxVzcM3zIPr2EdJ6dRKDoxUvcND5NIWCVEsBQYYmRMg4UUuKYT9
1FBCrKQ9+MVKGsTwHERX8eRCzEMrVsM3kMMmGhUmro7jxKRBXOU8SFVM8sS4eFA2+eRZomVKBGVK
vMMuRMIglFFatoZUAVEVHMIp9MKzpANRLoQ2DEI3yWVgCuZgEmZhGuZhIuZPRgREDEwS+eRaJmZi
yos5HeUS2ZBjHmWWJBHkJMYObWb8gCYPsc9oro/6EIxN3JD8mM5okiZjFsxicqbpyJBpwolpztBr
OiZqglFWVIVr/lBqpib4uI9uug9nMmZmFuf7dqCmcp6mD2Hmc+oGpwjnZ7LJEhlnD9XmDkXOcl5m
Y/LQb87mdopnbBIRDdlQZaqmdmYndlqQUjind8KncH6nq1SnD6GnbuJnfq5lZVIJZEZmJu1mpKhl
bhLoSrhmbZxTgf7ngjJoutBngy6mbCbFFPknhA5mQAAAOw==
--===============1535165371==--
EDIT: A few of my other recipients have also reported that this has happened in the past, but it only lasted a day or two, and they didn't think much of it. (I believe they are all also Gmail users...)
EDIT: Here's a slightly stripped-down version of the code that sends the emails. There is a file called addresses.py in the same directory that has a nested array with all the email addresses on my list.
#!/usr/bin/python
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
import hashlib
import os
import datetime
from addresses import arrayTo # Addresses to send to
# Note: Calvin and Hobbes ran from 1985-11-18 to 1995-12-31
today = datetime.datetime.now()
comicDay = datetime.datetime(((today.year - 6) % 10 + 1990), today.month, today.day)
dateString = str(comicDay.year) + '-' + str(comicDay.month) + '-' + str(comicDay.day)
# Some definitions
for n in range(0,len(arrayTo)):
strTo = ''
numAddresses = len(arrayTo[n])
for i in range(0,numAddresses): # Concatenate address array into CSV
strTo += arrayTo[n][i]
if i < numAddresses - 1: # Don't end with a comma
strTo += ', '
strFrom = '{sender}#{my-domain}'
comicFile = '/path/to/files/picture_' + dateString + '.png'
if os.path.exists(comicFile):
# Open the image, assuming the image is in the current directory
fp = open(comicFile, 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
# Generate a hash to use as the CID
comicHash = hashlib.sha256(comicFile).hexdigest()
# Create the root message and fill in the from, to, and subject headers
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'Calvin and Hobbes of the day'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'
# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
msgText = MIMEText('Calvin and Hobbes of the day email. Image not displayed for techical reasons. To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.')
msgAlternative.attach(msgText)
# We reference the image in the IMG SRC attribute by the ID we chose above
msgText = MIMEText('<img src="cid:' + comicHash + '"><p>This Calvin and Hobbes was originally published on ' + comicDay.strftime('%A, %B %d, %Y') + '. Enjoy!</p><p style="font-family:serif;text-size:9pt;">To unsubscribe, send an email to {sender}#{my-domain} with the subject "Unsubscribe please". You may briefly continue to recieve emails until the system processes your request.</p>', 'html')
msgAlternative.attach(msgText)
# Define the image's ID as referenced above
msgImage.add_header('Content-ID', '<' + comicHash + '>')
msgRoot.attach(msgImage)
# Send the email
import smtplib
smtpObj = smtplib.SMTP('localhost', 25)
smtpObj.helo()
smtpStatus = smtpObj.sendmail(strFrom, arrayTo[n], msgRoot.as_string())
smtpObj.quit()
if (smtpStatus != {}):
# code to log this error
else:
# code to log this error
I am using VM, Ubuntu 16.04, Python 2.7.12. I learn an example from here. I am using demo account and TWS.
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
def error_handler(msg):
"""Handles the capturing of error messages"""
print "Server Error: %s" % msg
def reply_handler(msg):
"""Handles of server replies"""
print "Server Response: %s, %s" % (msg.typeName, msg)
def create_contract(symbol, sec_type, exch, prim_exch, curr):
"""Create a Contract object defining what will
be purchased, at which exchange and in which currency.
symbol - The ticker symbol for the contract
sec_type - The security type for the contract ('STK' is 'stock')
exch - The exchange to carry out the contract on
prim_exch - The primary exchange to carry out the contract on
curr - The currency in which to purchase the contract"""
contract = Contract()
contract.m_symbol = symbol
contract.m_secType = sec_type
contract.m_exchange = exch
contract.m_primaryExch = prim_exch
contract.m_currency = curr
return contract
def create_order(order_type, quantity, action):
"""Create an Order object (Market/Limit) to go long/short.
order_type - 'MKT', 'LMT' for Market or Limit orders
quantity - Integral number of assets to order
action - 'BUY' or 'SELL'"""
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
if __name__ == "__main__":
# Connect to the Trader Workstation (TWS) running on the
# usual port of 7496, with a clientId of 100
# (The clientId is chosen by us and we will need
# separate IDs for both the execution connection and
# market data connection)
tws_conn = Connection.create("127.0.0.1", port=7496, clientId=100)
tws_conn.connect()
# Assign the error handling function defined above
# to the TWS connection
tws_conn.register(error_handler, 'Error')
# Assign all of the server reply messages to the
# reply_handler function defined above
tws_conn.registerAll(reply_handler)
# Create an order ID which is 'global' for this session. This
# will need incrementing once new orders are submitted.
order_id = 1
# Create a contract in GOOG stock via SMART order routing
goog_contract = create_contract('GOOG', 'STK', 'SMART', 'SMART', 'USD')
# Go long 100 shares of Google
goog_order = create_order('MKT', 100, 'BUY')
# Use the connection to the send the order to IB
print(tws_conn.placeOrder(order_id, goog_contract, goog_order))
# Disconnect from TWS
tws_conn.disconnect()
Here is my TWS configuration:
I can connect to the TWS since from the log I can see that:
2019-06-02 10:57:03.974 [GS] INFO [JTS-EServerSocket-153] - [0:62:76:1:0:0:0:SYS] Server version is 76
2019-06-02 10:57:03.974 [GS] INFO [JTS-EServerSocket-153] - [0:62:76:1:0:0:0:SYS] Client version is 62
2019-06-02 10:57:03.974 [GS] INFO [JTS-EServerSocket-153] - [0:62:76:1:0:0:0:SYS] is 3rdParty false
2019-06-02 10:57:03.974 [GS] INFO [JTS-EServerSocketNotifier-154] - Starting async queue thread
2019-06-02 10:57:03.977 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:0:0:SYS] Starting new conversation with client{100} at 127.0.0.1
2019-06-02 10:57:03.977 [GS] INFO [AWT-EventQueue-0] - MDConnectionsModel: Updated [127.0.0.1:34076 CLIENT ACCEPTED 100]
But the I cannot make an order, and I get errors from log:
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:9:1:INFO] Sending next valid order id.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:9:1:DET] [9;1;1]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Sending error.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] [4;2;-1;2104;Market data farm connection is OK:usfarm.nj]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Error sent.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Sending error.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] [4;2;-1;2104;Market data farm connection is OK:cashfarm]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Error sent.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Sending error.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] [4;2;-1;2104;Market data farm connection is OK:usfarm]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Error sent.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Sending error.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] [4;2;-1;2106;HMDS data farm connection is OK:hkhmds]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Error sent.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Sending error.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] [4;2;-1;2106;HMDS data farm connection is OK:ushmds]
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:4:2:DET] Error sent.
2019-06-02 10:57:03.978 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:0:0:INFO] Start processing incoming messages for client {100}.
2019-06-02 10:57:03.980 [GS] INFO [JTS-EServerSocket-153] - [100:62:76:1:0:0:0:INFO] Handling incoming PlaceOrder(3) message.
2019-06-02 10:57:03.982 [GS] INFO [JTS-EWriter2-155] - Broken pipe (Write failed)
2019-06-02 10:57:03.982 [GS] INFO [JTS-EWriter2-155] - [100:62:76:1:0:0:0:ERR] Unable write to socket client{100} -
2019-06-02 10:57:03.982 [GS] INFO [JTS-EWriter2-155] - Broken pipe (Write failed)
2019-06-02 10:57:03.982 [GS] INFO [JTS-EWriter2-155] - [100:62:76:1:0:0:0:INFO] Close call made for client{100} socket connection.
2019-06-02 10:57:04.000 [GS] INFO [JTS-EWriter2-155] - Cleaning up [serverId: 100]...
2019-06-02 10:57:04.000 [GS] INFO [JTS-EWriter2-155] - Cleaning up [serverId: 100]...
2019-06-02 10:57:04.000 [GS] INFO [JTS-EWriter2-155] - Cleaning up [serverId: 100]...
2019-06-02 10:57:04.000 [GS] INFO [JTS-EWriter2-155] - [100:62:76:1:0:0:0:DET] closePrim called. Stopping all mkt data and HMDS requests for client{100}.
Broken pipe, what does it means? How can I fix it and make order through python API? Thank you very much.
You call disconnect at the end of your program. I'm guessing that's why it gets disconnected;)
A few random thoughts.
There is a new python API available from IB so unless you want to use python 2.7 you should use the newer API as it has more features and probably more users as well by now.
It's not a problem with your program but you call connect and don't wait to make sure you're connected. Notice that next valid id is the first thing sent when the connection is established, you should use this as a signal to start your interaction with TWS/Gateway. Usually you implement the nextValidId callback and put a call to your startup code there, like placeAllOrders() or something.
Most people put a sleep() in their program to wait for it to finish before disconnecting. This is a bad idea since you never know when it's finished. In your case, imagine you want to disconnect after the order is received. You can implement the orderStatus callback and disconnect after it says it got your order. But you can put a sleep(5) or something just before your disconnect() call for testing.
I don't know what this line does print(tws_conn.placeOrder(order_id, goog_contract, goog_order)) placeOrder doesn't return anything, after TWS receives the order it will send an orderStatus callback.
The 'errors' saying that the market data is working aren't really errors, just information. If it says 'connection is broken' then you know you're not getting data from that particular farm.
It won't matter for goog but primary exchange is never SMART. That's an actual exchange where the contract you're using primarily trades. This is only used for disambiguation in case goog trades in USD in some other country.