1671541050
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.
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
Trying 192.168.2.62...
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
1657107416
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.
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 –
#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.
1561523460
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:
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
Matplotlib is a Python 2D plotting library which produces publication-quality figures in a variety of hardcopy formats and interactive environments across platforms.
>>> import numpy as np
>>> x = np.linspace(0, 10, 100)
>>> y = np.cos(x)
>>> z = np.sin(x)
>>> 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'))
>>> 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)
>>> plt.savefig('foo.png') #Save figures
>>> plt.savefig('foo.png', transparent=True) #Save transparent figures
>>> plt.show()
>>> 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
>>> fig, ax = plt.subplots()
>>> im = ax.imshow(img, #Colormapped or RGB arrays
cmap= 'gist_earth',
interpolation= 'nearest',
vmin=-2,
vmax=2)
>>> 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
>>> 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
>>> ax1.hist(y) #Plot a histogram
>>> ax3.boxplot(y) #Make a box and whisker plot
>>> ax3.violinplot(z) #Make a violin plot
y-axis
x-axis
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],
[5,15,25],
color= 'darkgreen',
marker= '^' )
>>> ax.set_xlim(1, 6.5)
>>> plt.savefig('foo.png' ) #Step 5
>>> plt.show() #Step 6
>>> plt.cla() #Clear an axis
>>> plt.clf(). #Clear the entire figure
>>> plt.close(). #Close a window
>>> 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)
>>> ax.text(1,
-2.1,
'Example Graph',
style= 'italic' )
>>> ax.annotate("Sine",
xy=(8, 0),
xycoords= 'data',
xytext=(10.5, 0),
textcoords= 'data',
arrowprops=dict(arrowstyle= "->",
connectionstyle="arc3"),)
>>> plt.title(r '$sigma_i=15$', fontsize=20)
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
Legends
>>> 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
Ticks
>>> 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',
length=10)
Subplot Spacing
>>> fig3.subplots_adjust(wspace=0.5, #Adjust the spacing between subplots
hspace=0.3,
left=0.125,
right=0.9,
top=0.9,
bottom=0.1)
>>> 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 https://www.datacamp.com
#matplotlib #cheatsheet #python
1653464648
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.
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! :)
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:
>>> from bokeh.plotting import figure
>>> from bokeh.io 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
x_axis_label='x',
y_axis_label='y')
>>> p.line(x, y, legend="Temp.", line_width=2) #Step 3
>>> output_file("lines.html") #Step 4
>>> show(p) #Step 5
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)
>>> 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()
Scatter Markers
>>> p1.circle(np.array([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
>>> pl.line([1,2,3,4], [3,4,5,6], line_width=2)
>>> p2.multi_line(pd.DataFrame([[1,2,3],[5,6,7]]),
pd.DataFrame([[3,4,5],[3,2,1]]),
color="blue")
Selection and Non-Selection Glyphs
>>> p = figure(tools='box_select')
>>> p. circle ('mpg', 'cyl', source=cds_df,
selection_color='red',
nonselection_alpha=0.1)
Hover Glyphs
>>> from bokeh.models import HoverTool
>>>hover= HoverTool(tooltips=None, mode='vline')
>>> p3.add_tools(hover)
Color Mapping
>>> from bokeh.models import CategoricalColorMapper
>>> color_mapper = CategoricalColorMapper(
factors= ['US', 'Asia', 'Europe'],
palette= ['blue', 'red', 'green'])
>>> p3. circle ('mpg', 'cyl', source=cds_df,
color=dict(field='origin',
transform=color_mapper), legend='Origin')
>>> from bokeh.io 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 bokeh.io import output_file, show
>>> output_file('my_bar_chart.html', mode='cdn')
Components
>>> from bokeh.embed import components
>>> script, div= components(p)
>>> from bokeh.io import export_png
>>> export_png(p, filename="plot.png")
>>> from bokeh.io import export_svgs
>>> p. output_backend = "svg"
>>> export_svgs(p,filename="plot.svg")
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')
>>> p.legend. border_line_color = "navy"
>>> p.legend.background_fill_color = "white"
>>> p.legend.orientation = "horizontal"
>>> p.legend.orientation = "vertical"
Rows
>>> from bokeh.layouts import row
>>>layout= row(p1,p2,p3)
Columns
>>> from bokeh.layouts import columns
>>>layout= column(p1,p2,p3)
Nesting Rows & Columns
>>>layout= row(column(p1,p2), p3)
>>> from bokeh.layouts import gridplot
>>> rowl = [p1,p2]
>>> row2 = [p3]
>>> layout = gridplot([[p1, p2],[p3]])
>>> 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 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')
>>> p4.circle('mpg', 'cyl' , source=cds_df)
>>> p5 = figure(plot_width = 200, tools='box_select,lasso_select')
>>> p5.circle('mpg', 'hp', source=cds df)
>>>layout= row(p4,p5)
>>> show(p1)
>>> show(layout)
>>> save(p1)
Have this Cheat Sheet at your fingertips
Original article source at https://www.datacamp.com
#python #datavisualization #bokeh #cheatsheet
1659727800
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.
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.
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.
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.
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.
Instalando el único paquete que necesitarías para configurar Hangfire.
Install-Package 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>"));
services.AddHangfireServer();
services.AddControllers();
}
Explicación.
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.
app.UseHangfireDashboard("/mydashboard");
Explicación.
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.
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.
Después de cargar la aplicación, vaya a <localhost>/mydashboard. Podrá ver el panel de control de Hangfire.
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.
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.
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)
¿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.
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.
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.
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.
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.
[HttpPost]
[Route("welcome")]
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}");
}
Explicación.
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.
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.
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.
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.
[HttpPost]
[Route("delayedWelcome")]
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}");
}
Explicación.
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.
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.
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.
[HttpPost]
[Route("invoice")]
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.
Entonces, esto funcionó. Pasemos a Hangfire Dashboard y vayamos a la pestaña Trabajos recurrentes.
¡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?
[HttpPost]
[Route("unsubscribe")]
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}");
}
Explicación.
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.
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!
Fuente: https://codewithmukesh.com/blog/hangfire-in-aspnet-core-3-1/
1645619585
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).
You can install Django-Chartit from PyPI. Just do
$ pip install django_chartit
Then, add chartit to INSTALLED_APPS in "settings.py".
You also need supporting JavaScript libraries. See the Required JavaScript Libraries section for more details.
Plotting a chart or pivot chart on a webpage involves the following steps.
DataPool
or PivotDataPool
object that specifies what data you need to retrieve and from where.Chart
or PivotChart
object to plot the data in the DataPool
or PivotDataPool
respectively.Chart
/PivotChart
object from a django view
function to the django template.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.
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 = \
DataPool(
series=
[{'options': {
'source': MonthlyWeatherByCity.objects.all()},
'terms': [
'month',
'houston_temp',
'boston_temp']}
])
#Step 2: Create the Chart object
cht = Chart(
datasource = weatherdata,
series_options =
[{'options':{
'type': 'line',
'stacking': False},
'terms':{
'month': [
'boston_temp',
'houston_temp']
}}],
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.
<head>
<!-- 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" }}
</head>
<body>
<div id='container'> Chart will be rendered here </div>
</body>
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(
series=[{
'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(
datasource=rainpivotdata,
series_options=[{
'options': {
'type': 'column',
'stacking': True
},
'terms': ['avg_rain']
}],
chart_options={
'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.
<head>
<!-- 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" }}
</head>
<body>
<div id='container'> Chart will be rendered here </div>
</body>
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:
<head>
{% load chartit %}
{{ chart_list|load_charts:"chart_1,chart_2" }}
</head>
<body>
<div id="chart_1">First chart will be rendered here</div>
<div id="chart_2">Second chart will be rendered here</div>
</body>
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 ./manage.py migrate
PYTHONPATH=../ python ./manage.py runserver
Full documentation is available here .
The following JavaScript Libraries are required for using Django-Chartit.
Note
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)
0.2.0 as django-chartit2 (January 20, 2016):
0.2.2 as django-chartit2 (January 28, 2016)
0.2.3 (July 30, 2016)
0.2.4 (August 2, 2016)
get_all_field_names()
and get_field_by_name()
removal in Django 1.10. Fixes #390.2.5 (August 3, 2016)
0.2.6 (August 16, 2016)
chartit_tests/
with demoproject/
simplejson
extra()
or annotate()
fields. Fixes #8 and #12RecursiveDefaultDict
to allow chart objects to be serialized to/from cache. Fixes #100.2.7 (September 14, 2016)
super(self.__class__)
b/c that breaks chart class inheritance. Fixes #410.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``!demoproject/
0.2.9 (January 17, 2017)
master
legendIndex
as an option to a data serie. Closes #48.Download Details:
Author: chartit
Source Code: https://github.com/chartit/django-chartit
License: View license