<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Omer Farooq Ahmed </title>
    <description>The latest articles on DEV Community by Omer Farooq Ahmed  (@omer95).</description>
    <link>https://dev.to/omer95</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F160695%2F28b8e8d6-c1f3-4957-b94e-0a3922cc9b72.jpeg</url>
      <title>DEV Community: Omer Farooq Ahmed </title>
      <link>https://dev.to/omer95</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omer95"/>
    <language>en</language>
    <item>
      <title>An Introduction to Hive UDFs with Scala</title>
      <dc:creator>Omer Farooq Ahmed </dc:creator>
      <pubDate>Thu, 14 Dec 2023 10:04:25 +0000</pubDate>
      <link>https://dev.to/omer95/an-introduction-to-hive-udfs-with-scala-2cg6</link>
      <guid>https://dev.to/omer95/an-introduction-to-hive-udfs-with-scala-2cg6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;For anyone looking to do big data analytics at scale, Apache Spark is your best bet. Spark's rich Dataframes API allows intuitive transformations on structured data and helps engineers build fast and optimized data pipelines.&lt;/p&gt;

&lt;p&gt;However, developing large data applications involves numerous teams and personas with a diverse set of skills, and not everyone is comfortable writing Spark. SQL seems to be the common denominator in most data teams and this is where Apache Hive shines: Petabyte scale analytics using HiveQL (a flavor of SQL). Most transformations that are expressed using dataframes APIs on Spark can be written in SQL, as for the remaining, more complex queries, there's always User Defined Functions (UDFs).&lt;/p&gt;

&lt;p&gt;User Defined Functions allow end users to write custom business logic that can be applied to each record of a column. UDFs are useful when the equivalent functionality requires multiple complex SQL queries, where a simple Scala UDF can do the same thing in a few lines of code. This article demonstrates how to use the Hive UDF and GenericUDF abstract classes to build user defined functions in Scala (as there are plenty of articles on building Java UDFs).&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple UDF
&lt;/h3&gt;

&lt;p&gt;Hive defines two approaches to writing UDFs: Simple and Generic. Simple UDFs can be built by extending the UDF abstract class and implementing the evaluate() function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;HiveUDFs&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hadoop.hive.ql.exec.UDF&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Increment&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;UDF&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, simply create a JAR using sbt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sbt package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the JAR to Hive classpath, create the temporary function increment, and use it with a Select statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;ADD JAR hdfs:///{path}/{to}/{jar}.jar
&amp;gt;CREATE TEMPORARY FUNCTION increment AS 'HiveUDFs.Increment';
&amp;gt;SELECT increment(1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now obviously the above UDF is an extremely simple example that can easily be written in a simple SQL query. A practical UDF would be something more complex such as a proprietary algorithm (better for maintainability and readability to write the algo in your org's preferred programming language). That being said, Simple UDFs can be bad for performance because every call to the evaluate function performs &lt;a href="https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful"&gt;Reflection&lt;/a&gt; which carries an overhead. Furthermore, while you can overload the evaluate function to accept/return a number of different primitive types, it gets complicated if your Hive table column is an Array, Map or Struct type. Here are the Hive column types and their equivalent Java types for UDFs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hive&lt;/th&gt;
&lt;th&gt;Java&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;java.lang.String, org.apache.hadoop.io.Text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int&lt;/td&gt;
&lt;td&gt;int, java.lang.Integer, org.apache.hadoop.io.IntWritable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;bool, java.lang.Boolean, org.apache.hadoop.io.BooleanWritable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;array&lt;/td&gt;
&lt;td&gt;java.util.List&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;map&lt;/td&gt;
&lt;td&gt;java.util.Map&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;While simple UDFs do support arrays with List/ArrayList in Java, writing a UDF to work with arrays in Scala does not always yield expected results. This is where Generic UDFs are more useful. Generic UDFs are the only approach when dealing with a nested array or struct type in a Hive column, or when you want to work with a dynamic number of columns in a UDF.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generic UDFs
&lt;/h3&gt;

&lt;p&gt;The second way to write a UDF is with the GenericUDF abstract class. Generic UDFs are faster than simple UDFs because there's no reflective call, the arguments are parsed lazily, and Hive passes arguments as generic Object types so there's no need to instantiate and deserialize an Object when it's not needed. Generic UDFs can also deal with complex types such as structs and nested arrays, and can accept a variable number of parameters. The downside is that writing a GenericUDF is a bit more complicated as it defines three functions rather than one, and there is very little documentation to understand the purpose of these functions, especially in Scala. Let's consider writing a Generic UDF that returns the length of an array of integers. The three functions we need to implement are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;initialize:&lt;br&gt;
Since Hive passes all parameters as Object types, in order to interact with the Object (get it's value and type, and write an output) we need to use an ObjectInspector. When Hive analyzes a query with a UDF, it computes the parameter types and passes the appropriate ObjectInspector type for each of the parameters into the initialize function and calls the function (In our case it will be one listInputObjectInspector). We can use this function for type checking and validation of our input. Finally, Hive expects the output to be an ObjectInpector of the return type (in our case this is a javaIntObjectInspector). We also want to store the ObjectInpector from the arguments as a class property because we will need it in the evaluate function to interact with the Deferred Objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;evaluate:&lt;br&gt;
This function contains the core business logic that is applied to every record of the input column(s). The difference is that it accepts an array of Deferred Objects (the input parameters to the UDF) and we need to call the get() function on each DeferredObject to get the Object. We then need to use the stored ObjectInspector to retrieve the value(s) of the actual UDF parameter(s). Finally we can write our algorithm and return the result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;getDisplayString:&lt;br&gt;
Hive calls this method whenever there is an error running the UDF and so it's used to diaply troubleshooting information.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's how we write our ListLength GenericUDF that takes one input parameter of type array and returns an int:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;HiveUDFs&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hadoop.hive.ql.exec.UDFArgumentException&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hadoop.hive.ql.udf.generic.GenericUDF&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.hadoop.hive.serde2.objectinspector.&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;ListObjectInspector&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ObjectInspector&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;scala.collection.JavaConverters._&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListLength&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;GenericUDF&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;listInputObjectInspector&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ListObjectInspector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@throws&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classOf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;UDFArgumentException&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ObjectInspector&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ObjectInspector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;getCategory&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nv"&gt;ObjectInspector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;LIST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;listInputObjectInspector&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;asInstanceOf&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ListObjectInspector&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="nv"&gt;PrimitiveObjectInspectorFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;javaIntObjectInspector&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;GenericUDF.DeferredObject&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;listInputObjectInspector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;getList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;sList&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;asScala&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;toList&lt;/span&gt;
    &lt;span class="nv"&gt;sList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getDisplayString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Getting size of array"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While genericUDFs can be complicated for trivial functions such as this, they can be powerful tools to apply custom logic to the millions of rows of a complex column on Hive, enabling a more diverse group of data users to reuse abstracted business logic on all sorts of structured data. &lt;/p&gt;

</description>
      <category>hive</category>
      <category>spark</category>
      <category>scala</category>
    </item>
    <item>
      <title>Top 30 Microsoft Azure Services</title>
      <dc:creator>Omer Farooq Ahmed </dc:creator>
      <pubDate>Sun, 11 Jul 2021 17:03:29 +0000</pubDate>
      <link>https://dev.to/omer95/top-30-microsoft-azure-services-27lb</link>
      <guid>https://dev.to/omer95/top-30-microsoft-azure-services-27lb</guid>
      <description>&lt;p&gt;Jeff Delaney from &lt;a href="https://www.youtube.com/channel/UCsBjURrPoezykLs9EqgamOA"&gt;Fireship.io&lt;/a&gt; recently made a video describing the 50+ most popular cloud services offered by Amazon Web Services with common use cases. Inspired by that video, here are the top 30 Microsoft Azure cloud services.&lt;/p&gt;

&lt;p&gt;Microsoft Azure started off in 2010 as Windows Azure with just three services. Today, Azure offers over 200 products across compute, storage, databases, networking, artificial intelligence and more, enabling developers to create robust applications without worrying about infrastructure management. Let's explore some of these products and services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compute
&lt;/h2&gt;

&lt;p&gt;Cloud computing is essentially leasing out computational resources that may be too expensive or cumbersome to manage on premises, from a wide distribution network of managed data centers. &lt;a href="https://azure.microsoft.com/en-us/services/virtual-machines/"&gt;Virtual Machines&lt;/a&gt; spin up Windows and Linux virtual operating systems that share physical resources, but are completely self contained environments that users can remotely access to deploy large scale workloads.&lt;/p&gt;

&lt;p&gt;If you don't want to worry about the operating system and want to completely hand over management of the hosting environment to Azure, simply deploy an application on &lt;a href="https://azure.microsoft.com/en-us/services/app-service/"&gt;App Service&lt;/a&gt;. This service allows you to focus on your code; deploy a .NET, Python, Java, Ruby, PHP or NodeJS application in a few clicks and have it running on the cloud in no time (giving a higher level of abstraction, albeit lesser control, than VMs).&lt;/p&gt;

&lt;p&gt;Serverless computing is all the rage these days, and along with AWS and Google, Azure has thrown its hat in the ring with &lt;a href="https://azure.microsoft.com/en-us/services/functions/"&gt;Azure Functions&lt;/a&gt;. While technically not server-less, Functions abstracts away interaction with the actual web app server and lets users deploy a piece of programming logic, wrapped in a function and triggered by an event such as a database entry or a specific time of day. Users only write the core logic rather than an entire application, and their function only runs when invoked by the chosen trigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage
&lt;/h2&gt;

&lt;p&gt;If you're deploying applications to the cloud, you'll need persistent data storage. &lt;a href="https://azure.microsoft.com/en-us/services/storage/blobs/"&gt;Azure Blob Storage&lt;/a&gt; allows scalable storage for objects and files and provides an SDK to easily access them. Blob storage is a great trigger for Azure Functions, where uploading a file can automatically run your custom logic in the cloud (for example, if you wanted to run OCR on a file as soon as it's uploaded to a storage container). However, if you wanted to mount a filesystem as a native share on a virtual machine, use &lt;a href="https://azure.microsoft.com/en-us/services/storage/files/"&gt;Azure Files&lt;/a&gt; instead. &lt;a href="https://azure.microsoft.com/en-us/services/storage/archive/"&gt;Azure Archive Storage&lt;/a&gt; allows businesses to store terabytes of archived data that will rarely be accessed, at the fraction of the cost of regular file storage. This is great for backups, medical history, audit and compliance data, or for migrating decades of magnetic tape storage to the cloud. Finally, use &lt;a href="https://azure.microsoft.com/en-us/services/storage/data-lake-storage/"&gt;Azure Data Lake Storage&lt;/a&gt; to store both structured and unstructured data as-is and run high performance analytics workloads at scale, with support for the most common analytics frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database
&lt;/h2&gt;

&lt;p&gt;Developers need databases to store structured data, like application state and user data. Azure offers a range of managed SQL and NoSQL database solutions. &lt;a href="https://azure.microsoft.com/en-us/services/virtual-machines/sql-server/"&gt;Azure SQL&lt;/a&gt; is a suite of services that offer a cloud based relational database experience for different use cases. &lt;a href="https://azure.microsoft.com/en-us/services/virtual-machines/sql-server/"&gt;SQL Server on Azure Virtual Machines&lt;/a&gt; creates an entire operating system environment running the popular Microsoft Relational Database Management System, allowing seamless migration of on premises SQL workloads to the cloud. &lt;a href="https://azure.microsoft.com/en-us/products/azure-sql/database/"&gt;Azure SQL Database&lt;/a&gt; abstracts away resource management and scalability to let developers focus on building applications. Finally, &lt;a href="https://azure.microsoft.com/en-us/products/azure-sql/edge/"&gt;Azure SQL Edge&lt;/a&gt; is an architecture agnostic, containerized database that runs on IoT and edge devices with native support for streaming and time series data, so developers can perform real-time analytics on a myriad of data captured by sensors.&lt;/p&gt;

&lt;p&gt;Moving away from relational databases, &lt;a href="https://azure.microsoft.com/en-us/services/cosmos-db/"&gt;Azure Cosmos DB&lt;/a&gt; is a schema agnostic, globally distributed NoSQL database. Cosmos  abstracts away its internal data model and provides APIs for interacting with data as if it were a MongoDB or Cassandra database, making it truly multi-model.&lt;/p&gt;

&lt;p&gt;If you're looking for a low latency, in memory database, &lt;a href="https://azure.microsoft.com/en-us/services/cache/"&gt;Azure Cache for Redis&lt;/a&gt; is a blazing fast database for applications that have millions of users generating extremely high traffic, like a social media.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containers
&lt;/h2&gt;

&lt;p&gt;When you develop an application, you want to be able to run it in any environment. Containers offer the ability to ship the app within an image of its environment configurations, allowing faster and more flexible deployment than on VMs. &lt;a href="https://azure.microsoft.com/en-us/services/container-instances/"&gt;Container Instances&lt;/a&gt; provides running instances of a virtualized operating system running your application and managing environment variables, configuration and networking itself. The aforementioned configurations, networking, operating system and other features of the container are described in a blueprint called an image, and these images are usually stored on online repositories, like Docker Hub. &lt;a href="https://azure.microsoft.com/en-us/services/container-registry/"&gt;Container Registry&lt;/a&gt; is Azure’s private repository for Docker and Open Container Initiative images. Managing containers can be tricky, especially if you’ve deployed a number of microservices, each running as a stand alone container. Kubernetes is an open source container orchestration tool that manages container scaling, state management, health and deployment. &lt;a href="https://azure.microsoft.com/en-us/services/kubernetes-service/"&gt;Azure Kubernetes Service&lt;/a&gt; is a fully managed, serverless Kubernetes experience on the cloud that leverages Azure’s enterprise grade security and governance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Artificial Intelligence
&lt;/h2&gt;

&lt;p&gt;Developing AI applications is challenging. Training sophisticated machine learning models requires incredibly large, mostly labelled datasets that are difficult to acquire, and high performance computing that uses powerful and expensive graphics processing units. Researchers at Azure have developed ML models for common AI use cases using public and proprietary datasets and exposed APIs for developers to transform their applications and processes with AI, without training models from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/"&gt;Azure Cognitive Services&lt;/a&gt; is a family of AI services across vision, speech, language and decision support. &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/computer-vision/"&gt;Computer Vision&lt;/a&gt; labels everyday objects and links them to 10,000 ontology concepts, reads signs and text using optical character recognition and analyzes spatial movement in images and videos. If your image analysis tasks are specific to an industry or domain, such as medical image analysis or using vision in optimizing manufacturing, use &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/custom-vision-service/"&gt;Custom Vision&lt;/a&gt;. This service provides a user-friendly interface to upload your own images, label them and train custom models with high performance computing in the cloud. Finally, &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/face/"&gt;Face API&lt;/a&gt; provides facial verification based on two images, facial recognition of your own organization’s employees by integrating your own private repository and detection of various features on faces, such as emotions, expressions, facial hair and even masks.&lt;/p&gt;

&lt;p&gt;Cognitive services also offer a range of products for natural language processing. &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/language-understanding-intelligent-service/"&gt;Language Understanding&lt;/a&gt; or LUIS can extract key user goals and intentions, as well as entities, from natural language input. This can be combined with &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/qna-maker/"&gt;QnA Maker&lt;/a&gt;, a conversational agent that can answer questions based on FAQs and similar knowledge bases, to build simple chatbots. &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/translator/"&gt;Translator&lt;/a&gt; uses neural machine translation to translate text and documents (with ability to preserve original document format) in 90 supported languages. &lt;a href="https://azure.microsoft.com/en-us/services/cognitive-services/text-analytics/#features"&gt;Text Analytics&lt;/a&gt; can extract sentiments, key phrases, entities, entity links and input language from unstructured text. This also includes the &lt;a href="https://techcommunity.microsoft.com/t5/azure-ai/introducing-text-analytics-for-health/ba-p/1505152"&gt;Text Analytics for Health&lt;/a&gt; preview, which is a medical domain specific Named Entity Recognition service that can recognize biomedical entities, link them to medical ontology concepts such as UMLS, extract entity relations such as the dosage of a medication entity and recognize negation relating to an entity.&lt;/p&gt;

&lt;p&gt;Besides building informational chatbots using QnA Maker, Azure also provides a larger &lt;a href="https://azure.microsoft.com/en-us/services/bot-services/"&gt;Bot Service&lt;/a&gt; for developing more sophisticated chatbots. Transactional chatbots perform operations such as accessing and modifying internal IT documents and databases and dynamic and context aware chatbots can be used as virtual assistants. &lt;a href="https://dev.botframework.com/"&gt;Bot Framework&lt;/a&gt; is an SDK that lets developers create these kinds of chatbots using their programming language of choice. &lt;a href="https://docs.microsoft.com/en-us/composer/introduction?tabs=v2x"&gt;Bot Framework Composer&lt;/a&gt; improves this experience by providing a visual tool to build conversational flows using pre-built templates and a number of triggers and actions that you can drag and drop onto a visual canvas.&lt;/p&gt;

&lt;p&gt;In the big data space, Azure offers &lt;a href="https://azure.microsoft.com/en-us/services/databricks/"&gt;Azure Databricks&lt;/a&gt;. This is an Apache Spark big data analytics and machine learning service over a Distributed File System. The distributed cluster of nodes running analytics and AI operations in parallel allow for fast processing of large volumes of data and integration with popular machine learning libraries such as PyTorch unleash endless possibilities for custom ML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dev Tools, Management, Security and Networking
&lt;/h2&gt;

&lt;p&gt;Here are a few services that make the overall Azure experience so amazing. Every Azure resource automatically generates metrics and logs. &lt;a href="https://azure.microsoft.com/en-us/services/monitor/"&gt;Azure Monitor&lt;/a&gt; collects, analyzes and acts on this data to ensure availability, maximize performance and proactively detect problems. &lt;a href="https://azure.microsoft.com/en-us/services/active-directory/"&gt;Azure Active Directory&lt;/a&gt; is Azure’s cloud Identity Access Management system. Azure AD provides single sign on for your apps and governs access by ensuring the right people have access to the right resources. Developing applications involves calls to numerous APIs and therefore secret and key management can get cumbersome. &lt;a href="https://azure.microsoft.com/en-us/services/key-vault/"&gt;Key Vault&lt;/a&gt; simplifies this process by providing a single location to store all secrets and an SDK to easily access them, ensuring data protection and compliance. The advantage of deploying applications on the cloud as opposed to on premises, is the ability to autoscale on demand and have your data always available. &lt;a href="https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview"&gt;Azure Load Balancer&lt;/a&gt; evenly distributes incoming network traffic to multiple instances of your application, while &lt;a href="https://azure.microsoft.com/en-gb/services/cdn/"&gt;Content Delivery Network&lt;/a&gt; caches your resources in multiple geographies intelligently, to reduce load times and save bandwidth.&lt;/p&gt;

&lt;p&gt;Last but not least, you can create, deploy and manage all your Azure resources using &lt;a href="https://azure.microsoft.com/en-gb/features/cloud-shell/"&gt;Azure Cloud Shell&lt;/a&gt;. Cloud Shell provides a secure Bash or PowerShell session to administer Azure resources using Azure command line tools and even provides support for common programming languages and persistent storage with an attached storage account.&lt;/p&gt;

&lt;p&gt;With a host of user friendly, secure and highly available services, the Azure cloud is a great place to focus on your application and leave the rest to Microsoft.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>azure</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Docker Container on Azure Functions with Python</title>
      <dc:creator>Omer Farooq Ahmed </dc:creator>
      <pubDate>Tue, 13 Oct 2020 00:37:22 +0000</pubDate>
      <link>https://dev.to/omer95/docker-container-on-azure-functions-with-python-1lgd</link>
      <guid>https://dev.to/omer95/docker-container-on-azure-functions-with-python-1lgd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Serverless Computing, also known as Serverless Architecture, Functions as a Service (FaaS) or just Serverless, is all the rage these days. For any developer looking to quickly deploy their code to the cloud without having to worry about managing server resources or getting charged insane amounts for running a hello world application, services like AWS Lambda, Google Cloud Functions or Azure Functions is the solution. With a host of event triggers, and rich CLI tooling to create boilerplate code and deploy straight to the cloud, all three cloud powerhouses provide a great service to use. However, serverless can be a double edged sword. While providing convenience, it also restricts setting up custom environments on the machine the functions are running on. This is where Docker shines. Cloud Functions like Azure Functions provide the ability to run custom containers from a repository like Docker Hub. In this tutorial, I will show how to create a custom container with an Azure Function that performs optical character recognition (OCR) in python, and deploy it to the Azure Functions app in the cloud. At the end of the tutorial, we will be able to send an HTTP GET request with an image attached to trigger the Azure Function to perform OCR on the image and return the extracted text.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A Microsoft Azure Account. Get a free account with 1,000,000 free requests per month for Azure Functions: &lt;a href="https://azure.microsoft.com/en-gb/free/" rel="noopener noreferrer"&gt;https://azure.microsoft.com/en-gb/free/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure Functions core tools. Installation steps here: &lt;a href="https://github.com/Azure/azure-functions-core-tools" rel="noopener noreferrer"&gt;https://github.com/Azure/azure-functions-core-tools&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure CLI. Installation steps here: &lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-apt" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-apt&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker. Get Docker here: &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;https://docs.docker.com/get-docker/&lt;/a&gt;&lt;br&gt;
If you're new to Docker, check out this excellent introduction from my favorite dev, Jeff Delaney:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/gAkwW2tuIqE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An account on Docker Hub: &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;https://hub.docker.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python 3.*&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tesseract OCR: Install both the python module and core libraries:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install tesseract-ocr
pip install pytesseract
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pillow for image processing:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pillow
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating an Azure Function
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Run the following command to create a local function app project called &lt;code&gt;OcrFunctionsProject&lt;/code&gt;. The &lt;code&gt;--docker&lt;/code&gt; option will generate a &lt;code&gt;Dockerfile&lt;/code&gt; that we can edit to install custom libraries and dependencies in the Azure Functions app where the container will be deployed:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func init OcrFunctionsProject --worker-runtime python --docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigate into the &lt;code&gt;OcrFunctionsProject&lt;/code&gt; folder and edit the &lt;code&gt;Dockerfile&lt;/code&gt; to look like this:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mcr.microsoft.com/azure-functions/python:3.0-python3.7&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; AzureWebJobsScriptRoot=/home/site/wwwroot \&lt;/span&gt;
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt /&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /requirements.txt
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;tesseract-ocr
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /home/site/wwwroot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
This will allow us to install Tesseract OCR in the base Debian machine where the Azure Functions will be hosted. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a function to the project using the following command. The &lt;code&gt;--name&lt;/code&gt; option specifies a unique name for the function and &lt;code&gt;--template&lt;/code&gt; specifies the trigger. In our case we want our function to run in response to an HTTP trigger.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func new --name HttpOcrFunc --template "HTTP trigger"
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;pytesseract&lt;/code&gt; and &lt;code&gt;pillow&lt;/code&gt; as a new line to the &lt;code&gt;requirements.txt&lt;/code&gt; file so that modules are automatically installed once our container is deployed on the Azure Functions app in the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test the new function locally by running the following command in the project root folder:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
Navigate to the &lt;code&gt;HttpOcrFunc&lt;/code&gt; endpoint URL in the terminal output and if there is a response with 'This HTTP triggered function executed successfully...', then we're good to go.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit the &lt;code&gt;OcrFunctionsProject/HttpOcrFunc/__init__.py&lt;/code&gt; file and add the following code:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytesseract&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;azure.functions&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Python HTTP trigger function processed a request.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# test code for OCR
&lt;/span&gt;    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/tmp/1.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pytesseract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/tmp/1.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text Extracted from Image: {}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
Since the instance on which our Function will be deployed has a read only filesystem, we will persist our data to the /tmp/ directory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Build and push Docker container
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Build the docker image for the container described by our &lt;code&gt;Dockerfile&lt;/code&gt; Remember to replace &lt;code&gt;&amp;lt;YOUR_DOCKER_HUBB_ID&amp;gt;&lt;/code&gt; with your own Docker ID:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build --tag &amp;lt;YOUR_DOCKER_HUBB_ID&amp;gt;/ocrfunctionsimage:v1.0.0 .
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test the build by running the following command:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 8080:80 -it &amp;lt;YOUR_DOCKER_HUB_ID&amp;gt;/ocrfunctionsimage:v1.0.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
Navigate to &lt;code&gt;http://localhost:8080&lt;/code&gt; and you should see a placeholder image that says: Your Functions 3.0 app is up and running. We can't test the function running in this container because we need an access key that hasn't been generated yet as we haven't associated this local project to an Azure Functions app in the cloud.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Push this image to Docker Hub by logging in:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
and pushing:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push &amp;lt;YOUR_DOCKER_HUB_ID&amp;gt;/ocrfunctionsimage:v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create Azure Functions App
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to Azure portal: &lt;a href="https://portal.azure.com/" rel="noopener noreferrer"&gt;https://portal.azure.com/&lt;/a&gt; and create a new Resource Group by clicking on Create a resource and searching for Resource group. Give it a unique name, select your preferred location and click Review + Create. A resource group is a container of related resources for a specific Azure cloud solution. In our case, we will group an Azure Functions app and a Storage account in our resource group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the portal home, click Create a resource and search for and select Function App. In the Basics tab, select your Subscription, the resource group you just created, a unique Function App name and then for the publish field select Docker Container and finally region. Select Next: Hosting. In the Hosting tab, for storage, select a new storage account, then select a plan and select Review + Create. Finally, select create and then on the new page, select Go to resource.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F1.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F2.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the Function App page, go to Container settings on the sidebar, select Docker Hub in image source and enter YOUR_DOCKER_HUB_ID/ocrfunctionsimage:v1.0.0 in the Full Image Name and Tag field and then click save.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F3.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Functions on the sidebar, select the HttpOcrFunc function and click on Get Function URL.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F4.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download Postman &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;https://www.postman.com/&lt;/a&gt; and create a new GET request. Paste the Function URL in the GET request endpoint field and in the body tab, select form-data, then add a key called file, change the type from Text to File, and in the value field upload any image with text in it. Click submit!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F5.PNG" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you followed all steps in this tutorial, you should get the extracted text as a response on Postman.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logs!
&lt;/h2&gt;

&lt;p&gt;Logs are an important part of serverless functions as they can help troubleshoot any errors in the code that might prevent getting the expected output. While you can view the logs on the Azure Functions app portal by clicking on Functions in the sidebar, then clicking the relevant function and then clicking Monitoring in the sidebar, these logs are often very slow to appear after the initial request is made.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fomer-public.s3.eu-west-2.amazonaws.com%2F6.PNG" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A better way to view logs is to test your function locally. This can be done as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, navigate to &lt;code&gt;OcrFunctionsProject/HttpOcrFunc/function.json&lt;/code&gt; and change the value of the &lt;code&gt;authLevel&lt;/code&gt; key in httpTrigger bindings to "anonymous".&lt;/li&gt;
&lt;li&gt;Build the image using &lt;code&gt;docker build&lt;/code&gt; as described in a previous step.&lt;/li&gt;
&lt;li&gt;Run the container image using &lt;code&gt;docker run&lt;/code&gt; as described in a previous step.&lt;/li&gt;
&lt;li&gt;Use Postman to send a request to &lt;a href="http://localhost:8080/api/HttpOcrFunc" rel="noopener noreferrer"&gt;http://localhost:8080/api/HttpOcrFunc&lt;/a&gt; with an image file attached as form-data as described in a previous step and you can get immediate results from the local container as well as logs directly in your terminal. It's a good idea to test the function locally, and once you're done, change authLevel back to "function", rebuild the image, push to docker hub and save the new image on Azure Functions app portal container settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We now have a fully functioning Python OCR Docker container deployed to an Azure Function. We can trigger the function using an HTTP GET request to its public endpoint URL and attach an image file that will be parsed by tesseract OCR in the cloud function to extract text and return it in a response. We can create more functions and play around with triggers, for example initiating the function in response to an entry in a relational database.  &lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings?tabs=csharp" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings?tabs=csharp&lt;/a&gt;&lt;br&gt;
We can also persist an output file to blob storage using the Azure Blob Storage Python SDK. &lt;a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python&lt;/a&gt;&lt;br&gt;
The sky is the limit and once the infrastructure is set up, you can easily edit the function python code, build the container, test is locally, push to Docker hub and then deploy it to Azure Functions. Hope this tutorial was useful for anyone looking to spin up a custom container on Azure Functions.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>python</category>
      <category>docker</category>
      <category>serverless</category>
    </item>
  </channel>
</rss>
