#python #api #csv #request
#python #API #csv #запрос
Вопрос:
У меня есть raspberry pi с термопарой, записывающей строки данных о температуре в два csv: локальный для pi и data_queue
csv. Затем у меня есть другой скрипт, который запускается как отдельный процесс-демон, который должен использовать содержимое data_queue csv и отправлять post-запрос с каждой строкой в api. Чтобы избежать дубликатов, я хочу удалить каждую строку csv-файла очереди, которая публикуется в api. У меня есть следующий код:
def post(root):
headers = []
sent = [] # this will contain every line that is sent to the api
with open(root '/data_queue.csv', 'r') as f:
reader = csv.reader(f)
request_headers = {'Content-Type': 'application/json'}
headers = next(reader) # grab headers
for line in reader: # loop over lines in csv
payload = {} # make a payload dict with the headers as keys and the values as the line content
sent.append(line)
for i in range(len(headers)): # fill the payload
if i == 0 or i == 1 or i == 3: # convert data to its appropriate type
line[i] = int(line[i])
if i == 5 or i == 6 or i == 7:
try:
line[i] = float(line[i])
except ValueError as m: # correction and uncertainty are filled as 'None' until we actually calibrate the thermos
logger.warning('{}: No data was found for {}'.format(m, headers[i]))
line[i] = 0
payload.update( {headers[i]: line[i]} )
# convert the dict to json, and make a post request to the api
response = requests.post('http://192.168.1.67:5000/new_row', headers=request_headers, data = json.dumps(payload))
status = response.status_code
logger.debug('{}: sent'.format(status) if status == 200 else '{}: failed to send'.format(status))
if status == 500: # remove line from sent list if the line fails to post
sent.pop(len(sent)-1)
print(sent)
logger.debug('starting clean')
csv_cleanup(root, sent, headers)
logger.debug('csv cleaned')
def csv_cleanup(root, sent, headers):
leftovers = []
new = root '/data_queue_edit.csv'
old = root '/data_queue.csv'
with open(new, 'w') as out: # create edit csv
logger.error('made new csv')
writer = csv.writer(out)
writer.writerow(headers)
logger.error('wrote headers')
with open(old, 'r') as inp: # open old csv and grab leftovers
logger.error('opened old csv')
reader = csv.reader(inp)
next(reader) # skip headers
for old_row in reader:
leftovers.append(old_row)
for new_row in sent: # compare old csv and all sent rows, if dt's match up then remove it from leftovers
if old_row[2] == new_row[2]:
leftovers.pop(leftovers.index(old_row))
logger.error('removed {}'.format(new_row))
with open(new, 'a') as out: # append leftovers to new csv
logger.error('appending to new csv')
writer = csv.writer(out)
for row in leftovers:
logger.error('writing {}'.format(row))
writer.writerow(row)
os.remove(old)
os.rename(new, old) # replace old csv with new csv
logger.error('renamed file')
Хотя это работает, если есть ситуация, когда raspberry pi добавляет данные перемещения в очередь csv после их публикации, но до того, как они были очищены, тогда я потеряю указанные данные. Есть ли какая-либо работа вокруг этого, кроме синхронизации моих сценариев для синхронизации очереди, чтобы избежать потери данных?
Комментарии:
1. Почему бы вам не загрузить новый файл json / csv для каждой новой записи, а затем попросить приложение-потребителя удалить этот файл после его обработки? Таким образом, у вас не возникнет проблем с обоими приложениями, пытающимися заблокировать файл?
2. Просто попробовал это и заработало, я, похоже, не могу обнаружить никаких недостатков, из-за которых данные были бы потеряны. Большое спасибо за предложение!