Amal KM


Verify LDAP In Zimbra | In 5 Steps

In this article, the steps to verify LDAP in Zimbra are outlined. Skynats offers solutions to all of your questions as part of our Server Management Services.

How can LDAP be verified in Zimbra?

Zimbra utilizes the LDAP service to store information regarding Zimbra Global configuration, user and authentication information, server, domain, and class of service (COS) details. The Zimbra LDAP service employs OpenLDAP software.

Let's examine the Zimbra verification steps for the LDAP or slapd process.

1. We must first execute the Zimbra user.

[zimbra@centos64 ~]$ ldap status

slapd running pid: 1351

2. Now, use the following command to determine whether the LDAP process is active:

ps auxww | grep zimbra | grep slapd

3. We use telnet to test for connection failure on the default LDAP port, 389.

[zimbra@centos64 ~]$ telnet centos64.ehowstuff.local 389


Connected to centos64.ehowstuff.local.

Escape character is '^]'.


telnet> quit

Connection closed.

4. Using the following code, we can start and stop Zimbra.

To start,

[zimbra@centos64 ~]$ ldap stop

Killing slapd with pid 1351 done.


To stop,

[zimbra@centos64 ~]$ ldap start

Started slapd: pid 47807


5. Now, using the zmcontrol command, check the status of LDAP:

[zimbra@centos64 ~]$ zmcontrol status

Host centos64.ehowstuff.local

antispam Running

antivirus Running

ldap Running

logger Running

mailbox Running

memcached Running

mta Running

opendkim Running

proxy Running

snmp Running

spell Running

stats Running

zmconfigd Running

What is GEEK

Buddha Community

John  Smith

John Smith


Find the Best Restaurant Mobile App Development Company in Abu Dhbai

The era of mobile app development has completely changed the scenario for businesses in regions like Abu Dhabi. Restaurants and food delivery businesses are experiencing huge benefits via smart business applications. The invention and development of the food ordering app have helped all-scale businesses reach new customers and boost sales and profit. 

As a result, many business owners are searching for the best restaurant mobile app development company in Abu Dhabi. If you are also searching for the same, this article is helpful for you. It will let you know the step-by-step process to hire the right team of restaurant mobile app developers. 

Step-by-Step Process to Find the Best Restaurant App Development Company

Searching for the top mobile app development company in Abu Dhabi? Don't know the best way to search for professionals? Don't panic! Here is the step-by-step process to hire the best professionals. 

#Step 1 – Know the Company's Culture

Knowing the organization's culture is very crucial before finalizing a food ordering app development company in Abu Dhabi. An organization's personality is shaped by its common beliefs, goals, practices, or company culture. So, digging into the company culture reveals the core beliefs of the organization, its objectives, and its development team. 

Now, you might be wondering, how will you identify the company's culture? Well, you can take reference from the following sources – 

  • Social media posts 
  • App development process
  • About us Page
  • Client testimonials

#Step 2 - Refer to Clients' Reviews

Another best way to choose the On-demand app development firm for your restaurant business is to refer to the clients' reviews. Reviews are frequently available on the organization's website with a tag of "Reviews" or "Testimonials." It's important to read the reviews as they will help you determine how happy customers are with the company's app development process. 

You can also assess a company's abilities through reviews and customer testimonials. They can let you know if the mobile app developers create a valuable app or not. 

#Step 3 – Analyze the App Development Process

Regardless of the company's size or scope, adhering to the restaurant delivery app development process will ensure the success of your business application. Knowing the processes an app developer follows in designing and producing a top-notch app will help you know the working process. Organizations follow different app development approaches, so getting well-versed in the process is essential before finalizing any mobile app development company. 

#Step 4 – Consider Previous Experience

Besides considering other factors, considering the previous experience of the developers is a must. You can obtain a broad sense of the developer's capacity to assist you in creating a unique mobile application for a restaurant business.

You can also find out if the developers' have contributed to the creation of other successful applications or not. It will help you know the working capacity of a particular developer or organization. Prior experience is essential to evaluating their work. For instance, whether they haven't previously produced an app similar to yours or not. 

#Step 5 – Check for Their Technical Support

As you expect a working and successful restaurant mobile app for your business, checking on this factor is a must. A well-established organization is nothing without a good technical support team. So, ensure whatever restaurant mobile app development company you choose they must be well-equipped with a team of dedicated developers, designers, and testers. 

Strong tech support from your mobile app developers will help you identify new bugs and fix them bugs on time. All this will ensure the application's success. 

#Step 6 – Analyze Design Standards

Besides focusing on an organization's development, testing, and technical support, you should check the design standards. An appealing design is crucial in attracting new users and keeping the existing ones stick to your services. So, spend some time analyzing the design standards of an organization. Now, you might be wondering, how will you do it? Simple! By looking at the organization's portfolio. 

Whether hiring an iPhone app development company or any other, these steps apply to all. So, don't miss these steps. 

#Step 7 – Know Their Location

Finally, the last yet very crucial factor that will not only help you finalize the right person for your restaurant mobile app development but will also decide the mobile app development cost. So, you have to choose the location of the developers wisely, as it is a crucial factor in defining the cost. 

Summing Up!!!

Restaurant mobile applications have taken the food industry to heights none have ever considered. As a result, the demand for restaurant mobile app development companies has risen greatly, which is why businesses find it difficult to finalize the right person. But, we hope that after referring to this article, it will now be easier to hire dedicated developers under the desired budget. So, begin the hiring process now and get a well-craft food ordering app in hand. 

Dylan  Iqbal

Dylan Iqbal


Matplotlib Cheat Sheet: Plotting in Python

This Matplotlib cheat sheet introduces you to the basics that you need to plot your data with Python and includes code samples.

Data visualization and storytelling with your data are essential skills that every data scientist needs to communicate insights gained from analyses effectively to any audience out there. 

For most beginners, the first package that they use to get in touch with data visualization and storytelling is, naturally, Matplotlib: it is a Python 2D plotting library that enables users to make publication-quality figures. But, what might be even more convincing is the fact that other packages, such as Pandas, intend to build more plotting integration with Matplotlib as time goes on.

However, what might slow down beginners is the fact that this package is pretty extensive. There is so much that you can do with it and it might be hard to still keep a structure when you're learning how to work with Matplotlib.   

DataCamp has created a Matplotlib cheat sheet for those who might already know how to use the package to their advantage to make beautiful plots in Python, but that still want to keep a one-page reference handy. Of course, for those who don't know how to work with Matplotlib, this might be the extra push be convinced and to finally get started with data visualization in Python. 

You'll see that this cheat sheet presents you with the six basic steps that you can go through to make beautiful plots. 

Check out the infographic by clicking on the button below:

Python Matplotlib cheat sheet

With this handy reference, you'll familiarize yourself in no time with the basics of Matplotlib: you'll learn how you can prepare your data, create a new plot, use some basic plotting routines to your advantage, add customizations to your plots, and save, show and close the plots that you make.

What might have looked difficult before will definitely be more clear once you start using this cheat sheet! Use it in combination with the Matplotlib Gallery, the documentation.


Matplotlib is a Python 2D plotting library which produces publication-quality figures in a variety of hardcopy formats and interactive environments across platforms.

Prepare the Data 

1D Data 

>>> import numpy as np
>>> x = np.linspace(0, 10, 100)
>>> y = np.cos(x)
>>> z = np.sin(x)

2D Data or Images 

>>> data = 2 * np.random.random((10, 10))
>>> data2 = 3 * np.random.random((10, 10))
>>> Y, X = np.mgrid[-3:3:100j, -3:3:100j]
>>> U = 1 X** 2 + Y
>>> V = 1 + X Y**2
>>> from matplotlib.cbook import get_sample_data
>>> img = np.load(get_sample_data('axes_grid/bivariate_normal.npy'))

Create Plot

>>> import matplotlib.pyplot as plt


>>> fig = plt.figure()
>>> fig2 = plt.figure(figsize=plt.figaspect(2.0))


>>> fig.add_axes()
>>> ax1 = fig.add_subplot(221) #row-col-num
>>> ax3 = fig.add_subplot(212)
>>> fig3, axes = plt.subplots(nrows=2,ncols=2)
>>> fig4, axes2 = plt.subplots(ncols=3)

Save Plot 

>>> plt.savefig('foo.png') #Save figures
>>> plt.savefig('foo.png',  transparent=True) #Save transparent figures

Show Plot


Plotting Routines 

1D Data 

>>> fig, ax = plt.subplots()
>>> lines = ax.plot(x,y) #Draw points with lines or markers connecting them
>>> ax.scatter(x,y) #Draw unconnected points, scaled or colored
>>> axes[0,0].bar([1,2,3],[3,4,5]) #Plot vertical rectangles (constant width)
>>> axes[1,0].barh([0.5,1,2.5],[0,1,2]) #Plot horiontal rectangles (constant height)
>>> axes[1,1].axhline(0.45) #Draw a horizontal line across axes
>>> axes[0,1].axvline(0.65) #Draw a vertical line across axes
>>> ax.fill(x,y,color='blue') #Draw filled polygons
>>> ax.fill_between(x,y,color='yellow') #Fill between y values and 0

2D Data 

>>> fig, ax = plt.subplots()
>>> im = ax.imshow(img, #Colormapped or RGB arrays
      cmap= 'gist_earth', 
      interpolation= 'nearest',
>>> axes2[0].pcolor(data2) #Pseudocolor plot of 2D array
>>> axes2[0].pcolormesh(data) #Pseudocolor plot of 2D array
>>> CS = plt.contour(Y,X,U) #Plot contours
>>> axes2[2].contourf(data1) #Plot filled contours
>>> axes2[2]= ax.clabel(CS) #Label a contour plot

Vector Fields 

>>> axes[0,1].arrow(0,0,0.5,0.5) #Add an arrow to the axes
>>> axes[1,1].quiver(y,z) #Plot a 2D field of arrows
>>> axes[0,1].streamplot(X,Y,U,V) #Plot a 2D field of arrows

Data Distributions 

>>> ax1.hist(y) #Plot a histogram
>>> ax3.boxplot(y) #Make a box and whisker plot
>>> ax3.violinplot(z)  #Make a violin plot

Plot Anatomy & Workflow 

Plot Anatomy 




The basic steps to creating plots with matplotlib are:

1 Prepare Data
2 Create Plot
3 Plot
4 Customized Plot
5 Save Plot
6 Show Plot

>>> import matplotlib.pyplot as plt
>>> x = [1,2,3,4]  #Step 1
>>> y = [10,20,25,30] 
>>> fig = plt.figure() #Step 2
>>> ax = fig.add_subplot(111) #Step 3
>>> ax.plot(x, y, color= 'lightblue', linewidth=3)  #Step 3, 4
>>> ax.scatter([2,4,6],
          color= 'darkgreen',
          marker= '^' )
>>> ax.set_xlim(1, 6.5)
>>> plt.savefig('foo.png' ) #Step 5
>>> #Step 6

Close and Clear 

>>> plt.cla()  #Clear an axis
>>> plt.clf(). #Clear the entire figure
>>> plt.close(). #Close a window

Plotting Customize Plot 

Colors, Color Bars & Color Maps 

>>> plt.plot(x, x, x, x**2, x, x** 3)
>>> ax.plot(x, y, alpha = 0.4)
>>> ax.plot(x, y, c= 'k')
>>> fig.colorbar(im, orientation= 'horizontal')
>>> im = ax.imshow(img,
            cmap= 'seismic' )


>>> fig, ax = plt.subplots()
>>> ax.scatter(x,y,marker= ".")
>>> ax.plot(x,y,marker= "o")


>>> plt.plot(x,y,linewidth=4.0)
>>> plt.plot(x,y,ls= 'solid') 
>>> plt.plot(x,y,ls= '--') 
>>> plt.plot(x,y,'--' ,x**2,y**2,'-.' ) 
>>> plt.setp(lines,color= 'r',linewidth=4.0)

Text & Annotations 

>>> ax.text(1,
           'Example Graph', 
            style= 'italic' )
>>> ax.annotate("Sine", 
xy=(8, 0),
xycoords= 'data', 
xytext=(10.5, 0),
textcoords= 'data', 
arrowprops=dict(arrowstyle= "->", 


>>> plt.title(r '$sigma_i=15$', fontsize=20)

Limits, Legends and Layouts 

Limits & Autoscaling 

>>> ax.margins(x=0.0,y=0.1) #Add padding to a plot
>>> ax.axis('equal')  #Set the aspect ratio of the plot to 1
>>> ax.set(xlim=[0,10.5],ylim=[-1.5,1.5])  #Set limits for x-and y-axis
>>> ax.set_xlim(0,10.5) #Set limits for x-axis


>>> ax.set(title= 'An Example Axes',  #Set a title and x-and y-axis labels
            ylabel= 'Y-Axis', 
            xlabel= 'X-Axis')
>>> ax.legend(loc= 'best')  #No overlapping plot elements


>>> ax.xaxis.set(ticks=range(1,5),  #Manually set x-ticks
             ticklabels=[3,100, 12,"foo" ])
>>> ax.tick_params(axis= 'y', #Make y-ticks longer and go in and out
             direction= 'inout', 

Subplot Spacing 

>>> fig3.subplots_adjust(wspace=0.5,   #Adjust the spacing between subplots
>>> fig.tight_layout() #Fit subplot(s) in to the figure area

Axis Spines 

>>> ax1.spines[ 'top'].set_visible(False) #Make the top axis line for a plot invisible
>>> ax1.spines['bottom' ].set_position(( 'outward',10))  #Move the bottom axis line outward

Have this Cheat Sheet at your fingertips

Original article source at

#matplotlib #cheatsheet #python

Garry Taylor

Garry Taylor


Python Data Visualization: Bokeh Cheat Sheet

A handy cheat sheet for interactive plotting and statistical charts with Bokeh.

Bokeh distinguishes itself from other Python visualization libraries such as Matplotlib or Seaborn in the fact that it is an interactive visualization library that is ideal for anyone who would like to quickly and easily create interactive plots, dashboards, and data applications. 

Bokeh is also known for enabling high-performance visual presentation of large data sets in modern web browsers. 

For data scientists, Bokeh is the ideal tool to build statistical charts quickly and easily; But there are also other advantages, such as the various output options and the fact that you can embed your visualizations in applications. And let's not forget that the wide variety of visualization customization options makes this Python library an indispensable tool for your data science toolbox.

Now, DataCamp has created a Bokeh cheat sheet for those who have already taken the course and that still want a handy one-page reference or for those who need an extra push to get started.

In short, you'll see that this cheat sheet not only presents you with the five steps that you can go through to make beautiful plots but will also introduce you to the basics of statistical charts. 

Python Bokeh Cheat Sheet

In no time, this Bokeh cheat sheet will make you familiar with how you can prepare your data, create a new plot, add renderers for your data with custom visualizations, output your plot and save or show it. And the creation of basic statistical charts will hold no secrets for you any longer. 

Boost your Python data visualizations now with the help of Bokeh! :)

Plotting With Bokeh

The Python interactive visualization library Bokeh enables high-performance visual presentation of large datasets in modern web browsers.

Bokeh's mid-level general-purpose bokeh. plotting interface is centered around two main components: data and glyphs.

The basic steps to creating plots with the bokeh. plotting interface are:

  1. Prepare some data (Python lists, NumPy arrays, Pandas DataFrames and other sequences of values)
  2. Create a new plot
  3. Add renderers for your data, with visual customizations
  4. Specify where to generate the output
  5. Show or save the results
>>> from bokeh.plotting import figure
>>> from import output_file, show
>>> x = [1, 2, 3, 4, 5] #Step 1
>>> y = [6, 7, 2, 4, 5]
>>> p = figure(title="simple line example", #Step 2
>>> p.line(x, y, legend="Temp.", line_width=2) #Step 3
>>> output_file("lines.html") #Step 4
>>> show(p) #Step 5

1. Data 

Under the hood, your data is converted to Column Data Sources. You can also do this manually:

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.OataFrame(np.array([[33.9,4,65, 'US'], [32.4, 4, 66, 'Asia'], [21.4, 4, 109, 'Europe']]),
                     columns= ['mpg', 'cyl',   'hp',   'origin'],
                      index=['Toyota', 'Fiat', 'Volvo'])

>>> from bokeh.models import ColumnOataSource
>>> cds_df = ColumnOataSource(df)

2. Plotting 

>>> from bokeh.plotting import figure
>>>p1= figure(plot_width=300, tools='pan,box_zoom')
>>> p2 = figure(plot_width=300, plot_height=300,
x_range=(0, 8), y_range=(0, 8))
>>> p3 = figure()

3. Renderers & Visual Customizations 


Scatter Markers 
Bokeh Scatter Markers

>>>[1,2,3]), np.array([3,2,1]), fill_color='white')
>>> p2.square(np.array([1.5,3.5,5.5]), [1,4,3],
color='blue', size=1)

Line Glyphs 

Bokeh Line Glyphs

>>> pl.line([1,2,3,4], [3,4,5,6], line_width=2)
>>> p2.multi_line(pd.DataFrame([[1,2,3],[5,6,7]]),

Customized Glyphs

Selection and Non-Selection Glyphs 

Selection Glyphs

>>> p = figure(tools='box_select')
>>> p. circle ('mpg', 'cyl', source=cds_df,

Hover Glyphs

Hover Glyphs

>>> from bokeh.models import HoverTool
>>>hover= HoverTool(tooltips=None, mode='vline')
>>> p3.add_tools(hover)

Color Mapping 

Bokeh Colormapping Glyphs

>>> from bokeh.models import CategoricalColorMapper
>>> color_mapper = CategoricalColorMapper(
             factors= ['US', 'Asia', 'Europe'],
             palette= ['blue', 'red', 'green'])
>>>  p3. circle ('mpg', 'cyl', source=cds_df,
                 transform=color_mapper), legend='Origin')

4. Output & Export 


>>> from import output_notebook, show
>>> output_notebook()


Standalone HTML 

>>> from bokeh.embed import file_html
>>> from bokeh.resources import CON
>>> html = file_html(p, CON, "my_plot")

>>> from  import  output_file,  show
>>> output_file('my_bar_chart.html',  mode='cdn')


>>> from bokeh.embed import components
>>> script, div= components(p)


>>> from import export_png
>>> export_png(p, filename="plot.png")


>>> from import export_svgs
>>> p. output_backend = "svg"
>>> export_svgs(p,filename="plot.svg")

Legend Location 

Inside Plot Area 

>>> p.legend.location = 'bottom left'

Outside Plot Area 

>>> from bokeh.models import Legend
>>> r1 = p2.asterisk(np.array([1,2,3]), np.array([3,2,1])
>>> r2 = p2.line([1,2,3,4], [3,4,5,6])
>>> legend = Legend(items=[("One" ,[p1, r1]),("Two",[r2])], location=(0, -30))
>>> p.add_layout(legend, 'right')

Legend Background & Border 

>>> p.legend. border_line_color = "navy"
>>> p.legend.background_fill_color = "white"

Legend Orientation 

>>> p.legend.orientation = "horizontal"
>>> p.legend.orientation = "vertical"

Rows & Columns Layout


>>> from bokeh.layouts import row
>>>layout= row(p1,p2,p3)


>>> from bokeh.layouts import columns
>>>layout= column(p1,p2,p3)

Nesting Rows & Columns 

>>>layout= row(column(p1,p2), p3)

Grid Layout 

>>> from bokeh.layouts import gridplot
>>> rowl = [p1,p2]
>>> row2 = [p3]
>>> layout = gridplot([[p1, p2],[p3]])

Tabbed Layout 

>>> from bokeh.models.widgets import Panel, Tabs
>>> tab1 = Panel(child=p1, title="tab1")
>>> tab2 = Panel(child=p2, title="tab2")
>>> layout = Tabs(tabs=[tab1, tab2])

Linked Plots

Linked Axes 

Linked Axes
>>> p2.x_range = p1.x_range
>>> p2.y_range = p1.y_range

Linked Brushing 

>>> p4 = figure(plot_width = 100, tools='box_select,lasso_select')
>>>'mpg', 'cyl' , source=cds_df)
>>> p5 = figure(plot_width = 200, tools='box_select,lasso_select')
>>>'mpg', 'hp', source=cds df)
>>>layout= row(p4,p5)

5. Show or Save Your Plots  

>>> show(p1)
>>> show(layout)
>>> save(p1)

Have this Cheat Sheet at your fingertips

Original article source at

#python #datavisualization #bokeh #cheatsheet

Saul  Alaniz

Saul Alaniz


Hangfire en ASP.NET Core 3.1

En este artículo, aprendamos sobre Hangfire en ASP.NET Core 3.1 y cómo integrarlo con sus aplicaciones principales. Una tarea de programación común a la que nos enfrentamos regularmente es ejecutar trabajos en segundo plano. Y ejecutar estos trabajos correctamente sin estropear su código no es una tarea fácil, pero tampoco es difícil. Solía ​​trabajar con los servicios de Windows para programar varias tareas dentro de mi aplicación C#. Luego, me encontré con esta biblioteca casi increíble: Hangfire, y nunca me fui.

Trabajos en segundo plano en ASP.NET Core

Básicamente, los trabajos en segundo plano son aquellos métodos o funciones que pueden tardar mucho tiempo en ejecutarse (cantidad de tiempo desconocida). Estos trabajos, si se ejecutan en el subproceso principal de nuestra aplicación, pueden o no bloquear la interacción del usuario y puede parecer que nuestra aplicación .NET Core se ha bloqueado y no responde. Esto es bastante crítico para las aplicaciones orientadas al cliente. Por lo tanto, tenemos trabajos en segundo plano, similares a los subprocesos múltiples, estos trabajos se ejecutan en otro subproceso, lo que hace que nuestra aplicación parezca bastante asíncrona.

También deberíamos tener la posibilidad de programarlos en un futuro cercano para que esté completamente automatizado. La vida de un desarrollador sería muy dura sin estas increíbles posibilidades.

¿Qué es Hangfire?

Hangfire es una biblioteca de código abierto que permite a los desarrolladores programar eventos en segundo plano con la mayor facilidad. Es una biblioteca altamente flexible que ofrece varias funciones necesarias para hacer que la tarea de programación de trabajos sea pan comido. Hangfire en ASP.NET Core es la única biblioteca que no puede perderse.

Integración de Hangfire en ASP.NET Core 3.1

Para este tutorial, tengamos un escenario específico para que podamos explicar Hangfire y su potencial completo. Digamos que estamos desarrollando una API que se encarga de enviar correos al Usuario para diferentes escenarios. Tiene más sentido explicar Hangfire de esta manera. Hangfire es una de las bibliotecas más fáciles de adaptar, pero también muy poderosa. Es uno de los paquetes que ayuda por completo a crear aplicaciones de forma asíncrona y desacoplada.

Como mencioné anteriormente, Hangfire usa una base de datos para almacenar los datos del trabajo. Usaremos la base de datos del servidor MSSQL en esta demostración. Hangfire crea automáticamente las tablas requeridas durante la primera ejecución.

Configuración del proyecto ASP.NET Core

Comenzaremos creando un nuevo proyecto ASP.NET Core con la plantilla API seleccionada. Ahora cree un controlador de API vacío. Llamémoslo HangfireController. Estoy usando Visual Studio 2019 Community como mi IDE y POSTMAN para probar las API.

Instalación de los paquetes Hangfire

Instalando el único paquete que necesitarías para configurar Hangfire.

Install-Package Hangfire

Configuración de Hangfire

Una vez que haya instalado el paquete, ahora estamos listos para configurarlo para que sea compatible con nuestra aplicación ASP.NET Core API. Este es un paso bastante sencillo, además, una vez que instale el paquete, se le mostrará un Léame rápido que le muestra el paso para completar la configuración.

Navigate to Startup.cs / ConfigureServices so that it looks like the below code snippet.
public void ConfigureServices(IServiceCollection services)
services.AddHangfire(x => x.UseSqlServerStorage("<connection string>"));

Línea #3 Agrega el servicio Hangfire a nuestra aplicación. También hemos mencionado el almacenamiento que se utilizará, el servidor MSSQL, junto con la cadena/nombre de conexión.
La línea n.º 4 en realidad enciende el servidor Hangfire, que es responsable del procesamiento de trabajos.

Una vez hecho esto, vayamos al método Configurar y agregue la siguiente línea.


Lo que hace esta línea es que nos permite acceder al panel de hangfire en nuestra aplicación ASP.NET Core. El tablero estará disponible yendo a /URL de mi tablero. Iniciemos la aplicación.

Esquema de la base de datos Hangfire

Cuando inicia su aplicación ASP.NET Core por el momento, Hangfire verifica si tiene un esquema de Hangfire asociado disponible en su base de datos. Si no, creará un montón de tablas para ti. Así es como se vería su base de datos.

hangfire dbschema Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Panel de Hangfire

Después de cargar la aplicación, vaya a <localhost>/mydashboard. Podrá ver el panel de control de Hangfire.

Hangfire en ASP.NET Core

Desde el tablero podrás monitorear los trabajos y sus estados. También le permite activar manualmente los trabajos disponibles. Esta es la característica ÚNICA que diferencia a Hangfire de otros programadores. Tablero incorporado. ¿Cuan genial es eso? La captura de pantalla anterior es la de la descripción general del panel. Exploremos también las otras pestañas.

Pestaña de trabajos.

Todos los trabajos que están disponibles en el almacén de datos (nuestro servidor MSSQL) se enumerarán aquí. Obtendrá una idea completa del estado de cada trabajo (En cola, Exitoso, Procesando, Fallido, etc.) en esta pantalla.

trabajos hangfire Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Pestaña Reintentos.

Los trabajos tienden a fallar de vez en cuando debido a factores externos. En nuestro caso, nuestra api intenta enviar un correo al usuario, pero hay un problema de conexión interna, lo que hace que el trabajo no se ejecute. Cuando falla un trabajo, Hangfire continúa intentándolo hasta que pasa. (configurable)

hangfire vuelve a intentar Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Pestaña de trabajos recurrentes.

¿Qué sucede si necesita enviar por correo el uso de su factura mensualmente? Esta es la característica principal de Hangfire, trabajos recurrentes. Esta pestaña le permite monitorear todos los trabajos configurados.

hangfire recurrente Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Pestaña Servidores.

Recuerde, al configurar Hangfire en la clase Startup.cs, lo hemos mencionado. services.AddHangfireServer().. Esta es la pestaña donde muestra todos los Hangfire Server activos. Estos servidores son responsables de procesar los trabajos. Digamos que no ha agregado los servicios. AddHangfireServer() en la clase de inicio, aún podría agregar trabajos Hangfire a la base de datos, pero no se ejecutarán hasta que inicie un servidor Hangfire.

servidor hangfire Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Protección del panel Hangfire

Esta es una característica bastante obvia. Dado que el tablero puede exponer datos muy confidenciales como nombres de métodos, valores de parámetros, ID de correo electrónico, es muy importante que protejamos/restringamos este punto final. Hangfire, listo para usar, hace que el tablero sea seguro al permitir solo solicitudes locales. Sin embargo, puede cambiar esto implementando su propia versión de IDashboardAuthorizationFilter . Si ya implementó la Autorización en su API, puede implementarla para Hangfire. Consulte estos pasos para asegurar el tablero.

Tipos de trabajo en Hangfire

Los trabajos en segundo plano en ASP.NET Core (o digamos cualquier tecnología) pueden ser de muchos tipos según los requisitos. Repasemos los tipos de trabajo disponibles con Hangfire con la implementación adecuada y la explicación en nuestro proyecto ASP.NET Core API. Vamos a codificar.

Despedir y olvidar trabajos

Los trabajos de disparar y olvidar se ejecutan  solo una vez  y casi  inmediatamente  después de la creación. Crearemos nuestro primer trabajo de fondo. Abre el controlador Hangfire que habíamos creado. Crearemos un punto final POST que dé la bienvenida a un usuario con un correo electrónico (idealmente). Añade estos códigos.

public IActionResult Welcome(string userName)
var jobId = BackgroundJob.Enqueue(() => SendWelcomeMail(userName));
return Ok($"Job Id {jobId} Completed. Welcome Mail Sent!");

public void SendWelcomeMail(string userName)
//Logic to Mail the user
Console.WriteLine($"Welcome to our application, {userName}");

La línea #5 almacena JobId en una variable. Puede ver que en realidad estamos agregando un trabajo en segundo plano representado por una función ficticia SendWelcomeMail. El JobId se vuelve a publicar más tarde en el Panel de control de Hangfire. Cree la aplicación y ejecútela. Vamos a probarlo con Postman.

hangfire faf postman Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Tenga en cuenta la URL y cómo estoy pasando el nombre de usuario al controlador. Una vez que lo ejecute, obtendrá nuestra respuesta requerida. “Id. de trabajo 2 completado. ¡Correo de bienvenida enviado!”. Ahora veamos el tablero de Hangfire.

hangfire faf dash Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

En la pestaña Correcto, puede ver el recuento de trabajos completados. También puede ver los detalles de cada trabajo, similar a la captura de pantalla anterior. Todos los parámetros y nombres de funciones se exponen aquí. ¿Quiere volver a ejecutar este trabajo con los mismos parámetros? Presiona el botón Volver a poner en cola. Vuelve a agregar su trabajo en la cola para que Hangfire lo procese. Sucede casi de inmediato.

Trabajos retrasados

Ahora, qué pasa si queremos enviar un correo a un usuario, no inmediatamente, sino después de 10 minutos. En tales casos, utilizamos trabajos retrasados. Veamos su implementación, después de lo cual lo explicaré en detalle. En el mismo controlador, agregue estas líneas de código. Es bastante similar a la variante anterior, pero le introducimos un factor de retraso.

public IActionResult DelayedWelcome(string userName)
var jobId = BackgroundJob.Schedule(() => SendDelayedWelcomeMail(userName),TimeSpan.FromMinutes(2));
return Ok($"Job Id {jobId} Completed. Delayed Welcome Mail Sent!");

public void SendDelayedWelcomeMail(string userName)
//Logic to Mail the user
Console.WriteLine($"Welcome to our application, {userName}");

La línea #5 programó el trabajo en un período de tiempo definido, en nuestro caso son 2 minutos. Eso significa que nuestro trabajo se ejecutará 2 minutos después de que Postman haya llamado a la acción. Abramos Postman de nuevo y probemos.

hangfire retrasó al cartero Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Puede ver que recibimos la respuesta esperada de Postman. Ahora. vuelva rápidamente al Panel de control de Hangfire y haga clic en la pestaña Trabajos/programados. Diría que el trabajo se ejecutará en un minuto. Ahí estás para. Ha creado su primer trabajo programado usando Hangfire con facilidad.

hangfire retraso dash Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

trabajos recurrentes

Nuestro Cliente tiene una suscripción a nuestro servicio. Obviamente, tendríamos que enviarle un recordatorio sobre el pago o la factura en sí. Esto llama la necesidad de un trabajo recurrente, donde puedo enviar correos electrónicos a mis clientes mensualmente. Esto es compatible con Hangfire mediante el programa CRON.
¿Qué es CRON? CRON es una utilidad basada en el tiempo que puede definir intervalos de tiempo. Veamos cómo lograr tal requisito.

public IActionResult Invoice(string userName)
RecurringJob.AddOrUpdate(() => SendInvoiceMail(userName), Cron.Monthly);
return Ok($"Recurring Job Scheduled. Invoice will be mailed Monthly for {userName}!");

public void SendInvoiceMail(string userName)
//Logic to Mail the user
Console.WriteLine($"Here is your invoice, {userName}");

La línea #5 establece claramente que estamos tratando de agregar/actualizar un trabajo recurrente, que llama a una función tantas veces como lo define el esquema CRON. Aquí enviaremos la factura al cliente mensualmente el primer día de cada mes. Ejecutemos la aplicación y cambiemos a Postman. Estoy ejecutando este código el 24 de mayo de 2020. Según nuestro requisito, este trabajo debe despedirse el 1 de junio de 2020, que es dentro de 7 días. Vamos a ver.

hangfire cartero recurrente Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Entonces, esto funcionó. Pasemos a Hangfire Dashboard y vayamos a la pestaña Trabajos recurrentes.

hangfire recurrente dash Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

¡Perfecto! Funciona como excepción. Puede pasar por varios esquemas CRON aquí que pueden coincidir con sus requisitos. Aquí hay una pequeña documentación agradable para comprender cómo se usan varias expresiones CRON.


Este es un escenario más complicado. Permítanme tratar de mantenerlo muy simple. Un usuario decide darse de baja de su servicio. Después de que confirme su acción (tal vez haciendo clic en el botón para cancelar la suscripción), nosotros (la aplicación) tenemos que cancelar la suscripción del sistema y enviarle un correo de confirmación después de eso también. Entonces, el primer trabajo es realmente cancelar la suscripción del usuario. El segundo trabajo es enviar un correo confirmando la acción. El segundo trabajo debe ejecutarse solo después de que el primer trabajo se haya completado correctamente. Obtener el escenario?

public IActionResult Unsubscribe(string userName)
var jobId = BackgroundJob.Enqueue(() => UnsubscribeUser(userName));
BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine($"Sent Confirmation Mail to {userName}"));
return Ok($"Unsubscribed");

public void UnsubscribeUser(string userName)
//Logic to Unsubscribe the user
Console.WriteLine($"Unsubscribed {userName}");

Línea #5 El primer trabajo que realmente contiene lógica para eliminar la suscripción del usuario.
Línea #6 Nuestro segundo trabajo que continuará después de que se ejecute el primer trabajo. Esto se hace pasando el Id. de trabajo del trabajo principal a los trabajos secundarios.

Iniciemos la aplicación y vayamos a Postman.

hangfire coont postman Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

hangfire coont dash Hangfire en ASP.NET Core 3.1 - Trabajos en segundo plano simplificados

Ahora, vaya al Tablero y verifique el trabajo exitoso. Verá 2 nuevos trabajos ejecutados en el orden exacto que queríamos. Eso es todo por este tutorial. Espero que tengan claro estos conceptos y les resulte fácil integrar Hangfire en las aplicaciones ASP.NET Core.


En esta guía detallada, hemos repasado los conceptos de trabajos en segundo plano, características e implementación de Hangfire en aplicaciones ASP.NET Core y varios tipos de trabajos en Hangfire. El código fuente utilizado para demostrar este tutorial está publicado en GitHub. Te dejo el enlace a continuación para que lo consultes. ¿Tienes experiencia con Hangfire? ¿Tienes alguna consulta/sugerencia? Siéntase libre de dejar a continuación en la sección de comentarios. ¡Feliz codificación!


#aspdotnet #hangfire 

Django Chartit: A Django App to Plot Charts and Pivot Charts Directly

Django Chartit is a Django app that can be used to easily create charts from the data in your database. The charts are rendered using Highcharts and jQuery JavaScript libraries. Data in your database can be plotted as simple line charts, column charts, area charts, scatter plots, and many more chart types. Data can also be plotted as Pivot Charts where the data is grouped and/or pivoted by specific column(s).



  • Plot charts from models.
  • Plot data from multiple models on the same axis on a chart.
  • Plot pivot charts from models. Data can be pivoted by across multiple columns.
  • Legend pivot charts by multiple columns.
  • Combine data from multiple models to plot on same pivot charts.
  • Plot a pareto chart, paretoed by a specific column.
  • Plot only a top few items per category in a pivot chart.
  • Python 3 compatibility
  • Django 1.8 and 1.9 compatibility
  • Documentation to ReadTheDocs
  • Automated testing via Travis CI
  • Test coverage tracking via Coveralls


You can install Django-Chartit from PyPI. Just do

$ pip install django_chartit

Then, add chartit to INSTALLED_APPS in "".

You also need supporting JavaScript libraries. See the Required JavaScript Libraries section for more details.

How to Use

Plotting a chart or pivot chart on a webpage involves the following steps.

  1. Create a DataPool or PivotDataPool object that specifies what data you need to retrieve and from where.
  2. Create a Chart or PivotChart object to plot the data in the DataPool or PivotDataPool respectively.
  3. Return the Chart/PivotChart object from a django view function to the django template.
  4. Use the load_charts template tag to load the charts to HTML tags with specific ids.

It is easier to explain the steps above with examples. So read on.

How to Create Charts

Here is a short example of how to create a line chart. Let's say we have a simple model with 3 fields - one for month and two for temperatures of Boston and Houston.

class MonthlyWeatherByCity(models.Model):
    month = models.IntegerField()
    boston_temp = models.DecimalField(max_digits=5, decimal_places=1)
    houston_temp = models.DecimalField(max_digits=5, decimal_places=1)

And let's say we want to create a simple line chart of month on the x-axis and the temperatures of the two cities on the y-axis.

from chartit import DataPool, Chart

def weather_chart_view(request):
    #Step 1: Create a DataPool with the data we want to retrieve.
    weatherdata = \
            [{'options': {
               'source': MonthlyWeatherByCity.objects.all()},
              'terms': [

    #Step 2: Create the Chart object
    cht = Chart(
            datasource = weatherdata,
            series_options =
                  'type': 'line',
                  'stacking': False},
                  'month': [
            chart_options =
              {'title': {
                   'text': 'Weather Data of Boston and Houston'},
               'xAxis': {
                    'title': {
                       'text': 'Month number'}}})

    #Step 3: Send the chart object to the template.
    return render_to_response({'weatherchart': cht})

And you can use the load_charts filter in the django template to render the chart.

    <!-- code to include the highcharts and jQuery libraries goes here -->
    <!-- load_charts filter takes a comma-separated list of id's where -->
    <!-- the charts need to be rendered to                             -->
    {% load chartit %}
    {{ weatherchart|load_charts:"container" }}
    <div id='container'> Chart will be rendered here </div>

How to Create Pivot Charts

Here is an example of how to create a pivot chart. Let's say we have the following model.

class DailyWeather(models.Model):
    month = models.IntegerField()
    day = models.IntegerField()
    temperature = models.DecimalField(max_digits=5, decimal_places=1)
    rainfall = models.DecimalField(max_digits=5, decimal_places=1)
    city = models.CharField(max_length=50)
    state = models.CharField(max_length=2)

We want to plot a pivot chart of month (along the x-axis) versus the average rainfall (along the y-axis) of the top 3 cities with highest average rainfall in each month.

from django.db.models import Avg
from chartit import PivotDataPool, PivotChart

def rainfall_pivot_chart_view(request):
    # Step 1: Create a PivotDataPool with the data we want to retrieve.
    rainpivotdata = PivotDataPool(
            'options': {
                'source': DailyWeather.objects.all(),
                'categories': ['month'],
                'legend_by': 'city',
                'top_n_per_cat': 3,
            'terms': {
                'avg_rain': Avg('rainfall'),

    # Step 2: Create the PivotChart object
    rainpivcht = PivotChart(
            'options': {
                'type': 'column',
                'stacking': True
            'terms': ['avg_rain']
            'title': {
                'text': 'Rain by Month in top 3 cities'
            'xAxis': {
                'title': {
                    'text': 'Month'

    # Step 3: Send the PivotChart object to the template.
    return render_to_response({'rainpivchart': rainpivcht})

And you can use the load_charts filter in the django template to render the chart.

    <!-- code to include the highcharts and jQuery libraries goes here -->
    <!-- load_charts filter takes a comma-separated list of id's where -->
    <!-- the charts need to be rendered to                             -->
    {% load chartit %}
    {{ rainpivchart|load_charts:"container" }}
    <div id='container'> Chart will be rendered here </div>

Rendering multiple charts

It is possible to render multiple charts in the same template. The first argument to load_charts is the Chart object or a list of Chart objects, and the second is a comma separated list of HTML IDs where the charts will be rendered.

When calling Django's render you have to pass all you charts as a list:

return render(request, 'index.html',
                'chart_list' : [chart_1, chart_2],

Then in your template you have to use the proper syntax:

    {% load chartit %}
    {{ chart_list|load_charts:"chart_1,chart_2" }}
    <div id="chart_1">First chart will be rendered here</div>
    <div id="chart_2">Second chart will be rendered here</div>


The above examples are just a brief taste of what you can do with Django-Chartit. For more examples and to look at the charts in actions, check out the demoproject/ directory. To execute the demo run the commands

cd demoproject/
PYTHONPATH=../ python ./ migrate
PYTHONPATH=../ python ./ runserver


Full documentation is available here .

Required JavaScript Libraries

The following JavaScript Libraries are required for using Django-Chartit.

  • jQuery - versions 1.6.4 and 1.7 are known to work well with django-chartit.
  • Highcharts - versions 2.1.7 and 2.2.0 are known to work well with django-chartit.


While Django-Chartit itself is licensed under the BSD license, Highcharts is licensed under the Highcharts license and jQuery is licensed under both MIT License and GNU General Public License (GPL) Version 2. It is your own responsibility to abide by respective licenses when downloading and using the supporting JavaScript libraries.

0.1 (November 5, 2011)

  • Initial release of django-chartit

0.2.0 as django-chartit2 (January 20, 2016):

  • Fixed issue that could prevent installation via PyPI

0.2.2 as django-chartit2 (January 28, 2016)

  • Fixed another issue that prevented installation via PyPI

0.2.3 (July 30, 2016)

  • New to_json() method for charts. Useful for creating Highcharts in AJAX
  • Merged with django-chartit2 fork by Grant McConnaughey which adds Python 3 and latest Django 1.8.x and 1.9.x support
  • Allow dictionary fields in conjunction with lambda fields. Closes #26
  • Documentation improvements
  • Lots of code cleanups and style improvements

0.2.4 (August 2, 2016)

  • Fix for get_all_field_names() and get_field_by_name() removal in Django 1.10. Fixes #39
  • Updated for django.db.sql.query.Query.aggregates removal

0.2.5 (August 3, 2016)

  • Workaround Python 3 vs. Python 2 list sort issue which breaks charts with multiple data sources displayed on the same axis!
  • Make demoproject/ compatible with Django 1.10

0.2.6 (August 16, 2016)

  • Merge chartit_tests/ with demoproject/
  • Load test DB with real data to use during testing
  • Add more tests
  • Update the path to demoproject.settings when building docs. Fixes a problem which caused some API docs to be empty
  • Fix ValueError: not enough values to unpack (expected 2, got 0) with PivotChart when the QuerySet returns empty data
  • Dropped requirement on simplejson
  • Properly handle unicode data in Pivot charts. Fixes #5
  • Demo project updated with Chart and PivotChart examples of rendering DateField values on the X axis
  • Allow charting of extra() or annotate() fields. Fixes #8 and #12
  • Refactor RecursiveDefaultDict to allow chart objects to be serialized to/from cache. Fixes #10
  • Add information about supported 3rd party JavaScript versions. Fixes #14

0.2.7 (September 14, 2016)

  • Don't use super(self.__class__) b/c that breaks chart class inheritance. Fixes #41

0.2.8 (December 4, 2016)

  • PivotChart and PivotDataPool will be deprecated soon. Both are marked with deprecation warnings. There is a lot of duplication and special handling between those classes and the Chart and DataPool classes which make it harder to expand the feature set for django-chartit. The next release will focus on consolidating all the functionality into Chart and DataPool so that users will still be able to draw pivot charts. You will have to construct your pivot charts manually though!
  • DataPool terms now supports model properties. Fixes #35. Model properties are not supported for PivotDataPool! WARNING: when using model properties chartit can't make use of ``QuerySet.values()`` internally. This means results will not be groupped by the values of the fields you supplied. This may lead to unexpected query results/charts!
  • DataPool now supports RawQuerySet as data source. Fixes #44. RawQuerySet is not supported for PivotDataPool! WARNING: when using ``RawQuerySet`` don't use double underscores in field names because these are interpreted internally by chartit and will cause exceptions. For example don't do this ``SELECT AVG(rating) as rating__avg`` instead write it as ``SELECT AVG(rating) as rating_avg``!
  • README now tells how to execute demoproject/

0.2.9 (January 17, 2017)

  • Enable pylint during testing but don't block Travis-CI on failures. Closes #42.
  • Handle unicode data in pie and scatter plot charts under Python 2.7. PR#47.


  • Update demo with an example of how to pass legendIndex as an option to a data serie. Closes #48.
  • Update demo with an example of how to change the label of any term instead of using the default one. Closes #46.

Download Details:
Author: chartit
Source Code:
License: View license