I’m getting the same error:
Here is my code:
# Importa las librerías necesarias para la encripción de datos
from hmac import new
from hashlib import md5
# Importa la librerías necesarias para realizar consultas web
from requests import get, post
# Importa la librería necesaria para manipular objetos de tipo fecha-tiempo
from datetime import datetime, timedelta
# Importa la librería necesaría para manipular datos
from pandas import read_json
# Importa las librerías necesarias para crear una web app de tipo dashboard para visualización de datos
from dash import Dash
from dash.dependencies import Input, Output
from dash_html_components import Div, H2, Img
from dash_core_components import Dropdown, DatePickerRange
from dash_table import DataTable
# crea las variables necesarias para conectarse al servicio web de future time
url = 'some_url'
usr = 'some_user'
pwd = 'some_pwd'
pwdh = pwd.encode()
ts = str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')) # ; del datetime
msg = (usr + pwd + ts).encode()
# crea la firma hash HMAC MD5 utilizando la contraseña como llave y la guarda en la variable digest
digest = new(pwdh, msg, md5).hexdigest()
# Crea los argumentos necesarios para acceder al webservice y los asigna a la variable argumentos
arg = {'LoginName': usr,
'Signature': digest,
'TimeStamp': ts}
# Establece la conexión al web service, utiliza el recurso /System/LoginUser y autentica al usuario,
# guarda en la variable r el resultado de la conexión.
r = post(url, arg)
# Obtiene el UserID
UserId = str(r.json()['Result'][11:13])
# Crea las variable necesarias para consumir el servicio de Working Day
url = 'some_url'
Keywords = ''
StartDate = str((datetime.today() - timedelta(1)).strftime('%Y-%m-%d')) + ' 00:00:00'
EndDate = str((datetime.today() - timedelta(1)).strftime('%Y-%m-%d')) + ' 23:59:59'
Filter = 'todos'
OrderBy = ''
# Construye el nuevo mensaje a ser firmado
msg = (Keywords + StartDate + EndDate + Filter + OrderBy + UserId).encode()
# Crea la firma hash HMAC MD5
digest = new(pwdh, msg, md5).hexdigest() # ; del new, pwdh, msg, md5
# Crea los argumentos necesarios para acceder al webservice y los asigna a la variable argumentos
arg = {'Keywords': '',
'StartDate': StartDate,
'EndDate': EndDate,
'Filter': Filter,
'OrderBy': '',
'UserID': UserId,
'Signature': digest} # ; del Keywords, StartDate, EndDate, Filter, OrderBy, UserId, digest
# Invoca mediante get el recurso /WorkingDay/Get
r = get(url, arg) # ; del url, arg
# Convierte la cadena json del webservice a dataframe de pandas
df = read_json(r.json()['Result']) # ; del r; read_json
# Filtra las columnas necesarias para el reporte de faltas injustificadas
df = df.filter(items=['ExportId', 'Name', 'OU5', 'Date', 'TimeGroup', 'Exceptions'])
# Renombra las columnas del reporte
df.columns = ['Código de empleado', 'Nombre del empleado',
'Departamento', 'Fecha', 'Horario', 'Excepción']
# Inicializa la aplicación web
app = Dash('BI-UYEDA')
# Define las hojas de estilos externas a utilizar
external_css = [
"https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css", # Normalize the CSS
"https://fonts.googleapis.com/css?family=Open+Sans|Roboto", # Fonts
"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",
"https://cdn.rawgit.com/TahiriNadia/styles/faf8c1c3/stylesheet.css",
"https://cdn.rawgit.com/TahiriNadia/styles/b1026938/custum-styles_phyloapp.css"
]
# Añade las hojas de estilos a la aplicación
for css in external_css:
app.css.append_css({"external_url": css})
server = app.server
# Define la estructura de la aplicación
app.layout = Div([
Div([
H2("Inteligencia de negocios UYEDA"),
Img(src="some_url")],
className="banner"),
Div([
Div([
], style={
'margin': '5px',
'text-align': 'center',
'vertical-align': 'middle',
'width': '48%',
'display': 'inline-block'
}),
Div([
DatePickerRange(
id='fechas',
start_date=str((datetime.today() - timedelta(1)).strftime('%Y-%m-%d')),
end_date=str((datetime.today() - timedelta(1)).strftime('%Y-%m-%d')),
display_format='DD/MM/YYYY',
max_date_allowed=str((datetime.today() - timedelta(1)).strftime('%Y-%m-%d')),
min_date_allowed='2018/01/01'
),
], style={
'margin': '5px',
'text-align': 'center',
'vertical-align': 'middle',
'width': '48%',
'display': 'inline-block'
})
],
className="container"
),
Div([
DataTable(id='table',
columns=[{'name': i, 'id': i} for i in df.columns],
data=[{}], #df.to_dict('rows'),
sorting=True,
style_table={'overflowX': 'scroll'},
style_cell={'minWidth': '0px',
'maxWidth': '180px',
'whiteSpace': 'normal'},
css=[{
'selector': '.dash-cell div.dash-cell-value',
'rule': 'display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;'
}],
virtualization=True,
pagination_mode=True,
n_fixed_rows=1,
merge_duplicate_headers=True
)
],
className="container")
])
# Crea las llamadas a la aplicación para actualizar las filas
@app.callback(
Output('table', 'data'),
[Input('fechas', 'start_date'),
Input('fechas', 'end_date')]
)
# Crea la función que actualiza las filas de la tabla
def act_filas(start_date, end_date):
"""
Esta función actualiza las filas de un datatable
:param start_date: Cadena de caracteres que indica la fecha inicial del reporte
:param end_date: Cadena de caracteres que indica la fehca final del reporte
:return: Retorna las filas que actualizaran las filas del datatable
"""
# crea las variables necesarias para conectarse al servicio web de future time
url = 'some_url'
usr = 'some_usr'
pwd = 'some_pwd'
pwdh = pwd.encode()
ts = str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')) # ; del datetime
msg = (usr + pwd + ts).encode()
# crea la firma hash HMAC MD5 utilizando la contraseña como llave y la guarda en la variable digest
digest = new(pwdh, msg, md5).hexdigest()
# Crea los argumentos necesarios para acceder al webservice y los asigna a la variable argumentos
arg = {'LoginName': usr,
'Signature': digest,
'TimeStamp': ts}
# Establece la conexión al web service, utiliza el recurso /System/LoginUser y autentica al usuario,
# guarda en la variable r el resultado de la conexión.
r = post(url, arg)
# Obtiene el UserID
UserId = str(r.json()['Result'][11:13])
# Crea las variable necesarias para consumir el servicio de Working Day
url = 'some_url'
Keywords = ''
StartDate = start_date + ' 00:00:00'
EndDate = end_date + ' 23:59:59'
Filter = 'todos'
OrderBy = ''
# Construye el nuevo mensaje a ser firmado
msg = (Keywords + StartDate + EndDate + Filter + OrderBy + UserId).encode()
# Crea la firma hash HMAC MD5
digest = new(pwdh, msg, md5).hexdigest() # ; del new, pwdh, msg, md5
# Crea los argumentos necesarios para acceder al webservice y los asigna a la variable argumentos
arg = {'Keywords': '',
'StartDate': StartDate,
'EndDate': EndDate,
'Filter': Filter,
'OrderBy': '',
'UserID': UserId,
'Signature': digest} # ; del Keywords, StartDate, EndDate, Filter, OrderBy, UserId, digest
# Invoca mediante get el recurso /WorkingDay/Get
r = get(url, arg) # ; del url, arg
# Convierte la cadena json del webservice a dataframe de pandas
df = read_json(r.json()['Result']) # ; del r; read_json
# Reemplaza los valores nulos por caracter vacio
df.fillna('', None, None, True)
# Descarta los registros correspondientes a practicantes, del cómputo de faltas
df.drop(df[df['TimeGroup'] == 'Practicantes'].index, inplace=True)
# Descarta los registros correspondientes a horarios libres, del cómputo de faltas
df.drop(df[df['TimeGroup'] == 'Libre'].index, inplace=True)
# Descarta los registros correspondientes a descansos, del cómputo de faltas
df.drop(df[df['ProjectedTimeToWork'].str.contains('00:00:00')].index, inplace=True)
# Descarta los registros correspondientes a trabajadores borrados, del cómputo de faltas
df.drop(df[df['Name'].str.contains('Borrado')].index, inplace=True)
# Descarta los registros correspondientes a visitantes, del cómputo de faltas
df.drop(df[df['Name'].str.contains('Visitante')].index, inplace=True)
# Descarta los registros correspondientes a personal directivo, del cómputo de faltas
df.drop(df[df['Name'].str.contains('Director')].index, inplace=True)
# Descarta los registros correspondientes a trabajadores borrados, del cómputo de faltas
df.drop(df[df['Name'].str.contains('New node')].index, inplace=True)
# Descarta los registros correspondientes a personal de soporte y pruebas, del cómputo de faltas
df.drop(df[df['Name'].str.contains('Soporte y Pruebas')].index, inplace=True)
# Descarta los registros correspondientes a Incapacidad IMSS Riesgo de Trabajo, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('[057]')].index, inplace=True)
# Descarta los registros correspondientes a permiso sin goce de sueldo 069, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('Permiso Sin Goce de Sueldo')].index, inplace=True)
# Descarta los registros correspondientes a Día de castigo 069, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('Día de castigo')].index, inplace=True)
# Descarta los registros correspondientes a vacaciones, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('[801]')].index, inplace=True)
# Descarta los registros correspondientes a falta con goce de sueldo 800, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('falta con goce de sueldo')].index, inplace=True)
# Descarta los registros correspondientes a dias feriados, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('Dia No Laborable General de Ley día feriado')].index, inplace=True)
# Descarta los registros correspondientes a Incapacidad IMSS Enfermedad General 060, del cómputo de faltas
df.drop(df[df['Exceptions'].str.contains('Incapacidad IMSS Enfermedad General')].index, inplace=True)
# Descarta los registros correspondientes a omisión de registro de entrada
df.drop(df[df['InHour'].str[11:16] > '00:00'].index, inplace=True)
# Filtra las columnas necesarias para el reporte de faltas injustificadas
df = df.filter(items=['ExportId', 'Name', 'OU5', 'Date', 'TimeGroup', 'Exceptions'])
# Renombra las columnas del reporte
df.columns = ['Código de empleado', 'Nombre del empleado',
'Departamento', 'Fecha', 'Horario', 'Excepción']
# Envía los resultados del DataFrame a las filas del data table
data = [{'name': i, 'id': i} for i in df.to_dict('rows')]
# Retorna los registros para actualizar la tabla
return data
if __name__ == '__main__':
app.run_server(debug=True)
The only diference is that i get the same error when updating the datepicker, not in the initial table, then the rows are retrieved but data appears in blank.