#python #python-3.x #ftp #plotly #plotly-dash
#python #python-3.x #ftp #сюжет #plotly-dash
Вопрос:
Я работаю над проектом, в котором я должен отслеживать каталог ftp на наличие любых новых файлов, которые появляются, как только появляется новый файл, я хочу извлечь данные и отобразить результаты в режиме реального времени. пока я разобрался с функцией ftp, которая отслеживает каталог, для целей тестирования, которые я использую мой телефон в качестве тестового ftp-сервера, и я создал функцию, которая загружает новый файл каждые n секунд :
from ftplib import FTP
from time import sleep
import os
ftp = FTP()
ftp.connect('192.168.1.109', 2221)
ftp.login('android', 'android')
ftp.cwd('/test_folder')
folder = 'C:\Users\QC\Desktop\sample_files_to_upload'
for file in os.listdir(folder):
fp = open(folder file,'rb')
ftp.storbinary('STOR %s' % os.path.basename(file), fp, 1024)
sleep(2)
fp.close()
sleep(2)
print("File {} uploaded sucessfully".format(file))
У меня также есть функция которая отслеживает каталог на наличие любых новых файлов которые появляются в каталоге и как только появляется файл копирует его на локальном компьютере выполняет извлечение данных распечатывает выходные данные и удаляет файл:
from ftplib import FTP
from time import sleep
import time
import os
def monitor_ftp():
ftp = FTP()
ftp.connect('192.168.1.109', 2221', 21)
ftp.login('android', 'android)
ftp.cwd('/test_folder')
print("Connection Established {}".format(ftp.getwelcome()))
direct = 'C:\Users\QC\Desktop\local_temp_directory\'
old_files = ['1']
#print(old_files)
while True:
try:
new_files = ftp.nlst()
#print(new_files)
#print(new_files)
if len(old_files) != 0 and new_files != old_files:
changes = [i for i in new_files if i not in old_files]
#
# print(changes)
for x in changes:
filename = str(direct x)
localfile = open(filename, 'wb')
ftp.retrbinary('RETR' ' ' x , localfile.write, 1024)
localfile.close()
xcorr = extract_function(filename)
print("updating data ***************************************************")
print("found new file---> {}".format(str(filename).split('\')[-1]))
print("Calculating cross-correlation")
print("*****************************************************************")
print(" ")
sleep(3)
os.remove(filename)
a = time.perf_counter()
if time.perf_counter() > a 20:
print("Done Waiting")
break
old_files = new_files
except KeyboardInterrupt:
ftp.quit()
Я также создал базовое приложение test_dash :
import dash
import plotly.graph_objects as go
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from app import app
app = dash.Dash(__name__)
app.layout = html.Div(
[
dcc.Graph(id = 'live-graph', animate = True),
dcc.Interval(
id = 'graph-update',
interval = 10000,
n_intervals = 0
),
html.Div(dbc.Row([
dbc.Col(html.H2(id='check_update_div', children='check ' ))
]) )
]
)
@app.callback(
Output('check_update_div', 'children'),
[ Input('graph-update', 'n_intervals') ]
)
def update_graph_scatter(n):
print('one loop done ')
a = monitor_ftp()
return ("this is X {}".format(a))
Я хочу связать все вместе и создать приложение dash, которое отслеживает каталог ftp и отображает результат извлечения данных, в настоящее время у меня нет графика в моем приложении, я только что поместил div, который я хочу обновить с именем файла для каждого нового файла, который появляется в папке, но я не уверен, как объединить эти функции вместе. Не могли бы вы помочь.
Редактировать:
У меня есть рабочий пример, который показывает, что ftp внутри функции обратного вызова не позволяет функции возвращать что-либо, если ftp находится вне функции возврата, тогда обратный вызов возвращает и обновляет div каждые n_intervals
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import random
import plotly.graph_objs as go
from collections import deque
from ftplib import FTP
from time import sleep
#ftp otside the function and function works fine
#Deactivae this part and activate ftp inside the function , and function
#stops returning anything and div is not updated every n_interval
ftp = FTP()
ftp.connect('10.199.44.240', 21)
ftp.login('display')
ftp.cwd('/home/display/test_qc')
print("Connection Established {}".format(ftp.getwelcome()))
direct = 'C:\Users\QC\Desktop\Gunlink_local\'
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([
dcc.Interval(
id = 'graph-update',
interval = 10000,
n_intervals = 0
)
]),
html.Div([
html.H1(id='print_value', children="Output Value"),
])
])
@app.callback(
Output('print_value', 'children'),
[ Input('graph-update', 'n_intervals') ]
)
def update_value(n):
# ftp inside the function prevents the function from returning anything
# Div is not updated every n_interval
'''
ftp = FTP()
ftp.connect('10.199.44.240', 21)
ftp.login('display')
ftp.cwd('/home/display/test_qc')
print("Connection Established {}".format(ftp.getwelcome()))
a = ftp.nlst()
'''
a = ftp.nlst()
sleep(2)
print('one loop done ')
return ("this is X {}".format(a))
if __name__ == '__main__':
app.run_server()
Ответ №1:
Вам нужен компонент интервала.
Dash не может выполнять постоянные обновления, например, запускать этот while
цикл без остановки, но вы можете установить интервал для запуска обратного вызова каждые X секунд. Используя этот обратный вызов, вы можете проверить наличие обновлений на FTP-сервере в этом расписании.
Ознакомьтесь с этой страницей документации, чтобы найти несколько хороших примеров ее использования для создания страницы обновления в реальном времени.
Комментарии:
1. У меня есть рабочий пример, который показывает, что ftp внутри функции обратного вызова не позволяет функции возвращать что-либо, если ftp находится вне функции возврата, тогда обратный вызов возвращает и обновляет div каждые n_intervals
2. Я отредактировал свой вопрос, чтобы добавить пример, который показывает, что выполнение ftp внутри обратного вызова каждые n_intervals не позволяет обратному вызову возвращать что-либо
3. Выдает ли это ошибку или завершается беззвучно? Интервал выглядит как 10 секунд, что, я думаю, достаточно, но, возможно, это не так. Если вы измените его на 60 секунд, он будет работать? Если вы можете запустить отладчик и установить точку останова, с которой начинается вызов FTP, попробуйте пошагово просмотреть каждую строку, чтобы увидеть, что происходит.
4. На самом деле это не сбой, он просто ничего не возвращает, иногда количество файлов может быть больше, и функции потребуется гораздо больше времени, чем 10 секунд, для обработки и извлечения данных, есть ли какой-нибудь способ, которым я могу сказать dash, чтобы он запускал счетчик n_interval только после завершения функции, или в качестве альтернативы я могу запустить обратный вызов только один раз, который просматривает каталог в цикле while и выполняет извлечение, выдавая выходные данные в скрытый div, добавляя извлеченные данные к фреймам данных, и я могу написать dcc. Интервальные вызываемые функции только для обновления моих графиков, отображающих эти фреймы данных?
5. Можно ли будет запустить функцию, основанную на цикле while True, из dash?