YouTube2Text

End-to-End Spark Streaming Project | Databricks + Kafka + PostgreSQL + Real-Time Dashboard — Transcript

by DataBeli · 41,939 words · 5,864 segments · language en · Watch on YouTube

Full transcript

  1. 0:00Hi, I'm Narendra Kumar. I a senior data
  2. 0:03architect with 12 years of experience in
  3. 0:05IT. I'm a certified datab brick solution
  4. 0:08architect champion as well. And in this
  5. 0:11video, we are going to build an end
  6. 0:13toend streaming data project. We will
  7. 0:16mainly build it in databicks free
  8. 0:18edition. And to bring in streaming data,
  9. 0:21we will set up our own Confluent Kafka
  10. 0:24account for free. We will send realtime
  11. 0:27data to our topic. Then process that
  12. 0:29data in real time and generate uh
  13. 0:32immediate email alerts based on the
  14. 0:34detected fraud. And apart from this
  15. 0:36Kafka streaming source, we will also set
  16. 0:39up a file streaming source of our own.
  17. 0:42And then we will use a third source as
  18. 0:44Postgress SQL that will be a static
  19. 0:47source so that we can understand how can
  20. 0:49we join streams, how can we join static
  21. 0:52data with streaming data. So all those
  22. 0:55scenarios we will cover and we will also
  23. 0:58build an dashboard that also will
  24. 1:00refresh in near real time and apart from
  25. 1:04covering all these things hands-on. We
  26. 1:06will also cover the theoretical part
  27. 1:08also so that our basic is strong. We
  28. 1:11will understand all the streaming
  29. 1:12concepts the Kafka architecture the
  30. 1:15stateful and stateless streaming
  31. 1:18processing how we can handle late
  32. 1:20arriving data using watermarks. how to
  33. 1:22use tumbling and sliding windows and
  34. 1:25then do aggregations on the streaming
  35. 1:27data. So all these concepts we will
  36. 1:30clear and whatever data code and other
  37. 1:33files that I will be using for this
  38. 1:35project those I will I have uploaded
  39. 1:37them on GitHub so that you can also do a
  40. 1:40hands-on on your own and be confident
  41. 1:42with it. I also provide a link to this
  42. 1:45presentation as well. And to help you
  43. 1:47further, I have prepared this PDF
  44. 1:49document with all the project details
  45. 1:52including the details that you can
  46. 1:53directly put it in your resume. You can
  47. 1:56use this document as a revision document
  48. 1:58before going to any of the interview. I
  49. 2:01have created four other projects as well
  50. 2:03related to batch data processing, AI and
  51. 2:06data modeling. I have also created an
  52. 2:08interview series and there are many more
  53. 2:11videos related to data engineering. So
  54. 2:13feel free to check them out and if you
  55. 2:15want to stay tuned for more such videos
  56. 2:18you shall hit the subscribe button and
  57. 2:20if you are already a subscriber then
  58. 2:22let's get started.
  59. 2:24Let's start by understanding what
  60. 2:26exactly is streaming and how it is
  61. 2:28different from batch processing. So
  62. 2:31streaming it is the continuous injection
  63. 2:33processing and anal analysis of realtime
  64. 2:36events which enables low latency
  65. 2:40analytics and immediate decision making.
  66. 2:43What it means is that uh in streaming we
  67. 2:45continuously ingest new data. We process
  68. 2:48it and analyze it in real time so that
  69. 2:51we can make any decision with minimum
  70. 2:53latency in subseconds or seconds. And
  71. 2:57how it is different from batch
  72. 2:58processing is that in batch processing
  73. 3:01we collect data over time. We keep
  74. 3:04collecting the data maybe for 1 hour or
  75. 3:06sometimes even for a day. Then we
  76. 3:09schedule the jobs on daily or hourly
  77. 3:11basis which process all the data which
  78. 3:14is accumulated over that period of time
  79. 3:16and then we write it to a storage or we
  80. 3:19do whatever we want to do. Whereas in
  81. 3:21streaming uh we don't store the data
  82. 3:24over period of time. we move it as and
  83. 3:28when it is being generated from the data
  84. 3:30source till our analytic system. So even
  85. 3:34a single event which is being generated
  86. 3:36we keep pushing it. We don't wait for
  87. 3:39any more events to be gathered so that
  88. 3:42the latency is minimum. So the data it
  89. 3:45is coming continuously without any delay
  90. 3:48and then we process it in real time as
  91. 3:51and when it is coming which provide
  92. 3:53instant results and insights. So if we
  93. 3:56visualize it in terms of timeline. So
  94. 3:58let's say if the data is being generated
  95. 4:01here each dot represents a data point.
  96. 4:04So in batch processing we collect the
  97. 4:06data over uh some period of time then we
  98. 4:09process that batch wherein in streaming
  99. 4:13we process each and every event as and
  100. 4:15when it is coming. And the examples of
  101. 4:18batch processing are like daily sales
  102. 4:20reports, monthly billing, payroll
  103. 4:22processing or historical data analysis.
  104. 4:24These kind of examples come under batch
  105. 4:27processing where in stream processing it
  106. 4:29comes like a realtime fraud detection or
  107. 4:32live dashboard or if you want to monitor
  108. 4:35IoT sensors in real time. If users are
  109. 4:38clicking on website we want to monitor
  110. 4:41that in real time or stock price
  111. 4:43monitoring in like uh real time. So all
  112. 4:47these examples are of stream processing.
  113. 4:50So batch processing it is based for uh
  114. 4:54huge volume of data where latency is
  115. 4:56acceptable where in stream processing it
  116. 4:59is for low latency and wherever we need
  117. 5:01any immediate decision
  118. 5:03and in our demo we will be using datab
  119. 5:06bricks which supports both batch and
  120. 5:08stream processing.
  121. 5:11So now as we understand both types of
  122. 5:13processing next let's understand a use
  123. 5:15case we will pick up that use case and
  124. 5:18then using that use case we will build
  125. 5:20it step by step and along the way we
  126. 5:23will understand each and every concept
  127. 5:25of streaming as well as batch
  128. 5:27processing.
  129. 5:29So the background for this fine guard
  130. 5:31use case fine guard is like a financial
  131. 5:34guard. So the background for this
  132. 5:36company is that it processes millions of
  133. 5:39credit card transactions daily which
  134. 5:41comes from ATMs, point of sales
  135. 5:43terminals and other online payment
  136. 5:46gateways. And this bank it receives
  137. 5:48continuous fraud intelligence from
  138. 5:51internal fraud teams also and external
  139. 5:53security partners also. they get some uh
  140. 5:56like data in in some form like JSON or
  141. 6:00other files which tells like which cards
  142. 6:03are marked for fraud and all and then
  143. 6:07like the problem is that the delayed
  144. 6:09fraud detection this can result in
  145. 6:11significant financial loss and poor
  146. 6:13customer experience. So the problem they
  147. 6:16are facing is that whenever they get
  148. 6:19continuous transactions and fraud
  149. 6:20related data they are not able to act
  150. 6:23immediately and they are not able to
  151. 6:25detect the frauds immediately in current
  152. 6:27scenario. So this is the background.
  153. 6:30Now the core problem is that the
  154. 6:34fraudulent transactions those must be
  155. 6:36identified within seconds. So that is
  156. 6:39why it has to be some processing in real
  157. 6:42time. And then fraud indicators they
  158. 6:44arrive from multiple sources like live
  159. 6:47transactions, some watch lists are
  160. 6:49there, some customer master data is
  161. 6:52there which all these come from
  162. 6:53different sources. So currently there is
  163. 6:55no way to combine all the all that data
  164. 6:58and the traditional batch processing
  165. 7:00this cannot react quickly enough to
  166. 7:03prevent fraudulent activities. So if we
  167. 7:05do a batch processing here hourly or
  168. 7:08daily basis it is not sufficient because
  169. 7:10frauds has to be detected immediately
  170. 7:12and then decision or the action has to
  171. 7:15be taken immediately.
  172. 7:17Then the solution approach is this. So
  173. 7:20we are going to ingest realtime credit
  174. 7:23card transactions from Kafka. So they
  175. 7:26get the transactions in Kafka and that
  176. 7:30that we are going to ingest using
  177. 7:31managed streaming pipelines. Then we are
  178. 7:35going to also continuously process fraud
  179. 7:37watch list updates that we got get as a
  180. 7:40JSON files. This is also streaming data.
  181. 7:43We will enrich it with transactions and
  182. 7:45also with the customer and merchant
  183. 7:47reference data and after that we will
  184. 7:50apply streaming joins window-based
  185. 7:53analytics and we will detect frauds in
  186. 7:55real time to generate realtime alerts
  187. 7:58and operational dashboards. So this is
  188. 8:00the solution we are going to build in
  189. 8:02this video end to end. So as we
  190. 8:05understand the overall use case now
  191. 8:08let's understand the architecture step
  192. 8:10by step how exactly we are going to
  193. 8:12build this. So we will start by setting
  194. 8:16up a confluent Kafka source of our own.
  195. 8:18We will set up the source. We will send
  196. 8:21some credit card transactions to it and
  197. 8:24then we will receive those transactions
  198. 8:26on our side. So we will consume those
  199. 8:29transactions from Kafka using spark
  200. 8:32streaming. Uh using this we will ingest
  201. 8:35that streaming data and then we will
  202. 8:38process that data. For processing we
  203. 8:40will use lakeflow spark declarative
  204. 8:43pipelines. Previously these were also
  205. 8:45called as delta live tables. Now they
  206. 8:48call it call call this as lakeflow spark
  207. 8:50declarative pipelines. So using this we
  208. 8:53will process uh the real time data and
  209. 8:56along with the the streaming data from
  210. 8:59Kafka which come as events we will also
  211. 9:02ingest some streaming files. So these
  212. 9:05will be in JSON form. These will be the
  213. 9:08watch list data that comes which tells
  214. 9:11like uh which of the cards has been
  215. 9:13marked as fraud and there shall be no
  216. 9:16transactions coming from Kafka for
  217. 9:18those. So that those streaming files
  218. 9:20also we will generate on our own
  219. 9:22continuously. Then we will ingest them
  220. 9:25in real time using autoloader.
  221. 9:28And after ingestion like we will process
  222. 9:31them also using same uh declarative
  223. 9:34pipelines. And along with these two
  224. 9:37streaming sources we will also ingest
  225. 9:40the data from Postgress SQL which will
  226. 9:42be the customer master data and then
  227. 9:45this data we will ingest from lakeflow
  228. 9:48connect. So this will be a batch
  229. 9:50injection because this customer related
  230. 9:53information it is kind of static. It
  231. 9:55doesn't get updated like in seconds. So
  232. 9:58this data also we will bring in here.
  233. 10:01After that when we process the data
  234. 10:03using these lakeflow spark declarative
  235. 10:06pipelines that time we will build the
  236. 10:08standard bronze silver and gold
  237. 10:11architecture for realtime data
  238. 10:13processing. We will see what we do at
  239. 10:15each and every stage as per the industry
  240. 10:18standards.
  241. 10:19And when we build these layers, we will
  242. 10:21be building all these in the delta lake.
  243. 10:23We will be building the streaming tables
  244. 10:25as delta tables.
  245. 10:28And along the way, the processing that
  246. 10:30we will do that will include stream
  247. 10:33stream join that will be joining this
  248. 10:35Kafka stream with the streaming files.
  249. 10:38It will also include stream static join
  250. 10:41that will be joining this information
  251. 10:43with the batch data that we are
  252. 10:45ingesting. And we will also detect the
  253. 10:48frauds in real time. And once we have
  254. 10:52processed all that then on the
  255. 10:55consumption side whenever we will detect
  256. 10:57a fraud in real time we will send
  257. 10:59realtime alerts as emails. So we will
  258. 11:02see that immediately how custom emails
  259. 11:04will be sent and then we will also build
  260. 11:07the dashboard which will refresh every
  261. 11:10every minute and it will provide the
  262. 11:12updated uh data up to date data for each
  263. 11:15and every minute
  264. 11:18and once we have built everything which
  265. 11:20is running fine end to end then we will
  266. 11:23orchestrate it end to end using lakeflow
  267. 11:26jobs and we will run it end to end in
  268. 11:29real time for an hour or so. so that we
  269. 11:32will see the streaming data flowing
  270. 11:34throughout the system and for governance
  271. 11:37of course we will use unity catalog
  272. 11:39which is ready to be used within datab
  273. 11:42bricks.
  274. 11:43So now as we understand the overall
  275. 11:46architecture and what exactly we are
  276. 11:48going to build. So let's start building
  277. 11:50this. We will start by building our
  278. 11:52actual Kafka source. But before we go
  279. 11:55ahead and build it, uh first let's
  280. 11:58understand the key terminologies in
  281. 12:00Kafka and how does it exactly work so
  282. 12:03that when we create it, you are able to
  283. 12:05relate all the terms and all the items
  284. 12:07which are there. So this is the standard
  285. 12:10Kafka architecture and this architecture
  286. 12:12it is followed by most of the streaming
  287. 12:15services as a standard. So on on the
  288. 12:19left side we always start with
  289. 12:21producers. So producers are like the
  290. 12:24data generators wherever the actual data
  291. 12:26is being generated in real time. It can
  292. 12:29be a web application, mobile
  293. 12:31application, any micros service even
  294. 12:33from databases and then there can be
  295. 12:36many more. So producers they publish the
  296. 12:39messages and where do they publish the
  297. 12:42messages is with to the Kafka cluster.
  298. 12:46So we set up a Kafka cluster where all
  299. 12:49the messages coming from the producers
  300. 12:52are stored and within the cluster we
  301. 12:56have something called as brokers. So
  302. 12:58brokers they are the actual Kafka server
  303. 13:01that stores the data. So these are like
  304. 13:04the actual nodes where the the the
  305. 13:07streaming data is stored and uh it is
  306. 13:10like uh managed and how it is managed is
  307. 13:14in terms of topics. So topic it is like
  308. 13:17a logical channel for messages. So if
  309. 13:21you have worked on any database so topic
  310. 13:23you can relate it to kind of a table. So
  311. 13:27on a database we create a table and then
  312. 13:29we put some data into it and then read
  313. 13:32the data from it. Similarly in terms of
  314. 13:35streaming data we have a topic. So we
  315. 13:38have a topic and in that topic we send
  316. 13:41some data to that particular topic and
  317. 13:44then read the data from that topic. So
  318. 13:46the name of the topic is very important
  319. 13:49and in one cluster there can be multiple
  320. 13:52topics like we have multiple tables in
  321. 13:54databases. So that is why this logical
  322. 13:58understanding of topic is very
  323. 14:00important. We can correlate it as a
  324. 14:01table but there is no actual table here
  325. 14:04because these are all messages. But
  326. 14:06topic is the logical channel where we
  327. 14:09send and receive the messages. And
  328. 14:12because these streaming systems they can
  329. 14:15also be a very high uh they can also
  330. 14:19receive very high volume of data. So
  331. 14:22they also have to support parallel
  332. 14:24processing and they have to support
  333. 14:26massive volume of data which can be uh
  334. 14:29like there shall be incoming and
  335. 14:31outgoing of messages in real time. So
  336. 14:35for that what they do is to support the
  337. 14:38parallelism within a topic there is they
  338. 14:41create multiple partitions. So within
  339. 14:44one topic we can have multiple
  340. 14:46partitions which we configure while
  341. 14:49creating the topic which that we will
  342. 14:51see when we do that. So within one topic
  343. 14:54we have multiple partitions. So whenever
  344. 14:57a publish producer is sending message to
  345. 15:00a topic it can go to any of the
  346. 15:03partition. So if there are like multiple
  347. 15:06producers data coming in or even if it
  348. 15:09is coming from one the data will be
  349. 15:11distributed across different partitions
  350. 15:14so that it can be written in parallel
  351. 15:16and it can be read in parallel. So to
  352. 15:19consume the data from these topic uh
  353. 15:22there is something called as consumers.
  354. 15:25So consumers are the entities which
  355. 15:28consume the data or which read the data
  356. 15:31from these topics.
  357. 15:34And the consumer these can again be any
  358. 15:37analytic system. It can go to any
  359. 15:39databases, machine learning or
  360. 15:40dashboard. So there it can go for any
  361. 15:43consumption. But the actual consumer
  362. 15:46technical consumer it can be any program
  363. 15:48programmatic consumer as well which can
  364. 15:51read the streaming data and then put the
  365. 15:53data into any of these actual consumers
  366. 15:56and
  367. 15:58the the entities like the that read the
  368. 16:02data there can be multiple consumers as
  369. 16:06well. So each of the consumer those can
  370. 16:09be individual consumer as well or if we
  371. 16:12want to read the data also in parallel.
  372. 16:15So we can create something called as
  373. 16:17consumer group. So within a group if we
  374. 16:20have multiple consumers then those
  375. 16:23consumers will read the data parallelly
  376. 16:26from different partitions and then they
  377. 16:29can store their output into a single
  378. 16:31system. So if multiple consumers they
  379. 16:34belong to same consumer group then they
  380. 16:38will read a subset of the incoming data
  381. 16:40and then write it into the output. If
  382. 16:43any consumer is not part of any consumer
  383. 16:45group or uh they are part of different
  384. 16:48consumer groups then they read like the
  385. 16:51data parallelly but they read their own
  386. 16:54copy of the data and the numbers that we
  387. 16:57see here within a partition these are
  388. 17:00called as offset. So whenever let's say
  389. 17:04a first message will come from the
  390. 17:06producer it will go to let's say the
  391. 17:08partition zero it will go into zero
  392. 17:10position the next message can go to the
  393. 17:14zero position in partition one zero
  394. 17:16sorry partition one the next message can
  395. 17:19go here and the next message after that
  396. 17:21it will go to this first position first
  397. 17:24position first position like that so
  398. 17:27that is how the data is distributed
  399. 17:29across these partitions ideally it is
  400. 17:32distributed evenly like I explained but
  401. 17:34practically there can be couple of
  402. 17:36offsets into one partition then to other
  403. 17:39so practically things are little bit
  404. 17:41different but overall things are in
  405. 17:43parallel so whenever a consumer read the
  406. 17:46data from these partitions they read
  407. 17:49based on these offsets so first it will
  408. 17:52let's say read the offset zero then
  409. 17:54offset one offset two offset three like
  410. 17:56that and internally it keep track also
  411. 18:00up to which offset that it has read the
  412. 18:03data so that next time when it is
  413. 18:05reading the data again continuously then
  414. 18:08it knows up to which point it has
  415. 18:10already read the data and from that
  416. 18:12point onwards it will start. So this
  417. 18:15offset is also very important uh concept
  418. 18:19to know so that we know how exactly it
  419. 18:22tracks how much data it has read and
  420. 18:24from where it is getting started.
  421. 18:27So these are all the core concepts of
  422. 18:30the Kafka architecture. I hope these are
  423. 18:32clear. Just to summarize, producers they
  424. 18:36produce the data then they publish their
  425. 18:38messages into a topic. A topic is the
  426. 18:41logical entity like a table in a
  427. 18:43database. And within a topic the data is
  428. 18:47parallely stored as partitions and
  429. 18:49within partition the data is stored
  430. 18:51position wise one event per position.
  431. 18:54That position is called as offset and
  432. 18:57the actual storage of data within the
  433. 18:59Kafka cluster is stored into brokers
  434. 19:02which uh which are like the nodes or the
  435. 19:05server systems where we connect and read
  436. 19:07the data and then to read the data out
  437. 19:12whatever is reading the data those
  438. 19:14entities are called as consumer.
  439. 19:16Consumer can be individual or there can
  440. 19:18be group of consumers as well which can
  441. 19:21read the subset of the data and then the
  442. 19:24data can be sent into any output system
  443. 19:27or whatever we want to do.
  444. 19:30So now as we understand each and
  445. 19:32everything now we will go ahead and set
  446. 19:34up the actual Kafka and where we will
  447. 19:37set up is in the confluent. So Confluent
  448. 19:40it is the name of the company which was
  449. 19:43founded by the same people who built
  450. 19:46Apache Kafka when they were in LinkedIn.
  451. 19:48So in 2014 there were some people in
  452. 19:50LinkedIn who actually built Apache Kafka
  453. 19:53opensourced it those those same people
  454. 19:56they founded this company Conflint and
  455. 19:59that is why whenever it comes to
  456. 20:01streaming this Confluent Kafka is the
  457. 20:04most famous and reliable one. So this is
  458. 20:07the one we are going to use.
  459. 20:10So to start setting up Confluent Kafka
  460. 20:13what we will do is we will simply search
  461. 20:16for the term Confluent
  462. 20:18and the first page that will come will
  463. 20:20be the official Confluent website. So we
  464. 20:23will click this try Confluent for free
  465. 20:27and once we do that this is our sign up
  466. 20:29page. So we can enter our email ids and
  467. 20:32all or we can sign in with Google. I
  468. 20:35will use this option because I have a
  469. 20:37Google account.
  470. 20:40Uh then you can select any of the Google
  471. 20:43account that you have which you want to
  472. 20:45use for the sign up part.
  473. 20:49Now it is asking for some permissions
  474. 20:51which I will allow.
  475. 20:54Now it is asking for some more
  476. 20:56information. So company name we can
  477. 20:58provide anything. We don't want the
  478. 21:00emails. So I will simply click on submit
  479. 21:03here.
  480. 21:07So after submit this is the page we are
  481. 21:09getting. I will simply skip this piece.
  482. 21:12Uh this is kind of the survey. So you
  483. 21:15can select anything that you want.
  484. 21:18So we are exploring it.
  485. 21:26So these options these are for kind of
  486. 21:28survey purpose. It doesn't matter here.
  487. 21:31This says like create your first
  488. 21:33cluster. So
  489. 21:35uh this cluster name it's not that
  490. 21:37important. We can leave it or if you
  491. 21:40want to customize it you can do it here.
  492. 21:43This region we can change to the nearest
  493. 21:45region that is that is there. For me as
  494. 21:48I'm in India I will select Delhi but
  495. 21:51feel free to choose anything that is
  496. 21:52near to you.
  497. 21:55After that it is asking for credit card
  498. 21:58number but instead of that below we see
  499. 22:01a option like do you have a promo code
  500. 22:04we will I have a promo code that works
  501. 22:07without any credit card details. So we
  502. 22:09will click here and you can also use
  503. 22:11this same code. I will put this code in
  504. 22:14the description of the video.
  505. 22:17So this is the promo code which is there
  506. 22:20and I'm going to paste it and then click
  507. 22:23on save.
  508. 22:26So it has been successfully added
  509. 22:29and now it says like cluster is already
  510. 22:32created.
  511. 22:34Now it is saying like do you want to use
  512. 22:35sample data or we want to use our own
  513. 22:39data. So we will use our own data here.
  514. 22:44And now we are getting these options. So
  515. 22:47this one I don't exactly remember. Uh
  516. 22:49let's try this one if it works. So okay
  517. 22:54we don't want to build any client here.
  518. 22:57So what we will do is we see here like
  519. 22:59we have home environment this was our
  520. 23:02cluster. So I will click on this
  521. 23:04cluster. Now we are on our cluster page.
  522. 23:07And if by any chance you are you forget
  523. 23:10this option or you are not able to
  524. 23:12figure out you just click on this home
  525. 23:14icon here this confluent icon and then
  526. 23:17also we shall be able to find our
  527. 23:19cluster here. So here we can go to
  528. 23:22environments
  529. 23:24and here we can see that we have this
  530. 23:26default environment with one cluster.
  531. 23:29Here we can see that we have one
  532. 23:31cluster.
  533. 23:33Uh this is our cluster
  534. 23:37and if I click this cluster it will take
  535. 23:39us to that very same page.
  536. 23:43So now as our cluster is ready next
  537. 23:46thing we are going to do is we are going
  538. 23:48to create a topic in our clusters. So we
  539. 23:51will click on this topics then click on
  540. 23:54create topic. Here we need to give a
  541. 23:57name to the topic and the name that we
  542. 24:00are going to give to our topic is credit
  543. 24:03card transactions because this is the
  544. 24:05data that we will be publishing and then
  545. 24:08consuming from here and then this is the
  546. 24:11number of partitions like the parallel
  547. 24:13parallelism that we were talking about.
  548. 24:16So this one we will leave default but it
  549. 24:18means that it is going to have six
  550. 24:20partitions and this option it says like
  551. 24:23in enable infinite retention for this
  552. 24:26topic. So this is like by default it is
  553. 24:30disabled. So the data it will be stored
  554. 24:33for some default period of time but if
  555. 24:36you want to store it infinitely then we
  556. 24:38can enable it so that the data it is
  557. 24:40never deleted once it is published here.
  558. 24:44But uh that is not uh advised for
  559. 24:48production scenarios. And if we go to
  560. 24:51advanced we can even configure what
  561. 24:53shall be our retention time. By default
  562. 24:55we can see it is 1 week. So uh like that
  563. 24:59like the these are some advanced
  564. 25:00configurations that we can make but we
  565. 25:03don't need to change anything here. This
  566. 25:05was just for the knowledge purpose. So
  567. 25:07we just need to put our name to the
  568. 25:09topic. Rest everything we will leave as
  569. 25:12default and then we will click on save
  570. 25:14and create.
  571. 25:16So now our topic it is successfully
  572. 25:19created. That's it. We don't need to do
  573. 25:22anything else. This contract and all we
  574. 25:24don't need to add it. We will skip it.
  575. 25:27So now our topic it is ready to be send
  576. 25:30data to this topic and then rece or
  577. 25:32receive the data from this topic. For
  578. 25:36that what we need to do is we need to
  579. 25:39first send some data to this topic and
  580. 25:42to send and receive the data we need
  581. 25:44connection details obviously right. So
  582. 25:47connection details where we can find is
  583. 25:49if we go back to this cluster part then
  584. 25:53we will need to generate API keys as
  585. 25:56well. Uh before API keys we also need
  586. 25:58this bootstrap server. So this is the
  587. 26:02link to the server so that it can come
  588. 26:04come and connect to our cluster
  589. 26:08and this link I'm going to copy here and
  590. 26:11then paste it to a notepad so that later
  591. 26:14on we will use it and we will also need
  592. 26:17the API keys. So I will click on API key
  593. 26:20and then click on create key.
  594. 26:24Uh here we will click on next
  595. 26:28and then this is our key and secret. So
  596. 26:30both of these we will need. So this is
  597. 26:33our key I have copied. So key is this
  598. 26:38and then secret or password whatever we
  599. 26:41call it is this. So I have pasted here
  600. 26:45and then we it says like download and
  601. 26:48continue because uh later on these may
  602. 26:50not be visible. So it is important to
  603. 26:52take a note of these so that we can use
  604. 26:55these later on. So it it has been
  605. 26:57downloaded here as well. So that's it.
  606. 27:01Our keys are ready and these keys like
  607. 27:03even I'm not going to hide it but I'm
  608. 27:06going to delete my cluster before I
  609. 27:08publish the video. So don't spend time
  610. 27:10copying mine. So you shall go ahead and
  611. 27:13create your own cluster and try out on
  612. 27:15your own environment.
  613. 27:18So now as we have the all the connection
  614. 27:20details next we are going to put some
  615. 27:23data to this topic. So for that we I
  616. 27:27have created a producer. So let's check
  617. 27:29it out. So for that I have created a
  618. 27:33Python Kafka producer. So this is the
  619. 27:35folder that I will include in the
  620. 27:37GitHub. So you will see the folder in
  621. 27:40the in the link that I will provide. So
  622. 27:44this entire thing we will need to run it
  623. 27:46from VS code. So you need to install
  624. 27:49like VS studio like sorry Visual Studio
  625. 27:52Code which is free. So after
  626. 27:55installation we need to simply open it
  627. 27:58and then we need to go to file open
  628. 28:01folder and we need to open that folder
  629. 28:04TFA producer. So we need to select this
  630. 28:08particular folder Kafka producer and
  631. 28:10click on select folder then it will open
  632. 28:14this folder. So I have already opened it
  633. 28:16that is why it is showing like this. And
  634. 28:19in this folder what we need to do is let
  635. 28:22me close all these files first.
  636. 28:25Uh there is this environment file. So if
  637. 28:28we go over here we will see that there
  638. 28:30are options for bootstrap server API key
  639. 28:34secret and the topic name. So these
  640. 28:36details we need to provide which we had
  641. 28:39copied from there. So this is our
  642. 28:41bootstrap server. So I'm going to paste
  643. 28:44it here. Then this is our API key. So I
  644. 28:48will provide the key here. Uh let me
  645. 28:51paste it. And this is the secret that we
  646. 28:54had brought in. So I will put the secret
  647. 28:57here. And topic name I have already
  648. 28:59provided. In case if you are using any
  649. 29:01other topic then you can provide that
  650. 29:04topic. And these other things you can
  651. 29:06leave as is. These are some
  652. 29:08configuration I made for this code. So
  653. 29:10that we can control how many uh
  654. 29:13transactions it is generating how much
  655. 29:15fraud and total customers and all are
  656. 29:17there. These things you can leave as is.
  657. 29:20So after putting these details I will
  658. 29:23put press control S. So these are saved.
  659. 29:27Now we will need to run it. But to run
  660. 29:30this environment uh we need to set up a
  661. 29:33like virtual environment and then
  662. 29:36install these libraries as well.
  663. 29:39And all these steps we don't need to do
  664. 29:41manually here. So in VS code we can
  665. 29:44directly do all these things. So we need
  666. 29:47to click this show run commands. Then
  667. 29:50this option will come Python create
  668. 29:53environment. we will uh click create and
  669. 29:57then it says like quick create. So
  670. 30:01we will select this option and to use
  671. 30:03this option like any of the Python shall
  672. 30:06be installed in your laptop. So if
  673. 30:08Python is not there that you need to
  674. 30:10install first and then come here and do
  675. 30:12this. So now it is setting up this
  676. 30:15virtual environment. So and now it is
  677. 30:18installing the packages as well. So
  678. 30:21whenever it is setting up that
  679. 30:22environment, so this folder is created
  680. 30:24and this is where it will do all this
  681. 30:27all the stuff it want to do. So now let
  682. 30:30me pause it until this environment is
  683. 30:32set up. So now the environment is uh set
  684. 30:36up the pop-ups are gone now. So now the
  685. 30:40we will be able to produce some data. So
  686. 30:43for that I have created these three
  687. 30:45files producer normal which will produce
  688. 30:48normal transaction data without any
  689. 30:51fraud. It will simply send it and then
  690. 30:54it will send some fraud transaction data
  691. 30:58and then this is another like fraud card
  692. 31:01related data. So these things we will
  693. 31:03see for now we need to just test if we
  694. 31:06we are able to send our data to the
  695. 31:08topic or not. For that we will use this
  696. 31:11producer normal. py. So we can there are
  697. 31:15two ways to run it. We can open the file
  698. 31:18and simply click on this run python file
  699. 31:21option. So it will automatically run the
  700. 31:23file for us.
  701. 31:25Uh looks like it didn't start. Let me
  702. 31:28try one more time.
  703. 31:36So now it is trying to make that
  704. 31:38connection and we can see it is saying
  705. 31:40the data has been produced. So each and
  706. 31:42every line here it is sending some data.
  707. 31:45So now I will putt controll C so that I
  708. 31:49cancel it because uh some data it has
  709. 31:52sent this data we will be able to use it
  710. 31:55and later on we will come back send some
  711. 31:57more data so that we will see in real
  712. 31:59time how we are we are able to read it
  713. 32:03but if these statements are coming
  714. 32:05properly it means that the data has been
  715. 32:07produced and it has been sent to the
  716. 32:10topic that we had created there and how
  717. 32:13it was able to send it was based based
  718. 32:15on this environment details. So on this
  719. 32:18server using these credentials it sent
  720. 32:21the data to this particular topic. So
  721. 32:24now our data is published. It is ready
  722. 32:27to be consumed
  723. 32:29and we are going to consume the data
  724. 32:31using spark streaming. So let's check it
  725. 32:34out. So we are going to use uh spark
  726. 32:38streaming in datab bricks and datab
  727. 32:40bricks it comes with a free edition. So
  728. 32:43if you don't have a account in the free
  729. 32:44edition simply search for datab bricks
  730. 32:47free edition and then you will be able
  731. 32:49to uh sign up using any of your email
  732. 32:52account for free and then login. It is a
  733. 32:55very simple step you can do it. Once you
  734. 32:58have done it then we need to go to
  735. 33:01login.databicks.com
  736. 33:04and then we need to login using our
  737. 33:06account. So this is my account which I
  738. 33:08have already logged in. So it will take
  739. 33:10me to the same one.
  740. 33:13So now this is our homepage
  741. 33:16and here we need to go to workspace.
  742. 33:20So in workspace we will create some
  743. 33:21notebook and everything we will whatever
  744. 33:24we will create it will go to workspace.
  745. 33:26So for that we need to create a folder
  746. 33:29first for our project. So we will name
  747. 33:32it as fine guard
  748. 33:35uh project.
  749. 33:40So now our folder is created and we will
  750. 33:44click this favorite also because we are
  751. 33:47going to work on it for maybe couple of
  752. 33:49days. So then once we click this
  753. 33:51favorites it will whenever you will go
  754. 33:54to workspace then if you click favorites
  755. 33:57it will be there. So directly you will
  756. 33:59be able to open it. Now we are going to
  757. 34:02create a notebook here.
  758. 34:07So this is the blank notebook created
  759. 34:09for us. And this notebook we are going
  760. 34:12to name it as 01 because it is our first
  761. 34:15notebook. Then Kafka streaming test
  762. 34:21because first we are going to test it
  763. 34:23properly. Then we will use it properly
  764. 34:25in the spark declarative pipeline.
  765. 34:29So to consume the data from that topic,
  766. 34:32first thing we need is the connection
  767. 34:33details. So for that we need the
  768. 34:37bootstrap
  769. 34:39uh servers.
  770. 34:42So bootstrap servers it is going to be
  771. 34:45the same URL which we had copied here.
  772. 34:50So this is our URL.
  773. 34:52Then we have API key which is our key
  774. 35:02and then we have API secret.
  775. 35:07So this is our secret
  776. 35:16and then finally we have topic. So our
  777. 35:20topic it was the credit card
  778. 35:22transactions.
  779. 35:29So these are all the connection details
  780. 35:31that we have. So now using these
  781. 35:34connection details we are going to read
  782. 35:36some sample data. So we will call it
  783. 35:39sample batch.
  784. 35:42So first what we are going to do is we
  785. 35:44will not read the streaming data
  786. 35:45directly but we will read the uh batch
  787. 35:49data first from that streaming source so
  788. 35:52that first we understand the normal
  789. 35:54batch reading and then we will
  790. 35:56understand what option is changing when
  791. 35:58we convert it to streaming. So for that
  792. 36:01we will do spark dot read dot format.
  793. 36:05format is going to be Kafka because we
  794. 36:08are going to read from Kafka here
  795. 36:13and then we are going to provide some
  796. 36:15options. So what we will do is we will
  797. 36:18put it in a bracket so that we can use
  798. 36:21multiple lines here. So this bracket we
  799. 36:23will close here. After that we need to
  800. 36:26provide dot option and within the option
  801. 36:29there will be a key and there will be a
  802. 36:31value. So like this we are going to
  803. 36:34provide multiple options that are
  804. 36:36required to make this connection. So let
  805. 36:39me copy paste it multiple times so that
  806. 36:41every time I don't have to type
  807. 36:44and looks like it was trying to run it.
  808. 36:46So for now ignore the error.
  809. 36:50So or I can clear the output as well so
  810. 36:52that it is not confusing.
  811. 36:55So format is Kafka. After that the next
  812. 36:58option we are going to provide here it
  813. 37:00will be Kafka dot bootstrap
  814. 37:06dot servers. So the value part as you
  815. 37:10may have guessed already it is going to
  816. 37:12be this particular value. So let me run
  817. 37:14this cell so that these values are
  818. 37:16stored and available. So this this
  819. 37:19option it is ready. Now the next option
  820. 37:22we are going to provide is subscribe.
  821. 37:26And subscribe it is like we we subscribe
  822. 37:29to a topic so that whatever is published
  823. 37:32to that topic it will be subscribed and
  824. 37:35it will be received to us. That is how
  825. 37:37it works. So here will be the name of
  826. 37:39our topic which is stored here.
  827. 37:43So now we have the server details we
  828. 37:46have the topic name. Next is pending is
  829. 37:50the uh authentication details. how we
  830. 37:53provide the key secrets and all these.
  831. 37:56So this part is bith tricky not exactly
  832. 37:59tricky there is a very standard way of
  833. 38:02providing the API keys and secrets here.
  834. 38:05So those options I'm going to directly
  835. 38:07paste here because remembering them it
  836. 38:10is not possible at least for me. So
  837. 38:13these are the options we need to provide
  838. 38:16and just to remove these red lines let
  839. 38:19me just clear it out. So that later on
  840. 38:23we will use this dot load also.
  841. 38:27So uh let's understand these options. So
  842. 38:30this this is all about like providing
  843. 38:33the authentication detail. So here we
  844. 38:36are saying like which security protocol
  845. 38:39we are going to use. So there are
  846. 38:41different uh authentication protocols.
  847. 38:44So this one is like a simple
  848. 38:45authentication
  849. 38:47uh security layer. So this is the one we
  850. 38:50are going to use. Similarly for you to
  851. 38:53use this particular protocol the next
  852. 38:56set of options we are providing is like
  853. 38:58which mechanism we are using. So here we
  854. 39:01are using plane that means the
  855. 39:03connection details we will provide it as
  856. 39:05plain text and then we also need to
  857. 39:09provide something called as J uh JAS
  858. 39:12configs and the full form of JAS is Java
  859. 39:16authentication and authorization
  860. 39:18service. So this is a very specific like
  861. 39:21uh authentication mechanism which is
  862. 39:24used by Kafka. So we don't need to like
  863. 39:27understand each and every point here or
  864. 39:30we we can simply put these options and
  865. 39:32say that these are required to make the
  866. 39:35connection or this is how we make the
  867. 39:36connection but I wanted to explain it in
  868. 39:39detail. So I explained if you are new
  869. 39:42you can just assume that these three
  870. 39:43lines are for authentication and then
  871. 39:46there is another thing that to provide
  872. 39:48these uh JAS config this also has to be
  873. 39:52provided in a standard way. So how do we
  874. 39:55provide this is uh like this. So this is
  875. 39:59a very standard mechanism that we need
  876. 40:01to type this exact thing and then we
  877. 40:04provide the username as API key this API
  878. 40:07key and this is our API secret. There
  879. 40:11seem to be some typo. Let me correct it.
  880. 40:13So yes this is the secret. So this is
  881. 40:16how we provide the API key and secret in
  882. 40:19a very standard way and nobody can
  883. 40:21remember this. So we just need to paste
  884. 40:24this and change our API key and secret
  885. 40:27here. Let me run this so that this is
  886. 40:29also available.
  887. 40:31Uh okay, I didn't run it again after
  888. 40:33correction. So let me run again. So now
  889. 40:37this is ready. So now our connection it
  890. 40:40is ready and we can read the sample data
  891. 40:43now. But before we read it, there is one
  892. 40:46more option we need to provide. So by
  893. 40:48default what will happen is if we run
  894. 40:50this now, so from this point onwards it
  895. 40:54will start reading the data from Kafka.
  896. 40:56But we want to read all the data that is
  897. 40:59currently available. So we need to play
  898. 41:01around the offset. So for that we need
  899. 41:04to provide another option here. And that
  900. 41:07option is uh simple like starting
  901. 41:10offsets
  902. 41:15and the value for these option is like
  903. 41:17earliest.
  904. 41:20So earliest means like start from very
  905. 41:22beginning of the data that is available
  906. 41:24in this particular topic. And its
  907. 41:26default value is latest. So that
  908. 41:29whenever this is starting after that
  909. 41:31whatever data is available that data it
  910. 41:33will pick up. But as we are reading it
  911. 41:35as a batch so we shall provide this
  912. 41:38option or we shall provide the exact
  913. 41:41offsets from where we want to begin
  914. 41:43reading the data. So now all our options
  915. 41:46are ready. So let's go ahead and read
  916. 41:49our first Kaf data from Kafka. So now
  917. 41:52our data frame is created. But this
  918. 41:55doesn't mean like connection is
  919. 41:56successful because this is a spark
  920. 41:58follows d a follows lazy evaluation. So
  921. 42:02when we actually read the data that time
  922. 42:04we will see. So first let's see how many
  923. 42:07records
  924. 42:08which records that are available here.
  925. 42:11So we will do a simple count sample
  926. 42:14batch dot count. It will give us the
  927. 42:16count of records which are available.
  928. 42:19So here we can see that 61 records are
  929. 42:23available into our Kafka topic which
  930. 42:26were produced by our producer. So here
  931. 42:29it has published 61 records when we ran
  932. 42:32it. So those records are available. So
  933. 42:35now let's see what exact data is
  934. 42:38available. So if we go there and then we
  935. 42:41need to what we need to do is we need to
  936. 42:44display this data frame to see which
  937. 42:46data is available. So we are going to
  938. 42:49display this data frame now. So this
  939. 42:52this is the data which is coming here.
  940. 42:55We can see that this is the key which we
  941. 42:57had provided in our producer. It was the
  942. 43:00transaction ID but here it is available
  943. 43:03as binary. If I hover over here, it will
  944. 43:06say that the type of this column is
  945. 43:08binary. Later on we will cast it to
  946. 43:11string to see the actual value.
  947. 43:13Similarly, the value is also available
  948. 43:16as binary here. So, this value contains
  949. 43:20our actual data. Let me minimize this
  950. 43:22left section from here. And apart from
  951. 43:26this actual data, so all the data which
  952. 43:29is coming from which is being put up or
  953. 43:31coming from Kafka is always sent and
  954. 43:34received as key value pair. These two
  955. 43:36are very standard columns. So we provide
  956. 43:39a key and in the value part we provide
  957. 43:41the actual data. In the key part we
  958. 43:44provide a unique key for each and every
  959. 43:46data point
  960. 43:48and then we get some standard uh
  961. 43:51standard options also standard
  962. 43:53additional columns also which come by
  963. 43:56default whenever we read data from
  964. 43:58Kafka. So those columns are topic which
  965. 44:01is the name of our topic then partition.
  966. 44:04So if you remember we had six
  967. 44:06partitions. So the partition number it
  968. 44:09will be from 0 to 5 because it follows
  969. 44:11the zero standard and then this is the
  970. 44:14offset. Offset what it means is like the
  971. 44:17position of the of this particular data
  972. 44:21point within that partition. So let's
  973. 44:23say from second partition it was read
  974. 44:26from the 0 1 2 all these positions.
  975. 44:29Similarly from first partition it was
  976. 44:32read from these positions. So that is
  977. 44:34how these offsets and partitions they
  978. 44:37provide exactly from where the data was
  979. 44:39being read. And this is the timestamp
  980. 44:42column and the timestamp type. It is
  981. 44:44like whether the time stamp column is
  982. 44:46available or not. This is the actual
  983. 44:48timestamp column which is the event
  984. 44:51timestamp. So these are the additional
  985. 44:53columns that we are getting. So now to
  986. 44:56actually use this data we need to
  987. 44:59obviously cast these two into uh
  988. 45:02strings.
  989. 45:04So now to cast this data we will create
  990. 45:06another data frame. We can name it as uh
  991. 45:10casted or let's say pared
  992. 45:13batch.
  993. 45:15It is going to be like our sample batch
  994. 45:19dot
  995. 45:20and then we are going to put a select
  996. 45:22statement and within select we will
  997. 45:25provide multiple select options here. So
  998. 45:28first we will read the column key
  999. 45:31column. So this is how we read in pi
  1000. 45:34path. So call key dot then we use cast
  1001. 45:39and we want to cast it as string.
  1002. 45:43So this call this is again a function
  1003. 45:46which is in there in python. So by
  1004. 45:49default it is not available. So we will
  1005. 45:51need to import this. So we directly
  1006. 45:55don't use import. we use like from so it
  1007. 45:58is coming here like pispark SQL
  1008. 46:01functions call so it is automatically
  1009. 46:03coming using genie I'm just pressing tab
  1010. 46:06so as we have imported it now it will
  1011. 46:09work fine so this will cast our key
  1012. 46:12column to string similarly we need to
  1013. 46:16cast the value as well so I will simply
  1014. 46:19oh it is coming automatically so I will
  1015. 46:21simply press tab so value also it is
  1016. 46:24casting a string
  1017. 46:26topic it is not casting. It has that
  1018. 46:28intelligence that it knows that uh these
  1019. 46:31are there is no need to cast these. So
  1020. 46:34for you it may or may not come. If it is
  1021. 46:37not coming you can type it. But for me
  1022. 46:39it is coming. So I will simply press
  1023. 46:41tab. Uh that's all. So now all the
  1024. 46:44columns has been selected. So and these
  1025. 46:48two has been casted. So which is the
  1026. 46:50more important part. So now I will run
  1027. 46:53it and then I will display this parsed
  1028. 46:56batch.
  1029. 47:05So it took couple of seconds and now the
  1030. 47:07results are here. This time we can see
  1031. 47:10proper data here. So this is the data
  1032. 47:12which is being generated from the
  1033. 47:14producer that I have created here and
  1034. 47:18this is the data it is passing like this
  1035. 47:20is the transaction ID, customer ID, card
  1036. 47:24number, merchant ID and then many other
  1037. 47:28columns which are there and there is a
  1038. 47:30transaction timestamp column as well and
  1039. 47:33out of all these columns the transaction
  1040. 47:35ID is unique. So that is what we are
  1041. 47:38using as key column here. So this key
  1042. 47:40and value are being passed from the
  1043. 47:43producer that is generating the data and
  1044. 47:46this is how like when it is converted to
  1045. 47:48string this is how it looks like and uh
  1046. 47:52this is the data it is passing the other
  1047. 47:54columns we were not making any changes
  1048. 47:57so those are available as it is here
  1049. 48:01and now let's say if you want to store
  1050. 48:03this data into a table so what we will
  1051. 48:06do is we will take our batch and we will
  1052. 48:09save it as table. So let's say this dot
  1053. 48:13uh write
  1054. 48:16dot save as table and then we need to
  1055. 48:19provide the table name and in the table
  1056. 48:22name we need to provide a complete name
  1057. 48:25which is three name space like catalog
  1058. 48:27name dot schema name dot table name. So
  1059. 48:30for that first of all let's go ahead and
  1060. 48:32create our catalog and schema
  1061. 48:35and for that I will simply duplicate
  1062. 48:37this tab
  1063. 48:40and then we will go to this catalog
  1064. 48:42section here
  1065. 48:45and from here I will click this plus
  1066. 48:48icon and then click on create a catalog.
  1067. 48:51So this catalog we will name it as fine
  1068. 48:54guard which is the name of our project.
  1069. 48:59So catalog is created. Now we will view
  1070. 49:01it. Within this catalog we will create
  1071. 49:04multiple schemas. So to store our brunch
  1072. 49:07data we will create branch.
  1073. 49:11So we will create a schema named bronze.
  1074. 49:14And then this is where we will create
  1075. 49:16our bronze tables. And let's go ahead
  1076. 49:19and create for silver and gold as well.
  1077. 49:26So this silver and gold we will use them
  1078. 49:29later on.
  1079. 49:32Oh sorry silver already we created.
  1080. 49:35Let's create gold.
  1081. 49:39So if I open this bronze one and if I
  1082. 49:42copy this name this it is copied. Now if
  1083. 49:46we go back here I paste that name. So it
  1084. 49:49will show catalog dot schema and then
  1085. 49:52dot we need to give a table name. So
  1086. 49:55table name let's say it is uh
  1087. 49:58transactions
  1088. 50:00batch test because still it is batch
  1089. 50:04data that we are writing.
  1090. 50:07So it is complete now and this means our
  1091. 50:10table it is created now. So let me go to
  1092. 50:13the tab where we had created the schema.
  1093. 50:16And if we refresh this from here we can
  1094. 50:18refresh.
  1095. 50:22And now we can see our table that is
  1096. 50:24created. And if you want to check out
  1097. 50:27some sample data we can click this tab.
  1098. 50:30We need to select a compute. It will
  1099. 50:32start and then it will show the data. So
  1100. 50:35after a few seconds we can see the data.
  1101. 50:37It is the same data that we saw. So our
  1102. 50:40table it has been created now and here
  1103. 50:43in this icon we can see it is a table
  1104. 50:46and why I'm showing this because we will
  1105. 50:48see how this looks like when we create a
  1106. 50:51streaming table also. So if we go back
  1107. 50:54so this is how like reading the data
  1108. 50:56from Kafka and then writing it to a
  1109. 50:59delta table as a as a batch data it
  1110. 51:02looks like. So it will read entire data
  1111. 51:04from that Kafka and then it will write
  1112. 51:07it into a into this table again and if
  1113. 51:10you run this code again again it will
  1114. 51:12whatever complete data is available in
  1115. 51:15that Kafka topic it will read and then
  1116. 51:18it will write into this table that is
  1117. 51:20how it will work end to end. Now as we
  1118. 51:24have understood like how it works for
  1119. 51:26batch data. Now let's understand how we
  1120. 51:30can use it for streaming data that is
  1121. 51:33the main purpose of this video and this
  1122. 51:36project itself. So I have copied the
  1123. 51:38code that we had from above to uh create
  1124. 51:42this batch and in this time instead of
  1125. 51:45batch or sample we will call it as
  1126. 51:48streaming data frame or streaming df.
  1127. 51:53So for that instead of spark dot read we
  1128. 51:57need to mention spark dot read stream.
  1129. 52:00So so this becomes a streaming data
  1130. 52:03frame.
  1131. 52:04And do you know what other changes are
  1132. 52:06required to make it as a streaming data
  1133. 52:08frame? Nothing else. So this single word
  1134. 52:11it will change it from a batch read to a
  1135. 52:14streaming read. But this is not the
  1136. 52:17complete picture. While writing there
  1137. 52:19are other multiple options we need to
  1138. 52:21provide. then only it works end to end.
  1139. 52:24But for the reading part only changing
  1140. 52:26this from read to read stream it will
  1141. 52:28create a streaming data frame. So let me
  1142. 52:31run it. It will simply create a
  1143. 52:33streaming data frame.
  1144. 52:35And now as we already know that we need
  1145. 52:38to transform some of the data and we
  1146. 52:41need to uh do this transformation here.
  1147. 52:44So I will copy this and then we will
  1148. 52:47make the same transformation here. And
  1149. 52:50before I do that, I want to tell that
  1150. 52:53this is a streaming data frame. So we
  1151. 52:55cannot display it. It will throw an
  1152. 52:58error if we try to display this. So if
  1153. 53:01you try it out and it fails, uh don't be
  1154. 53:03worried because uh this is a streaming
  1155. 53:06data. It is expected to be continuously
  1156. 53:09reading and then writing. So displaying
  1157. 53:12uh it becomes problematic. So that is
  1158. 53:14why uh display on streaming data frame
  1159. 53:17is not supported.
  1160. 53:19So how we will come to know whether
  1161. 53:21things are working? We will write it
  1162. 53:23into a streaming table and then we will
  1163. 53:26check out the data there. So this is the
  1164. 53:29same data frame. So let me change the
  1165. 53:31name here. So that now it will perform
  1166. 53:34the same transformation on the uh
  1167. 53:39on the streaming data frame and then it
  1168. 53:42will be parsed uh instead of batch.
  1169. 53:44Let's call this also streaming df.
  1170. 53:48So now this will become our parsed
  1171. 53:51streaming DF
  1172. 53:53and next what we need to do we need to
  1173. 53:56write this into a streaming table and
  1174. 53:59the options to write the data as a
  1175. 54:01streaming table are totally different.
  1176. 54:03So we will not copy paste the same from
  1177. 54:06above. We will write on our own. So
  1178. 54:09first of all we need to provide format
  1179. 54:12which is delta. By default also it is
  1180. 54:16delta but it is better to provide that
  1181. 54:19and then we need to provide output mode.
  1182. 54:25So output mode for streaming data it
  1183. 54:27will be append mode because we want to
  1184. 54:30append the new data as and when it is
  1185. 54:32coming. In very rare case cases it may
  1186. 54:35be complete mode also where we want to
  1187. 54:37replace complete data but for streaming
  1188. 54:39data like append mode makes more sense.
  1189. 54:43So this is our append mode
  1190. 54:46and then uh let me press a new line
  1191. 54:49here. The next option that we are going
  1192. 54:52to talk about it will be a checkpoint
  1193. 54:55location. As you can see it is coming
  1194. 54:57automatically here. So I will simply
  1195. 54:59press tab and for now I will remove
  1196. 55:02these other options as I will explain
  1197. 55:04them step by step. So checkpoint
  1198. 55:07location it is a location in our DBFS.
  1199. 55:11It can be any location which is mounted
  1200. 55:14or created as a volume. This is the
  1201. 55:17location where it will store the
  1202. 55:19progress. So if we run this streaming
  1203. 55:21data once uh it will read the current
  1204. 55:24data write it into table. Next time when
  1205. 55:27it will run again then it need to keep a
  1206. 55:30track like up to which offsets it has
  1207. 55:33read. From there onwards it will read
  1208. 55:35the next time. So to store that progress
  1209. 55:38it needs a checkpoint location and we
  1210. 55:42will specify this location. So to
  1211. 55:44specify this location we need to create
  1212. 55:47a volume and to create a volume we will
  1213. 55:50go to our catalog tab. So this is our
  1214. 55:53catalog. The fine guard is our catalog
  1215. 55:56and then uh we will create a new schema
  1216. 55:59here with the name source.
  1217. 56:05And this source is our new schema where
  1218. 56:08we will create a volume. So when we will
  1219. 56:12create this volume, we will name it as
  1220. 56:15transactions. We can give it any name.
  1221. 56:17It doesn't matter. And you will notice
  1222. 56:19that here we are creating a managed
  1223. 56:21volume. So this volume is managed by
  1224. 56:23datab bricks itself. And we can also
  1225. 56:26create a external volume which can point
  1226. 56:28to a Azure data lakeink storage or S3 or
  1227. 56:32Google storage anywhere. So the actual
  1228. 56:34location can be on any storage account
  1229. 56:36as well. Here we will use managed volume
  1230. 56:38for simplicity.
  1231. 56:42And now our volume is ready. And this
  1232. 56:44volume is like a directory. So in this
  1233. 56:47in this uh location or volume we will
  1234. 56:50create a directory or folder that will
  1235. 56:53be our checkpoint.
  1236. 56:56So this will be our checkpoint location.
  1237. 56:59So now I will copy it from here. so that
  1238. 57:02it will copy this complete path. Then we
  1239. 57:05will go back to our notebook and we will
  1240. 57:07replace this path. So now this is where
  1241. 57:10it will store the checkpoint location
  1242. 57:14and before we see other options let me
  1243. 57:16wrap it into brackets so there's so that
  1244. 57:19these red dots go away and it is not
  1245. 57:24going away. Looks like I forgot to
  1246. 57:26specify the right stream.
  1247. 57:29So uh here while reading we specify like
  1248. 57:33read stream and while writing we specify
  1249. 57:36data frame streaming data frame dot
  1250. 57:38write stream and then dot format and
  1251. 57:41other options
  1252. 57:44and then the next option that we are
  1253. 57:47going to provide it will be
  1254. 57:50uh dot trigger
  1255. 57:52and in trigger like there can be
  1256. 57:54different options.
  1257. 57:56So uh the option that we are going to
  1258. 57:59use is available now
  1259. 58:03equal to true. I will explain other
  1260. 58:06options also.
  1261. 58:08So this is the option that we are going
  1262. 58:10to use. So in terms of trigger apart
  1263. 58:13from available now
  1264. 58:16there there is like another trigger also
  1265. 58:18supported which is uh processing time.
  1266. 58:23So in the processing time we need to
  1267. 58:25provide some time as well. So for
  1268. 58:28example here we specify that 10 seconds.
  1269. 58:32So what this will do is uh it will keep
  1270. 58:35running the streaming job and it will
  1271. 58:37process the data every 10 seconds. So
  1272. 58:41whatever duration we specify. So after
  1273. 58:44that many seconds or minute also it will
  1274. 58:47process the data. So then it will
  1275. 58:49process the data in micro batches. So
  1276. 58:52all it will sim it will be similar to
  1277. 58:54batch processing but because this is
  1278. 58:56doing every second or every 10 second it
  1279. 58:59will kind of become a streaming data. So
  1280. 59:02this is the processing time trigger and
  1281. 59:05in datab bricks free edition in this
  1282. 59:07compute which is serverless it will say
  1283. 59:10that this trigger is not supported on
  1284. 59:12this compute because this is something
  1285. 59:14like currently they have not allowed but
  1286. 59:17if you have like a paid datab bricks uh
  1287. 59:20then it will allow it. So there that is
  1288. 59:22why this one we will not use. We will we
  1289. 59:25will use like a continuous processing
  1290. 59:27that is allowed when we will go to the
  1291. 59:30uh declarative pipelines but here as a
  1292. 59:33spark streaming it is not supported. So
  1293. 59:35the trigger which is supported is
  1294. 59:37available now and what this does is uh
  1295. 59:41instead of like running it continuously
  1296. 59:44it will run it only once. So available
  1297. 59:47now equal to true what it means is that
  1298. 59:50load all the new data that is available
  1299. 59:53now. So if you run it for the first time
  1300. 59:55it will load everything that is
  1301. 59:57available. If you run it for the second
  1302. 59:59time it will check on this checkpoint
  1303. 1:00:01location what data it has read
  1304. 1:00:03previously and that point onwards it
  1305. 1:00:06will read the new data that is available
  1306. 1:00:08now and then stop. So that is how this
  1307. 1:00:12trigger will work.
  1308. 1:00:14And then the final option will come that
  1309. 1:00:17is to table where we specify the table
  1310. 1:00:20name that we want to create and the
  1311. 1:00:23table that we want to create we it will
  1312. 1:00:25be in our fine guard only fine guard
  1313. 1:00:28branch and then transaction uh streaming
  1314. 1:00:31test. This is the name we can provide.
  1315. 1:00:33It has suggested automatically because
  1316. 1:00:36we had created transactions batch test.
  1317. 1:00:38So this time we are creating streaming
  1318. 1:00:40test
  1319. 1:00:42and this it covers all the options and
  1320. 1:00:45when we are writing streaming data it is
  1321. 1:00:47better to capture it into a another
  1322. 1:00:51variable because whenever it is writing
  1323. 1:00:54any streaming data we get a query id as
  1324. 1:00:57well. So if I print it
  1325. 1:01:01uh we can print a message like
  1326. 1:01:04query ID is this. So let's see if it is
  1327. 1:01:09providing it automatically with
  1328. 1:01:13query id
  1329. 1:01:15and then uh it is providing normally it
  1330. 1:01:19is available as dot id simply
  1331. 1:01:24and that's it. So this ID it is
  1332. 1:01:27sometimes available for debugging and
  1333. 1:01:29tracking purpose. So because this is
  1334. 1:01:31available I want it to show otherwise
  1335. 1:01:33this is completely optional only this
  1336. 1:01:35much code it will run fine. So this it
  1337. 1:01:39completes our uh streaming writing code
  1338. 1:01:42and now the code becomes end to end. So
  1339. 1:01:45we are reading the streaming data
  1340. 1:01:48here we are creating a stream we are
  1341. 1:01:51performing some transformation which is
  1342. 1:01:53casting operation then we are writing
  1343. 1:01:56the stream. So now let's run this code
  1344. 1:01:59and we will see it running end to end.
  1345. 1:02:04So now it is saying query has been
  1346. 1:02:06started. It is currently running
  1347. 1:02:09and this is the query ID I was talking
  1348. 1:02:11about. So this is this ID is unique for
  1349. 1:02:15every time it is doing some processing.
  1350. 1:02:18And now we can see that the processing
  1351. 1:02:20has been completed. So let's check out
  1352. 1:02:22our data now.
  1353. 1:02:33And here we can see the data. It has
  1354. 1:02:36been written successfully. It has 61
  1355. 1:02:39rows which are there available in the
  1356. 1:02:41producer. And if we go to the uh schema
  1357. 1:02:45here which was the bronze schema. And if
  1358. 1:02:48I refresh it from here,
  1359. 1:02:55we can see that our table has been
  1360. 1:02:57created. And this table also it is not
  1361. 1:03:00marked as streaming table. Uh why?
  1362. 1:03:03Because these are marked by datab bricks
  1363. 1:03:06inbuilt functionalities not by uh spark
  1364. 1:03:10streaming. We will see the difference.
  1365. 1:03:11We will use the uh declarative pipeline.
  1366. 1:03:15But this is where our table has been
  1367. 1:03:16created.
  1368. 1:03:18And now let's explore the checkpoint
  1369. 1:03:20location also so that we understand how
  1370. 1:03:23the progress has been tracked. So if we
  1371. 1:03:26go to the volume which we had created
  1372. 1:03:28the transactions volume this location we
  1373. 1:03:30had specified for checkpoint and here we
  1374. 1:03:33can see that it is storing some metadata
  1375. 1:03:36commits offset source related
  1376. 1:03:39information. So different different
  1377. 1:03:40information it is storing and the the
  1378. 1:03:43one that where we are interested in it
  1379. 1:03:46is the offset because we want to see how
  1380. 1:03:48it is storing the offset. So this is a
  1381. 1:03:50small file. I will simply download it
  1382. 1:03:54and then if I go to my downloads and if
  1383. 1:03:57I open this file
  1384. 1:04:00in a notepad or something then this is
  1385. 1:04:03where we will see the offsets being
  1386. 1:04:05stored. So this is our topic name and
  1387. 1:04:09then these are the offsets. So what it
  1388. 1:04:11means is like from zero partition it has
  1389. 1:04:14read 11 records. One partition it has
  1390. 1:04:17read seven records. Second like
  1391. 1:04:20partition number 2 3 4 5. So 0 to 5 six
  1392. 1:04:24partitions and it has read these records
  1393. 1:04:27like 11 7 6 11 9 and 17. If we sum these
  1394. 1:04:32up it will come up 61. So that is how it
  1395. 1:04:36now it knows that from each of the
  1396. 1:04:38partition how many records it has read
  1397. 1:04:40and next time whenever it will read the
  1398. 1:04:42data. So it will read the data this
  1399. 1:04:45point onwards from each of the partition
  1400. 1:04:47and then it will know that this is the
  1401. 1:04:49new data. So now we will try to write
  1402. 1:04:53some new data and we will see how it is
  1403. 1:04:55being put up. So I'm back in my VS code
  1404. 1:04:58and earlier I showed the option to run
  1405. 1:05:01it from top like if you open and run it
  1406. 1:05:03from here. The second option I was
  1407. 1:05:05talking about is from here. So if I
  1408. 1:05:08press the up key it will show the script
  1409. 1:05:10which was run previously which is this
  1410. 1:05:13producer normal and by default it use
  1411. 1:05:16the complete paths here. And if you
  1412. 1:05:18don't want to use this simply what we
  1413. 1:05:20can do is we can say python and then the
  1414. 1:05:24name of the file. So in our case it is
  1415. 1:05:26producer fraud not fraud like producer
  1416. 1:05:31uh normal this is the file we want to
  1417. 1:05:33run. So like this also we can run it. So
  1418. 1:05:36we will put some if put a few extra
  1419. 1:05:39records it is putting. Now I will press
  1420. 1:05:41Ctrl C so that it is cancelled and we
  1421. 1:05:45will see if now it is reading these new
  1422. 1:05:48records only. So now I will go back to
  1423. 1:05:51my code and then I will run our
  1424. 1:05:54streaming write again
  1425. 1:05:58and we are not running the reading part
  1426. 1:06:00again because spark it runs a DAZ
  1427. 1:06:03operation. So it will create it will
  1428. 1:06:06store only the reference and the
  1429. 1:06:08progress is stored here. So now it shall
  1430. 1:06:10be able to check based on those
  1431. 1:06:12checkpoint location and it will read
  1432. 1:06:14only the new data. So now it is
  1433. 1:06:17completed. So previously it has it had
  1434. 1:06:2061 rows. Now let's see how many rows it
  1435. 1:06:23has.
  1436. 1:06:25So this time we can see now it has 79
  1437. 1:06:28rows. So the extra 18 rows which were
  1438. 1:06:31written here those has been read and
  1439. 1:06:34those has been appended here. So that is
  1440. 1:06:37how using this trigger type available.
  1441. 1:06:41Now it read only the new data and then
  1442. 1:06:44it wrote into this table. So this is how
  1443. 1:06:47like the streaming processing looks end
  1444. 1:06:49to end in terms of spark streaming and
  1445. 1:06:52this spark streaming it is not specific
  1446. 1:06:54to data bricks it is like apache spark
  1447. 1:06:57streaming. So whatever platforms they
  1448. 1:06:59support Spark there we can use it like
  1449. 1:07:03uh we have uh Synapse we have MS fabric
  1450. 1:07:07and even if you use opensource spark
  1451. 1:07:10there we can use it but as we are using
  1452. 1:07:13datab bricks and datab bricks they have
  1453. 1:07:15the people who built spark so on top of
  1454. 1:07:18this spark streaming they have provided
  1455. 1:07:21some advanced and additional
  1456. 1:07:22functionalities that we can use for
  1457. 1:07:26spark streaming and batch processing.
  1458. 1:07:28both but in a easier way with some
  1459. 1:07:31advanced settings advanced options that
  1460. 1:07:33we get and those things we get when we
  1461. 1:07:36use the lakeflow
  1462. 1:07:39lakeflow spark declarative pipeline.
  1463. 1:07:42This is the name they have given.
  1464. 1:07:44Previously it used to be called as DT
  1465. 1:07:47delta live tables but now they call it
  1466. 1:07:49as lakeflow spark declarative pipeline.
  1467. 1:07:53So when we will use that we will see
  1468. 1:07:55that many of these options will be taken
  1469. 1:07:58care automatically by datab bricks and
  1470. 1:08:00we will need to write fewer code we will
  1471. 1:08:02get data quality checks capabilities and
  1472. 1:08:06we will get it more managed way where we
  1473. 1:08:08can monitor in a better way. So these
  1474. 1:08:11are some advantages we will get if we
  1475. 1:08:13use the uh lake floor spark declarative
  1476. 1:08:16pipelines. That is why now as you
  1477. 1:08:20understand the base how opensource or
  1478. 1:08:22the normal spark streaming works. So now
  1479. 1:08:25we will use the same thing in lakeflow
  1480. 1:08:27spark declarative pipeline and see what
  1481. 1:08:30advantages we will get there and then
  1482. 1:08:32there we will build it completely and we
  1483. 1:08:35will build the rest of the project there
  1484. 1:08:37itself.
  1485. 1:08:39And before we do that uh we will now we
  1486. 1:08:42will store these credentials also
  1487. 1:08:45securely because when we work on
  1488. 1:08:47production projects we never store
  1489. 1:08:49credentials like this. So we store these
  1490. 1:08:52credentials in a secret scope where we
  1491. 1:08:55store them once we can use them anywhere
  1492. 1:08:58in a secure way. So first let's go ahead
  1493. 1:09:01and store these credentials in a secret
  1494. 1:09:03scope
  1495. 1:09:05and for that I have created a notebook
  1496. 1:09:08already because there we need to use
  1497. 1:09:10secret scope APIs and all and normally
  1498. 1:09:13these are done by the admin people or
  1499. 1:09:17senior architect people but I wanted to
  1500. 1:09:20show the proper use case of credentials
  1501. 1:09:22so I created this notebook the same can
  1502. 1:09:25be used by you. So here first we need to
  1503. 1:09:29provide a name of our secret scope where
  1504. 1:09:31all our secrets will be stored. The name
  1505. 1:09:34we are going to give is fine guard dash
  1506. 1:09:37scope. So I will simply run it and you
  1507. 1:09:40can use any other name if you want. And
  1508. 1:09:43then because we will be creating the
  1509. 1:09:45secret scope and secret using APIs
  1510. 1:09:48because we creating them through the UI
  1511. 1:09:50it is not there in the free edition. So
  1512. 1:09:53we will be using the API and to do that
  1513. 1:09:55we will need token for that. So this
  1514. 1:09:58cell it will automatically uh take our
  1515. 1:10:01current user generate a token and store
  1516. 1:10:04them into the variable. That is what it
  1517. 1:10:07will do. And here we are saying that the
  1518. 1:10:09backend type it is datab bricks. It can
  1519. 1:10:12be Azure key volt or the other
  1520. 1:10:14cloud-based services as well. But here
  1521. 1:10:17we are we will be storing them within
  1522. 1:10:19datab bricks itself.
  1523. 1:10:21And after that when we run this
  1524. 1:10:24particular cell it will create the
  1525. 1:10:26secret scope. I have already created
  1526. 1:10:28mine when I did it previously. So
  1527. 1:10:31probably it will say that it failed to
  1528. 1:10:33create because it is already there. If
  1529. 1:10:35you are creating for the first time it
  1530. 1:10:37will create for you. So now as the
  1531. 1:10:39secret is created sorry scope is created
  1532. 1:10:43then we need to create our uh secret
  1533. 1:10:46inside this secret scope and there we
  1534. 1:10:49want to store these uh server topic key
  1535. 1:10:53and secret details. So let me copy them
  1536. 1:10:56from our other notebook. So these are
  1537. 1:10:58the details we will be specifying there.
  1538. 1:11:02So I'm pasting it in into a new cell so
  1539. 1:11:05that I can copy paste them and replace
  1540. 1:11:07these older values that I had
  1541. 1:11:10previously.
  1542. 1:11:14So yeah, this is our secret. Sorry, that
  1543. 1:11:18was the key. This is the secret
  1544. 1:11:24and topic name it is the same only. So I
  1545. 1:11:26don't need to replace it. But we need to
  1546. 1:11:28provide it for sure. Now I will delete
  1547. 1:11:31this cell. So now what it it is doing is
  1548. 1:11:34it will take these four values and it
  1549. 1:11:37will create a JSON out of it. In the
  1550. 1:11:39JSON it will store them as bootstrap
  1551. 1:11:42server topic API key and API secret and
  1552. 1:11:46then it will create this as a JSON
  1553. 1:11:49string.
  1554. 1:11:51So it is created. So if I try to print
  1555. 1:11:53this,
  1556. 1:11:56it will print it as the JSON and that is
  1557. 1:11:59what we will store it as a secret this
  1558. 1:12:01JSON
  1559. 1:12:03and to create a secret we have this API
  1560. 1:12:06called secrets dot sorry secrets /put
  1561. 1:12:10and there we are providing our scope
  1562. 1:12:12name the secret key name this key is the
  1563. 1:12:16name of the key Kafka connection details
  1564. 1:12:19I'm providing it as a hardcoded values
  1565. 1:12:21here and the same key we will use later
  1566. 1:12:24on to retrieve these secrets and the
  1567. 1:12:27value part it is this JSON that I showed
  1568. 1:12:29here so this is the payload we are
  1569. 1:12:33providing we are making the API whole
  1570. 1:12:36and then it will create our secret so if
  1571. 1:12:39I run it will say it is created
  1572. 1:12:42successfully I had previously also
  1573. 1:12:44created but it is replaced when I ran it
  1574. 1:12:47again this for secret part it doesn't
  1575. 1:12:49throw an error so now It is uh like the
  1576. 1:12:53secret is created inside the secret
  1577. 1:12:55scope with these details and it is
  1578. 1:12:58ready. And if you want to confirm if it
  1579. 1:13:01is working properly. So this is the
  1580. 1:13:04command we use like dbuttils do.cses.get
  1581. 1:13:08that we will use in our code also to get
  1582. 1:13:10these details and then the name of the
  1583. 1:13:13secret scope and the name of our key.
  1584. 1:13:16then it will retrieve the data and that
  1585. 1:13:19JSON it will parse it and then print it.
  1586. 1:13:23So it has run successfully and we can
  1587. 1:13:25see that it is able to retrieve the data
  1588. 1:13:28that JSON from the secret and then it is
  1589. 1:13:31able to print that in production
  1590. 1:13:33projects never print this. I just wanted
  1591. 1:13:35to print to showcase you that these
  1592. 1:13:37values are coming properly. So now our
  1593. 1:13:41secrets has been stored successfully
  1594. 1:13:43into the secret scope. So from there we
  1595. 1:13:46will use it and then we have a next cell
  1596. 1:13:49also where we will put a secret about uh
  1597. 1:13:52Gmail API key. This we will cover later
  1598. 1:13:55on when we will come to email
  1599. 1:13:56notification piece. But for now like
  1600. 1:13:59only using these secret is enough for
  1601. 1:14:02us. So as we have stored these secrets
  1602. 1:14:04next let's understand how we can read
  1603. 1:14:06these secrets and then use in our code.
  1604. 1:14:09So for that we will go back to our
  1605. 1:14:11original notebook. I will uh comment
  1606. 1:14:16this cell so that it will not be used
  1607. 1:14:18anymore. I will add a new cell so that
  1608. 1:14:21when you try you can still use it and
  1609. 1:14:24then here we will use like Kafka
  1610. 1:14:28connection JSON. So this one we will be
  1611. 1:14:32reading it from our secret. So dv utils
  1612. 1:14:35dot uh secrets dot get and the name of
  1613. 1:14:40our scope it it was the fine guard dash
  1614. 1:14:43scope fine
  1615. 1:14:46guard dash scope this was the name and
  1616. 1:14:49the name of the key it was uh the kafka
  1617. 1:14:54connection detail so let me copy paste
  1618. 1:14:56that so that there is no typo in that
  1619. 1:14:59one so this is the name of our key
  1620. 1:15:08and here for the key part also we need
  1621. 1:15:10to specify that this is a key then it
  1622. 1:15:13will work. So now it will read that JSON
  1623. 1:15:17as a string and then we need to parse
  1624. 1:15:19that JSON.
  1625. 1:15:24So what we will say is like kafka
  1626. 1:15:28we will call it as config this will be
  1627. 1:15:32JSON
  1628. 1:15:33dot loads and it is automatically coming
  1629. 1:15:37up. So I will press tab here. I will
  1630. 1:15:41remove these for now. So now we can say
  1631. 1:15:45that like the Kafka config is there. And
  1632. 1:15:48now we will need to read these one by
  1633. 1:15:51one. And this Kafka config it is kind of
  1634. 1:15:55a dictionary now. And this dictionary it
  1635. 1:15:58has all these four values. So this value
  1636. 1:16:01it will be if I paste this and if I type
  1637. 1:16:05so it is automatically coming. So if I
  1638. 1:16:08simply press tab it will say that these
  1639. 1:16:10values are there including the topic as
  1640. 1:16:13well. So I will press tab again. So
  1641. 1:16:16topic part it is kind of hard coding but
  1642. 1:16:19in our case we know that that is there
  1643. 1:16:21in the Kafka config. So we will read
  1644. 1:16:24from there itself.
  1645. 1:16:27So now it will read all those secrets
  1646. 1:16:30from our secret scope. So this one we
  1647. 1:16:33don't use this in this in production
  1648. 1:16:35scenarios. So let me run this so that it
  1649. 1:16:38is able to read that scope and it threw
  1650. 1:16:41an error saying that the secret does not
  1651. 1:16:45exist. So there shall be some typo. Let
  1652. 1:16:48me double check again.
  1653. 1:16:51So it is details not the detail. So
  1654. 1:16:55looks like I was not able to copy it
  1655. 1:16:57properly. Let me run it again. So now it
  1656. 1:17:00is able to read it and these connections
  1657. 1:17:02has been set. Now with this new API key
  1658. 1:17:05and secret let me set up this JAS config
  1659. 1:17:09and then batch part we will not run
  1660. 1:17:11again. We will directly run our
  1661. 1:17:13streaming part. So this stream has been
  1662. 1:17:17created now after I run this with the
  1663. 1:17:19new details. The transformation it is
  1664. 1:17:23done now
  1665. 1:17:25and then we will write it into our
  1666. 1:17:27table. But before that let's write some
  1667. 1:17:30data again
  1668. 1:17:32so that we will know that the new data
  1669. 1:17:34is being written. So I will press up. It
  1670. 1:17:36will bring in the same command. Then I
  1671. 1:17:39will press enter. So it will read. I
  1672. 1:17:41will put press control C. So only these
  1673. 1:17:45three records it is writing. And then I
  1674. 1:17:48will go back. I will uh run our write
  1675. 1:17:52query now.
  1676. 1:17:54And it is still running. So in free
  1677. 1:17:57edition sometimes the resources in
  1678. 1:17:59serverless are not available that is why
  1679. 1:18:02sometimes it is stuck it takes longer
  1680. 1:18:04time. So you can interrupt it and run
  1681. 1:18:06again or you can let it run for some
  1682. 1:18:09time and looks like this time the time
  1683. 1:18:11out happened. So I will run it again
  1684. 1:18:15and if it is taking very long then we
  1685. 1:18:17will go to the next step and then we
  1686. 1:18:19will come back here and then check it
  1687. 1:18:21out. And looks like this time also it is
  1688. 1:18:24running for longer. So to save my time
  1689. 1:18:28of recording uh I will we will continue
  1690. 1:18:30building with the uh
  1691. 1:18:34spark declarative pipeline and this
  1692. 1:18:36piece we will check later on but I think
  1693. 1:18:38you know you believe me that it will
  1694. 1:18:40work fine. So to build the declarative
  1695. 1:18:43pipeline we have different options. So
  1696. 1:18:46one of them it is that from here we can
  1697. 1:18:49create it. So if I click here, if I
  1698. 1:18:51click create and then we need to click
  1699. 1:18:54this ETL pipeline. So it will create a
  1700. 1:18:57pipeline in that same folder
  1701. 1:19:01and when it creates it creates a
  1702. 1:19:03different type of UI. This UI itself it
  1703. 1:19:06is the lakeflow spark declarative
  1704. 1:19:08pipeline UI. So from now onwards like
  1705. 1:19:11spark declarative pipeline we the short
  1706. 1:19:13form we use is SDP. So whenever I
  1707. 1:19:16mention SDP it is like spark declarative
  1708. 1:19:19pipeline. So for this STP we can see
  1709. 1:19:23this is the pipeline part where it is
  1710. 1:19:25showing only this pipeline related
  1711. 1:19:27table. It has created a sorry this
  1712. 1:19:29pipeline related files and if you go to
  1713. 1:19:32all files it will show the main
  1714. 1:19:34workspace. So these were the two
  1715. 1:19:36notebooks we were working previously and
  1716. 1:19:38this is the new folder it has created
  1717. 1:19:40for this pipeline. So if I open it, we
  1718. 1:19:43will see the same thing that we see
  1719. 1:19:45here. But while working on SDP, we will
  1720. 1:19:48see that this pipeline section is more
  1721. 1:19:51useful or it is like easy to work with.
  1722. 1:19:55And then this pipeline we will rename
  1723. 1:19:57it. We will name it as fine guard
  1724. 1:20:02streaming.
  1725. 1:20:05This is the name that we will provide
  1726. 1:20:08here. And this folder name also we will
  1727. 1:20:11rename it with the same name. So it says
  1728. 1:20:14rename root folder. We will name it as
  1729. 1:20:16fine
  1730. 1:20:19fine streaming
  1731. 1:20:28and then it has created this
  1732. 1:20:30transformations folder but we will use
  1733. 1:20:33our own folder here. So we will create
  1734. 1:20:36our folders based on our medallion
  1735. 1:20:38architecture. So first we will create a
  1736. 1:20:41folder named branch
  1737. 1:20:45and then this folder we are not going to
  1738. 1:20:48use. So this folder we will delete it
  1739. 1:20:52and looks like it will not let us delete
  1740. 1:20:54because at least one folder shall be
  1741. 1:20:57there. Uh this other folder which is
  1742. 1:20:59there. So by default it will be ignored
  1743. 1:21:01for execution. So to include this we
  1744. 1:21:04need to click this include folder as
  1745. 1:21:06pipeline source code then this folder
  1746. 1:21:10will be considered and this option now
  1747. 1:21:12it will allow us to delete it and why we
  1748. 1:21:15need to do that because this is also a
  1749. 1:21:17good functionality that if some folder
  1750. 1:21:20or pipeline we are doing for testing and
  1751. 1:21:22if we don't want to run we can include
  1752. 1:21:25or exclude them as pipeline source code.
  1753. 1:21:28So this is the branch folder. Now we
  1754. 1:21:31will create our file
  1755. 1:21:34and this file we will name it as uh
  1756. 1:21:38transactions
  1757. 1:21:42branch.
  1758. 1:21:45So I will remove rest of the name and
  1759. 1:21:47dot py we need to keep it.
  1760. 1:21:52So now this is where we will write the
  1761. 1:21:54code for spark streaming or specifically
  1762. 1:21:57for SDP and we will see how it is
  1763. 1:21:59different from the normal spark
  1764. 1:22:01streaming. So to start with the code we
  1765. 1:22:04will first need to import something. So
  1766. 1:22:07from
  1767. 1:22:09pispark we will import
  1768. 1:22:13pipelines
  1769. 1:22:17sp
  1770. 1:22:19in pipelines there is a e as well. So
  1771. 1:22:22this is our declarative pipeline and
  1772. 1:22:24this is a decorator as well. So how do
  1773. 1:22:28we use a decorator is a the rate dp so
  1774. 1:22:31that it will know it is the uh a a
  1775. 1:22:35standard like sdp decorator
  1776. 1:22:38and then dot table and in this table we
  1777. 1:22:42need to specify the name of the table
  1778. 1:22:44that we want to create. So it take
  1779. 1:22:47different values like name and this name
  1780. 1:22:50it is the name of our target table that
  1781. 1:22:53will be created. So our target table we
  1782. 1:22:56want to create it as fine guard dot
  1783. 1:22:59branch dot transactions. This time there
  1784. 1:23:03is no test or something. We want to
  1785. 1:23:05create it with the name transactions.
  1786. 1:23:08And then there are some additional
  1787. 1:23:10properties as well. For example comment
  1788. 1:23:13is there. So there we can mention like
  1789. 1:23:16what is the purpose of this
  1790. 1:23:22and here it is comma not a dot. So in
  1791. 1:23:26the comment we can mention what is the
  1792. 1:23:28intention of this particular table or
  1793. 1:23:30this particular file. So we can say like
  1794. 1:23:34transactions
  1795. 1:23:36row stream data ingested from Kafka that
  1796. 1:23:41is what we will store into this table.
  1797. 1:23:45Now with this decorator we will create a
  1798. 1:23:48function like div then we can name the
  1799. 1:23:51functions as like transactions bronze
  1800. 1:23:54only.
  1801. 1:23:58And now after this name of the function
  1802. 1:24:02uh we will say what it will return and
  1803. 1:24:04there is a standard that it shall be
  1804. 1:24:06returning a data frame.
  1805. 1:24:09So this data frame as of now we have not
  1806. 1:24:12yet imported. So so this also we need to
  1807. 1:24:15import this like from pispark.sql
  1808. 1:24:20we need to import dataf frame and it is
  1809. 1:24:23SQL dot dataf frame. This is how we
  1810. 1:24:27import it. Now it is imported and here
  1811. 1:24:30we need to return a proper data frame
  1812. 1:24:33which is our streaming data frame. So
  1813. 1:24:36the structure until here it is very
  1814. 1:24:38standard for SDP and we will see like
  1815. 1:24:41what advantages we are getting with this
  1816. 1:24:44proper structure.
  1817. 1:24:46So now what we need to do is we need to
  1818. 1:24:48write our streaming code here and for
  1819. 1:24:51that we will reuse the code that we had
  1820. 1:24:53written already. So we will go there and
  1821. 1:24:57first we will copy this code which will
  1822. 1:24:59read our secrets
  1823. 1:25:02uh from there. So I will copy paste that
  1824. 1:25:04same code here. This import piece I will
  1825. 1:25:07cut it from here. I will keep it at the
  1826. 1:25:10top because all the libraries we shall
  1827. 1:25:12keep it at the top. I will select it.
  1828. 1:25:15Press tab so that the indentation is
  1829. 1:25:18properly it has to be with some space.
  1830. 1:25:21This is the standard Python.
  1831. 1:25:23And after we have our secrets ready then
  1832. 1:25:27the next thing we need to do is we need
  1833. 1:25:29to create this uh JAS config. So this
  1834. 1:25:32code also I will copy from previous
  1835. 1:25:35notebook and put it here. And next we
  1836. 1:25:38will need to write our streaming piece.
  1837. 1:25:41So as we are back in the notebook let's
  1838. 1:25:44confirm if our previous code was
  1839. 1:25:46successful. And looks like it it's still
  1840. 1:25:49timed out. So either the Kafka is not
  1841. 1:25:52available or as we were trying it for
  1842. 1:25:55the first time after putting our
  1843. 1:25:56secrets. So maybe we may have made some
  1844. 1:25:59typo as well. So let's confirm that
  1845. 1:26:02piece first. So let me copy this. I will
  1846. 1:26:05go to our setup secret notebook and we
  1847. 1:26:08will try to compare if we are we are
  1848. 1:26:10using the right thing. So this is
  1849. 1:26:13starting properly. Oh, looks like here
  1850. 1:26:16we missed a two. So it was 9092
  1851. 1:26:20but we kept only 909. So now I have
  1852. 1:26:23added this two and we will add this
  1853. 1:26:26secret again so that it can connect
  1854. 1:26:28again. So earlier it was trying with
  1855. 1:26:30some different port and it was not able
  1856. 1:26:33to reach there and uh it is saying JSON
  1857. 1:26:37not defined because it was imported in
  1858. 1:26:39earlier cell. So let me run these above
  1859. 1:26:42cells again and secret scope it was
  1860. 1:26:45already created only secret we will need
  1861. 1:26:48to create again. So now this JSON is
  1862. 1:26:51ready. It will print it again. So now it
  1863. 1:26:54is 9092.
  1864. 1:26:56Let me put this new secret. Now this new
  1865. 1:27:00secret has been put. Earlier it was 909.
  1866. 1:27:03Now it is 92. So now our streaming code
  1867. 1:27:07shall work fine. Uh let's run it one
  1868. 1:27:10more time.
  1869. 1:27:11So this is run. Now let's run the
  1870. 1:27:14streaming code directly.
  1871. 1:27:16So this is our streaming code. Let's run
  1872. 1:27:19it.
  1873. 1:27:22Uh let's run this as well.
  1874. 1:27:25And this time it is successful. It ran
  1875. 1:27:28quickly. Now let's check out our table
  1876. 1:27:31again.
  1877. 1:27:32And here we can see now it has 89
  1878. 1:27:35records. I was expecting like three new
  1879. 1:27:38records on top of 79 but it has inserted
  1880. 1:27:4210 records. Let me double check. So I
  1881. 1:27:45thought it has written these three but
  1882. 1:27:47looks like this is some line. It has
  1883. 1:27:48written these seven plus these three. So
  1884. 1:27:51total 10 records. So we are good. So
  1885. 1:27:54those additional 10 records has been
  1886. 1:27:56written means our code is working fine.
  1887. 1:27:59So now let's take this streaming code to
  1888. 1:28:01the SDP pipeline.
  1889. 1:28:05So where it is?
  1890. 1:28:08Yeah, this is our streaming code. So
  1891. 1:28:10this is uh reading the stream. So let me
  1892. 1:28:14copy this from here and then we will
  1893. 1:28:17take it to our uh SDP pipeline. So after
  1894. 1:28:21that I will provide it here. So this is
  1895. 1:28:24the streaming piece
  1896. 1:28:26and once we have the streaming data
  1897. 1:28:28frame then what we did was the uh we
  1898. 1:28:32parsed it we converted these into
  1899. 1:28:34timestamps. So let me copy this code as
  1900. 1:28:37well and let me put it here
  1901. 1:28:45and this import statement I will keep it
  1902. 1:28:47at the top.
  1903. 1:28:53So now this piece is also ready and I
  1904. 1:28:56also want to add a new column here as as
  1905. 1:28:59the current time stamp as the injection
  1906. 1:29:02timestamp so that it is available for
  1907. 1:29:04better tracking. For that we need to do
  1908. 1:29:07something like f dot current timestamp
  1909. 1:29:10but uh yeah it is coming here and then
  1910. 1:29:13we will name it as injection timestamp.
  1911. 1:29:23So this will be the name and here it
  1912. 1:29:25will be available as the current time
  1913. 1:29:27stamp and this f it is the function. So
  1914. 1:29:30we will need to import that as well. So
  1915. 1:29:33it is like from pispar
  1916. 1:29:37dossql dot
  1917. 1:29:40uh functions
  1918. 1:29:44as f. So this functions it will be
  1919. 1:29:47imported as f and f dot current
  1920. 1:29:50timestamp will be our current timestamp.
  1921. 1:29:55So you will think like I am just copy
  1922. 1:29:56pasting the code from there. So what is
  1923. 1:29:59the advantage? So now comes the
  1924. 1:30:01advantage part. So as you already know
  1925. 1:30:05that for writing this stream we had to
  1926. 1:30:07provide these modes the checkpoint
  1927. 1:30:10location the trigger type the table name
  1928. 1:30:13and everything. But that one advantage
  1929. 1:30:16of this is that we don't need to
  1930. 1:30:18maintain any uh checkpoint or anything
  1931. 1:30:22any location nothing simply what we need
  1932. 1:30:24to do is we need to return this data
  1933. 1:30:27frame and that's all. So that is how the
  1934. 1:30:30writing part it has been simplified. How
  1935. 1:30:33it will work internally is that it will
  1936. 1:30:36return this data frame. This data frame
  1937. 1:30:39will be written into this table as a
  1938. 1:30:42streaming table automatically
  1939. 1:30:45and the checkpoint and everything will
  1940. 1:30:47be maintained automatically by datab
  1941. 1:30:49bricks. We don't need to maintain
  1942. 1:30:51anything there. And when it comes to to
  1943. 1:30:53the trigger type so for that we get the
  1944. 1:30:56trigger type here. So if we go to the
  1945. 1:30:59settings the pipeline mode it is
  1946. 1:31:02triggered. So we can schedule it. we
  1947. 1:31:04also get a continuous mode where it will
  1948. 1:31:07run it in the actual real runtime way.
  1949. 1:31:10So that is that is something we will try
  1950. 1:31:12later on when we will build the silver
  1951. 1:31:15part and then we will see the end to end
  1952. 1:31:18streaming data flowing. But for this
  1953. 1:31:20particular table that's the entire code
  1954. 1:31:23that we need. So now for this table the
  1955. 1:31:26code is ready. So we are going to simply
  1956. 1:31:29go ahead and run this code. And to run
  1957. 1:31:32that we simply click this run pipeline.
  1958. 1:31:36And there are other advantages also we
  1959. 1:31:38get. Oh before that let me select the uh
  1960. 1:31:41catalog and schema name. So it has some
  1961. 1:31:44default catalog and schema we need to
  1962. 1:31:46provide. So it will be fine guard and
  1963. 1:31:49branch will be the default one. And then
  1964. 1:31:52we need to run the pipeline. This is
  1965. 1:31:54where we can also configure the default
  1966. 1:31:56catalog and schema names. Currently it
  1967. 1:31:59is waiting for the resources.
  1968. 1:32:02And this is another advantage that we
  1969. 1:32:04are getting a good monitoring screen
  1970. 1:32:07here. We can also apply data quality
  1971. 1:32:09checks that we will apply in the later
  1972. 1:32:11state and also connecting different
  1973. 1:32:14streaming table that is also made very
  1974. 1:32:16easy when we go with these STP pipelines
  1975. 1:32:19that also we will see. And now the
  1976. 1:32:22resources are available. It is
  1977. 1:32:24initializing the pipeline
  1978. 1:32:28and looks like it threw an error. If we
  1979. 1:32:30go it says invalid syntax. If we click
  1980. 1:32:33this jump to code, it is taking here. So
  1981. 1:32:36it is saying oh. So we didn't mention
  1982. 1:32:39the import keyword. So in between here
  1983. 1:32:42we need to import functions as f. That
  1984. 1:32:45is the correct that is how we actually
  1985. 1:32:48use it. Now let me run it again.
  1986. 1:32:52So and this time it threw another error.
  1987. 1:32:54It is saying find guard is not found. So
  1988. 1:32:57again I made a typo. I will correct it
  1989. 1:33:00and then run it again.
  1990. 1:33:03And this time looks like syntax wise
  1991. 1:33:05things are fine. So it is currently
  1992. 1:33:07setting up the tables. And now the
  1993. 1:33:09pipeline has been started. And if you
  1994. 1:33:12are also using the free addition
  1995. 1:33:14sometimes the waiting for resources it
  1996. 1:33:16may take lot of time also depending on
  1997. 1:33:18the time of the day when you are
  1998. 1:33:20running. So if it is taking lot of time
  1999. 1:33:23you can stop and try at some other time.
  2000. 1:33:25That is how it works.
  2001. 1:33:28And this pipeline it is executed
  2002. 1:33:29successfully. Now we can see the success
  2003. 1:33:32here. It ran for 23 seconds. It it wrote
  2004. 1:33:3689 records in the output. And then uh if
  2005. 1:33:41you click here view in catalog. So then
  2006. 1:33:44it will open a new tab and show us that
  2007. 1:33:47table which is created in the catalog
  2008. 1:33:49directly.
  2009. 1:33:51So this is the table which is created.
  2010. 1:33:53If we go to sample data, we will check
  2011. 1:33:55out some sample data of this table.
  2012. 1:33:59And if I scroll on the left side, so
  2013. 1:34:01this is the icon I was talking about. So
  2014. 1:34:04now because it was created by SDP
  2015. 1:34:07pipeline, so now it is marked as a
  2016. 1:34:09proper streaming table. So datab bricks
  2017. 1:34:12it will also know automatically that it
  2018. 1:34:14is a streaming table and internally it
  2019. 1:34:17is managing its uh checkpoint and all
  2020. 1:34:19the things internally without mentioning
  2021. 1:34:22or doing anything.
  2022. 1:34:24And here we can see the data that has
  2023. 1:34:27has been written into this table. The
  2024. 1:34:29key the value the topic partition offset
  2025. 1:34:34timestamp everything and this is the
  2026. 1:34:36injection timestamp that we had added
  2027. 1:34:38from our site. So now this is how our
  2028. 1:34:42row data looks like and uh next thing
  2029. 1:34:45what we need to do is we need to parse
  2030. 1:34:47this value the JSON value and we need to
  2031. 1:34:51create proper columns so that we can use
  2032. 1:34:53this data properly. So to parse this raw
  2033. 1:34:56data we are going to create our next
  2034. 1:34:59silver layer where we will parse these
  2035. 1:35:01columns and write them into their
  2036. 1:35:03individual columns. So let's go ahead
  2037. 1:35:05and do it. And for that I'm back in our
  2038. 1:35:09pipeline. Here again I will click on
  2039. 1:35:12create and I will create a separate
  2040. 1:35:14folder for silver layer.
  2041. 1:35:19And here we will create again a new
  2042. 1:35:22file.
  2043. 1:35:27And this file we will name it as
  2044. 1:35:29transactions silver
  2045. 1:35:39and now the top part it will be almost
  2046. 1:35:42same. So I'm going to copy it from here
  2047. 1:35:45and then we will use the same here. So
  2048. 1:35:49imports and all we will keep it the
  2049. 1:35:51same. Uh looks like it is gone. Let me
  2050. 1:35:53paste it again.
  2051. 1:35:55And then this time the table name will
  2052. 1:35:57be same but the schema name it will be
  2053. 1:36:00different because we will create it in
  2054. 1:36:01silver layer this time. And the comment
  2055. 1:36:04we will name it as like par
  2056. 1:36:08and cleaned
  2057. 1:36:14transactions
  2058. 1:36:16data
  2059. 1:36:20and this function also we will name it
  2060. 1:36:22as transactions silver
  2061. 1:36:26and in here now we need to write our
  2062. 1:36:28logic. So first of all we will re read
  2063. 1:36:31the bronze table as a streaming table.
  2064. 1:36:34So we will name it as bronze df and then
  2065. 1:36:37we will select spark dot read dot table
  2066. 1:36:43so that it will read the bronze table as
  2067. 1:36:45a streaming table and the name of the
  2068. 1:36:48table. Oh it is guessing automatically.
  2069. 1:36:50So this is the name of our table.
  2070. 1:36:54So this is our bronze streaming data
  2071. 1:36:56frame. Now we will transform it. So we
  2072. 1:37:01will say transformed df equals to this
  2073. 1:37:05bronze df
  2074. 1:37:07and then we will say dot select
  2075. 1:37:13and in the select part we will specify
  2076. 1:37:15multiple things. So first of all we want
  2077. 1:37:18to parse our JSON right. So for that we
  2078. 1:37:21will say that we have imported the
  2079. 1:37:24function as f. So there are multiple
  2080. 1:37:27functions inside the functions. Then we
  2081. 1:37:30will say from JSON and here we need to
  2082. 1:37:33specify the uh column. So we will say
  2083. 1:37:38our column it is value only like it is
  2084. 1:37:40guessing.
  2085. 1:37:45And then we need to specify a schema. So
  2086. 1:37:49for now I will mention only the word
  2087. 1:37:51schema and then we need to give it as a
  2088. 1:37:54alias. we will name it as maybe data
  2089. 1:37:57like it is suggesting. So but before we
  2090. 1:38:00proceed further we need to specify a
  2091. 1:38:03schema. So whenever we are parsing a
  2092. 1:38:06JSON the best practice it is to specify
  2093. 1:38:09a schema. So what we will do is we will
  2094. 1:38:12copy this sample data and then uh we
  2095. 1:38:16will create this schema. So we will do
  2096. 1:38:18it using uh genie code. So here we will
  2097. 1:38:22select this. Then we will press this
  2098. 1:38:25icon and we will say like create the
  2099. 1:38:31schema
  2100. 1:38:32based on the sample
  2101. 1:38:35data this. So we will provide some
  2102. 1:38:38sample data and then we will ask it to
  2103. 1:38:41create that schema for us
  2104. 1:38:44and looks like it is trying to use like
  2105. 1:38:47f schema of JSON. So this sample it has
  2106. 1:38:50provided automatically. And then it is
  2107. 1:38:53asking to derive the schema from this.
  2108. 1:38:56But this is not a best practice. So I'm
  2109. 1:38:59going to reject this change.
  2110. 1:39:01So I pressed escape because that is not
  2111. 1:39:04what we want. So I will say like here
  2112. 1:39:08we will need to be more specific here.
  2113. 1:39:11So we will say that schema
  2114. 1:39:16and then we will say like uh create this
  2115. 1:39:20schema
  2116. 1:39:26is strct type and strruct
  2117. 1:39:31fields from the sample JSON.
  2118. 1:39:35Then the JSON that we had copied let me
  2119. 1:39:38copy it again. So now we are saying like
  2120. 1:39:41created a strct type and strct fields so
  2121. 1:39:44that it will create it in the very
  2122. 1:39:46standard pi spark way. So this time it
  2123. 1:39:50is creating it properly. So I will
  2124. 1:39:52accept this change and now we can see
  2125. 1:39:55that it has created this fstruct type.
  2126. 1:39:58This is the standard way of creating
  2127. 1:40:00schema. Then the field it is creating
  2128. 1:40:03each and every field like it is a
  2129. 1:40:05string. It is these all are string
  2130. 1:40:08amount is a double type. So it has
  2131. 1:40:10specified each and everything and this
  2132. 1:40:13is the standard way of creating schema.
  2133. 1:40:16Now this schema will be put up there. So
  2134. 1:40:19what it will do is it will take the
  2135. 1:40:20value column. It will attach this schema
  2136. 1:40:24and then uh it will point out all these
  2137. 1:40:27columns properly.
  2138. 1:40:29So now what it is doing is it is reading
  2139. 1:40:32this data column is it will create it as
  2140. 1:40:34a kind of dictionary and apart from this
  2141. 1:40:37value and this data column. What other
  2142. 1:40:40things we need is uh this the other
  2143. 1:40:43column for tracking for example the
  2144. 1:40:46Kafka topic partition offset and these
  2145. 1:40:50timestamps. So what we will do is we
  2146. 1:40:52will say that f dot call and then we
  2147. 1:40:57will uh take the column or it is taking
  2148. 1:41:00automatically topic partition offset and
  2149. 1:41:04then we also need to take time stamp.
  2150. 1:41:09So that also it is taking time stamp
  2151. 1:41:11type we don't need it
  2152. 1:41:15and then we had the column like uh
  2153. 1:41:20the injection time stamp. So that is
  2154. 1:41:23something we will take
  2155. 1:41:28and this column we will need to add
  2156. 1:41:30alias so that uh we will give them as
  2157. 1:41:34some meaningful name so that in silver
  2158. 1:41:36layer these are understood properly. So
  2159. 1:41:39instead of topic we will say uh Kafka
  2160. 1:41:42topic
  2161. 1:41:50and instead of simple partition we will
  2162. 1:41:52say Kafka partition
  2163. 1:41:56and instead of offset we will say Kafka.
  2164. 1:42:00So let's see it is able to like suggest
  2165. 1:42:02automatically
  2166. 1:42:12and then uh instead of injection time
  2167. 1:42:14stamp we will name it as bronze
  2168. 1:42:17injection time stamp.
  2169. 1:42:22So this is how we are going to select
  2170. 1:42:23all these columns. Now this data column
  2171. 1:42:26is available as a dictionary but what we
  2172. 1:42:29want is we want each and every value as
  2173. 1:42:32a separate thing. So for that what we
  2174. 1:42:35will do is
  2175. 1:42:38uh so I will press tab for now so that
  2176. 1:42:41it is selecting all the columns and
  2177. 1:42:43returning this d this uh transform df
  2178. 1:42:48and this is how we will return all these
  2179. 1:42:50columns here the data dotstar what it
  2180. 1:42:54means is that whatever fields are there
  2181. 1:42:57with this schema so it will create each
  2182. 1:42:59and every field inside data as a
  2183. 1:43:02separate separate column. So all the
  2184. 1:43:04columns will be extracted and then those
  2185. 1:43:07will be created as separate columns. And
  2186. 1:43:10here we want to also add a uh current
  2187. 1:43:14timestamp.
  2188. 1:43:16So that we will name it as silver
  2189. 1:43:18injection time stamp.
  2190. 1:43:22So this will be additional column. Now
  2191. 1:43:25we are returning this transformed df. So
  2192. 1:43:28this is this df. This transform data is
  2193. 1:43:31being returned as a streaming data frame
  2194. 1:43:34and then this data frame will be
  2195. 1:43:36automatically written into this table
  2196. 1:43:38like we understand how STP works now.
  2197. 1:43:43So now we will try and run this pipeline
  2198. 1:43:46see if it is working as expected. But
  2199. 1:43:49before that we will see that this is the
  2200. 1:43:52mark. So it means like this file is
  2201. 1:43:54excluded from pipeline source code. So
  2202. 1:43:56by default it will not run it. So we
  2203. 1:44:00need to include this. So I will include
  2204. 1:44:02this silver folder itself. So that it is
  2205. 1:44:05included going forward.
  2206. 1:44:08So now it is included and this will also
  2207. 1:44:11run now. So now we will go ahead and run
  2208. 1:44:13our pipeline. So I will click on run
  2209. 1:44:16pipeline.
  2210. 1:44:18And here looks like our pipeline failed
  2211. 1:44:20saying that uh SQL functions has no
  2212. 1:44:24attribute uh strct field. So looks like
  2213. 1:44:27this is a like mistake made by Genie
  2214. 1:44:30code. Sometimes AI can make mistake for
  2215. 1:44:32sure. So what we will do is we will
  2216. 1:44:35import it separately like from pispa
  2217. 1:44:42dossql.types.
  2218. 1:44:45Uh it is saying like import all these.
  2219. 1:44:47So I just pressed tab and it imported
  2220. 1:44:50all these separately automatically. Or
  2221. 1:44:53simply what we can do is we can also
  2222. 1:44:55mention star so that it will import all
  2223. 1:44:58the types but these are not available as
  2224. 1:45:01f dot. So we will need to remove these
  2225. 1:45:07or what we will do is we will simply say
  2226. 1:45:10like uh we will use genie code to remove
  2227. 1:45:12it. We will say like
  2228. 1:45:16remove f dot
  2229. 1:45:21from all places here.
  2230. 1:45:27So here looks like it has removed it but
  2231. 1:45:31the accept button it is gone. So
  2232. 1:45:33sometimes it it may be bit weird that we
  2233. 1:45:36don't see that button button anymore. So
  2234. 1:45:39I will put escape for now. So the
  2235. 1:45:41changes will be ignored. And this time I
  2236. 1:45:44will try not to scroll. So I will do
  2237. 1:45:47control I and I will say remove F dot
  2238. 1:45:52from all places.
  2239. 1:45:58And this time without scrolling I will
  2240. 1:46:00first click on accept so that the
  2241. 1:46:03changes are made. And looks like it is
  2242. 1:46:05it has made the right changes now. And
  2243. 1:46:08before we run the pipeline again, let's
  2244. 1:46:11add one more thing that is about data
  2245. 1:46:13quality which I just forgot. So when we
  2246. 1:46:17use this declarative pipeline, so it
  2247. 1:46:19comes up uh with the uh standard way of
  2248. 1:46:22defining data quality checks. So how do
  2249. 1:46:25we define is either rate DP dot
  2250. 1:46:29expect
  2251. 1:46:31or drop. So this is the standard word we
  2252. 1:46:35use like either this condition shall be
  2253. 1:46:37satisfied or otherwise drop this record.
  2254. 1:46:41So then we name the we give a name to
  2255. 1:46:44the DQ rule saying like transaction ID
  2256. 1:46:48is not null. This is the name it can be
  2257. 1:46:51any name and this is a valid SQL syntax
  2258. 1:46:54as well. So the name we will give it
  2259. 1:46:57maybe before this any other name we will
  2260. 1:47:00name it as like valid
  2261. 1:47:04transaction ID.
  2262. 1:47:07So this is the name of the DQ rule. This
  2263. 1:47:09is the actual rule. So it shall not be
  2264. 1:47:13null. That is the expectation we are
  2265. 1:47:15setting. If it comes anywhere null, it
  2266. 1:47:17will drop that record.
  2267. 1:47:20And this is one type of rule. We can
  2268. 1:47:22define multiple also. For example, oh
  2269. 1:47:25this is putting automatically. So I will
  2270. 1:47:27just press tab and it says valid
  2271. 1:47:30customer ID shall not be null. Card
  2272. 1:47:32number shall not be null. Merchant ID
  2273. 1:47:35shall not be null. And then there there
  2274. 1:47:38is another type of rule as well which
  2275. 1:47:41says like uh it can be either expect or
  2276. 1:47:44drop or only expect and not drop. So we
  2277. 1:47:49don't need to specify anything like not
  2278. 1:47:51drop. uh but if we specify only expect
  2279. 1:47:55it will check it uh and in the output it
  2280. 1:47:58will show that the rule was failed but
  2281. 1:48:00it will not drop this record that is how
  2282. 1:48:03it works. So this is how we define these
  2283. 1:48:05data quality checks and when we run the
  2284. 1:48:08pipeline we will see how the output
  2285. 1:48:10comes and in this rule the rule is valid
  2286. 1:48:13amount and amount shall be greater than
  2287. 1:48:15zero that is the expectation we are
  2288. 1:48:17setting here. So this is additional
  2289. 1:48:20functionality that comes ready to be
  2290. 1:48:22used along with the spark declarative
  2291. 1:48:24pipelines.
  2292. 1:48:26So now as we have defined our dq rules
  2293. 1:48:28and fixed the f dot that error let's run
  2294. 1:48:32the pipeline again.
  2295. 1:48:35So now it has initialized the pipelines
  2296. 1:48:37and looks like there was no syntax error
  2297. 1:48:40and now it we will see two transactions
  2298. 1:48:43here. One for bronze, one for silver. So
  2299. 1:48:46first it is running the bronze one
  2300. 1:48:48because both of these are included in
  2301. 1:48:50this pipeline. So it will always run uh
  2302. 1:48:54every pipeline sorry every table or
  2303. 1:48:56every file that is there. And here we
  2304. 1:48:59can see that when it ran branch so it
  2305. 1:49:02did not write any output record. And why
  2306. 1:49:05is that? Because we already ran it there
  2307. 1:49:08are no new record pushed from our side.
  2308. 1:49:11So that is why it is not coming. And on
  2309. 1:49:14the other hand on silver table it has
  2310. 1:49:16written those 89 records and
  2311. 1:49:19expectations this is the effect of of
  2312. 1:49:22these rules that we had defined. We had
  2313. 1:49:25five rules and it is saying five met. It
  2314. 1:49:28means that all the five rules were met.
  2315. 1:49:30If I click this we see this that 89 100%
  2316. 1:49:35records has been written and all these
  2317. 1:49:38uh
  2318. 1:49:40all these rules has been satisfied.
  2319. 1:49:42There were no failures and this is the
  2320. 1:49:45action it would take if it was there. So
  2321. 1:49:47expect or drop it will drop it and
  2322. 1:49:50amount it will allow it because it was
  2323. 1:49:52only expect and not the drop part. And
  2324. 1:49:56if I close this and if you want to check
  2325. 1:49:58out our table the silver table that has
  2326. 1:50:01been created. So we will click this icon
  2327. 1:50:05here it will open this catalog explorer
  2328. 1:50:08and our silver table. And in our silver
  2329. 1:50:11table we can see all the individual
  2330. 1:50:13columns inside the value piece the JSON
  2331. 1:50:17it has been passed and created as
  2332. 1:50:19individual columns. So now let's check
  2333. 1:50:21out the sample data here. And here we
  2334. 1:50:25can see the silver table. So the data
  2335. 1:50:27has been passed. We have proper separate
  2336. 1:50:30column for each of the data point like
  2337. 1:50:32customer ID, card number, merchant ID,
  2338. 1:50:35name, amount, everything. It is created
  2339. 1:50:38as a separate column here and then these
  2340. 1:50:42Kafka columns has been renamed like we
  2341. 1:50:45did. This is our bronze injection time
  2342. 1:50:47and our silver injection time. So all
  2343. 1:50:50the columns has been created properly.
  2344. 1:50:53And now we can say that bronze and
  2345. 1:50:55silver layer for this Kafka stream has
  2346. 1:50:58been built properly. And now let's try
  2347. 1:51:01to run some incremental data. But this
  2348. 1:51:04time we will run it in continuous mode
  2349. 1:51:07because we are done we have done lot of
  2350. 1:51:10with this triggered mode. Let's see some
  2351. 1:51:12realtime data coming in how it comes. So
  2352. 1:51:15if I click this continuous and click on
  2353. 1:51:18save.
  2354. 1:51:19So this pipeline it will start running
  2355. 1:51:21in continuous mode. Now it will start
  2356. 1:51:24and never stop it until we stop it
  2357. 1:51:27manually or something goes wrong. So
  2358. 1:51:30till then it will keep running. So it is
  2359. 1:51:33currently waiting for resources. In the
  2360. 1:51:36meantime, let me show you this pipeline
  2361. 1:51:38graph. If you click this, we can see
  2362. 1:51:41that automatically it has detected the
  2363. 1:51:43dependency that first it has to run the
  2364. 1:51:46silver sorry bronze uh transaction one
  2365. 1:51:49and then it will run the silver
  2366. 1:51:51transaction one. So due to this
  2367. 1:51:53dependency, it will always run this one
  2368. 1:51:55first then this one.
  2369. 1:51:58And like I was saying in free edition it
  2370. 1:52:00can take time sometimes for waiting for
  2371. 1:52:03the resources. So let me pause it here.
  2372. 1:52:07And looks like it has found the
  2373. 1:52:08resources. It took only around 2
  2374. 1:52:10minutes. Currently it is initializing
  2375. 1:52:13the pipeline. And now it is running.
  2376. 1:52:17So by default it will first run both the
  2377. 1:52:19tables one after the other. And as you
  2378. 1:52:22may guess there is currently no data
  2379. 1:52:25going to the producer. So it will not
  2380. 1:52:27find any new data and it will pause it
  2381. 1:52:30after some time. So now it goes into the
  2382. 1:52:33idle state as there is no data but it
  2383. 1:52:36doesn't mean it has stopped. It is still
  2384. 1:52:38running. So without making any changes
  2385. 1:52:41here let's start producing some data and
  2386. 1:52:44then we will see some realtime data
  2387. 1:52:47flowing in. So I'm running our producer
  2388. 1:52:51script again so that it start pushing
  2389. 1:52:53new data. It has started pushing. And if
  2390. 1:52:56we go back here here now we will see
  2391. 1:52:58that without making any changes it will
  2392. 1:53:01pick up that data automatically from
  2393. 1:53:03that Kafka topic and then it will start
  2394. 1:53:06processing.
  2395. 1:53:08So here it goes automatically it started
  2396. 1:53:10the bronze script first. It has started
  2397. 1:53:13writing output record and then silver
  2398. 1:53:16also it started automatically and we
  2399. 1:53:18will see that the bronze part first it
  2400. 1:53:21is coming here like 100 to 123 then
  2401. 1:53:24those records are going there as a
  2402. 1:53:26batch. So as a micro batches it is
  2403. 1:53:29performing uh the the end to end
  2404. 1:53:32injection of the data. First it is it is
  2405. 1:53:35ingesting into our bronze table then
  2406. 1:53:37into silver table after applying these
  2407. 1:53:40data quality checks and after the
  2408. 1:53:42parsing. So currently this is how the
  2409. 1:53:45real streaming pipeline looks like our
  2410. 1:53:48data it is going in real time. Uh then
  2411. 1:53:52this is being read in real time and it
  2412. 1:53:55is being processed in both the bronze
  2413. 1:53:57and silver layer end to end. And this
  2414. 1:54:00pipeline it will keep running until we
  2415. 1:54:02stop it or we make any change here and
  2416. 1:54:04there.
  2417. 1:54:06So I hope now it gives a better sense
  2418. 1:54:09how the end to end data flow looks like.
  2419. 1:54:13So first of all I will stop our producer
  2420. 1:54:16script and these records that it has put
  2421. 1:54:18up so many records. So it will keep
  2422. 1:54:21processing them and then uh once it has
  2423. 1:54:25processed all those records then it will
  2424. 1:54:28go into idle state. So now after a few
  2425. 1:54:31seconds it has read all those records
  2426. 1:54:33and it is again in the idle state. So
  2427. 1:54:36this is how the end to end streaming
  2428. 1:54:38data looks like. So now I will go ahead
  2429. 1:54:41and stop this pipeline because we don't
  2430. 1:54:44want to keep it running for rest of the
  2431. 1:54:47development. And the trigger type also
  2432. 1:54:49for now we will change it to triggered
  2433. 1:54:52so that we make the changes we add more
  2434. 1:54:55scripts and then we run it whenever we
  2435. 1:54:58want to. So here I would like to take a
  2436. 1:55:01pose and then to to uh add a checkpoint
  2437. 1:55:06right. So what we have done we have set
  2438. 1:55:08up our Kafka topic everything properly.
  2439. 1:55:11Our producer is sending the data in real
  2440. 1:55:14time. We are getting the data in real
  2441. 1:55:16time in bronze and silver layer and
  2442. 1:55:18processing it end to end properly. So
  2443. 1:55:21what I would suggest is that here you
  2444. 1:55:23take a pause you do a hands on on all
  2445. 1:55:27these pieces whatever has been explained
  2446. 1:55:29so far. Once you are comfortable with
  2447. 1:55:31all these pieces then you move on to the
  2448. 1:55:34next part of the demo because that will
  2449. 1:55:36be on top of it. So once you are
  2450. 1:55:40comfortable with these pieces then you
  2451. 1:55:42will be able to understand the next
  2452. 1:55:44pieces better
  2453. 1:55:46and if you are already comfortable until
  2454. 1:55:48here then let's move on. Now let's
  2455. 1:55:51understand first what we are going to
  2456. 1:55:53work on next. So so far we have brought
  2457. 1:55:56in the data from Kafka. We uh tested out
  2458. 1:55:59Spark streaming and then we have built
  2459. 1:56:02bronze and silver layer with Kafka data.
  2460. 1:56:06Now we are going to set up our first
  2461. 1:56:08fraud detection mechanism and for that
  2462. 1:56:12we will take one uh simple example of
  2463. 1:56:15fraud. So for example if our
  2464. 1:56:17transactions are coming so as a customer
  2465. 1:56:20if I have set up a transaction amount
  2466. 1:56:23let's say it is 50k or 100k it is a
  2467. 1:56:26transaction limit in my account and if
  2468. 1:56:29any transaction has been performed more
  2469. 1:56:31than that value that means it is a
  2470. 1:56:33fraud. So that is the fraud we are going
  2471. 1:56:36to detect and for that we will need
  2472. 1:56:38additional data now because our stream
  2473. 1:56:41our current streaming data it is having
  2474. 1:56:44a transaction customer id transaction
  2475. 1:56:46amount and everything but we will need
  2476. 1:56:49the for that given customer what is the
  2477. 1:56:52uh transaction limit that I have set up
  2478. 1:56:54for that kind of data it is not a
  2479. 1:56:56streaming data the customer related data
  2480. 1:56:59that is uh considered as batch data
  2481. 1:57:02because normally that is stored code in
  2482. 1:57:04a postgrace or any other transactional
  2483. 1:57:07system. So now what we are going to do
  2484. 1:57:10is we will prepare our Postgress SQL
  2485. 1:57:13with as a free addition. We will put our
  2486. 1:57:16customer data there. We will ingest that
  2487. 1:57:19data as a batch load using lakeflow
  2488. 1:57:22connect into bronze and then into silver
  2489. 1:57:24layer as well using similar lakeflow
  2490. 1:57:27declarative pipelines and after that we
  2491. 1:57:29will join both this streaming and the
  2492. 1:57:32static data. So we will cover this
  2493. 1:57:34stream static join part and using that
  2494. 1:57:37we will build the gold layer as well as
  2495. 1:57:40we will detect the fraud and then we
  2496. 1:57:43will send the real time alert as a
  2497. 1:57:46email. So this is the piece we are going
  2498. 1:57:48to work on next. So for that let's start
  2499. 1:57:51by setting up our Postgress SQL.
  2500. 1:57:55So for Postgress there are lot of
  2501. 1:57:57different options we can use. Different
  2502. 1:57:59companies they provide their own hosted
  2503. 1:58:01version of postgrace. One of them a good
  2504. 1:58:04one is neon. So I normally prefer this
  2505. 1:58:07one if you follow regularly because here
  2506. 1:58:10the sign up process is simple using
  2507. 1:58:12this. It has been made very simple. So
  2508. 1:58:14if you search for neon postgress this is
  2509. 1:58:17the link that will come. You shall open
  2510. 1:58:19it and do a sign up. Here we don't the
  2511. 1:58:22sign up process is very very simple. We
  2512. 1:58:24just need to uh like login using our
  2513. 1:58:28Gmail account or using our email id. It
  2514. 1:58:30is very straightforward. And once we
  2515. 1:58:33sign up then we will get a login page.
  2516. 1:58:36And after login this is like the
  2517. 1:58:39homepage that we will get. Here we need
  2518. 1:58:41to go to this project section. And in
  2519. 1:58:44here we can uh create a new project. And
  2520. 1:58:47as you can see I'm using the free
  2521. 1:58:48edition currently. So I didn't add any
  2522. 1:58:51credit card or anything. So here we
  2523. 1:58:53simply need to create a new project. We
  2524. 1:58:56will name it as fine guard which is the
  2525. 1:58:58name of our current project. Uh rest of
  2526. 1:59:01it we will leave as default. A region
  2527. 1:59:03maybe we can select whichever is closest
  2528. 1:59:06to our location. So after selecting
  2529. 1:59:08these options we will simply click
  2530. 1:59:10create and our project it will be
  2531. 1:59:13created. A database has been spinning
  2532. 1:59:15up.
  2533. 1:59:17Uh and here you can see that the project
  2534. 1:59:20that we just created has been selected
  2535. 1:59:23and then uh what we need to do is we
  2536. 1:59:26will need to create some table now. So
  2537. 1:59:29we will go to table section and here we
  2538. 1:59:32will see that currently there is no
  2539. 1:59:34table at all. So to create a table we
  2540. 1:59:36will go to SQL editor part
  2541. 1:59:39and to run the SQL query I have created
  2542. 1:59:42two scripts customer historic and
  2543. 1:59:44incremental load. So these scripts also
  2544. 1:59:47these are included in GitHub. So you can
  2545. 1:59:50directly use these. So I will simply
  2546. 1:59:52copy the content and then I will come
  2547. 1:59:55here. I will delete this part and paste
  2548. 1:59:58it and then run it.
  2549. 2:00:01So this has been executed successfully.
  2550. 2:00:04First it dropped the table if it was
  2551. 2:00:06there. It created it inserted,000
  2552. 2:00:09records and it did a commit on those
  2553. 2:00:11records. So now if we simply do select
  2554. 2:00:15star from customers so this table shall
  2555. 2:00:19be there. If we run the query we can see
  2556. 2:00:22that a customer related data has been
  2557. 2:00:24inserted here. Now so customer ID,
  2558. 2:00:27customer name, gender, age, city, there
  2559. 2:00:30are different different details which
  2560. 2:00:32has been added here. The one which we
  2561. 2:00:34are interested in is this transaction
  2562. 2:00:36limit. So for each customer this limit
  2563. 2:00:39has been configured and uh if the actual
  2564. 2:00:43transaction is more than this amount
  2565. 2:00:45then we will send a realtime alert to
  2566. 2:00:48email id of that particular customer. So
  2567. 2:00:52if you see here I have added a static
  2568. 2:00:54email id which is my own email id so
  2569. 2:00:56that I can show the email that is being
  2570. 2:00:59sent. So if you want to you shall uh
  2571. 2:01:01replace this email id in this script. So
  2572. 2:01:04you can simply uh find that email id
  2573. 2:01:07this one and replace it with your own.
  2574. 2:01:10So if I putt ctrl h I can find and
  2575. 2:01:12replace it with anything. So you shall
  2576. 2:01:15use your own email id and amount part
  2577. 2:01:17also currently I I am using this uh 100k
  2578. 2:01:21everywhere because uh like sending some
  2579. 2:01:24fraud transaction is easy while
  2580. 2:01:26generating the data that is why I'm
  2581. 2:01:28keeping it fixed. So now our table is
  2582. 2:01:31ready. If we go to the table section
  2583. 2:01:35then here we will notice our customers
  2584. 2:01:37table has been created. So this is the
  2585. 2:01:40table that we are going to ingest into
  2586. 2:01:42datab bricks. Now for that we will need
  2587. 2:01:45connection details
  2588. 2:01:47and for connection details we need to go
  2589. 2:01:49to settings.
  2590. 2:01:51Uh looks like it is not here. Let me see
  2591. 2:01:55if we go to dashboard. Yes here we can
  2592. 2:01:58see. So if we click on this connect
  2593. 2:02:00option uh we will see this connection
  2594. 2:02:02string. So this contains the details
  2595. 2:02:06that we will need to uh to connect to
  2596. 2:02:10this uh postgress SQL. So I'm going to
  2597. 2:02:12copy this snippet by clicking this
  2598. 2:02:15button. Then I will go to a notepad open
  2599. 2:02:18a new tab and I will paste it. So this
  2600. 2:02:21contains like multiple things that we
  2601. 2:02:23will understand how to use this in datab
  2602. 2:02:26bricks. So now to ingest the data from
  2603. 2:02:28here we will go to datab bricks. So this
  2604. 2:02:32is our datab bricks page and here we
  2605. 2:02:34will go to the jobs and pipeline
  2606. 2:02:37section. First I will duplicate this tab
  2607. 2:02:39so that uh I can still use the current
  2608. 2:02:42tab and here we will go to jobs and
  2609. 2:02:45pipelines.
  2610. 2:02:46And here there are three types of uh
  2611. 2:02:49jobs we can create. So injection
  2612. 2:02:51pipeline is the one we will use now to
  2613. 2:02:53ingest the data. ETL pipeline. This is
  2614. 2:02:56the Spark declarative pipeline that we
  2615. 2:02:58created previously. From here also we
  2616. 2:03:01can create the same. This job it is for
  2617. 2:03:03orchestration running things end to end.
  2618. 2:03:06This one we will use later on. So for
  2619. 2:03:08now I will click on this injection
  2620. 2:03:10pipeline. And here we get all these
  2621. 2:03:13options from all these sources we can
  2622. 2:03:15ingest the data. So the one we are going
  2623. 2:03:18to use is Postgress SQL. So this is the
  2624. 2:03:20one we are going to use.
  2625. 2:03:23So here first of all we are going to
  2626. 2:03:26create a connection and here connection
  2627. 2:03:29name we can provide anything like fine
  2628. 2:03:32guard
  2629. 2:03:33uh postgress
  2630. 2:03:36that is the name I'm going to provide it
  2631. 2:03:39then we need to provide the user
  2632. 2:03:41password and the host name here so for
  2633. 2:03:44that we need to go to this URL and get
  2634. 2:03:47the details so after this double slash
  2635. 2:03:50this neon owner so This is what is our
  2636. 2:03:54username. So this is what I will paste
  2637. 2:03:56here. And after this colon, so this
  2638. 2:04:00colon is not included in any part. And
  2639. 2:04:03before this add the rate, this is our
  2640. 2:04:06password. So I will copy this password.
  2641. 2:04:10And after this 8 the rate
  2642. 2:04:13uh before this neon slash. So this is
  2643. 2:04:16what is our URL. So this thing you can
  2644. 2:04:19maybe take a screenshot and then refer
  2645. 2:04:22and then you can like uh use your own.
  2646. 2:04:25So just remember before colon is the
  2647. 2:04:28username before read the rate is the
  2648. 2:04:30password and before neon db not
  2649. 2:04:33including slash that is our URL. So
  2650. 2:04:36these things I have pasted. Now I will
  2651. 2:04:38simply click on create connection.
  2652. 2:04:42So now my connection is created. It is
  2653. 2:04:44not yet verified. it will be verified in
  2654. 2:04:47the next step. So for now it has been
  2655. 2:04:50selected. I will click on next.
  2656. 2:04:53Now we need to give a name to the
  2657. 2:04:55pipeline and this pipeline we will name
  2658. 2:04:58it as pine guard
  2659. 2:05:01customers
  2660. 2:05:03injection
  2661. 2:05:06and uh
  2662. 2:05:08then we need to select a catalog. Here
  2663. 2:05:10we will simply select our fine guard
  2664. 2:05:13schema also we will select bronze one
  2665. 2:05:15here. This is for like event log. So
  2666. 2:05:18internally it tracks some events. So
  2667. 2:05:20that is what it will do here. Then we
  2668. 2:05:22will click on create pipeline and
  2669. 2:05:24continue.
  2670. 2:05:28So this step it took couple of seconds.
  2671. 2:05:30I had paused the video in the meantime.
  2672. 2:05:32Here we need to provide a database name.
  2673. 2:05:35So database name it is going to be our
  2674. 2:05:38neon db. So I will put it here and click
  2675. 2:05:41on this plus icon. Now it will check in
  2676. 2:05:44this database what all schemas are
  2677. 2:05:46available and then the list of tables.
  2678. 2:05:50So it has these three schemas and if we
  2679. 2:05:52go to our uh Postgress UI there we will
  2680. 2:05:56notice that our customers table it is
  2681. 2:05:59available inside the public schema and
  2682. 2:06:02neon DB is our database. So here if we
  2683. 2:06:05go inside this public one uh this is
  2684. 2:06:08where we will find our customers table.
  2685. 2:06:12So we will select this table. Uh
  2686. 2:06:15destination table name we will keep the
  2687. 2:06:17same. We don't want to change it. Cursor
  2688. 2:06:19column it is for incremental data load.
  2689. 2:06:22So here normally we use timestamp kind
  2690. 2:06:24of column which helps while doing the
  2691. 2:06:27incremental loads.
  2692. 2:06:29So currently it is fetching the list of
  2693. 2:06:31columns from source. So it is taking
  2694. 2:06:33some time. Now it is ready. If you don't
  2695. 2:06:35want incremental load, we can click this
  2696. 2:06:37batch snapshot as well. So that every
  2697. 2:06:40time it will do a full load but we have
  2698. 2:06:43a incremental column. So we will select
  2699. 2:06:45this update time stamp and in the
  2700. 2:06:47primary key we will select customer ID.
  2701. 2:06:50So now our configurations are ready. We
  2702. 2:06:52will click next.
  2703. 2:06:55Here this is the destination selection.
  2704. 2:06:57So in destination we want to create our
  2705. 2:06:59table into bronze schema only. So it is
  2706. 2:07:02already selected. We will click on next.
  2707. 2:07:06And here it is creating a schedule
  2708. 2:07:08automatically. So by default it want to
  2709. 2:07:10run it every 1 hour. We don't want to do
  2710. 2:07:13that. So I will simply delete it. Uh
  2711. 2:07:16because initially we will run it
  2712. 2:07:18manually. Then we will add some
  2713. 2:07:20orchestration. And this is the failure
  2714. 2:07:22notification. So on failure it will send
  2715. 2:07:25an email. We can keep it or delete it if
  2716. 2:07:28we want. And finally we will click on
  2717. 2:07:30save and run pipeline. Once I click it
  2718. 2:07:34then it will create the pipeline
  2719. 2:07:36completely and it will start running it.
  2720. 2:07:39And the running UI it will look similar
  2721. 2:07:41to the spark declarative pipeline UI. It
  2722. 2:07:44is kind of part of that only. So
  2723. 2:07:47currently it is initializing our
  2724. 2:07:49pipeline
  2725. 2:07:50and after it is uh initialization is
  2726. 2:07:53done then it has started our pipeline.
  2727. 2:07:56So it is saying like it is creating some
  2728. 2:07:58staging view and then it is writing to
  2729. 2:08:01our customers table.
  2730. 2:08:03Now the execution it is complete. So it
  2731. 2:08:06has been completed successfully. So I
  2732. 2:08:09will click here this icon to see the
  2733. 2:08:12table.
  2734. 2:08:16So this is our table and let's check out
  2735. 2:08:18some sample data here.
  2736. 2:08:21So this is how the data looks. All our
  2737. 2:08:23data has been loaded as it is from
  2738. 2:08:26source to this particular table.
  2739. 2:08:30So as we have loaded historical data now
  2740. 2:08:32let's try out some incremental data as
  2741. 2:08:35well. And for that I have created a
  2742. 2:08:37separate script. So this script it is
  2743. 2:08:40going to insert two new records with
  2744. 2:08:42customer ID 101 and 102 and the customer
  2745. 2:08:47ID 1 that is what it is going to update.
  2746. 2:08:50So this person with this customer ID. So
  2747. 2:08:54his current entry it is uh like it is in
  2748. 2:08:57Mumbai and Maharashtra and this is the
  2749. 2:09:00annual income and with this new entry it
  2750. 2:09:03is going to move from Mumbai to
  2751. 2:09:07Bangaluru and the salary it is going to
  2752. 2:09:09increase. So we are going to promote uh
  2753. 2:09:12this person.
  2754. 2:09:14So I'm going to copy this entire script.
  2755. 2:09:17Then we will go to our postgress.
  2756. 2:09:20There I will paste this script and
  2757. 2:09:23simply run it.
  2758. 2:09:25So now those records has been updated.
  2759. 2:09:29And now we will run our injection
  2760. 2:09:31pipeline again. So here is our pipeline.
  2761. 2:09:34I'm going to simply start it again.
  2762. 2:09:39So now as it is completed, we will go to
  2763. 2:09:41our customers table and we will simply
  2764. 2:09:44refresh this.
  2765. 2:09:45So now we will see that the customer ID
  2766. 2:09:481 is not visible here. It is because it
  2767. 2:09:51is probably updated and here it will
  2768. 2:09:53show only 100 records. So to confirm the
  2769. 2:09:57data we will have to query it in a
  2770. 2:09:59notebook. So we will go to our project
  2771. 2:10:01folder and here let me create a test
  2772. 2:10:04notebook.
  2773. 2:10:06And now let's try to query our table. So
  2774. 2:10:10we will do SQL
  2775. 2:10:14select star from this table.
  2776. 2:10:22So here is our data and if you see so
  2777. 2:10:25now it has,02 record two additional rows
  2778. 2:10:28has been inserted and one has been
  2779. 2:10:30updated. So if we sort by customer ID
  2780. 2:10:33for customer ID 1, we see that the city
  2781. 2:10:36has been changed to Bangaluru and the
  2782. 2:10:38income has also been updated. So this
  2783. 2:10:41row has been updated with the new data.
  2784. 2:10:44And if we do the descending order, so
  2785. 2:10:46these two ids are the new ids which we
  2786. 2:10:49inserted. So these are also inserted
  2787. 2:10:51into our table. So this is how
  2788. 2:10:54incremental load it is made very simple
  2789. 2:10:57uh using lakeflow connect. And here we
  2790. 2:11:00did not have to write any additional
  2791. 2:11:02code. We just selected the primary key
  2792. 2:11:04and the watermark or timestamp column
  2793. 2:11:07and automatically it is able to take
  2794. 2:11:09care of everything.
  2795. 2:11:11So now revisiting our architecture. So
  2796. 2:11:14we have now set up a postgra SQL in
  2797. 2:11:17neon. We used the lakeflow connect. So
  2798. 2:11:20the injection pipeline that we created
  2799. 2:11:23the technical term for datab bricks in
  2800. 2:11:25that is that is called as lakeflow
  2801. 2:11:26connect. we use used that and then we
  2802. 2:11:30have now brought in our customers table
  2803. 2:11:32to the bronze layer. So now is the time
  2804. 2:11:35to bring that table to silver layer. So
  2805. 2:11:38let's go ahead and do that. So next what
  2806. 2:11:42we are going to do is we are going to
  2807. 2:11:43load our customers table into silver
  2808. 2:11:46layer and that we will do using the
  2809. 2:11:49spark declarative pipeline only. So here
  2810. 2:11:52one option is that in this pipeline
  2811. 2:11:54itself our original streaming pipeline
  2812. 2:11:57we can add it but we we do not want to
  2813. 2:12:00run uh that silver injection and that uh
  2814. 2:12:03customer's injection piece continuously
  2815. 2:12:06when we run the streaming injection that
  2816. 2:12:08process will be running as a batch
  2817. 2:12:10process. So that is why we will not
  2818. 2:12:13create that within this pipeline and we
  2819. 2:12:16will create a small separate pipeline
  2820. 2:12:18for that. So I'm going to duplicate this
  2821. 2:12:21uh tab and in here I will go back to our
  2822. 2:12:25old files. So this is the folder for
  2823. 2:12:28fine guard streaming that we we are
  2824. 2:12:30already using. So here we will create a
  2825. 2:12:33new ETL pipeline
  2826. 2:12:36and this pipeline we are going to name
  2827. 2:12:39it as
  2828. 2:12:40uh maybe fine guard uh
  2829. 2:12:48customers
  2830. 2:12:50uh silver load because this is what we
  2831. 2:12:52will be doing here. So this is the name
  2832. 2:12:55we have given.
  2833. 2:12:58So looks like I already have a pipeline
  2834. 2:13:00with this name. So in my case I will put
  2835. 2:13:03a two here.
  2836. 2:13:07So uh this is our folder. So this folder
  2837. 2:13:10also we will rename it
  2838. 2:13:22customer silver load
  2839. 2:13:31and then this transformation folder we
  2840. 2:13:34will rename it as silver like we follow
  2841. 2:13:36the standards
  2842. 2:13:38and this This is the default file which
  2843. 2:13:40is created. So this one also we will uh
  2844. 2:13:43rename it to customers silver.
  2845. 2:13:53So this is where we now we will write
  2846. 2:13:55the code for silver load of customers
  2847. 2:13:57table.
  2848. 2:13:59And for the code piece we will copy our
  2849. 2:14:01code from our previous uh transaction
  2850. 2:14:04table. So this is the entire [music]
  2851. 2:14:06code. I will copy it from here
  2852. 2:14:10and then I will paste the same into the
  2853. 2:14:13pipeline that we are building. So this
  2854. 2:14:15time we won't need all these things
  2855. 2:14:17because it is going to be simple silver
  2856. 2:14:20load. So we will only need this uh DP
  2857. 2:14:24and the functions as F and the table
  2858. 2:14:27name it is going to be customers in
  2859. 2:14:29silver layer and then comment it can be
  2860. 2:14:32like passed and cleaned uh customers
  2861. 2:14:34data we can say
  2862. 2:14:38and in terms of uh data quality rule we
  2863. 2:14:41can say like valid customer ID
  2864. 2:14:46and then customer ID shall not be null.
  2865. 2:14:49So I will simply press a tab. So
  2866. 2:14:52transactions one it is not required. And
  2867. 2:14:55now we will write our main function. So
  2868. 2:14:58the function name it can be the same
  2869. 2:15:01customer silver.
  2870. 2:15:04And this it returns a data frame
  2871. 2:15:11and this data frame we have not yet
  2872. 2:15:13imported. So let's import that.
  2873. 2:15:19So it is suggesting it came
  2874. 2:15:20automatically and here we can write our
  2875. 2:15:23code. So we can say like branch df. So
  2876. 2:15:28here we will read our branch table. So
  2877. 2:15:31spark dot readstream
  2878. 2:15:35dot table and the table name it will be
  2879. 2:15:39our pine guard bronze and customers. And
  2880. 2:15:42here one thing to notice is that even
  2881. 2:15:44though this customers table we will be
  2882. 2:15:46using as a batch load but here we will
  2883. 2:15:49be reading it as a streaming table and
  2884. 2:15:52this why we are doing so that the
  2885. 2:15:54incremental part and all can be taken
  2886. 2:15:56care automatically for by this streaming
  2887. 2:15:59properties. So we will be running it in
  2888. 2:16:01a batch mode like once a day or
  2889. 2:16:03something. But uh to use those like
  2890. 2:16:05incremental capabilities and this uh
  2891. 2:16:08declarative pipelines here we will be
  2892. 2:16:10reading it kind of a streaming table.
  2893. 2:16:13And if you notice the customers table
  2894. 2:16:15that was created automatically. So the
  2895. 2:16:17type of that table also is streaming
  2896. 2:16:20table even though we loaded it in a
  2897. 2:16:23batch mode. So that is how things work
  2898. 2:16:25in datab bricks. So now our data frame
  2899. 2:16:28is ready and uh then like now we will do
  2900. 2:16:33some very basic transformation.
  2901. 2:16:35So we will call it as transform df
  2902. 2:16:39and then we will select the required
  2903. 2:16:41columns or like we will need all the
  2904. 2:16:43columns. So then we will write the
  2905. 2:16:46select statement here and in the select
  2906. 2:16:48we will be writing multiple columns. So
  2907. 2:16:51the first one obviously it is customer
  2908. 2:16:53id. So we will say f dot column and then
  2909. 2:16:57we need to specify customer id
  2910. 2:17:03and here the hint that it is providing
  2911. 2:17:05so it doesn't know for sure that these
  2912. 2:17:08are real columns it is providing them uh
  2913. 2:17:10just like whatever normal columns can be
  2914. 2:17:13there in a customer table. So be careful
  2915. 2:17:15we will need to provide the actual
  2916. 2:17:17column names only.
  2917. 2:17:23So here what we will do is because
  2918. 2:17:25typing all the columns is very boring.
  2919. 2:17:28So let's use genie code here to help us
  2920. 2:17:31out. So I'm copying this branch table
  2921. 2:17:34name. From this right side I will open
  2922. 2:17:36genie code
  2923. 2:17:39and then I will start a new thread. This
  2924. 2:17:42is where we start a new chat. And we
  2925. 2:17:44will say like in this file read all
  2926. 2:17:48columns from this table.
  2927. 2:17:51And here what we are going to do is we
  2928. 2:17:53we need all the columns as it is only
  2929. 2:17:56two small changes we will be doing. So
  2930. 2:17:59the first change it will be about the uh
  2931. 2:18:02date column. So the column that is here
  2932. 2:18:05account opening date. This is coming by
  2933. 2:18:08default as a vare which is a kind of
  2934. 2:18:10string. So this string we will convert
  2935. 2:18:13it to a actual date. And then what we
  2936. 2:18:16will do is we will add a new column also
  2937. 2:18:18that will be our silver injection time
  2938. 2:18:21stamp that will be current time stamp.
  2939. 2:18:23So only these two changes we will need.
  2940. 2:18:25So the same thing we will tell to this
  2941. 2:18:27genie code. So now here I will press alt
  2942. 2:18:31and then enter so that it it comes as a
  2943. 2:18:34new line. So then we will say first like
  2944. 2:18:37uh we will say that account open
  2945. 2:18:41date column shall be converted from
  2946. 2:18:46string to date and then we will say a
  2947. 2:18:50new column
  2948. 2:18:52uh silver
  2949. 2:18:54injection timestamp
  2950. 2:18:58shall be added as a new column.
  2951. 2:19:04And then third point we will say like
  2952. 2:19:06keep uh rest of
  2953. 2:19:10all columns as it is. So this is the
  2954. 2:19:14instruction we are giving. So based on
  2955. 2:19:16this it will uh do everything
  2956. 2:19:18automatically. Otherwise we would have
  2957. 2:19:20to copy paste it copy paste all the
  2958. 2:19:23column names. So that we don't want to
  2959. 2:19:25do. It is a very repetitive task.
  2960. 2:19:29So now it is thinking what it needs to
  2961. 2:19:31do and it is reading the table structure
  2962. 2:19:34of our branch table and then it will
  2963. 2:19:36decide what to do. And now it is trying
  2964. 2:19:39to make the changes to this file the
  2965. 2:19:42file which is currently open. And here
  2966. 2:19:44we can see that it has made all the
  2967. 2:19:47changes.
  2968. 2:19:49Uh so I will accept this.
  2969. 2:19:53Let me accept this.
  2970. 2:19:55And here let's have a quick look. So we
  2971. 2:19:58see all these columns are being taken
  2972. 2:20:00automatically as it is without any
  2973. 2:20:02change
  2974. 2:20:04and while I'm checking it is trying to
  2975. 2:20:07uh do a dry run automatically. So I will
  2976. 2:20:10stop it for now because I noticed one
  2977. 2:20:12thing. So let me uh okay it is still
  2978. 2:20:16cancelling I think. I click this stop
  2979. 2:20:18button and the thing I noticed is this
  2980. 2:20:21uh date conversion. So rest of the
  2981. 2:20:24columns it is taking as it is and it is
  2982. 2:20:27adding a new column as the current
  2983. 2:20:29timestamp also. But this date it seems
  2984. 2:20:32like it is not converting it properly.
  2985. 2:20:35It is just doing like alias and then to
  2986. 2:20:37date probably it has not checked the
  2987. 2:20:40data in which format the data is there.
  2988. 2:20:43So I I will copy this and then I will
  2989. 2:20:46select this line here and then press
  2990. 2:20:48this icon or I can use this shortcut
  2991. 2:20:51also that you see above control I. So
  2992. 2:20:54here I will tell that
  2993. 2:20:57uh this column
  2994. 2:21:02is in format this format change it
  2995. 2:21:06properly.
  2996. 2:21:10So now it has explicitly specified uh
  2997. 2:21:13how exactly it is going to convert. But
  2998. 2:21:16when we use genie from here it is kind
  2999. 2:21:18of a tricky like now if you scroll the
  3000. 2:21:21accept button is gone again. I there is
  3001. 2:21:24no way to accept this change. So if I
  3002. 2:21:27press escape then like uh the it is uh
  3003. 2:21:31undone. So I will ask it to do the same
  3004. 2:21:33thing here
  3005. 2:21:36like this column
  3006. 2:21:38is in
  3007. 2:21:40the format.
  3008. 2:21:42I lost the format. Let me copy again. So
  3009. 2:21:46this format
  3010. 2:21:49convert it properly.
  3011. 2:21:53So now it has made the same change. So
  3012. 2:21:56this time like if I scroll this accept
  3013. 2:21:58button doesn't go away. So it is a good
  3014. 2:22:01thing. And again it is trying to do a
  3015. 2:22:03dry run. Maybe we will let it do this
  3016. 2:22:05time. So this change I will accept it
  3017. 2:22:08because now it is looking good. And here
  3018. 2:22:11we can see that the dry run it is
  3019. 2:22:12successful. And whenever it does a dry
  3020. 2:22:15run it is like it will not load the
  3021. 2:22:18actual data. It will just try to run it
  3022. 2:22:20if everything looks good. There is no
  3023. 2:22:22syntax error. Those kind of things it
  3024. 2:22:24does. So that confirms that coding wise
  3025. 2:22:26there is no problem. And this dry run if
  3026. 2:22:30we want we can also do it from here. If
  3027. 2:22:32you click this button we can also do a
  3028. 2:22:34dry run.
  3029. 2:22:36And now it is just trying to remove one
  3030. 2:22:38space. So I will let it do it. It is
  3031. 2:22:41again trying to do a dry run. So let me
  3032. 2:22:45stop this time. So I will click this
  3033. 2:22:48stop here. I will stop this also because
  3034. 2:22:50we don't need this help anymore. So now
  3035. 2:22:53we are going to go ahead and run this
  3036. 2:22:55pipeline.
  3037. 2:22:57So it it is asking again for the default
  3038. 2:23:00catalog and the schema. So we will
  3039. 2:23:03select the same pine guard and then this
  3040. 2:23:06time we can select silver or bronze. So
  3041. 2:23:08this part it doesn't really matter
  3042. 2:23:10because in our code we have mentioned
  3043. 2:23:13the exact table name full name but we
  3044. 2:23:16need to select some default one that is
  3045. 2:23:18how it works.
  3046. 2:23:20So now it is actually trying to run the
  3047. 2:23:23pipeline and then load the data and
  3048. 2:23:26looks like it failed this time. It is
  3049. 2:23:28saying like cannot move tables across
  3050. 2:23:31arite catalog. So this error it is
  3051. 2:23:33strange sometimes I get it. So let's see
  3052. 2:23:36if this diagnose error it is able to fix
  3053. 2:23:38it or we will find some work around. So
  3054. 2:23:42it is trying to do some things like it
  3055. 2:23:44is trying to suggest to remove this
  3056. 2:23:47catalog and schema name which it it did
  3057. 2:23:49not work and it is trying to try out
  3058. 2:23:51different things. For now I will reject
  3059. 2:23:54this change
  3060. 2:23:56and then it is suggesting some options
  3061. 2:23:58here and there. So I will stop it
  3062. 2:24:00because this error it is strange. Uh
  3063. 2:24:02previously also I encounter one
  3064. 2:24:04encountered one time. If you have not
  3065. 2:24:07encountered that is totally fine. But if
  3066. 2:24:10you have encountered this so uh directly
  3067. 2:24:13here we cannot fix this one. I tried
  3068. 2:24:15previously also. So I what I will do is
  3069. 2:24:18I will copy this entire code and we will
  3070. 2:24:21just create a new pipeline. That is what
  3071. 2:24:23we will give it a try. So I will go to
  3072. 2:24:26this old files and this is our existing
  3073. 2:24:29f existing uh folder name. So here we
  3074. 2:24:33will create a new ETL pipeline. So we
  3075. 2:24:37will go ahead and create a new ETL
  3076. 2:24:39pipeline here
  3077. 2:24:41and let me close this right side.
  3078. 2:24:46So for now we will not rename anything.
  3079. 2:24:48We will keep everything as it is. Simply
  3080. 2:24:51let me paste our code here and let's
  3081. 2:24:54give it a try. Let's directly run this
  3082. 2:24:56pipeline. And it is asking for a
  3083. 2:24:59workspace and schema here. So again
  3084. 2:25:02let's select our fine guard
  3085. 2:25:07and this time let's give it a try for
  3086. 2:25:09brunch because we are reading the data
  3087. 2:25:11from brunch.
  3088. 2:25:13So now the pipeline has been started. It
  3089. 2:25:16is waiting for the resources
  3090. 2:25:19and it has set up the tables and now it
  3091. 2:25:22has started the injection process. So
  3092. 2:25:24like I was telling that error it is very
  3093. 2:25:26strange probably you won't get it but
  3094. 2:25:29you if you get it you simply create a
  3095. 2:25:31new pipeline and just paste your code
  3096. 2:25:33that is a workar around that I have
  3097. 2:25:35found so the injection it is complete
  3098. 2:25:38now and as you noticed the only change
  3099. 2:25:40was that this time we selected branch uh
  3100. 2:25:43so let's check if that is really a fix
  3101. 2:25:46let me open our old pipeline from here
  3102. 2:25:49once and let's change this one to branch
  3103. 2:25:52launch
  3104. 2:25:57and now let's give it a try just to
  3105. 2:25:59confirm if that is the real solution.
  3106. 2:26:04So this time also it failed. So like I
  3107. 2:26:07was doubting this is some internal error
  3108. 2:26:09in datab bricks. Maybe they will fix it
  3109. 2:26:12later on or it could be in free edition.
  3110. 2:26:14Maybe in actual datab bricks I have not
  3111. 2:26:16seen this. Uh but anyway it doesn't
  3112. 2:26:19matter much to us. So what it means is
  3113. 2:26:21that our code is working fine. It is
  3114. 2:26:24just that uh we just created a clone of
  3115. 2:26:28the pipeline and there it worked fine.
  3116. 2:26:30So now we know like this is the pipeline
  3117. 2:26:33that is working and this is the folder
  3118. 2:26:35where it did not work. So this one we
  3119. 2:26:38will move it to trash
  3120. 2:26:41and this one we will rename it. So now
  3121. 2:26:44let's give it proper naming.
  3122. 2:26:48So let me open it again. So now it will
  3123. 2:26:51become our fine
  3124. 2:26:55pine guard
  3125. 2:26:58customers
  3126. 2:27:00silver
  3127. 2:27:03injection
  3128. 2:27:05and then two because I have some other
  3129. 2:27:08pipeline with that name and this folder
  3130. 2:27:11also let me give it the same name.
  3131. 2:27:15So I will go here. I will rename this
  3132. 2:27:19root folder
  3133. 2:27:22and it is done.
  3134. 2:27:26And this piece also let's rename it.
  3135. 2:27:29This renaming is not that important but
  3136. 2:27:31just to maintain the standards uh let's
  3137. 2:27:34do that.
  3138. 2:27:39so this one also we will rename it to uh
  3139. 2:27:42customers.
  3140. 2:27:50So now our pipeline is uh finally ready
  3141. 2:27:54and we had already run it. The data was
  3142. 2:27:57loaded properly. So let's check out the
  3143. 2:27:59data. Now
  3144. 2:28:02it is open. Let's check out some sample
  3145. 2:28:05data.
  3146. 2:28:07And here we can see the sample data. So
  3147. 2:28:10if we look at the account open date it
  3148. 2:28:13is now a proper date column
  3149. 2:28:16and then rest of the things looks good.
  3150. 2:28:18We have our silver injection time stamp
  3151. 2:28:20as well. So now this table it is there
  3152. 2:28:23in silver layer and ready to be used. So
  3153. 2:28:26if we come back to our architecture
  3154. 2:28:29so our table is there in silver layer.
  3155. 2:28:32So now we are going to join this
  3156. 2:28:34customer's table with the transaction
  3157. 2:28:36data that was coming from Kafka. So this
  3158. 2:28:39Kafka transaction data is streaming
  3159. 2:28:41data. Our customers table it is the
  3160. 2:28:43static table. It it is not streaming. So
  3161. 2:28:46we will join this that is why we call it
  3162. 2:28:48a stream static join. And then we will
  3163. 2:28:51build a gold layer with the fraud
  3164. 2:28:53detection and then send realtime email
  3165. 2:28:56alerts. So let's work on that piece. So
  3166. 2:29:00now I'm back in our uh streaming
  3167. 2:29:04pipeline. So the goal layer we will
  3168. 2:29:06create it in the streaming part because
  3169. 2:29:08it it will be streaming data note the
  3170. 2:29:10static data. So for that we will create
  3171. 2:29:13a new folder first with the name gold.
  3172. 2:29:16And then inside there we will create a
  3173. 2:29:19file.
  3174. 2:29:25And this file we are going to name it
  3175. 2:29:30uh high
  3176. 2:29:33value value
  3177. 2:29:35transactions
  3178. 2:29:37alert because it will be used to send
  3179. 2:29:40alert for the transactions where the
  3180. 2:29:43value is higher than what is configured
  3181. 2:29:45by customer. So for this we will start
  3182. 2:29:49again with by copying the core stuff
  3183. 2:29:55and this time also we will not need lot
  3184. 2:29:58of stuff. So we will only need these
  3185. 2:30:01three. So let me remove these other
  3186. 2:30:03things. And the table it will be created
  3187. 2:30:06this time in the gold schema. And the
  3188. 2:30:09table name we will keep it as same as
  3189. 2:30:12our file name. So let me copy it from
  3190. 2:30:15here only.
  3191. 2:30:20So this will be our table name. And then
  3192. 2:30:24here we will say that uh
  3193. 2:30:28uh we can say alert details where
  3194. 2:30:34uh transaction has been performed
  3195. 2:30:41with value
  3196. 2:30:43higher than
  3197. 2:30:47what is
  3198. 2:30:51configured by customer.
  3199. 2:30:54So with this this is our target table
  3200. 2:30:57and now we will define our function. We
  3201. 2:31:00will give it the same name and this
  3202. 2:31:03function it will uh return a data frame.
  3203. 2:31:13So here we will start by reading our
  3204. 2:31:16tables. So first we will read our
  3205. 2:31:18transactions table. So that will be
  3206. 2:31:21spark dot read
  3207. 2:31:26dot table. So it is giving some
  3208. 2:31:28suggestion. I will press tab. I only
  3209. 2:31:31need this table for now. And then we
  3210. 2:31:34will read our customers table. So that
  3211. 2:31:38is our spark dot read. This time we
  3212. 2:31:41don't need to read that customer's table
  3213. 2:31:44as streaming table. We need it to read
  3214. 2:31:47it as a normal table. So that is why we
  3215. 2:31:50are saying read dot table. And this
  3216. 2:31:53piece it is actually very important
  3217. 2:31:56because uh joining a streaming table and
  3218. 2:31:59another streaming table we need to add
  3219. 2:32:01some additional details that we will see
  3220. 2:32:04when we will join the transactions with
  3221. 2:32:06the streaming data coming from files.
  3222. 2:32:09But uh the joining a streaming data with
  3223. 2:32:12a static data that is relatively
  3224. 2:32:14simpler. So using this keyword read and
  3225. 2:32:17not read stream that is very important.
  3226. 2:32:20So this customer table it is our static
  3227. 2:32:23table and transactions table is our
  3228. 2:32:25streaming table. So next thing we are
  3229. 2:32:28going to do is join them. So we will say
  3230. 2:32:32joined df equal to
  3231. 2:32:36uh so it is doing some suggestion
  3232. 2:32:38automatically.
  3233. 2:32:40So I will press tab for now and then I
  3234. 2:32:43will remove these extra lines. So here
  3235. 2:32:46it is saying that we can join the
  3236. 2:32:48transactions and customers
  3237. 2:32:50based on their customer ID. So this
  3238. 2:32:53piece it is fine but there is one more
  3239. 2:32:56thing we need to add here. So by default
  3240. 2:32:59any join it is a inner join and we can't
  3241. 2:33:02do directly a inner join of a stream
  3242. 2:33:05table and a static table because
  3243. 2:33:07streaming data it is streaming data
  3244. 2:33:09right it is continuously coming so we
  3245. 2:33:12don't know like after a few seconds the
  3246. 2:33:14record may come which is there in
  3247. 2:33:16customers table that is why by default
  3248. 2:33:18we never do a inner join with the like
  3249. 2:33:22on a streaming table so there is there
  3250. 2:33:25are ways to do it but uh whenever we
  3251. 2:33:27join between a stream and static table
  3252. 2:33:30we directly use a left join. So why we
  3253. 2:33:34do that? So that every record that is
  3254. 2:33:37coming in transaction that record is
  3255. 2:33:40being done as a left join in customers.
  3256. 2:33:42So for whatever transaction is coming
  3257. 2:33:45for every transaction it will check if
  3258. 2:33:47there is a record in customers or not
  3259. 2:33:50and vice versa it doesn't have to check
  3260. 2:33:52that is why we use left join here and
  3261. 2:33:55then we will apply a filter to identify
  3262. 2:33:58if it is a it is like more than the
  3263. 2:34:01limit. So for that we will say dot
  3264. 2:34:04filter and then we will mention that it
  3265. 2:34:07is f dot column to mention the column
  3266. 2:34:11name. So the column for amount it is
  3267. 2:34:14amount and then it is greater than f dot
  3268. 2:34:18column the column for transaction limit
  3269. 2:34:22it is the transaction limit. So this
  3270. 2:34:25column it is there in the transactions
  3271. 2:34:28table. Uh and this column it is there in
  3272. 2:34:30our customers table. So that is how is
  3273. 2:34:33combination now it is able to figure out
  3274. 2:34:36that the transactions where the amount
  3275. 2:34:39is more than what is currently
  3276. 2:34:41configured by customer. So it becomes a
  3277. 2:34:44fraud and this fraud it is detected by
  3278. 2:34:48this join and then it will be detected
  3279. 2:34:51in real time and then this
  3280. 2:34:53[clears throat] fraud it will be marked
  3281. 2:34:55and stored into our gold table. So to
  3282. 2:34:58store this data into gold table we need
  3283. 2:35:01to specify the columns that we need
  3284. 2:35:03there in our gold table and in the
  3285. 2:35:06select we will have multiple columns. So
  3286. 2:35:09we will type it inside these brackets.
  3287. 2:35:12So the first column we want to create is
  3288. 2:35:14a alert type. So for that what we will
  3289. 2:35:17do is so we will concat things. So for
  3290. 2:35:21that we have a function uh concat ws and
  3291. 2:35:26in here we will concat like a dash and
  3292. 2:35:30there what we want to concat is uh like
  3293. 2:35:34f dot uh lit lit it means like whatever
  3294. 2:35:38we specify that same string will be uh
  3295. 2:35:43will be done there. So now it is saying
  3296. 2:35:46that we can add transaction ID and
  3297. 2:35:48generate an alert ID. So I will press
  3298. 2:35:51tab here and delete this piece for now.
  3299. 2:35:54So now what it will do is it will like
  3300. 2:35:57wherever we see this lit lit it means
  3301. 2:36:00this alert this is a keyword that will
  3302. 2:36:02be taken as it is. So it will be alert
  3303. 2:36:04dash the transaction ID and the name of
  3304. 2:36:08that column alert- transaction ID will
  3305. 2:36:10be alert ID. So this will become our
  3306. 2:36:13alert ID. now and then we also need to
  3307. 2:36:17mention a column for alert type. So we
  3308. 2:36:20will say f dot lit and then we will say
  3309. 2:36:24like high value transaction. So it is
  3310. 2:36:27suggesting automatically. So I will
  3311. 2:36:29press tab otherwise we can type it. So
  3312. 2:36:32there will be a column alert type which
  3313. 2:36:34will always say high value transaction.
  3314. 2:36:37It is for future use if you want to add
  3315. 2:36:39more alert types into the same table.
  3316. 2:36:42And then the next thing that we want is
  3317. 2:36:44alert timestamp. So we will say like f
  3318. 2:36:48dot current timestamp and it is saying
  3319. 2:36:50itself it can be there as a alert
  3320. 2:36:53timestamp.
  3321. 2:36:55So current time stamp it will be added
  3322. 2:36:57as a alert time stamp and after that we
  3323. 2:37:00will bring in our id columns
  3324. 2:37:05and for that we will not use this f. We
  3325. 2:37:07will simply say like transactions dot uh
  3326. 2:37:12transaction id
  3327. 2:37:17and then we also want the customer id.
  3328. 2:37:20So we will say transactions dot customer
  3329. 2:37:24ID
  3330. 2:37:26and this why we are mentioning this dot.
  3331. 2:37:29So because for example customer ID is
  3332. 2:37:31there on both the tables. So it shall
  3333. 2:37:34take it from transaction and it will not
  3334. 2:37:36throw an error that it is ambiguous or
  3335. 2:37:38something. And next what we want is the
  3336. 2:37:41email id. So customers table that has a
  3337. 2:37:44column email like I showed you
  3338. 2:37:46previously that we want it as an alias
  3339. 2:37:50saying like customer email. So it is
  3340. 2:37:53more like meaningful that means like it
  3341. 2:37:56is the uh email id and this email id it
  3342. 2:38:00belongs to a customer.
  3343. 2:38:02And then I will press a tab here and
  3344. 2:38:05transaction amount I need it here. But
  3345. 2:38:09before that I need the the name of the
  3346. 2:38:12customer as well. So for that uh the
  3347. 2:38:15customer table it it contains the name
  3348. 2:38:18is first name and last name. So we are
  3349. 2:38:21concaten concatenating them and putting
  3350. 2:38:24a space in between them that will be
  3351. 2:38:27called as customer name. And then we
  3352. 2:38:30have transaction amount. So we need the
  3353. 2:38:33transaction limit as well that is there
  3354. 2:38:35in our uh customers table.
  3355. 2:38:40So transaction limit it has been
  3356. 2:38:42selected the alias here even if we
  3357. 2:38:44delete it it doesn't matter because the
  3358. 2:38:47name is same only and after the
  3359. 2:38:50transaction limit we need the
  3360. 2:38:52transaction currency. So transactions
  3361. 2:38:55dot currency
  3362. 2:38:59and then we need columns like
  3363. 2:39:03transactions dot merchant name so that
  3364. 2:39:06we can know where it has been
  3365. 2:39:08transaction has been performed and then
  3366. 2:39:11we have a merchant category as well. So
  3367. 2:39:15that also we will brought in here
  3368. 2:39:20and then we will need some other
  3369. 2:39:22columns. So let me just copy paste this
  3370. 2:39:25so that this transactions part I don't
  3371. 2:39:27have to type manually and looks like
  3372. 2:39:30intentionally I hit some run shortcut.
  3373. 2:39:32So it is throwing that error for now. We
  3374. 2:39:35will ignore it.
  3375. 2:39:40So the next column it will be
  3376. 2:39:43transaction type
  3377. 2:39:46then it will be payment
  3378. 2:39:49channel and then it will be city
  3379. 2:39:53then country
  3380. 2:39:55and then we will have a column like
  3381. 2:39:57whether it is is international.
  3382. 2:40:00So that is also very important
  3383. 2:40:04and then we will need two more columns.
  3384. 2:40:08So one will be transaction timestamp
  3385. 2:40:17and another one it will be status. So
  3386. 2:40:20these are all the columns that we will
  3387. 2:40:22keep into our gold table so that we can
  3388. 2:40:26use them while sending alerts.
  3389. 2:40:29So let me delete this extra space.
  3390. 2:40:33And here I noticed that we had a
  3391. 2:40:35transaction date. So we don't need a
  3392. 2:40:37date because we have a time stamp. So
  3393. 2:40:39I'm going to delete that piece.
  3394. 2:40:42And then all these pieces whatever is in
  3395. 2:40:45the joined df let me put this into a
  3396. 2:40:48bracket so that it is it is it knows
  3397. 2:40:51like these are the next lines and
  3398. 2:40:53everything
  3399. 2:40:56and then this is what we are going to
  3400. 2:40:58return and write into our gold table. So
  3401. 2:41:01we will say return this one. So now this
  3402. 2:41:07code it is ready. Let's give it a try
  3403. 2:41:09and let's see what all errors we are
  3404. 2:41:11going to get.
  3405. 2:41:13So here is our first error that we got.
  3406. 2:41:15It looks like there is some syntax
  3407. 2:41:17related problem. So if I expand this, if
  3408. 2:41:20I click jump to the code. So for this
  3409. 2:41:22return statement, it is saying it is a
  3410. 2:41:25syntax problem. So maybe the indentation
  3411. 2:41:28it it is not proper probably. So what we
  3412. 2:41:31will do is simply we will click on this
  3413. 2:41:34edit button here. It will open this
  3414. 2:41:36right side and we will say like uh fix
  3415. 2:41:40the indentation problem
  3416. 2:41:43of this file
  3417. 2:41:46because we typed this code manually. So
  3418. 2:41:49uh so uh some of the pieces are not
  3419. 2:41:52aligned properly. In Python it is
  3420. 2:41:54mandatory. So let genie fix that for us.
  3421. 2:41:58So it has made the changes for us. So we
  3422. 2:42:00are going to accept it
  3423. 2:42:04and now let's give it another try. So
  3424. 2:42:07let's run our pipeline again.
  3425. 2:42:10So this time the execution has started
  3426. 2:42:13and it is running. Let me close the
  3427. 2:42:16right side. Let me bring this into
  3428. 2:42:18picture. So now we can see the silver
  3429. 2:42:21bronze transactions is completed. There
  3430. 2:42:24is no new data. uh silver also completed
  3431. 2:42:28and high value transaction alert the one
  3432. 2:42:30gold table we created just now that is
  3433. 2:42:33also completed but output records is
  3434. 2:42:35zero and why is that because currently
  3435. 2:42:38there is no uh fraud data in our uh
  3436. 2:42:43stream that is coming so that is why
  3437. 2:42:45there is no data and why is that because
  3438. 2:42:48when we were pushing the streaming data
  3439. 2:42:50in Kafka we did not push any
  3440. 2:42:53uh fraud related or any corrupted data.
  3441. 2:42:56So let's do that first. So now I'm back
  3442. 2:42:59in the VS code our producer part and if
  3443. 2:43:03I press up. So so far as you know we
  3444. 2:43:05were running this Python normal. py it
  3445. 2:43:08is sending the normal transaction data
  3446. 2:43:10note any fraud related data. So to
  3447. 2:43:13control the fraud related data I have
  3448. 2:43:15created a separate file that is fraud
  3449. 2:43:18transaction. So that is the one we are
  3450. 2:43:20going to run now.
  3451. 2:43:23So here what we will do is we will
  3452. 2:43:26mention like FR and it is saying fraud
  3453. 2:43:29card but not the fraud card. We need to
  3454. 2:43:32run the fraud transaction. Fraud card it
  3455. 2:43:35has a different purpose. We may or may
  3456. 2:43:37not need later on. We will see that
  3457. 2:43:39part. But for now we want to send some
  3458. 2:43:41fraud transaction. So now if I press
  3459. 2:43:44enter.
  3460. 2:43:47So it has sent that fraud transaction.
  3461. 2:43:49And the way I have designed this file is
  3462. 2:43:52that it will send only one record so
  3463. 2:43:54that we don't end up detect detecting so
  3464. 2:43:57many frauds and then uh sending so many
  3465. 2:44:00emails. So for now it will just send one
  3466. 2:44:03fraud data and then it will exit. That
  3467. 2:44:06is how it will work. So now we have one
  3468. 2:44:09fraud uh transaction to work with. That
  3469. 2:44:12is good enough. So we will go back to
  3470. 2:44:14our pipeline and simply run our
  3471. 2:44:16pipeline.
  3472. 2:44:19So this time hopefully we will get our
  3473. 2:44:21first fraud. Let's see.
  3474. 2:44:24So the bronze table it has detected the
  3475. 2:44:27new record and it has loaded it from
  3476. 2:44:29Kafka silver also it has been loaded
  3477. 2:44:32successfully and yes in our uh fraud or
  3478. 2:44:36alert table we have got our first record
  3479. 2:44:39now. So let's check out this record. I
  3480. 2:44:42will click on this view in catalog
  3481. 2:44:44button.
  3482. 2:44:46So here is our table. Let's check out
  3483. 2:44:48that sample or one record that has been
  3484. 2:44:51created here.
  3485. 2:44:54So here is our record. This is the alert
  3486. 2:44:56ID that we created. Alert dash the
  3487. 2:44:59transaction ID, alert type, the
  3488. 2:45:02timestamp, transaction ID, customer ID,
  3489. 2:45:04customer email, the email part like I
  3490. 2:45:07was uh talking earlier. This is very
  3491. 2:45:09important. Using this ID, we will send
  3492. 2:45:12the email. This is the name of the
  3493. 2:45:14customer, the amount, the limit. As we
  3494. 2:45:17can see this is the limit set by
  3495. 2:45:18customer. This is the transaction
  3496. 2:45:20amount. That is why it has been
  3497. 2:45:22considered as a fraud. And then there is
  3498. 2:45:25this additional information that is also
  3499. 2:45:27useful about this fraud.
  3500. 2:45:30So now that this fraud has been detected
  3501. 2:45:33and our gold layer table streaming table
  3502. 2:45:36will get it in real time. The next step
  3503. 2:45:38is to send the alert email in real time.
  3504. 2:45:42So now let's work on that piece.
  3505. 2:45:45And for sending any custom email uh we
  3506. 2:45:48have like different uh options that we
  3507. 2:45:51can use. We can use any of the SMTP
  3508. 2:45:54services that are available and for this
  3509. 2:45:57project we are going to use the Gmail
  3510. 2:45:59one because it is very easy to set up. I
  3511. 2:46:02already have a Gmail account. So for
  3512. 2:46:04that what we need to do is we need to
  3513. 2:46:07simply say like Gmail SMPP
  3514. 2:46:11API key. So we will need a API key that
  3515. 2:46:15we are going to use. So this is what we
  3516. 2:46:18will search.
  3517. 2:46:20And here
  3518. 2:46:22uh I don't see that link. I think in
  3519. 2:46:26Gmail it is called as app key in terms
  3520. 2:46:28of Google. That's a different
  3521. 2:46:30terminology.
  3522. 2:46:32And yes this is the URL. So it is like
  3523. 2:46:34my account.google.com.
  3524. 2:46:36Then app password. So this is called as
  3525. 2:46:40app password not like a API key. It it
  3526. 2:46:43is kind of same thing but this is Google
  3527. 2:46:45terminology. So if I click this then we
  3528. 2:46:49need to select our Google account which
  3529. 2:46:52we want to use for sending the email. So
  3530. 2:46:54I have selected my account. Now it is
  3531. 2:46:57verifying. I will uh cancel it or let me
  3532. 2:47:02see if it works.
  3533. 2:47:07Yes, it is working. So now I am on my
  3534. 2:47:10app passwords screen. So this is where
  3535. 2:47:13we are going to create a new app
  3536. 2:47:15password. So here uh we need to give any
  3537. 2:47:19name maybe we can give it give it the
  3538. 2:47:22same name fine guard
  3539. 2:47:28project and then click on create.
  3540. 2:47:32So this is our API key or app password
  3541. 2:47:35that has been created. So I'm going to
  3542. 2:47:38copy it and uh you shall create your own
  3543. 2:47:41because this one I'm going to delete
  3544. 2:47:42before I upload this video. So don't try
  3545. 2:47:45this one. So let me save it to a notepad
  3546. 2:47:48first.
  3547. 2:47:51This I have saved here and I will click
  3548. 2:47:53on done. So now this is ready.
  3549. 2:47:56So first of all before sending the
  3550. 2:47:59actual email we will first confirm if
  3551. 2:48:02the app password that we have created is
  3552. 2:48:04it really working or not and we will put
  3553. 2:48:07it in our key uh in our secret scope not
  3554. 2:48:10the keyword. So let's confirm that for
  3555. 2:48:14that we are we can use this test
  3556. 2:48:16notebook that we had created or we can
  3557. 2:48:19create a new notebook as well.
  3558. 2:48:24So in this view it doesn't seem to be
  3559. 2:48:26allowing us. So simply I will select
  3560. 2:48:28this drop-down and click on workspace
  3561. 2:48:31because this is the pipeline view. So
  3562. 2:48:33normally there we can work on the stuff
  3563. 2:48:35related to uh these the spark
  3564. 2:48:39declarative pipelines. So now I am back
  3565. 2:48:42and let me find my project. This is my
  3566. 2:48:45project and this is our notebook.
  3567. 2:48:51So here let me bring in some code
  3568. 2:48:53related to email testing first. So this
  3569. 2:48:56code I have prepared it previously. We
  3570. 2:48:59don't need to type it completely because
  3571. 2:49:01it is a test code that we are going to
  3572. 2:49:03use. So this notebook I have included in
  3573. 2:49:06the GitHub link that I have that it is
  3574. 2:49:08there. You can use this same code. So
  3575. 2:49:12here simply what we are doing is this is
  3576. 2:49:14a body that we are preparing. It is a
  3577. 2:49:17HTML body. So the format is HTML. We
  3578. 2:49:20don't need to worry about it. It is just
  3579. 2:49:22sending a test email from datab bricks
  3580. 2:49:25like that. It is saying then this is the
  3581. 2:49:27subject of the email that we are we have
  3582. 2:49:30hardcoded here. And this is where we are
  3583. 2:49:33getting the API key from the secret
  3584. 2:49:36scope. So this is the name of that key.
  3585. 2:49:39So far we have not stored that. So it
  3586. 2:49:41will not work. So simply what we will do
  3587. 2:49:44is first maybe let me run this cell so
  3588. 2:49:47that this piece is ready and for this
  3589. 2:49:50API key for now we will provide the
  3590. 2:49:53hard-coded value and later on we will
  3591. 2:49:55put it in the secret scope. So I have
  3592. 2:49:58provided this value here and now this
  3593. 2:50:01one uh this is another piece you need to
  3594. 2:50:04be careful. So this is my email id. So
  3595. 2:50:07using which I created the API key. So
  3596. 2:50:10here you need to replace with your email
  3597. 2:50:12id then only it will work and this is
  3598. 2:50:15the Gmail API key this same one that we
  3599. 2:50:18just pasted here and this is to email
  3600. 2:50:21where we want to send the email. So this
  3601. 2:50:24can be the same email ID or a different
  3602. 2:50:26one. It is simply the ID where we want
  3603. 2:50:28to send the email. And now I will run
  3604. 2:50:31it.
  3605. 2:50:34So it says email sent successfully. So
  3606. 2:50:37let's confirm if we have received the
  3607. 2:50:39email.
  3608. 2:50:40So if I check my email, this is the
  3609. 2:50:42email that I have received. This is the
  3610. 2:50:44from email id. This is the to email id
  3611. 2:50:48and this is the test email. So if we
  3612. 2:50:51have received this email, what it means
  3613. 2:50:53is that our API key is working fine and
  3614. 2:50:56this sending of email as a testing it is
  3615. 2:50:59working fine. So we can use this
  3616. 2:51:01functionality now. So now instead of
  3617. 2:51:05like again providing this code to our
  3618. 2:51:08streaming pipeline, I'm going to copy
  3619. 2:51:11this code as well. But before doing
  3620. 2:51:14that, we will put this API key in secret
  3621. 2:51:16scope as well. So that we follow the
  3622. 2:51:19best practice. So I will copy it from
  3623. 2:51:22here. And let's go to the setup secret
  3624. 2:51:24scope.
  3625. 2:51:26And then if we go below, so this is the
  3626. 2:51:30last piece that earlier I was talking
  3627. 2:51:32about.
  3628. 2:51:34So it will be in the last cell. So this
  3629. 2:51:37is the name of the key and this is the
  3630. 2:51:39secret value. So I'm going to replace it
  3631. 2:51:42with the new one that I just uh created.
  3632. 2:51:46So now let's store it. Uh let's see if
  3633. 2:51:49it is running or I need to run above
  3634. 2:51:52cells. Probably I will need to. Yes,
  3635. 2:51:55secret scope name is not defined. So
  3636. 2:51:58this is the secret scope name that we
  3637. 2:52:00have.
  3638. 2:52:02Now let me run it.
  3639. 2:52:11So now it is saying datab bricks
  3640. 2:52:12instance. So yes, here it is. So let me
  3641. 2:52:16run this cell. Then this one is about
  3642. 2:52:19creating the scope. So probably this
  3643. 2:52:21time it will work.
  3644. 2:52:25Yes, now it says like this has been
  3645. 2:52:27created successfully. So now to confirm
  3646. 2:52:30if this is working through secret scope.
  3647. 2:52:33So I'm going to delete this cell that is
  3648. 2:52:35has hardcoded value and I'm going to run
  3649. 2:52:38this cell. So now it has read this API
  3650. 2:52:42key from this secret scope. And let's
  3651. 2:52:45give it another try by sending the same
  3652. 2:52:47email again. And it says it is
  3653. 2:52:50successful. So the same email has been
  3654. 2:52:52sent again. And this confirms that this
  3655. 2:52:54API key from the secret scope is working
  3656. 2:52:57fine. Now to integrate this piece, I'm
  3657. 2:53:00going to copy this code. This one cell
  3658. 2:53:03of the code is enough. So I have copied
  3659. 2:53:05it. Why? Because we are going to use
  3660. 2:53:08Genie code here to integrate this
  3661. 2:53:10functionality into our pipeline. So this
  3662. 2:53:13is our streaming pipeline. So I will
  3663. 2:53:15open in open it in the pipeline editor
  3664. 2:53:18now. And with this we are back in our
  3665. 2:53:21pipeline.
  3666. 2:53:24So here uh now what we are going to do
  3667. 2:53:27is we will use genie code and we will
  3668. 2:53:31need to give it instruction. So let's
  3669. 2:53:34give that. So what we will provide there
  3670. 2:53:37is uh probably let's type it in a
  3671. 2:53:40notepad so that it is easier to
  3672. 2:53:42understand and then we can paste it
  3673. 2:53:44there. So because I have copied the code
  3674. 2:53:47here. So let me first paste that code so
  3675. 2:53:50that I don't lose it and then we will
  3676. 2:53:53say that this is the table that contains
  3677. 2:53:56our alerts.
  3678. 2:54:00Okay. So we will say that the table
  3679. 2:54:04this one
  3680. 2:54:06created by this table has been created
  3681. 2:54:09by this file. So let's mention this also
  3682. 2:54:12so that it can read the file if
  3683. 2:54:14required.
  3684. 2:54:16You will say contains the
  3685. 2:54:20fraud related information where
  3686. 2:54:23transaction has been
  3687. 2:54:26performed
  3688. 2:54:28with higher value than provided by
  3689. 2:54:34customer.
  3690. 2:54:37And then what we will say is that like
  3691. 2:54:40this
  3692. 2:54:42table contains
  3693. 2:54:45information about
  3694. 2:54:47transaction and other columns
  3695. 2:54:51along with an email column. So we will
  3696. 2:54:55mention that
  3697. 2:54:57I want to send email to this ID in real
  3698. 2:55:04time.
  3699. 2:55:07by reading data from the table
  3700. 2:55:12in in real time or as streaming.
  3701. 2:55:17And then we will say that for sending
  3702. 2:55:21the email
  3703. 2:55:23I want
  3704. 2:55:26to use the below
  3705. 2:55:29uh sample code.
  3706. 2:55:33So integrate
  3707. 2:55:35this code and then we have our code. So
  3708. 2:55:39what it will do is we are giving it the
  3709. 2:55:41requirement what we want to do and we
  3710. 2:55:44are also giving it this sample code
  3711. 2:55:46saying that uh this is the example or
  3712. 2:55:49sample code that we want to use to send
  3713. 2:55:52the email. So now let's me let me copy
  3714. 2:55:55this entire thing. Let's go back there
  3715. 2:55:57and let's ask Genie code to do it.
  3716. 2:56:02So now it is thinking. Let's see how
  3717. 2:56:04much it is able to do.
  3718. 2:56:09So it has prepared some thoughts. It is
  3719. 2:56:11currently reading the pipeline details
  3720. 2:56:15and now it is considering different
  3721. 2:56:17things.
  3722. 2:56:20And now it is creating a separate file
  3723. 2:56:24looks like with the name notify.
  3724. 2:56:27So looks like it has done its
  3725. 2:56:29processing. So let's try to understand
  3726. 2:56:31that. So here is the file it has created
  3727. 2:56:35with the name email notifier
  3728. 2:56:38and first let's accept these changes so
  3729. 2:56:40that it is easier to read.
  3730. 2:56:43So how it is saying is that what it does
  3731. 2:56:45it reads the streaming data from this
  3732. 2:56:48table. It processes each micro batch in
  3733. 2:56:51real time as new alert arrive and then
  3734. 2:56:55it send the email to the customer. So
  3735. 2:56:58here we can see it has created multiple
  3736. 2:57:00functions here. So like we had dp table
  3737. 2:57:05and here it is using like a different
  3738. 2:57:07function like dp dot for each batch sync
  3739. 2:57:12and then we will find another function
  3740. 2:57:15here at the below. So it is about append
  3741. 2:57:18flow. So it has created two functions.
  3742. 2:57:22So let me ask it to like simplify this
  3743. 2:57:25so that we can understand it in little
  3744. 2:57:27bit little bit better way and also what
  3745. 2:57:30it is saying is that next steps it is
  3746. 2:57:32saying add your SMTP code. So this code
  3747. 2:57:35it has provided and it is asking us to
  3748. 2:57:38add here and uh
  3749. 2:57:42this Gmail API key also it is reading
  3750. 2:57:44from the session because we didn't uh
  3751. 2:57:47provide the code for the secret scope.
  3752. 2:57:50So we will provide that and uh currently
  3753. 2:57:54uh first let me explain like what it is
  3754. 2:57:57working and how we can make it simple.
  3755. 2:58:00So the flow it starts from here. So it
  3756. 2:58:04says append flow. So this is a standard
  3757. 2:58:07function or decorator. What it will do
  3758. 2:58:10is whatever stream it is reading from
  3759. 2:58:13this function it will send that stream
  3760. 2:58:15to this target. So the stream here this
  3761. 2:58:19is our table. So it is going to read
  3762. 2:58:21this table streaming data. Every record
  3763. 2:58:25or couple of record is a micro batch
  3764. 2:58:27that it will get it will read from here
  3765. 2:58:30and send to this target. So that is what
  3766. 2:58:33is this append flow. So append means
  3767. 2:58:35keep reading more data and keep sending
  3768. 2:58:38to this sync. And where is this sync is
  3769. 2:58:41that uh here is our sync. So the data or
  3770. 2:58:45the micro batches will be coming from
  3771. 2:58:48from there to this function and it will
  3772. 2:58:51be in micro batches. It can be single
  3773. 2:58:53single record or a like a couple of
  3774. 2:58:56records in one group also can come up.
  3775. 2:58:58So that is where we have this four each
  3776. 2:59:01batch sync function. So for each of the
  3777. 2:59:03batch let's say in one batch we got two
  3778. 2:59:06three alerts in a single uh batch. So
  3779. 2:59:09then it will perform that operation. So
  3780. 2:59:12automatically when the data will come
  3781. 2:59:14there it will it will be received as a
  3782. 2:59:17data frame and it will have a batch ID
  3783. 2:59:20also. So that is internally
  3784. 2:59:22automatically that will work and for
  3785. 2:59:24this batch this data frame. So this is
  3786. 2:59:27the email part and then uh from that
  3787. 2:59:31data frame it is collecting all the
  3788. 2:59:33data. Then each and every row it is
  3789. 2:59:36processing here and then it is sending
  3790. 2:59:38the email by preparing the email body
  3791. 2:59:41and everything. So first let's ask it to
  3792. 2:59:45like make some changes so that the code
  3793. 2:59:47looks bit clean. So we are going to uh
  3794. 2:59:51open our send email file again. Let's
  3795. 2:59:53see this time it is opening here.
  3796. 2:59:57And we will tell that API key is
  3797. 2:59:59available here. So here we will say
  3798. 3:00:02point number one that take the API key
  3799. 3:00:06from here.
  3800. 3:00:09And second point we will say I want
  3801. 3:00:15to segregate the email sending part from
  3802. 3:00:21for each
  3803. 3:00:23batch. So create a new function for
  3804. 3:00:27this.
  3805. 3:00:32So it shall be able to do that
  3806. 3:00:34automatically. So let's open that file.
  3807. 3:00:37Let's wait for it to do those changes.
  3808. 3:00:40And now what it is saying is it is
  3809. 3:00:42creating the file and it is saying it
  3810. 3:00:44will create a placeholder for the SMTP
  3811. 3:00:46code. So why it is doing this is it is a
  3812. 3:00:49safety measurement from the uh from the
  3813. 3:00:53genie code side because it don't want to
  3814. 3:00:55call external APIs automatically. So for
  3815. 3:00:58now what I will do is I will stop it
  3816. 3:01:00here and I will say that I have tested
  3817. 3:01:04SMTP and it is safe.
  3818. 3:01:08Usel integrate
  3819. 3:01:13complete code. So that it it is
  3820. 3:01:16confident that the code is fine to
  3821. 3:01:18integrate
  3822. 3:01:19and now it is saying that user has
  3823. 3:01:21confirmed. So now it will integrate that
  3824. 3:01:24code completely.
  3825. 3:01:26So now what is happening is it has
  3826. 3:01:29provided the code and it is saying that
  3827. 3:01:31you shall we shall manually copy paste
  3828. 3:01:33the code because due to this external
  3829. 3:01:35API its internal mechanism it is not
  3830. 3:01:38allowing it to uh replace the code. So I
  3831. 3:01:41will copy the code from here and then I
  3832. 3:01:45will select everything and paste it.
  3833. 3:01:50So here I don't know why it is showing
  3834. 3:01:51red. So I will reject this piece here.
  3835. 3:01:58And then again I will delete it and
  3836. 3:02:00paste one more time. And now the code
  3837. 3:02:03shall be complete. So let me close the
  3838. 3:02:06right part. Let's understand the code
  3839. 3:02:08one more time. Hopefully this time it
  3840. 3:02:10will be simpler. So this is the same
  3841. 3:02:13append flow. So it is reading our
  3842. 3:02:15streaming data as alert and sending to
  3843. 3:02:18this target email notifier sync. And
  3844. 3:02:22then yes sync part it is simple now. So
  3845. 3:02:25this is our sync and in the sync it is
  3846. 3:02:29receiving the data frame and the batch
  3847. 3:02:32id. This is the from email id which is
  3848. 3:02:34hardcoded because uh using this email id
  3849. 3:02:38only we generated our app password. So
  3850. 3:02:40from id will be this only. The app
  3851. 3:02:43password it is getting it from the
  3852. 3:02:46secret scope. So it is doing it uh
  3853. 3:02:50through like a difficult way. I would
  3854. 3:02:52say it this code looks strange to me. So
  3855. 3:02:55what I will simply do is I probably it
  3856. 3:02:58will work but I will simply remove this.
  3857. 3:03:00I have not seen this earlier. This way
  3858. 3:03:02it works fine.
  3859. 3:03:05Then uh it is collecting all the rows
  3860. 3:03:08from our data as rows and then it is
  3861. 3:03:12doing some processing row by row. So for
  3862. 3:03:15each of the row in the from the table
  3863. 3:03:17whatever it is reading it is first
  3864. 3:03:20preparing a dictionary like the alert
  3865. 3:03:23ID, customer name, transaction amount
  3866. 3:03:25all these things it is reading
  3867. 3:03:28and then it is uh it is like uh
  3868. 3:03:32preparing a subject. So this is the
  3869. 3:03:34subject that we will get when we get the
  3870. 3:03:36alert and in the body it is calling a
  3871. 3:03:39function like create alert email body
  3872. 3:03:42and it is passing this dictionary with
  3873. 3:03:45all these details that is where it has
  3874. 3:03:47like now more modular code so that we
  3875. 3:03:50don't see a complex code for this email
  3876. 3:03:53and get confused that part we will go
  3877. 3:03:55through but first let's say here it is
  3878. 3:03:57creating the body and then it is sending
  3879. 3:04:00the email and it is sending the email by
  3880. 3:04:03passing the email id, subject, body,
  3881. 3:04:06from and the app password. So then it is
  3882. 3:04:10saying how much how many emails it has
  3883. 3:04:12sent successfully and how many has been
  3884. 3:04:14failed so that it can print it. So this
  3885. 3:04:17is how it is sending the email and to
  3886. 3:04:20create the body part it has created a
  3887. 3:04:22separate function that we can see here
  3888. 3:04:26and send email also it is a separate
  3889. 3:04:28function. Earlier I thought it is the
  3890. 3:04:30Gmail function but for the body part it
  3891. 3:04:33is receiving that dictionary and from
  3892. 3:04:36that dictionary it is reading all that
  3893. 3:04:38different data and preparing a HTML well
  3894. 3:04:41formatted message. So what exactly is
  3895. 3:04:44this we will see when we get the email
  3896. 3:04:46we don't need to understand each and
  3897. 3:04:48everything here because this is HTML if
  3898. 3:04:50it looks good it will we will be fine
  3899. 3:04:53with it. If you want to make any
  3900. 3:04:55changes, we can ask Genie and it will be
  3901. 3:04:57able to make changes for us. So that is
  3902. 3:04:59how it is preparing this email body. And
  3903. 3:05:02then this send email function which is
  3904. 3:05:04the final function. So this is the
  3905. 3:05:07function that is there. And here we are
  3906. 3:05:09getting all those details and this is
  3907. 3:05:12where the the email code that we had
  3908. 3:05:14provided it is integrating that. So it
  3909. 3:05:17is calling the Gmail SMTP server and
  3910. 3:05:20then finally sending our email. So that
  3911. 3:05:23is how this code has been integrated. So
  3912. 3:05:27overall if we understand the flow. So it
  3913. 3:05:30will read the streaming data. It will uh
  3914. 3:05:33send the micro batches to another
  3915. 3:05:35function that from those microbatches it
  3916. 3:05:38will read rowby row data. It will
  3917. 3:05:41prepare subject body and all and then it
  3918. 3:05:44will send the email. That is how the the
  3919. 3:05:46flow looks like. And for this piece what
  3920. 3:05:50we are going to do is uh because it is
  3921. 3:05:52not creating any table it is sending an
  3922. 3:05:54email. So for that purpose we will
  3923. 3:05:57create a separate folder for this one so
  3924. 3:06:00that we manage it separately. So we will
  3925. 3:06:02name it as alert. So let me create this
  3926. 3:06:05folder and let me move this file inside
  3927. 3:06:09that folder.
  3928. 3:06:14So by default it is not included as
  3929. 3:06:17execution. So let me include this folder
  3930. 3:06:19first so that the file will get executed
  3931. 3:06:23when we do that. So yes now it is
  3932. 3:06:26included and it will run this file when
  3933. 3:06:29we run the pipeline. So with this our
  3934. 3:06:32code is ready. So let's try to run it
  3935. 3:06:35and let's confirm if it is working fine.
  3936. 3:06:38The expectation is that this one record
  3937. 3:06:40that it had written that same record it
  3938. 3:06:43will call this file and send the email
  3939. 3:06:46notification. So let me run it.
  3940. 3:06:50The execution it is complete now. And
  3941. 3:06:54looks like like this email notifier sync
  3942. 3:06:56it worked well and output record is one
  3943. 3:07:00which means it has probably sent our
  3944. 3:07:02email. And if you notice so it has not
  3945. 3:07:05received any new transaction. So other
  3946. 3:07:08pieces it was not able to process
  3947. 3:07:10anything just the email part it
  3948. 3:07:12processed one record because this alert
  3949. 3:07:14it had it and if you want to see the end
  3950. 3:07:17to end flow we can click on this
  3951. 3:07:19pipeline graph. So here we can see all
  3952. 3:07:23the steps that first the table was
  3953. 3:07:25loaded into bronze then silver then gold
  3954. 3:07:28and then the sync part which is for each
  3955. 3:07:31batch that sent the email and it will
  3956. 3:07:35look more beautiful when we will combine
  3957. 3:07:37another stream to it the file streaming
  3958. 3:07:39later on for now let's confirm if the
  3959. 3:07:42email has been received properly
  3960. 3:07:45so if I go to my email id so this email
  3961. 3:07:49probably it will not be coming to to
  3962. 3:07:51your inbox, it will go to spam because
  3963. 3:07:54this uh this Gmail it will know it will
  3964. 3:07:58see it that coming from a personal email
  3965. 3:08:01id and saving saying about transaction
  3966. 3:08:03fraud and all. So this one it will
  3967. 3:08:05probably go to spam. So check it out
  3968. 3:08:08there if you are trying it out. So this
  3969. 3:08:10is where we have received this email and
  3970. 3:08:13it says like we can report it as not
  3971. 3:08:16spam but for now I will leave it here so
  3972. 3:08:18that it doesn't go to my main inbox. But
  3973. 3:08:22this email has been generated saying
  3974. 3:08:24that like we detected a transaction that
  3975. 3:08:27exceeds your configuration limit. These
  3976. 3:08:30are all the details
  3977. 3:08:32and then it is saying like if you
  3978. 3:08:34authorized then no problem otherwise you
  3979. 3:08:36shall report the authorities and or and
  3980. 3:08:40all that immediately.
  3981. 3:08:42So this is how the real time alert looks
  3982. 3:08:45like. We'll see it working end to end
  3983. 3:08:47once we configure the other stream and
  3984. 3:08:49then run everything end to end. So now
  3985. 3:08:52if we revisit our architecture
  3986. 3:08:55we are done with this stream static
  3987. 3:08:57join. We are done with the basic gold
  3988. 3:09:00layer. Uh although we will be building
  3989. 3:09:02more into gold pro detection one we have
  3990. 3:09:05done and then real time alert also we
  3991. 3:09:08are able to send now. So the main pieces
  3992. 3:09:11pending now is like bringing in the
  3993. 3:09:13streaming files for injection through
  3994. 3:09:15autoloader and do do a stream stream
  3995. 3:09:18join and then detect another kind of
  3996. 3:09:20fraud and that also we will send
  3997. 3:09:22realtime alerts and later on we will
  3998. 3:09:25build a dashboard as well and at the end
  3999. 3:09:28we will do end to end orchestration
  4000. 3:09:30where we will see everything flowing in
  4001. 3:09:33real time end to end. So now let's get
  4002. 3:09:36started with this uh streaming piece.
  4003. 3:09:39But before that I would say like let's
  4004. 3:09:41use this point as another checkpoint and
  4005. 3:09:44you take some break you understand it
  4006. 3:09:47completely how it is working you do some
  4007. 3:09:49hands on and see it working understand
  4008. 3:09:52properly then you will be ready to
  4009. 3:09:54integrate the second stream. So once you
  4010. 3:09:58are ready then you can uh start again
  4011. 3:10:00from here. So now let's start with the
  4012. 3:10:03streaming files part. So to uh to
  4013. 3:10:07process streaming files, first thing we
  4014. 3:10:10need is streaming files, right? We need
  4015. 3:10:12some place where we will get streaming
  4016. 3:10:14files. So first let's prepare that
  4017. 3:10:17place. So in our sources, we already
  4018. 3:10:20have this transactions folder or volume.
  4019. 3:10:23It is a volume. Here we will create
  4020. 3:10:25another volume.
  4021. 3:10:28And this one let's name it as fraud
  4022. 3:10:31watch list.
  4023. 3:10:34And why we are choosing this name is
  4024. 3:10:35because here what we are assuming is
  4025. 3:10:38that we will be getting some files which
  4026. 3:10:41are being generated from a system
  4027. 3:10:44uh which are also like uh monitoring the
  4028. 3:10:47customer and card accounts. And whenever
  4029. 3:10:50customer reports that the card shall be
  4030. 3:10:52blocked or if the card is blocked
  4031. 3:10:54automatically due to some other fraud
  4032. 3:10:57related activities then what all cards
  4033. 3:11:00and other information is being blocked
  4034. 3:11:02that information we are receiving
  4035. 3:11:04through these files and if any card
  4036. 3:11:08let's say if it is marked as that it is
  4037. 3:11:10blocked or something and if it is marked
  4038. 3:11:12for fraud for example for this card we
  4039. 3:11:15shall not be getting any transactions
  4040. 3:11:17right. So if still we are getting any
  4041. 3:11:20transaction for that that will be a
  4042. 3:11:22fraud and that is what we will be
  4043. 3:11:24detecting through this stream.
  4044. 3:11:27And here looks like I did a typo. Let me
  4045. 3:11:29correct it first. So let me rename it.
  4046. 3:11:36And here first we are going to create a
  4047. 3:11:38folder where we will be receiving the
  4048. 3:11:40file. So we will name it as source data.
  4049. 3:11:45So this is where we will be generating
  4050. 3:11:47some files and then uh those files we
  4051. 3:11:51will be processing in in uh real time.
  4052. 3:11:55And to generate these files I have
  4053. 3:11:57prepared a notebook that will generate
  4054. 3:12:00the files automatically and keep sending
  4055. 3:12:03to this location in real time.
  4056. 3:12:06And that notebook I have kept in this
  4057. 3:12:08folder that I will be uploading in
  4058. 3:12:10GitHub. Inside this folder there is a
  4059. 3:12:13CSV file and then this is the notebook
  4060. 3:12:16that will generate that data
  4061. 3:12:19and in this notebook there are two path
  4062. 3:12:21that we need to update or confirm if
  4063. 3:12:24those are fine. One is the path of this
  4064. 3:12:27CSV file. So it contains some CSV data
  4065. 3:12:30that it will read one by one line by
  4066. 3:12:32line and it will prepare JSON file and
  4067. 3:12:35put it put it into that location. So we
  4068. 3:12:38need to copy the full path of this file.
  4069. 3:12:42So I have copied and here we need to
  4070. 3:12:44provide the full path. So this is the
  4071. 3:12:47full path and then this is the output
  4072. 3:12:50path where it will be generating the
  4073. 3:12:52files. So this path it is the folder
  4074. 3:12:54that we created just now. So from here I
  4075. 3:12:57will copy this path and I will update
  4076. 3:13:00this. So only these two paths we need to
  4077. 3:13:03update and then we will be good to go.
  4078. 3:13:06So now I will run this notebook to
  4079. 3:13:08generate those JSON files
  4080. 3:13:13and what it will do is it will send a
  4081. 3:13:16single JSON file for a single record and
  4082. 3:13:19it will keep sending files with an
  4083. 3:13:21interval of 5 seconds. So it will send a
  4084. 3:13:24file wait for 5 seconds then send
  4085. 3:13:26another file. That is how it will
  4086. 3:13:29process the data.
  4087. 3:13:31So currently we can see that one file it
  4088. 3:13:34has written it is waiting for 5 seconds.
  4089. 3:13:38Then a second file it has written it is
  4090. 3:13:40waiting for 5 seconds. So that is how it
  4091. 3:13:43will keep sending more and more files
  4092. 3:13:45there. So for now we will interrupt it
  4093. 3:13:48so that we have some sample files that
  4094. 3:13:50we will work upon. Later on we will run
  4095. 3:13:53it again when we will run our entire
  4096. 3:13:55process end to end. So now if we go to
  4097. 3:13:58the location that we had specified and
  4098. 3:14:01if we refresh there so we will see that
  4099. 3:14:04four files has been created. So if I
  4100. 3:14:07open any of the file here uh it contains
  4101. 3:14:10a JSON data and this data it contains a
  4102. 3:14:13watch list ID the watch type that it is
  4103. 3:14:16monitoring card and this is the entity
  4104. 3:14:19ID which is the card number
  4105. 3:14:22and for this one risk level is high. The
  4106. 3:14:25reason is that it is for it has been
  4107. 3:14:28marked as fishing card. So that way like
  4108. 3:14:31some other details are also being
  4109. 3:14:33generated here. So this is the data that
  4110. 3:14:36we will be ingesting now. So these are
  4111. 3:14:39the uh this is our streaming source now
  4112. 3:14:41where new files keep coming and to
  4113. 3:14:44ingest this data we are going to use
  4114. 3:14:46autoloader.
  4115. 3:14:48And to use the autoloader also again we
  4116. 3:14:50have two options either we can write it
  4117. 3:14:52in a normal notebook or we can write it
  4118. 3:14:55into our uh uh spark declarative
  4119. 3:14:58pipelines. So first we will understand
  4120. 3:15:00in a notebook so that we can understand
  4121. 3:15:02the functionality of autoloader first
  4122. 3:15:05then we will integrate it into our uh
  4123. 3:15:07SDP pipeline. So for that I will copy
  4124. 3:15:10this path
  4125. 3:15:12and then I will go to our project
  4126. 3:15:14folder. We will go back. So this is
  4127. 3:15:18where we will create that file. So we
  4128. 3:15:20will create a new notebook here
  4129. 3:15:24and we will name it as 04
  4130. 3:15:29autoloader test.
  4131. 3:15:32So first of all we will create a source
  4132. 3:15:35path variable here. That will be the
  4133. 3:15:37path that we have copied just now.
  4134. 3:15:43And after creating this variable first
  4135. 3:15:45let's confirm if it is showing the files
  4136. 3:15:48here. So it is like dbutils dot fs do ls
  4137. 3:15:54ls command it shows the list of files
  4138. 3:15:56available into this path. So as this is
  4139. 3:16:00the variable we don't need to provide
  4140. 3:16:01the quotes here. Let me run it. So here
  4141. 3:16:05it is showing that those files are
  4142. 3:16:07available here. So those four files are
  4143. 3:16:09showing. So the path is correct.
  4144. 3:16:12So now we will create a data frame. So
  4145. 3:16:15we will say like input stream equals to
  4146. 3:16:20then we will do spark dot read stream
  4147. 3:16:26and then it is suggesting some options.
  4148. 3:16:29So I will press a tab here and here.
  4149. 3:16:33This option we do not need. First let me
  4150. 3:16:36explain these options. So format cloud
  4151. 3:16:39files it means we are using autoloader.
  4152. 3:16:42So cloud files it is the keyword that is
  4153. 3:16:45used to specify that we are using
  4154. 3:16:48autoloader that is the standard name.
  4155. 3:16:50And then we have more options which are
  4156. 3:16:52specific to autoloader like the option
  4157. 3:16:55for format. So cloud files dot format
  4158. 3:16:59our file format is JSON. So that is why
  4159. 3:17:01we are specifying this. Then we need to
  4160. 3:17:04provide a schema location. So at this
  4161. 3:17:07location it will store the current
  4162. 3:17:10schema of the file so that in future it
  4163. 3:17:12can compare and evolve the schema if
  4164. 3:17:15required. So here we need to provide a
  4165. 3:17:17path where it can store the schema
  4166. 3:17:20location. So it will be similar to our
  4167. 3:17:23checkpoint location. So what we will do
  4168. 3:17:26is so this is where the source data is
  4169. 3:17:28coming. So here we will create a
  4170. 3:17:31directory with the name schema and then
  4171. 3:17:33this we will use as schema location
  4172. 3:17:37and after that we will provide another
  4173. 3:17:40option to infer the data types of the
  4174. 3:17:43file uh so that we don't have to uh
  4175. 3:17:47specify the uh schema of all the
  4176. 3:17:50columns. So we will specify
  4177. 3:17:55infer
  4178. 3:17:57column types
  4179. 3:17:59is true
  4180. 3:18:02and these are all the options that we
  4181. 3:18:04will need and then finally dot load will
  4182. 3:18:07be there
  4183. 3:18:09and in here we need to specify the path
  4184. 3:18:11that we are going to read.
  4185. 3:18:15So this is how like we read a we create
  4186. 3:18:18a stream using autoloader. And here one
  4187. 3:18:21thing to notice is that when we were
  4188. 3:18:24doing a Kafka stream test that time
  4189. 3:18:26first we tried it with only read. We try
  4190. 3:18:29to read the batch data uh and then we
  4191. 3:18:32tried the stream part. But in autoloader
  4192. 3:18:35the normal read operation it is
  4193. 3:18:37currently not supported. So it only
  4194. 3:18:39supports streaming way of injection. And
  4195. 3:18:42this streaming way also we can use it
  4196. 3:18:44kind of a batch injection as well when
  4197. 3:18:46we use the trigger type as available
  4198. 3:18:48now. So it can work in both scenarios.
  4199. 3:18:51So this will create our input uh
  4200. 3:18:54streaming data frame.
  4201. 3:18:57So it is ready now. Next we will do some
  4202. 3:19:00minor transformation.
  4203. 3:19:04So let's say transformed
  4204. 3:19:07df. So here what we will do is
  4205. 3:19:12uh we will take this data frame and
  4206. 3:19:14specific to autoloader or anything
  4207. 3:19:16whenever we read any file in spark uh
  4208. 3:19:20like outside autoloader outside
  4209. 3:19:22streaming anywhere then uh we get some
  4210. 3:19:25additional file related properties also
  4211. 3:19:28those we can read. So let's say in here
  4212. 3:19:31select what we will do is so all the
  4213. 3:19:34existing column we will select as it is.
  4214. 3:19:37So we will say star
  4215. 3:19:39and then we will add any additional
  4216. 3:19:41column. So f dot call and then there is
  4217. 3:19:45a specific keyword like underscore
  4218. 3:19:49meta data. So it is coming automatically
  4219. 3:19:52dot file path and alias is file path. So
  4220. 3:19:55this will add a new column file path
  4221. 3:19:58which will store the complete path of
  4222. 3:20:00the file. So this keyword it
  4223. 3:20:03automatically get that data. So we have
  4224. 3:20:05other things also like modify time, file
  4225. 3:20:08name, whatever we want we can get it.
  4226. 3:20:11And then also we will get the current
  4227. 3:20:14timestamp as well. So this one we will
  4228. 3:20:17call it as injection time stamp.
  4229. 3:20:26So this one will be a comma here
  4230. 3:20:30and that's it. So this is the data frame
  4231. 3:20:33that we are going to write. And as you
  4232. 3:20:36may have guessed this f is currently not
  4233. 3:20:39available. So we will need to import it.
  4234. 3:20:43So from
  4235. 3:20:46so it is giving it automatically. So we
  4236. 3:20:48will import it. So this will be our
  4237. 3:20:51transform data frame and now this one we
  4238. 3:20:54will need to write it to a table and for
  4239. 3:20:57that let's copy our code that we used in
  4240. 3:21:00Kafka streaming because it will be
  4241. 3:21:02almost the same only.
  4242. 3:21:06So uh yeah this is the code that we had.
  4243. 3:21:10Let me copy this
  4244. 3:21:15and if we go back here.
  4245. 3:21:17So here this is the transform df. So I
  4246. 3:21:20will replace it and it will write as a
  4247. 3:21:24delta table. It will write in append
  4248. 3:21:26mode and then we need to provide a
  4249. 3:21:28checkpoint location. So this location we
  4250. 3:21:31will create another one. So for fraud
  4251. 3:21:34watch list let's create a directory here
  4252. 3:21:37which will be called as checkpoint.
  4253. 3:21:40And at this checkpoint location it will
  4254. 3:21:42keep track of the files that it has
  4255. 3:21:44processed in the current run. So that in
  4256. 3:21:47the next run it pick up uh it it doesn't
  4257. 3:21:50pick up those files again and it only
  4258. 3:21:52pick ups the new files.
  4259. 3:21:54So that is the checkpoint location we
  4260. 3:21:56will update here. Trigger type so we
  4261. 3:21:59will use available now only so that it
  4262. 3:22:02will only run once and then exit and two
  4263. 3:22:05table. So this table name we will name
  4264. 3:22:07it as uh fraud
  4265. 3:22:11watch list
  4266. 3:22:13then batch test. So this is the name we
  4267. 3:22:17will provide.
  4268. 3:22:19Now I'm running it. So it will read
  4269. 3:22:22those files and write the data into this
  4270. 3:22:25table.
  4271. 3:22:27So now the execution it is complete.
  4272. 3:22:30Let's check out the data in this table.
  4273. 3:22:41So here is our data. All those four
  4274. 3:22:43records has been read here.
  4275. 3:22:46all the columns has been created
  4276. 3:22:47properly and this is the file path that
  4277. 3:22:50I was talking about. So for each and
  4278. 3:22:52every file it is putting the complete
  4279. 3:22:54path of the file using that underscore
  4280. 3:22:57metadata dot file path. So this is how
  4281. 3:23:00autoloader works. So writing part it is
  4282. 3:23:03exactly same reading part we need to
  4283. 3:23:05provide this cloud files and cloud file
  4284. 3:23:08specific options to read the data as uh
  4285. 3:23:12streaming using autoloader.
  4286. 3:23:14So now as we understand this using uh
  4287. 3:23:17normal batch data or through this
  4288. 3:23:20notebook now let's use the same in the
  4289. 3:23:23spark declarative pipeline. So for that
  4290. 3:23:25we will open our same streaming pipeline
  4291. 3:23:30and here let's go to branch. So this one
  4292. 3:23:34what we will do is we will clone it so
  4293. 3:23:36that some of the pieces will be same. So
  4294. 3:23:39we are going to name name it as
  4295. 3:23:42road
  4296. 3:23:46watch list
  4297. 3:23:50then branch. So this way we are going to
  4298. 3:23:52clone it.
  4299. 3:23:58So in here we will not need everything.
  4300. 3:24:00So we will remove these pieces. The
  4301. 3:24:03table name we will create it as fraud
  4302. 3:24:05watch list.
  4303. 3:24:09And this one it will be like
  4304. 3:24:12road watch list raw data ingested by
  4305. 3:24:16autoloader.
  4306. 3:24:19And this function also we can rename it
  4307. 3:24:22to fraud watch list branch.
  4308. 3:24:25It will return a data frame and all
  4309. 3:24:28these things we do not need. So this
  4310. 3:24:32streaming df creating this it is simple
  4311. 3:24:35in case of autoloader. So we will simply
  4312. 3:24:38copy it from the notebook that we
  4313. 3:24:40created just now. So let me open that.
  4314. 3:24:45So this is our streaming DF now. So let
  4315. 3:24:48me uh read it. So I have copied it. Now
  4316. 3:24:54let's take it to the streaming df here.
  4317. 3:24:58So I have replaced it now.
  4318. 3:25:03And here the source path it is also not
  4319. 3:25:06available. So directly we will put this
  4320. 3:25:09path there. So I will copy this and
  4321. 3:25:13directly put this into this code. And
  4322. 3:25:16one more thing so this schema location
  4323. 3:25:18also now as we are using SDP pipeline so
  4324. 3:25:22it will be maintained automatically. So
  4325. 3:25:25we don't need to specify this option. So
  4326. 3:25:27this is one advantage that we get. Rest
  4327. 3:25:30of the things will be same. So now we
  4328. 3:25:32have our streaming df and next what we
  4329. 3:25:36need to do is from the streaming df we
  4330. 3:25:38need to select the columns that we need.
  4331. 3:25:41So in our case now we have imported f.
  4332. 3:25:44So this is another way to specify those
  4333. 3:25:48and this current timestamp we will still
  4334. 3:25:50keep it. So uh let me put the other
  4335. 3:25:54columns that we are going to keep here.
  4336. 3:25:56So
  4337. 3:25:58uh let me simply copy paste it so that
  4338. 3:26:01we can paste those columns. So the
  4339. 3:26:03columns that we have now are like
  4340. 3:26:08watch list ID
  4341. 3:26:10and then we also do not need casting
  4342. 3:26:13here because the columns are already
  4343. 3:26:15string. So let me paste this one.
  4344. 3:26:24And then we have watch list type.
  4345. 3:26:28And then we had entity
  4346. 3:26:32ID. Entity type. Sorry, entity type is
  4347. 3:26:36not there. So let me remove this
  4348. 3:26:40or I will just use another column that
  4349. 3:26:43is risk level. Then we have action
  4350. 3:26:47and then we have reason code, reason
  4351. 3:26:50description. After that we need a status
  4352. 3:27:03and then we need effective from
  4353. 3:27:08and after that we need reported by
  4354. 3:27:11reported
  4355. 3:27:13uh source.
  4356. 3:27:18After that we have country and then city
  4357. 3:27:26and then we have something special which
  4358. 3:27:28is rescue data. This one I forgot to
  4359. 3:27:32talk about. We will talk about it. So
  4360. 3:27:35this column what it is? It is a column
  4361. 3:27:37added automatically by autoloader. So
  4362. 3:27:40the table which was created just now
  4363. 3:27:43using autoloader. So this is the column
  4364. 3:27:45like underscore rescued data. So this
  4365. 3:27:49column uh it is created by autoloader
  4366. 3:27:51where it will store any data that is
  4367. 3:27:54corrupted. So in JSON if we get any
  4368. 3:27:56corrupted data which doesn't fit
  4369. 3:27:58correctly into these columns. So that
  4370. 3:28:00data it will put into rescued data. So
  4371. 3:28:03this functionality is provide provided
  4372. 3:28:05automatically by autoloader.
  4373. 3:28:09So it is rescued data and now we are
  4374. 3:28:12left with only one
  4375. 3:28:15uh which is our file path.
  4376. 3:28:20So that one was underscore metadata
  4377. 3:28:26dot file path
  4378. 3:28:28and this one we will give it a alias as
  4379. 3:28:31well. We will name it as source file
  4380. 3:28:36so that we know it is a source file
  4381. 3:28:38path.
  4382. 3:28:41And then we will keep our current time
  4383. 3:28:43stamp as injection timestamp also. And
  4384. 3:28:47you may ask like why did we provide this
  4385. 3:28:49everything in a specific like by putting
  4386. 3:28:52it one by one. So the reason for that is
  4387. 3:28:56so even though in our file we had things
  4388. 3:28:58like watch list ID type in this order
  4389. 3:29:01but it read this entire JSON and the
  4390. 3:29:04order of these columns is not
  4391. 3:29:06guaranteed. So when this table was
  4392. 3:29:08created so if you look at it it has like
  4393. 3:29:11action city country so the column order
  4394. 3:29:14is different that is why we specified
  4395. 3:29:17each and every column so that we get
  4396. 3:29:19these columns in the same order.
  4397. 3:29:22So now this is our parsed streaming df
  4398. 3:29:25that we are returning and this will be
  4399. 3:29:28written into our branch table. So with
  4400. 3:29:30this our brunch uh this uh pipeline it
  4401. 3:29:34is ready now. So let's run it and let's
  4402. 3:29:37see this table created. So now I will go
  4403. 3:29:40ahead and run this pipeline
  4404. 3:29:46and while this is running so the other
  4405. 3:29:48thing to notice is that here also for
  4406. 3:29:50writing part we did not have to specify
  4407. 3:29:53any checkpoint location because it is
  4408. 3:29:55taken care automatically by the SDP
  4409. 3:29:58pipelines.
  4410. 3:29:59So it has been failed saying like no
  4411. 3:30:02such field is there file path. So we
  4412. 3:30:04forgot to put a underscore there. Let me
  4413. 3:30:07put it now.
  4414. 3:30:09So here we need to provide it. Now let
  4415. 3:30:12me run again.
  4416. 3:30:15And now we have a second error which
  4417. 3:30:16says like watch list type is not there.
  4418. 3:30:19So this is actually watch type. It was a
  4419. 3:30:22typo. Let me correct it.
  4420. 3:30:26And this time I missed the spelling
  4421. 3:30:28effective from. So let me correct it.
  4422. 3:30:33And the thing is it will not tell each
  4423. 3:30:35and every error in one go. So we have to
  4424. 3:30:38fix them one by one. And this reported
  4425. 3:30:41source also looks like I made a spelling
  4426. 3:30:44mistake. So sorry for all these typos.
  4427. 3:30:47Uh let me correct them.
  4428. 3:30:50So now we can see it has written those
  4429. 3:30:52four records and it is currently running
  4430. 3:30:54in the continuous mode because after
  4431. 3:30:57last time we did not change it to
  4432. 3:30:59trigger type. So I will stop it manually
  4433. 3:31:02for now.
  4434. 3:31:03And then I will change the trigger type
  4435. 3:31:05to triggered so that for the development
  4436. 3:31:07purpose we can run it only once.
  4437. 3:31:13So now our table it is ready. Let's
  4438. 3:31:15check out our branch table for fraud
  4439. 3:31:17watch list. So here is our table. Let's
  4440. 3:31:21check out our sample data.
  4441. 3:31:24So after working for a few minutes looks
  4442. 3:31:26like the compute is currently not
  4443. 3:31:28available. It is very busy. So this is
  4444. 3:31:30serverless type. So what I will do is I
  4445. 3:31:33will try to copy it in a notebook where
  4446. 3:31:36the
  4447. 3:31:38uh serverless like which is not SQL
  4448. 3:31:41compute the normal serverless compute is
  4449. 3:31:43used. So there let's see if it is
  4450. 3:31:45working fine. So we will try to query
  4451. 3:31:48this table
  4452. 3:31:51and yes here it is working. So if you
  4453. 3:31:54also encounter this kind of problem you
  4454. 3:31:56can try the normal serverless compute.
  4455. 3:31:59So here it is the data is coming
  4456. 3:32:01properly. We can see that the watch list
  4457. 3:32:04ID display level action. So action is in
  4458. 3:32:07upper case these are in lower cases. So
  4459. 3:32:09we will convert them to upper cases when
  4460. 3:32:12we go to silver layer. And then this
  4461. 3:32:14effective from column currently it is a
  4462. 3:32:17string. So we will convert it to
  4463. 3:32:20timestamp when we go there. Other
  4464. 3:32:22columns those are created properly.
  4465. 3:32:25So now is the time to load this
  4466. 3:32:28streaming table into silver layer.
  4467. 3:32:31For creating the silver uh notebook or
  4468. 3:32:34silver silver file for fraud watch list,
  4469. 3:32:37we will simply clone its branch because
  4470. 3:32:40there are only very few things we will
  4471. 3:32:42need to do there. So we will clone it in
  4472. 3:32:44the silver part.
  4473. 3:32:55So this is the clone file
  4474. 3:33:00and we will name it as fraud watch list
  4475. 3:33:02silver.
  4476. 3:33:08And here the name we will change to
  4477. 3:33:12silver schema so that it will create in
  4478. 3:33:14schema silver part. Here we will say
  4479. 3:33:17like we can say cleaned
  4480. 3:33:21uh
  4481. 3:33:22fraud watch list that is the only thing
  4482. 3:33:25we will give here
  4483. 3:33:28and then this one also we will rename it
  4484. 3:33:31to silver
  4485. 3:33:34and for this streaming DF so we don't
  4486. 3:33:37need to like
  4487. 3:33:39uh provide all these things
  4488. 3:33:42because here we will be reading a table
  4489. 3:33:44so we will simply
  4490. 3:33:46provide an option uh dot table and we
  4491. 3:33:50will read our branch table here. So it
  4492. 3:33:53is providing as an suggestion as well.
  4493. 3:33:55So this is our streaming df now or we
  4494. 3:33:58can name it as branch df
  4495. 3:34:03and now in this branch df we will say
  4496. 3:34:07like
  4497. 3:34:08uh cleaned df or standardized df we can
  4498. 3:34:12give it any name it doesn't matter.
  4499. 3:34:15And then
  4500. 3:34:17uh we will make some standardizations
  4501. 3:34:19like this watch list. So we need it in
  4502. 3:34:22the upper case. So we will change it to
  4503. 3:34:25upper case.
  4504. 3:34:27And apart from this watch list ID.
  4505. 3:34:31Uh this entity ID,
  4506. 3:34:34risk level and action these also we will
  4507. 3:34:38change them to upper case.
  4508. 3:34:46So it is done and then current time
  4509. 3:34:49stamp we will keep it as silver
  4510. 3:34:52injection timestamp
  4511. 3:34:54and then rescue data we normally don't
  4512. 3:34:57bring it into silver layer because it's
  4513. 3:34:59uh role it is until brunch for debugging
  4514. 3:35:02and everything and then the existing uh
  4515. 3:35:05injection timestamp column. So that one
  4516. 3:35:08we will name it as bronze injection time
  4517. 3:35:11stamp.
  4518. 3:35:36So it is done and now we need to make
  4519. 3:35:39one final change that is about the
  4520. 3:35:41timestamp column. So if you look into
  4521. 3:35:44the file that we are ingesting. So this
  4522. 3:35:47effective from column it is coming in
  4523. 3:35:50this format. So I will copy this. So
  4524. 3:35:52this format currently it is being
  4525. 3:35:54ingested as a string only. We will need
  4526. 3:35:57to convert it to the actual timestamp
  4527. 3:35:59column. So this one we will select it
  4528. 3:36:03and then I will press control I. We will
  4529. 3:36:06say convert this string
  4530. 3:36:10from this form
  4531. 3:36:15to the actual time stamp
  4532. 3:36:20and it has done it for us. So I will
  4533. 3:36:22accept this change. So this is also
  4534. 3:36:25casted properly.
  4535. 3:36:27And now this cleaned df this is the one
  4536. 3:36:29we want to return and write it into our
  4537. 3:36:32silver table. So now let me go ahead and
  4538. 3:36:35run our pipeline again.
  4539. 3:36:42So now it failed saying that there is
  4540. 3:36:45some invalid character. So let let us
  4541. 3:36:48ask Genie to fix this error. So we will
  4542. 3:36:51simply click diagnose error. It will
  4543. 3:36:53check where is the problem and it will
  4544. 3:36:55fix it.
  4545. 3:36:57So now it has updated these things. It
  4546. 3:36:59is trying to do a dry run. So I will
  4547. 3:37:02accept these changes
  4548. 3:37:04and here the fix it has done is it has
  4549. 3:37:07put alias. So looks like this upper
  4550. 3:37:09function it works only with alias
  4551. 3:37:12and now I will stop it and the next
  4552. 3:37:15error that we have is about this
  4553. 3:37:17metadata file path. So now because this
  4554. 3:37:20uh column file path itself it was there
  4555. 3:37:22in the branch. So underscore metadata
  4556. 3:37:26will not be available. So the actual
  4557. 3:37:28column name will work now. So this time
  4558. 3:37:31it is working fine.
  4559. 3:37:34And here we can see that in our silver
  4560. 3:37:36table it has written four records now.
  4561. 3:37:39So now let's check out these these four
  4562. 3:37:42records. For that we will go to a
  4563. 3:37:44notebook and then just try to query it.
  4564. 3:37:54So we will say fine guard dot silver
  4565. 3:38:01and then dot fraud watch list.
  4566. 3:38:05So here we can see that those four
  4567. 3:38:08records has been written properly. The
  4568. 3:38:10effective from column also it has been
  4569. 3:38:12converted to a proper timestamp column
  4570. 3:38:15and also the watch list ID the watch
  4571. 3:38:19type risk and action these columns also
  4572. 3:38:22has been changed to upper case now and
  4573. 3:38:24rest everything also looks fine. So with
  4574. 3:38:28this uh our fraud watch listed table
  4575. 3:38:31this is ready in the silver layer and if
  4576. 3:38:34we look at the pipeline graph now so we
  4577. 3:38:38can see fraud watch list is being
  4578. 3:38:39ingested parallelly and then
  4579. 3:38:41transactions are being ingested
  4580. 3:38:43parallelly. So now is a good time to
  4581. 3:38:47join both the streams and find some more
  4582. 3:38:51fraud detection scenario and then send
  4583. 3:38:53email. So if we revisit our architecture
  4584. 3:38:56so we can now say that two streams are
  4585. 3:39:00now being ingested in bronze and silver
  4586. 3:39:02and the next part we will work on this
  4587. 3:39:04stream stream join. This is going to be
  4588. 3:39:07interesting
  4589. 3:39:09and before we actually do it there are
  4590. 3:39:11some two three concepts that we need to
  4591. 3:39:14understand first so that once we are
  4592. 3:39:16clear with those concepts then when we
  4593. 3:39:19do the implementation it will be clear.
  4594. 3:39:21So let's understand those concepts
  4595. 3:39:23first.
  4596. 3:39:24So first of all let's understand the
  4597. 3:39:26concept of stateless versus stateful
  4598. 3:39:29stream processing. So so far what
  4599. 3:39:32whatever we did with the transactions
  4600. 3:39:34only data. So there we did a stateless
  4601. 3:39:37stream processing. There what it means
  4602. 3:39:40is that no memory of past events is
  4603. 3:39:42required and each event is processed
  4604. 3:39:44independently. So whenever we received
  4605. 3:39:47the transactions event from Kafka so
  4606. 3:39:50each and every event it was processed
  4607. 3:39:52independently and there was no
  4608. 3:39:55dependency on other events. So as and
  4609. 3:39:58when we were getting each event we were
  4610. 3:40:00processing them. So there was no
  4611. 3:40:01interdependency among events. So that is
  4612. 3:40:04why it is called as stateless stream
  4613. 3:40:07processing.
  4614. 3:40:08On the other hand we have second type
  4615. 3:40:10which is stateful stream processing. So
  4616. 3:40:13this it it need to maintain some state
  4617. 3:40:17or memory of past events to process the
  4618. 3:40:20current event.
  4619. 3:40:22So how it works is new events keep
  4620. 3:40:24coming. We do some processing and we
  4621. 3:40:27keep some memory for some time. How how
  4622. 3:40:30much time and all we can control it. We
  4623. 3:40:32will see. But we have some memory. So
  4624. 3:40:34new events they keep coming. We check
  4625. 3:40:37something in the memory and then we
  4626. 3:40:38process them and then we write some
  4627. 3:40:41output. So we need some kind of state
  4628. 3:40:43for this and that is why these are
  4629. 3:40:46called as stateful stream processing.
  4630. 3:40:49And if you take some example so
  4631. 3:40:52stateless it can be simple filter event
  4632. 3:40:55uh like we used wherever we we filtered
  4633. 3:40:57out the transaction amount greater than
  4634. 3:40:59some value. So if you have some fixed
  4635. 3:41:02value that can be a simple filter event.
  4636. 3:41:04If we have a simple map like one to one
  4637. 3:41:08record transformation we want to do like
  4638. 3:41:10casting conversion something like that
  4639. 3:41:13or if you want to enrich it with some
  4640. 3:41:14static data. So in our case we combined
  4641. 3:41:18our transaction with the customer static
  4642. 3:41:21data. So that kind of processing also
  4643. 3:41:23comes into stateless or if you want to
  4644. 3:41:26do some simple routing like based on
  4645. 3:41:28some value if you want to route between
  4646. 3:41:30different tables or various routes. So
  4647. 3:41:33for that we don't want any memory. So
  4648. 3:41:36that is why these examples come under
  4649. 3:41:38stateless wherein stateful there are
  4650. 3:41:41different type of example like if we
  4651. 3:41:43want to do some rolling window
  4652. 3:41:45aggregation. Let's say if you want to
  4653. 3:41:47know every 5 minutes how many
  4654. 3:41:49transactions are coming. So for that for
  4655. 3:41:525 minutes we need to keep counting and
  4656. 3:41:55keep things in memory. So that is why it
  4657. 3:41:57is there. And if you want to do like per
  4658. 3:42:00user session if you want to capture some
  4659. 3:42:02detail for some kind of processing for
  4660. 3:42:05running total counts like how many
  4661. 3:42:08records or how many events are coming in
  4662. 3:42:10total. So for that thing or for advanced
  4663. 3:42:14fraud detection also that we will do now
  4664. 3:42:16there also we will need a stateful kind
  4665. 3:42:19of processing. So simply putting on
  4666. 3:42:23stateless there is no state on stateful
  4667. 3:42:25we maintain a state in stateless the
  4668. 3:42:28latency it is less because as soon as we
  4669. 3:42:30are getting the data we are processing
  4670. 3:42:32each and every event in a stateful there
  4671. 3:42:36can be some latency and that will depend
  4672. 3:42:39on how much memory we are keeping. This
  4673. 3:42:42one we will see next how do we control
  4674. 3:42:44it. On stateless the resource usage is
  4675. 3:42:47less because we don't need memory and
  4676. 3:42:50single record processing can be there.
  4677. 3:42:52Here resource usage is more because we
  4678. 3:42:55need to process multiple set of records
  4679. 3:42:57together. This is easier to scale and
  4680. 3:43:00manage wherein stateful it is for
  4681. 3:43:02powerful use cases. So it is slightly
  4682. 3:43:06difficult to manage but it is worth it
  4683. 3:43:08because that is the use case that we
  4684. 3:43:10need. So this is the core definition of
  4685. 3:43:13stateless and stateful and to maintain
  4686. 3:43:16some of the things in stateful like how
  4687. 3:43:19do we handle late arriving data or how
  4688. 3:43:21much memory up to how much time we want
  4689. 3:43:24to keep the memory all these things we
  4690. 3:43:26need to control. So to control all these
  4691. 3:43:29things we need something called as
  4692. 3:43:31watermarking.
  4693. 3:43:33So watermarking this is a kind of
  4694. 3:43:36concept and a functionality in
  4695. 3:43:38structured streaming. So this is what is
  4696. 3:43:40a watermark. It is a threshold on the
  4697. 3:43:43event time. So here what we do is we
  4698. 3:43:46define a timing window like how much
  4699. 3:43:50late data we can consider when it is
  4700. 3:43:53arriving late. So we put some threshold.
  4701. 3:43:56So whatever data is earlier than that
  4702. 3:43:58threshold that will be considered final
  4703. 3:44:01and whatever data that is that we are
  4704. 3:44:04getting after after that threshold uh
  4705. 3:44:07limit. So that data we will not use. So
  4706. 3:44:11if we understand it from an example. So
  4707. 3:44:14let's say we are getting some data and
  4708. 3:44:16we have configured our watermark is 10
  4709. 3:44:19minutes. So how it works is so let's say
  4710. 3:44:23we are getting these different different
  4711. 3:44:25events on a particular time and the
  4712. 3:44:27latest event that we have that is from
  4713. 3:44:2912:30.
  4714. 3:44:31So if our watermark is 10 minute uh is
  4715. 3:44:3310 minutes then the current watermark
  4716. 3:44:36value or the latest allowed limit of the
  4717. 3:44:39data that will be 10 minutes before the
  4718. 3:44:42latest data point. So for this example
  4719. 3:44:45it will be 1220.
  4720. 3:44:47So whatever data is earlier than 1220
  4721. 3:44:50that data will be ignored. It will not
  4722. 3:44:52be considered and if the data is within
  4723. 3:44:56these 10 minutes that will be considered
  4724. 3:44:58for processing. So that is how this
  4725. 3:45:00watermarking it works. And how do we
  4726. 3:45:04define it? So we define it using this
  4727. 3:45:07with watermark. We give a column name
  4728. 3:45:09the the column that we are going to use
  4729. 3:45:12for watermarking. Then the value whether
  4730. 3:45:15it is minutes, seconds or hours. So most
  4731. 3:45:18cases it is a few minutes but it it
  4732. 3:45:20depends on the use case. But this is how
  4733. 3:45:23we define it. And then there is one
  4734. 3:45:26important aspect of it that is sometimes
  4735. 3:45:28misunderstood that whenever we have
  4736. 3:45:30defined this 10 minutes. So this 10
  4737. 3:45:33minute it is considered based on the
  4738. 3:45:36latest value received of this column. So
  4739. 3:45:39it is not like 10 minutes before the
  4740. 3:45:42current time. It is before the latest
  4741. 3:45:45value of this column. That is how the
  4742. 3:45:47watermarking works.
  4743. 3:45:49And these these are some key points that
  4744. 3:45:52this is used to handle late arriving
  4745. 3:45:54data. So here we define a threshold like
  4746. 3:45:57up to 10 minutes of late data we will
  4747. 3:46:00allow earlier than that like or older
  4748. 3:46:02than that we will not allow and with
  4749. 3:46:06this we get a kind of bounded state. So
  4750. 3:46:09we get a fixed window that we will
  4751. 3:46:11process and that this much of data we
  4752. 3:46:14will keep in memory and with this way we
  4753. 3:46:17get some accurate results because
  4754. 3:46:19otherwise there is no limit in the
  4755. 3:46:20streaming data how much data we can
  4756. 3:46:23process. So now in our use case we are
  4757. 3:46:27going to join to streaming data. So to
  4758. 3:46:30join to streaming data defining the
  4759. 3:46:32watermarks is important. So that
  4760. 3:46:34whatever data is falling within that
  4761. 3:46:37watermark values or that window of that
  4762. 3:46:41watermark that data will be considered
  4763. 3:46:43for joining. So continuously the data
  4764. 3:46:46will be coming whatever data is falling
  4765. 3:46:48within that window that will be joining
  4766. 3:46:52and then we will be getting the results.
  4767. 3:46:54And if some data arrives later than that
  4768. 3:46:56window or some like the value is late
  4769. 3:47:00value is like less than the watermark
  4770. 3:47:02and it is received after the processing
  4771. 3:47:05time then it will be ignored. That is
  4772. 3:47:07how the join will actually work. So now
  4773. 3:47:10let's go ahead and implement this
  4774. 3:47:12scenario.
  4775. 3:47:14So now to implement that scenario we are
  4776. 3:47:17back in our pipeline and to join both
  4777. 3:47:20the streams we will build another goal
  4778. 3:47:23table which will be doing like join of
  4779. 3:47:26the streams and then preparing another
  4780. 3:47:28kind of alert that alert we will name it
  4781. 3:47:31name it as fraud card alerts. So what
  4782. 3:47:35how what we are assuming is that
  4783. 3:47:37whatever data we are getting through
  4784. 3:47:39this watch list. So all those cards has
  4785. 3:47:42been marked for marked as inactive or
  4786. 3:47:46for related to fraud. So whatever
  4787. 3:47:48transactions we will be getting for
  4788. 3:47:50those cards. So those we will be
  4789. 3:47:53considering as fraud and we will be
  4790. 3:47:55sending an alert. So let's go ahead and
  4791. 3:47:58join both the streams.
  4792. 3:48:00And to do that we will uh copy this
  4793. 3:48:02ready to use code here the one we
  4794. 3:48:05prepared earlier.
  4795. 3:48:07So let me copy this much of the code
  4796. 3:48:11and then we will prepare another file
  4797. 3:48:13inside this gold one
  4798. 3:48:18and this one we will name it as
  4799. 3:48:24road
  4800. 3:48:26card alert.
  4801. 3:48:30So let me paste the code here. So this
  4802. 3:48:33will be same. This one we need to rename
  4803. 3:48:36it.
  4804. 3:48:41And this function name also we can name
  4805. 3:48:44the same.
  4806. 3:48:46And here as you can see one stream we
  4807. 3:48:49are already creating for transactions
  4808. 3:48:51and customers. So this also we will be
  4809. 3:48:54using it later on so that we can bring
  4810. 3:48:57in the email id to send the email. Uh
  4811. 3:49:00but this one we will be using it later
  4812. 3:49:02on. First we will join the second stream
  4813. 3:49:04here. So let's bring in the fraud watch
  4814. 3:49:07list.
  4815. 3:49:12So it will be similar like spark dot
  4816. 3:49:16readstream dot table
  4817. 3:49:23and it will be fine guard
  4818. 3:49:27dot silver
  4819. 3:49:30dot fraud watch list.
  4820. 3:49:34So now both the streams are ready. Next
  4821. 3:49:37what we are going to do is we are going
  4822. 3:49:40to add the watermarks to these so that
  4823. 3:49:43we can perform the join and to add the
  4824. 3:49:46watermark we will name those as like
  4825. 3:49:49transactions with watermark
  4826. 3:49:53and then we will say oh it is providing
  4827. 3:49:55some automatic suggestion so I will
  4828. 3:49:58press tab here so for customers we don't
  4829. 3:50:01need a watermark
  4830. 3:50:03and this is the syntax of watermark like
  4831. 3:50:06I was talking earlier here. So this is
  4832. 3:50:08the transaction column that it will be
  4833. 3:50:10using and currently it is saying 1 hours
  4834. 3:50:13but we don't need that much of a big
  4835. 3:50:16window. We will simply keep it 5 minutes
  4836. 3:50:21and then for fraud also like the column
  4837. 3:50:24that is there. So we will be using the
  4838. 3:50:26effective
  4839. 3:50:28pro column and then the watermark also
  4840. 3:50:32we will keep it 5 minutes. In practical
  4841. 3:50:35scenarios, it can be like multiple hours
  4842. 3:50:38also because the transaction that will
  4843. 3:50:40be happening and when it will be marked
  4844. 3:50:42for fraud. So we want more overlapping
  4845. 3:50:45for that or in real scenarios it can be
  4846. 3:50:48even in days. Uh that is also practical.
  4847. 3:50:51But in our case we will keep it 5
  4848. 3:50:53minutes so that within 5 minutes
  4849. 3:50:56whatever fraud card we are getting and
  4850. 3:50:58whatever transaction is happening for
  4851. 3:51:00that card that will be considered as
  4852. 3:51:03fraud.
  4853. 3:51:05So now we we have like provided a
  4854. 3:51:08boundary to the streaming data that uh
  4855. 3:51:12this watermark 5 minutes. So within 5
  4856. 3:51:15minutes it will keep doing joining and
  4857. 3:51:17whatever data is matching that it will
  4858. 3:51:20uh keep providing in our output table
  4859. 3:51:22and the data that will arrive later than
  4860. 3:51:255 minutes that will be ignored
  4861. 3:51:26automatically.
  4862. 3:51:28So now let's go ahead and detect this as
  4863. 3:51:31a fraud. So we will say that uh fraud
  4864. 3:51:36detected equals to we will be doing
  4865. 3:51:39multiple things here. So first of all
  4866. 3:51:42obviously it will be a join. So it is
  4867. 3:51:44providing this as a suggestion.
  4868. 3:51:48So we will take our transactions with
  4869. 3:51:51watermark dot join
  4870. 3:51:57and in this join uh first we will pass
  4871. 3:51:59the fraud watch list with watermark
  4872. 3:52:04and then we need to pass the joining
  4873. 3:52:06column.
  4874. 3:52:08So we will say that from this
  4875. 3:52:11transaction part we will be taking the
  4876. 3:52:14card number
  4877. 3:52:21and it shall be equal to uh in the watch
  4878. 3:52:24list it the column name it is entity ID.
  4879. 3:52:29So when both are matching that means it
  4880. 3:52:32is a fruit and the join type here it
  4881. 3:52:35this one we have to take it as inner
  4882. 3:52:37join. Why? Because once the entry is
  4883. 3:52:41available on both sides then only it is
  4884. 3:52:43a fraud otherwise it is not a fraud. And
  4885. 3:52:47this inner it will work because of our
  4886. 3:52:49watermark so that it will detect
  4887. 3:52:51everything within the 5 minutes.
  4888. 3:52:54So now we have detected our fraud. The
  4889. 3:52:57next thing we need is a email id so that
  4890. 3:53:00we can send the email. So we will now
  4891. 3:53:03join our customer table. And this one as
  4892. 3:53:06we know so it is not a streaming table.
  4893. 3:53:08It is kind of a lookup table. So this
  4894. 3:53:11one we will join customers. And this
  4895. 3:53:14joining condition we already know it is
  4896. 3:53:16like customer ID on both sides. So we
  4897. 3:53:20will take this one dot
  4898. 3:53:22customer id equals
  4899. 3:53:27uh then we will say customers dot
  4900. 3:53:29customer id
  4901. 3:53:34and then the join type.
  4902. 3:53:38So join type here uh this one it will be
  4903. 3:53:41left join because stream directly like
  4904. 3:53:45uh we shall not do inner join here
  4905. 3:53:49because like it is a lookup table and
  4906. 3:53:51when whenever email id is available that
  4907. 3:53:54we shall join and now our tables are
  4908. 3:53:58ready tables or the data frame. Next we
  4909. 3:54:01need to select the columns or the
  4910. 3:54:03details whatever we need to do here. So
  4911. 3:54:07this time let me pause it and type
  4912. 3:54:09everything first. So here I have typed
  4913. 3:54:12it. So similar similar to our
  4914. 3:54:15transaction with higher value we are
  4915. 3:54:17generating a alert ID. This time we are
  4916. 3:54:19saying it is a like fraud transaction
  4917. 3:54:22ID- watch list ID and then
  4918. 3:54:27alert type we are saying it is like
  4919. 3:54:29fraud watch list match and alert
  4920. 3:54:32timestamp we are taking as the current
  4921. 3:54:33time stamp. Then we are taking the
  4922. 3:54:36columns from like transaction ID,
  4923. 3:54:38customer ID and customer email also we
  4924. 3:54:41are taking that we will use to send the
  4925. 3:54:44email. Uh customer first name and last
  4926. 3:54:46name we are preparing and then multiple
  4927. 3:54:49columns we are taking from the uh
  4928. 3:54:52transactions. So all these columns are
  4929. 3:54:54direct selection city and all these we
  4930. 3:54:57are putting an alias to understand these
  4931. 3:54:59better. And then
  4932. 3:55:02uh from the watch list side also we are
  4933. 3:55:04selecting watch list ID, type all these
  4934. 3:55:07columns and effective from we are
  4935. 3:55:09renaming this column like watch list is
  4936. 3:55:11effective from and then these are as it
  4937. 3:55:14is and then uh city and country also we
  4938. 3:55:18are marking that this is watch list city
  4939. 3:55:20and country so that it is not like uh
  4940. 3:55:24misunderstood with the customer city
  4941. 3:55:26country etc.
  4942. 3:55:28So with this all the columns that we
  4943. 3:55:30want we have selected that and now our
  4944. 3:55:33table will be created automatically.
  4945. 3:55:37So now this table it will contain the
  4946. 3:55:40alert data like we had for transaction
  4947. 3:55:43alert and the next thing we need is the
  4948. 3:55:46actual alert. So for that we will need
  4949. 3:55:49to create this kind of sync and this
  4950. 3:55:51time we will not type everything. We
  4951. 3:55:53will use Genie code because it will be a
  4952. 3:55:55similar activity.
  4953. 3:55:57So let me open Genie code here and let's
  4954. 3:56:01start a new thread
  4955. 3:56:05and the prompt that we need to provide
  4956. 3:56:07here. First let's prepare that prompt
  4957. 3:56:09separately so that we can understand and
  4958. 3:56:12then we will paste it here. So how we
  4959. 3:56:14will provide it? We will say that we
  4960. 3:56:17have prepared this file which reads this
  4961. 3:56:19table and send an email notification.
  4962. 3:56:22Similarly prepare for this one.
  4963. 3:56:27So we will copy this name.
  4964. 3:56:33We will say that
  4965. 3:56:36there are high value
  4966. 3:56:42transaction alerts
  4967. 3:56:47logged in the table.
  4968. 3:56:52which are fraud
  4969. 3:56:55and an email is
  4970. 3:56:59sent using the file.
  4971. 3:57:03Let me copy the other file name
  4972. 3:57:14this file name. So we will say this is
  4973. 3:57:18working fine.
  4974. 3:57:21I want
  4975. 3:57:24you to implement or we can say like
  4976. 3:57:28create a new alert file
  4977. 3:57:33that read the road data from. Then we
  4978. 3:57:38will give our table name. So the table
  4979. 3:57:41name will be this one.
  4980. 3:57:49this table and send email
  4981. 3:57:54notification
  4982. 3:57:55and this table it is not yet created. So
  4983. 3:57:58let's give it the file name also so that
  4984. 3:58:01it can understand what all columns are
  4985. 3:58:03there. So we will say this table
  4986. 3:58:07prepared by this file.
  4987. 3:58:10So this is the prompt that we are going
  4988. 3:58:12to provide. Let's see how much it is
  4989. 3:58:15able to write for us. So I have typed
  4990. 3:58:18it. I will press enter. So it is
  4991. 3:58:21currently understanding all the details.
  4992. 3:58:23Now it will create a new file.
  4993. 3:58:26So looks like it has created this file.
  4994. 3:58:31So currently it seemed to be blank. It
  4995. 3:58:34is updating the file. And now it has
  4996. 3:58:37created the file but it is not able to
  4997. 3:58:40write the data. It is saying that
  4998. 3:58:42similar safety alert because we are
  4999. 3:58:45using the SMTP API call. So it has
  5000. 3:58:48provided the code. So I will need to
  5001. 3:58:50copy the code from here and then paste
  5002. 3:58:52it. So now I have pasted the code and
  5003. 3:58:57let me close this right side. Let's have
  5004. 3:58:59a look at the code. So the code is
  5005. 3:59:01similar only. This is our send email
  5006. 3:59:03function. This is the function that is
  5007. 3:59:06creating the body of the email with so
  5008. 3:59:08many details. And then there are these
  5009. 3:59:11other functions. So this one it is uh
  5010. 3:59:14reading our fraud alert card sorry fraud
  5011. 3:59:17card alert table as a streaming table
  5012. 3:59:20and it will keep appending the data
  5013. 3:59:22using append flow to this target sync
  5014. 3:59:26and what is this sync it is this one. So
  5015. 3:59:28here it will send that data as a data
  5016. 3:59:31frame and batch ID. It will it is
  5017. 3:59:34reading all the API key and preparing
  5018. 3:59:36the app password. Then the data that has
  5019. 3:59:39been read as a data frame. So it is
  5020. 3:59:41collecting all the rows. Then it is
  5021. 3:59:44going row by row here and after that it
  5022. 3:59:47is preparing the body of the email using
  5023. 3:59:50the above function and then it is
  5024. 3:59:52sending the email using above function.
  5025. 3:59:54So structure wise it is exactly same to
  5026. 3:59:56the other file and it will send the
  5027. 3:59:59alert notification.
  5028. 4:00:01So now this piece has been set up end to
  5029. 4:00:03end. So now let's see it in action. So
  5030. 4:00:07what I will do is I will change it to
  5031. 4:00:10continuous mode so that we can start it
  5032. 4:00:13and then send our data and see it in
  5033. 4:00:15action. So I have changed it
  5034. 4:00:18and now it is starting our pipeline
  5035. 4:00:22and this pipeline it seem to be having
  5036. 4:00:24an issue that comes up for a second and
  5037. 4:00:26then goes away. This is happening due to
  5038. 4:00:29continuous mode. So for debugging for
  5039. 4:00:32now let me change it to triggered
  5040. 4:00:35and let me stop it manually and then
  5041. 4:00:38let's do our first run as a batch kind
  5042. 4:00:42of run or one time run.
  5043. 4:00:45So now we are getting the actual error.
  5044. 4:00:47It is saying that transaction timestamp
  5045. 4:00:50it has the invalid type string but it is
  5046. 4:00:53expecting a time stamp. So probably we
  5047. 4:00:57have created our transaction timestamp
  5048. 4:00:59as string type we can see here. So this
  5049. 4:01:02one it needs to be of timestamp type. So
  5050. 4:01:06what we will do do is here we will
  5051. 4:01:08change it to timestamp type.
  5052. 4:01:13So it has been changed and now we will
  5053. 4:01:16run again but this time we will not do a
  5054. 4:01:18run pipeline instead we will do a full
  5055. 4:01:21refresh. So whenever we are making some
  5056. 4:01:24changes that can affect our historic
  5057. 4:01:26data so while development so for that we
  5058. 4:01:29need to do a full load so that it will
  5059. 4:01:32recreate the tables. So this time we
  5060. 4:01:34will do a full table refresh.
  5061. 4:01:40So this time the error is that we are
  5062. 4:01:42not returning anything probably it is
  5063. 4:01:44saying it is returning none type. So
  5064. 4:01:47let's jump to the code
  5065. 4:01:50and here we can see that this fraud that
  5066. 4:01:52we had detected. So we did not put a
  5067. 4:01:55return statement to this one. So let's
  5068. 4:01:58put it
  5069. 4:02:06now. Let's run it again.
  5070. 4:02:12And this time code wise things looks
  5071. 4:02:14good. So it has started the pipeline. So
  5072. 4:02:17first it is running the bronze layer
  5073. 4:02:19tables. So for fraud watch list in total
  5074. 4:02:22we have four records only. It has
  5075. 4:02:23written those and same it has written to
  5076. 4:02:27silver fraud list as well. And for
  5077. 4:02:30transactions also it has read all the
  5078. 4:02:32records again and then it has written to
  5079. 4:02:35silver layer as well. And then high
  5080. 4:02:38value transaction alert it has generated
  5081. 4:02:40one one record and for that it will be
  5082. 4:02:44sending the email as well. And for fraud
  5083. 4:02:47watch list it has detected two alerts.
  5084. 4:02:51So we have two such records based on
  5085. 4:02:53these four cards that were there. Two
  5086. 4:02:56transactions has been marked and it has
  5087. 4:02:58sent the email as well. And if you see
  5088. 4:03:01my email id so these are the three
  5089. 4:03:04emails that we have received. This is
  5090. 4:03:06the similar high value transaction
  5091. 4:03:08alert. The same email that we had got
  5092. 4:03:10previously. And this is the new email
  5093. 4:03:12for that uh fraud card related alert.
  5094. 4:03:16And depending on the risk, it is saying
  5095. 4:03:18whether it is high or low risk. And then
  5096. 4:03:20it is providing all these very detailed
  5097. 4:03:24uh all the details here. And we can see
  5098. 4:03:26the formatting also it looks really nice
  5099. 4:03:29here. This is because of the detailed
  5100. 4:03:31HTML code that Genie has generated for
  5101. 4:03:34us. So if you are fine with this then we
  5102. 4:03:36are good. Otherwise we can ask Genie to
  5103. 4:03:39customize it as well however we want to.
  5104. 4:03:43So this is how our stream and stream to
  5105. 4:03:46stream join is also working fine. And
  5106. 4:03:49now if we go and check our pipeline
  5107. 4:03:51graph. So this time it looks like more
  5108. 4:03:53interesting if I make it like uh bigger.
  5109. 4:03:57So this is how it will look like. So
  5110. 4:03:59both the streams are coming until silver
  5111. 4:04:02layer. For high transaction we are using
  5112. 4:04:04only one and sending the email. For
  5113. 4:04:07fraud card card alert we are joining the
  5114. 4:04:10both and then sending the email alert.
  5115. 4:04:12That is how it is working. And each and
  5116. 4:04:15at each and every step it is showing the
  5117. 4:04:18number of records as well. How many
  5118. 4:04:20records has been uh generated at each
  5119. 4:04:23and every stage so that we get proper
  5120. 4:04:26visibility.
  5121. 4:04:28So now as we have understood stream to
  5122. 4:04:30stream join as well. The next thing we
  5123. 4:04:33are going to understand is how can we do
  5124. 4:04:36aggregations on streaming data and
  5125. 4:04:39aggregations again it is it will be a
  5126. 4:04:41challenging piece because let's say if
  5127. 4:04:44we want to get number of transactions.
  5128. 4:04:47So if we uh if we go ahead and do number
  5129. 4:04:49of transactions like count of
  5130. 4:04:51transactions. So by default on streaming
  5131. 4:04:54data it will keep getting keep getting
  5132. 4:04:57keep adding more transaction and uh it
  5133. 4:05:00is kind of continuous right so there is
  5134. 4:05:02no limit when it will stop and give us
  5135. 4:05:04the count that this is the count. So
  5136. 4:05:07there also we need to provide some
  5137. 4:05:09boundary how much data we want or how
  5138. 4:05:13much after how much time we want to do
  5139. 4:05:15the aggregation and to to provide that
  5140. 4:05:19uh time limit we have some
  5141. 4:05:22functionalities specific to streaming
  5142. 4:05:24data that is called a window and we have
  5143. 4:05:27mainly two types of window that we can
  5144. 4:05:29use. So let's go ahead and understand
  5145. 4:05:31those.
  5146. 4:05:33So the two types that we have those are
  5147. 4:05:35tumbling window and sliding window and
  5148. 4:05:38this this one we call it as bounding the
  5149. 4:05:41unbounded stream because using these we
  5150. 4:05:43provide some boundary. So first let's
  5151. 4:05:46understand the tumbling window. So this
  5152. 4:05:50one it is like a nonover overlapping
  5153. 4:05:52fixed size window and how what what it
  5154. 4:05:56means by that is let's say here we are
  5155. 4:05:58getting some events continuously and we
  5156. 4:06:01define a window of let's say 10 minutes.
  5157. 4:06:04So 0 to 10 minute it is one window 10 to
  5158. 4:06:0720 it is window number two 20 to 30 it
  5159. 4:06:10is third window. So these three are
  5160. 4:06:13fixed size window which do not overlap
  5161. 4:06:16with each other and in this case each
  5162. 4:06:18event belongs to one window. So wherever
  5163. 4:06:21the event is it will belong to only one
  5164. 4:06:24window and results are produced when the
  5165. 4:06:27window closes. So it will keep getting
  5166. 4:06:29the data keep getting the data whenever
  5167. 4:06:31it will reach that 10 second then it
  5168. 4:06:33will provide the aggregation value
  5169. 4:06:35whatever is required. And the second
  5170. 4:06:38type of window that we have is sliding
  5171. 4:06:40window. So sliding window as the name
  5172. 4:06:43suggest it keeps sliding. So in the
  5173. 4:06:46similar case if we have this data from 0
  5174. 4:06:49to 30 minutes. So here also window size
  5175. 4:06:52is 10 minutes only but we keep sliding
  5176. 4:06:56this. So for example 0 to 10 minute it
  5177. 4:07:00is one window. Then 5 to 15 minutes.
  5178. 4:07:03This is our second window. So this
  5179. 4:07:05window it seem to be slided by 5
  5180. 4:07:08minutes. Then uh 10 to 20 is another
  5181. 4:07:12window. 15 to 25 is another window. Then
  5182. 4:07:1520 to 30 window comes. So within the
  5183. 4:07:18same time of 30 minutes here we had
  5184. 4:07:21these three windows. Here we have five
  5185. 4:07:23windows because the same window it keeps
  5186. 4:07:26sliding. So here we can say that window
  5187. 4:07:28have a has a size and a slide interval.
  5188. 4:07:32So what it means is that we will need to
  5189. 4:07:34provide two parameter whenever we
  5190. 4:07:36configure it. One will be the size, one
  5191. 4:07:38will be the interval. In case of
  5192. 4:07:41tumbling, we will only provide the size.
  5193. 4:07:44And here windows can overlap. And
  5194. 4:07:46because these can overlap, so whatever
  5195. 4:07:48event is there that may belong to one
  5196. 4:07:51window or two windows as well.
  5197. 4:07:54So in a nutshell, we use tumbling window
  5198. 4:07:58for simple non-over overlapping
  5199. 4:08:00aggregation. Let's say if you want count
  5200. 4:08:03of transactions every 10 minute then we
  5201. 4:08:06can use this kind of window and let's
  5202. 4:08:08say if you want more frequent up toate
  5203. 4:08:10insight let's say we want every 5 minute
  5204. 4:08:14we want the number of transaction of
  5205. 4:08:16last 10 minutes then we use this kind of
  5206. 4:08:19window that so that here it will give
  5207. 4:08:21these 10 minutes here it will give these
  5208. 4:08:2410 minutes here it will give these 10
  5209. 4:08:26minutes so these are more up to date
  5210. 4:08:28because every 5 minute we are getting
  5211. 4:08:31the data of last 10 minutes. We can do
  5212. 4:08:33it like every 1 minute also and window
  5213. 4:08:36size of five or 10 minutes. So that is
  5214. 4:08:39how we can customize it. So these are
  5215. 4:08:41the two types of windows that we can use
  5216. 4:08:44and do some aggregation. So let's now
  5217. 4:08:46understand how practically we can do it.
  5218. 4:08:50So to do that piece we will again create
  5219. 4:08:52another gold table. So for that let me
  5220. 4:08:56copy this piece of code from here and
  5221. 4:08:58then we will create a new file here
  5222. 4:09:02and this one uh we will name it as
  5223. 4:09:08transaction count. We will count the
  5224. 4:09:10number of transaction and then we will
  5225. 4:09:13say by
  5226. 4:09:15minute. We will try to do it every
  5227. 4:09:17minute.
  5228. 4:09:20So here I think I forgot to put the dot.
  5229. 4:09:24So it gave a warning. Let me type it
  5230. 4:09:26again.
  5231. 4:09:33And then here let me paste the code that
  5232. 4:09:36I had copied. And then let me copy this
  5233. 4:09:39name.
  5234. 4:09:47And then we will create a table with
  5235. 4:09:50this name. And this function also let's
  5236. 4:09:52give it the name. And here because we
  5237. 4:09:55are counting the number of transactions.
  5238. 4:09:57So this stream only we will be using.
  5239. 4:10:01So now before we do the aggregation
  5240. 4:10:03using window here also we will need to
  5241. 4:10:06specify a watermark so that we can we
  5242. 4:10:10can tell it how much late data we are
  5243. 4:10:12allowing it.
  5244. 4:10:15So that like uh it it will wait for that
  5245. 4:10:17much of time and then it will do the
  5246. 4:10:19aggregation.
  5247. 4:10:21So if we go back there so this same
  5248. 4:10:24watermark we will add here.
  5249. 4:10:27So here also we are saying that we will
  5250. 4:10:30allow the late data by 5 minutes.
  5251. 4:10:34And now we have everything. So now we
  5252. 4:10:36will do the actual aggregation. So what
  5253. 4:10:39we will do is we will say transaction
  5254. 4:10:46count equals to we will take this
  5255. 4:10:50watermark value
  5256. 4:10:52and then do a group by first.
  5257. 4:10:58So it is providing a suggestion here and
  5258. 4:11:01in the group by this is where we need to
  5259. 4:11:04specify our window. So the window that
  5260. 4:11:07we are going to use is it will be f dot
  5261. 4:11:10window
  5262. 4:11:13and then we will mention the timestamp
  5263. 4:11:16column that we will use for preparing
  5264. 4:11:19the window and then similar way we need
  5265. 4:11:22to mention the size of the window.
  5266. 4:11:26So this is how we will specify and
  5267. 4:11:30window size this time we will keep it 1
  5268. 4:11:32minute only. So this will be our
  5269. 4:11:34tumbling window. So every 1 minute it
  5270. 4:11:38will do the count of transactions.
  5271. 4:11:41So so far this is just the group by
  5272. 4:11:43part. Now let's mention it what we want
  5273. 4:11:46after doing the group by. So simply we
  5274. 4:11:49want like f dot countstar
  5275. 4:11:55and this count star that it will do we
  5276. 4:11:58will name it as
  5277. 4:12:02transaction count
  5278. 4:12:10and after doing the count we want to
  5279. 4:12:13select what data we want in the output
  5280. 4:12:16table. So in the select also there is
  5281. 4:12:19something specific to the window.
  5282. 4:12:23So when we say f dot column so the
  5283. 4:12:26window that we are using so we have
  5284. 4:12:28window dot start and window dot end
  5285. 4:12:31timestamps that we can take. So I will
  5286. 4:12:34press tab here and this window dot start
  5287. 4:12:38this one I will name it as window
  5288. 4:12:41start as a column
  5289. 4:12:45and then window dot end that we will
  5290. 4:12:48name it as window end and after that we
  5291. 4:12:51will take our transaction count and
  5292. 4:12:53that's all. So in our target table these
  5293. 4:12:56will be the three column we will be
  5294. 4:12:58creating. So we will see a window start
  5295. 4:13:00time, end time and the count of
  5296. 4:13:03transactions within that window. And now
  5297. 4:13:06this uh this is ready. So this name may
  5298. 4:13:10be confusing for this. So I will name
  5299. 4:13:13this one as DF because it is a data
  5300. 4:13:15frame. And this is what we will return
  5301. 4:13:20so that it doesn't fail this time. So
  5302. 4:13:22this is what it will create this as a
  5303. 4:13:24data frame and then this data frame it
  5304. 4:13:28will be written into this particular
  5305. 4:13:30table here. So now let's go ahead and
  5306. 4:13:33give it a try. So I'm going to run the
  5307. 4:13:35pipeline.
  5308. 4:13:38And this time also it failed with some
  5309. 4:13:40error saying like column object is not
  5310. 4:13:43callable. So if we jump to the code, it
  5311. 4:13:45is pointing something here. So let's
  5312. 4:13:48diagnose the error and let's see uh what
  5313. 4:13:51is the fix for this one. So now it has
  5314. 4:13:54made the changes. So looks like it made
  5315. 4:13:57it okay three places. So here we can see
  5316. 4:14:00it was a minor issue. So just this
  5317. 4:14:03bracket it has to be right side the
  5318. 4:14:07group Y. So let me accept this. And now
  5319. 4:14:10let's see what other change it has made.
  5320. 4:14:15So it has also made some change in this
  5321. 4:14:17alert not uh email notifier
  5322. 4:14:26and here what it is trying to do is
  5323. 4:14:29earlier this app password and this
  5324. 4:14:31secrets get it was inside this function
  5325. 4:14:34so for every batch it was calling it
  5326. 4:14:37again and again now it is putting it
  5327. 4:14:39outside so it will be optimized and
  5328. 4:14:42probably these warnings things like not
  5329. 4:14:44serializable these also it will be gone
  5330. 4:14:47because I think it noticed that and then
  5331. 4:14:49fixed it so that is also good for us so
  5332. 4:14:52I will simply accept all the changes now
  5333. 4:14:55and then let's go ahead and run it
  5334. 4:14:59so this time the pipeline has been
  5335. 4:15:01started
  5336. 4:15:06and now it is successfully complete and
  5337. 4:15:09this time this was the only new table so
  5338. 4:15:12it has written the five records for that
  5339. 4:15:15that were there in the last last 1
  5340. 4:15:18minute and delayed by 5 minutes. That
  5341. 4:15:20way it has prepared some data for 5
  5342. 4:15:23minutes and rest of the thing because we
  5343. 4:15:26did not have any new data. So there is
  5344. 4:15:28no new data coming in. So let's go ahead
  5345. 4:15:31and check out this table. So this time
  5346. 4:15:33we will copy it in a notebook directly.
  5347. 4:15:38So we will do a select star from
  5348. 4:15:41pinegard dot gold. Then uh this is the
  5349. 4:15:46table we have prepared.
  5350. 4:15:49So here we can see the data. So if I
  5351. 4:15:52sort it by transaction star time. So
  5352. 4:15:55here we can say see that uh 654 to 655.
  5353. 4:16:00This is one window where it got 61
  5354. 4:16:03transactions. Then 9:44 to 9:45 it got
  5355. 4:16:0718 transactions. And why we see this gap
  5356. 4:16:11is because this video I have been
  5357. 4:16:13recording this over different hours. I'm
  5358. 4:16:15taking breaks and all. So whenever we
  5359. 4:16:18send the data within 1 minute that is
  5360. 4:16:20what is what it is capturing. And here
  5361. 4:16:22we can see a good window that 116 to 17
  5362. 4:16:26was one window. Then 17 to 18 was the
  5363. 4:16:29next window. So this is how for every
  5364. 4:16:32minute we will keep getting data here.
  5365. 4:16:35So this is our tumbling window and this
  5366. 4:16:37is the aggregated value for each of the
  5367. 4:16:39tumbling window. So now as we understand
  5368. 4:16:42the tumbling window aggregation
  5369. 4:16:44completely. So next we will give it a
  5370. 4:16:47try for the sliding window and that one
  5371. 4:16:50it is going to be very similar to this
  5372. 4:16:52and very easy. So simply let's copy it.
  5373. 4:16:56So we will clone this file and make that
  5374. 4:16:58minor change.
  5375. 4:17:01So this one we will instead of simply
  5376. 4:17:03saying count by minute we will say count
  5377. 4:17:06by minute and then we will mention
  5378. 4:17:08sliding window
  5379. 4:17:14and in here I put a dot. So let me
  5380. 4:17:17remove this.
  5381. 4:17:24So now this has been cloned
  5382. 4:17:29and here also let's create another table
  5383. 4:17:32with the name sliding
  5384. 4:17:37window. So this will be our target
  5385. 4:17:40table. So here also we will be doing the
  5386. 4:17:43exact same thing but this time our
  5387. 4:17:45window size we will change it to 5
  5388. 4:17:48minutes.
  5389. 4:17:49So let me change it to 5 minutes. Why
  5390. 4:17:52I'm changing? Because we need a sliding
  5391. 4:17:55also. So sliding we will keep it for 1
  5392. 4:17:58minute. So what it will do is every 1
  5393. 4:18:01minute it will do the aggregation of
  5394. 4:18:04last 5 minutes.
  5395. 4:18:07So that is how it will work. For example
  5396. 4:18:09at like 4 0 it will get the data of last
  5397. 4:18:145 minutes. At 401
  5398. 4:18:17it will get the data again for the last
  5399. 4:18:195 minutes. So 4 minutes those will keep
  5400. 4:18:22overlapping again and again and by 1
  5401. 4:18:25minute it will keep sliding. So if you
  5402. 4:18:28want to understand from this perspective
  5403. 4:18:30so this window it we have kept it as 5
  5404. 4:18:33minutes and this sliding time like how
  5405. 4:18:35much it is going to jump to the next
  5406. 4:18:37one. That one we have kept it as 1
  5407. 4:18:40minute and that's all that's all the
  5408. 4:18:43change we want. So this is the only
  5409. 4:18:46difference only one additional parameter
  5410. 4:18:48and it becomes a sliding window. So now
  5411. 4:18:51let me go ahead and run this pipeline
  5412. 4:18:53again
  5413. 4:18:55and the execution has been started now.
  5414. 4:18:58So while it is running let's have a look
  5415. 4:19:01at our pipeline graph now. So it looks
  5416. 4:19:04more expanded now and as we can see uh
  5417. 4:19:08for for transactions now we are doing
  5418. 4:19:10multiple thing. So the fraud card alert,
  5419. 4:19:13the high value transaction alert and
  5420. 4:19:16also we are preparing two more streaming
  5421. 4:19:18tables now with the two different type
  5422. 4:19:21of window-based aggregations.
  5423. 4:19:24And here we can see that it has already
  5424. 4:19:26written 21 records now and then it has
  5425. 4:19:29stopped.
  5426. 4:19:31So now let's have a look at this newly
  5427. 4:19:34table that has been created. So let me
  5428. 4:19:37query this here itself.
  5429. 4:19:45So this is the sliding window table
  5430. 4:19:49and here we have like lot more data for
  5431. 4:19:52the same window that that was for
  5432. 4:19:54tumbling. So now we have more data and
  5433. 4:19:57there is a reason because it is a
  5434. 4:19:58sliding window. So this is what we were
  5435. 4:20:02talking about. So 50 to 55 650 to 655 we
  5436. 4:20:06have 61 records. Then 51 to 56 we have
  5437. 4:20:11again this many records. 52 to 57 again
  5438. 4:20:14we have this many record. So as we can
  5439. 4:20:17see it is sliding by 1 minute and the
  5440. 4:20:19window size it is again 5 minutes every
  5441. 4:20:22time. So that is how this sliding window
  5442. 4:20:25works.
  5443. 4:20:27So these are all the tables we wanted to
  5444. 4:20:29create using the streaming pipeline. So
  5445. 4:20:32now what we will do is now let's have a
  5446. 4:20:35look at at the streaming data flow end
  5447. 4:20:38to end in real time in all the layers.
  5448. 4:20:41So for that what we will do is we will
  5449. 4:20:43start our pipeline in continuous mode
  5450. 4:20:46and then we will start our streams as
  5451. 4:20:48well.
  5452. 4:20:50So it has been started here.
  5453. 4:20:54So now this pipeline has been started
  5454. 4:20:57and it is waiting for the data and as it
  5455. 4:21:00is not receiving any data it will go to
  5456. 4:21:03the idle mode. So now let's give it some
  5457. 4:21:06data and see the data flowing end to
  5458. 4:21:08end. So what I will do is I will go to
  5459. 4:21:11our notebook section and then we will
  5460. 4:21:14start pushing the uh fraud watch list
  5461. 4:21:18data continuously. So let me start this
  5462. 4:21:21uh run this cell so that it start
  5463. 4:21:23sending the fraud watch list data.
  5464. 4:21:27So now it has started sending the fraud
  5465. 4:21:29watch list data and also parallelly
  5466. 4:21:32let's start the other stream as well
  5467. 4:21:35where we were sending the uh transaction
  5468. 4:21:38related data. So uh this is the fraud
  5469. 4:21:41transaction. Let's send the uh normal
  5470. 4:21:44transaction. So that that will be having
  5471. 4:21:46like load lot uh lot much more data and
  5472. 4:21:51that is with the name normal.
  5473. 4:21:55So let me run this
  5474. 4:22:00and it has also started sending the data
  5475. 4:22:03in real time and parallelly. Let me go
  5476. 4:22:07to another tab another terminal here.
  5477. 4:22:12So here we will also call the fraud
  5478. 4:22:15transaction. Let's send one fraud
  5479. 4:22:17transaction as well. So it has sent this
  5480. 4:22:20transaction and it has exited and our
  5481. 4:22:23normal transaction it is going
  5482. 4:22:24continuously and also our fraud watch
  5483. 4:22:28list data that is also going
  5484. 4:22:30continuously. Now it is running. So now
  5485. 4:22:33let's go ahead and look at our pipeline.
  5486. 4:22:36So here we can now see some real data
  5487. 4:22:39coming in. So transactions also data is
  5488. 4:22:42coming. Fraud watch list also data is
  5489. 4:22:45coming properly.
  5490. 4:22:47And now the high value transaction
  5491. 4:22:49alert. So one transaction we has sent as
  5492. 4:22:52a fraud transaction with high value that
  5493. 4:22:55has been uh also detected here and an
  5494. 4:22:59email has been sent for the high value
  5495. 4:23:02transaction.
  5496. 4:23:04And similarly for fraud card alert also
  5497. 4:23:07it has detected like one fraudulent
  5498. 4:23:09transaction
  5499. 4:23:10and for that also it has sent the email
  5500. 4:23:14and for for these window functions
  5501. 4:23:16currently it is this is in idle state. I
  5502. 4:23:19think it is currently waiting for that 5
  5503. 4:23:22minute window then it will start doing
  5504. 4:23:24the aggregation. So it we will let it
  5505. 4:23:27run for some time parallelly. Let's go
  5506. 4:23:29ahead and check our email.
  5507. 4:23:32So here we can see now multiple emails
  5508. 4:23:35coming one by one of both the types. So
  5509. 4:23:38this is how it is running fine end to
  5510. 4:23:40end now
  5511. 4:23:42and this is how like end to end flow of
  5512. 4:23:46streaming data looks like. So now both
  5513. 4:23:49the streams the data is coming
  5514. 4:23:51continuously. Even if we go to our
  5515. 4:23:54pipeline graph, it will also show the
  5516. 4:23:56same that this is also running this is
  5517. 4:23:59getting the data this is from bronze to
  5518. 4:24:02silver we are getting then all these
  5519. 4:24:04aggregations are happening these frauds
  5520. 4:24:07are being detected and emails are being
  5521. 4:24:09sent in real time and this watch list
  5522. 4:24:12also we are getting continuous data.
  5523. 4:24:15This join also it is happening like
  5524. 4:24:17stream to stream join and then sending
  5525. 4:24:19the email and here the stream to static
  5526. 4:24:23join is happening and then the uh fraud
  5527. 4:24:26email are being sent. So this is how an
  5528. 4:24:29end toend streaming pipeline looks like.
  5529. 4:24:33So I will let it run for this amazing
  5530. 4:24:36pipeline.
  5531. 4:24:38And now let's understand what is left
  5532. 4:24:40for us to do now. So now revisiting our
  5533. 4:24:45uh architecture again. So these pieces
  5534. 4:24:48we have completed all the data injection
  5535. 4:24:50all the data processing is done and then
  5536. 4:24:53consumption side email alert part we are
  5537. 4:24:56done. So the pieces pending are the
  5538. 4:24:58dashboard and the orchestration. So
  5539. 4:25:01first we will prepare the dashboard and
  5540. 4:25:03then we will prepare an end toend
  5541. 4:25:05orchestration.
  5542. 4:25:07So now let's go ahead and create our
  5543. 4:25:09dashboard. So for creating the dashboard
  5544. 4:25:12we are not going to create it manually.
  5545. 4:25:15I find it boring and it the genie code
  5546. 4:25:18it can do lot of things automatically
  5547. 4:25:20when it comes to the dashboard part. So
  5548. 4:25:23what we will do is first let's go out of
  5549. 4:25:26this streaming pipeline. So let's go to
  5550. 4:25:28the workspace mode
  5551. 4:25:32and now we will ask the genie code to
  5552. 4:25:34create a dashboard for us.
  5553. 4:25:38And this time also instead of writing
  5554. 4:25:40the prompt here itself we will first
  5555. 4:25:42type it here. So we will say that create
  5556. 4:25:46a new dashboard
  5557. 4:25:51and the dashboard we wanted to create
  5558. 4:25:53from both our silver and gold tables. So
  5559. 4:25:57here I want to give it some minimum
  5560. 4:25:59instruction and then uh come up with a
  5561. 4:26:01dashboard that we can customize later
  5562. 4:26:04on.
  5563. 4:26:05So I will say that step one itself
  5564. 4:26:09understand all the tables
  5565. 4:26:12structure from
  5566. 4:26:16uh fine guard dot silver schema.
  5567. 4:26:21It shall do this
  5568. 4:26:25and then what it shall do is it shall
  5569. 4:26:27also do the same for gold layer.
  5570. 4:26:33So it shall also understand the tables
  5571. 4:26:35in the gold schema and then it shall
  5572. 4:26:39like uh
  5573. 4:26:42prepare some or we will say come up with
  5574. 4:26:46some come up with some good APIs
  5575. 4:26:51and prepare a nice dashboard for me. So
  5576. 4:26:56this is the prompt we are going to give
  5577. 4:26:58it so that it can understand all those
  5578. 4:27:01tables automatically and then create a
  5579. 4:27:04dashboard for us. So let's see what kind
  5580. 4:27:08of dashboard does it come up with.
  5581. 4:27:11So first it is doing a show tables in
  5582. 4:27:13silver layer so that it can see the list
  5583. 4:27:16of tables that are available.
  5584. 4:27:18So looks like it threw an exception that
  5585. 4:27:21the catalog is not find found. So like
  5586. 4:27:24always I may have made some typo.
  5587. 4:27:28Yes. So let me correct that. It is Z U A
  5588. 4:27:31R D.
  5589. 4:27:41So now let me create a new thread and
  5590. 4:27:44give this prompt again.
  5591. 4:27:48This time it we can see that it has
  5592. 4:27:50found the tables and now it is trying to
  5593. 4:27:54understand the structure of each and
  5594. 4:27:56every table.
  5595. 4:27:58Now we can see it has created a
  5596. 4:28:00dashboard a blank one and it will open
  5597. 4:28:03that and then create many things into
  5598. 4:28:05the dashboard.
  5599. 4:28:07So this is our blank dashboard that it
  5600. 4:28:10has opened automatically and now it is
  5601. 4:28:13thinking what to do. Now it has come up
  5602. 4:28:16with some KPIs that it is going to show
  5603. 4:28:18us
  5604. 4:28:20and now it is setting up some data sets.
  5605. 4:28:23So to create any dashboard now it is
  5606. 4:28:26starting a warehouse. Let me close this
  5607. 4:28:28pop up here. It will create some data
  5608. 4:28:31set. So if we go to the data tab we will
  5609. 4:28:33be able to see whatever it is currently
  5610. 4:28:36creating.
  5611. 4:28:38So this one it took quite some time. So
  5612. 4:28:41I took a break and then I came back. So
  5613. 4:28:43now I can see that it has completed the
  5614. 4:28:46things. It has created so many data sets
  5615. 4:28:48for us. So how it works is this is a
  5616. 4:28:51data set. First maybe let me close the
  5617. 4:28:53right side. So here for example from the
  5618. 4:28:57customers table it is applying a filter
  5619. 4:29:00wherever risk score is greater than 70
  5620. 4:29:03and that it is counting as a high risk
  5621. 4:29:06count customers. Similarly, this is
  5622. 4:29:08another data set where it is doing a
  5623. 4:29:11transaction count of today's data only.
  5624. 4:29:14It is today's data filter from the
  5625. 4:29:16transactions table. Likewise, it has
  5626. 4:29:19prepared different different SQL
  5627. 4:29:21queries. And then it has also prepared
  5628. 4:29:24this nice page with the visualizations.
  5629. 4:29:27So from here directly we can understand
  5630. 4:29:29what it has prepared. So these are the
  5631. 4:29:31total alerts that has been generated
  5632. 4:29:34today. So there are so many alerts which
  5633. 4:29:36are running because the pipeline it was
  5634. 4:29:38running for very long. After that I
  5635. 4:29:41stopped it manually and these are the
  5636. 4:29:44number of transactions that are that has
  5637. 4:29:46happened today. The data set that we
  5638. 4:29:48just now saw and this is the average
  5639. 4:29:52transaction amount. So it is doing
  5640. 4:29:54simply an average. These are high-risk
  5641. 4:29:56customer. The one that we saw this this
  5642. 4:30:00is where it is showing alerts over time.
  5643. 4:30:03So here if you want to understand this
  5644. 4:30:05we can simply click it and we can see
  5645. 4:30:08here which data set is being used here.
  5646. 4:30:11So this one it is alert uh alert trend
  5647. 4:30:14over time. So if we go there and if you
  5648. 4:30:18find the alert trend over time. So this
  5649. 4:30:20is what it is doing here. So it is
  5650. 4:30:24taking the alerts from both our tables
  5651. 4:30:27of the last 24 hours. That is what it is
  5652. 4:30:30doing. And it is doing a group by of the
  5653. 4:30:33date and it is taking hour part of it.
  5654. 4:30:36So for every hour it is checking like
  5655. 4:30:39how many alerts we are getting. So for
  5656. 4:30:43today like it only ran I ran it only
  5657. 4:30:47twice today. So that is why it is
  5658. 4:30:49showing only two entries. Here it is
  5659. 4:30:52showing a breakdown like for high value
  5660. 4:30:55transaction how many alerts are there.
  5661. 4:30:57Uh so this is the count we have only two
  5662. 4:31:00because this data we were sending
  5663. 4:31:02manually for fraud watch list we have so
  5664. 4:31:05many alerts that were generated
  5665. 4:31:07automatically
  5666. 4:31:08here it is showing top 10 customers by
  5667. 4:31:11the alert count. So this is it is this
  5668. 4:31:14one it is preparing from the uh by
  5669. 4:31:17joining the different table the customer
  5670. 4:31:20table and the other table probably and
  5671. 4:31:23this is our alert distribution sorry
  5672. 4:31:25alert status distribution.
  5673. 4:31:28So here it is taking taking some status
  5674. 4:31:31column which is always approved this one
  5675. 4:31:33doesn't seem to be that useful I would
  5676. 4:31:35say this is our transaction volume by
  5677. 4:31:38minute. So this is what it is preparing
  5678. 4:31:41from our aggregated table. So minute by
  5679. 4:31:44minute it is showing how many
  5680. 4:31:46transactions has been performed and
  5681. 4:31:49recently I have stopped it. So the
  5682. 4:31:51number of transactions has dropped. This
  5683. 4:31:53is our transaction amount by merchant
  5684. 4:31:56category. Then this is saying whether
  5685. 4:31:59the transactions has been domestic or
  5686. 4:32:01international. These are the top 10
  5687. 4:32:04merchants by the transaction count. uh
  5688. 4:32:07this is the country-wise transactions.
  5689. 4:32:10This is some uh risk level distribution
  5690. 4:32:12where currently there is no data coming
  5691. 4:32:14in. Maybe there is some null column or
  5692. 4:32:16something. And this one it is the
  5693. 4:32:20payment channel from which payment
  5694. 4:32:22channel is being done for each and every
  5695. 4:32:24transaction. So this is a nice dashboard
  5696. 4:32:26that it has prepared and for any of this
  5697. 4:32:29if you want to customize it, we can
  5698. 4:32:31customize it. For example, this one
  5699. 4:32:34doesn't seem to be useful. So we can
  5700. 4:32:36simply delete it. We can adjust anything
  5701. 4:32:39that we want and any of the chart we can
  5702. 4:32:42customize it as well however we want to
  5703. 4:32:45from this right side. For now we will
  5704. 4:32:47not focus on much customizations because
  5705. 4:32:50our intention was to show a nice
  5706. 4:32:52dashboard. And this is how the dashboard
  5707. 4:32:55looks like. This page also we can rename
  5708. 4:32:58it to anything. We will rename it to
  5709. 4:33:01fraud monitoring.
  5710. 4:33:04And that's all. With this we can say
  5711. 4:33:06that our dashboard is ready. And we will
  5712. 4:33:09publish this dashboard so that other
  5713. 4:33:11users they can use it.
  5714. 4:33:16And now the dashboard has been
  5715. 4:33:18published. So it is available. So if you
  5716. 4:33:20click here it will show the published
  5717. 4:33:23version of the same dashboard.
  5718. 4:33:26So this is how the published version of
  5719. 4:33:28dashboard will look like to the end
  5720. 4:33:30users.
  5721. 4:33:31So now as we are done with the
  5722. 4:33:33dashboard, let's see what is pending
  5723. 4:33:35next. So now we can see that all these
  5724. 4:33:38pieces we have completed. Only the
  5725. 4:33:41orchestration piece is pending now. So
  5726. 4:33:43let's go ahead and do this one. So for
  5727. 4:33:46orchestration, so there are three pieces
  5728. 4:33:49to our architecture. So one is batch
  5729. 4:33:53processing pipeline, one is streaming
  5730. 4:33:55pipeline and one is this dashboard. So
  5731. 4:33:58for streaming pipeline we do not need
  5732. 4:34:00any separate orchestration because once
  5733. 4:34:02we change the pipeline to continuous it
  5734. 4:34:05is always running. So there is no
  5735. 4:34:07separate orchestration required for
  5736. 4:34:09that. And for dashboard piece we get a
  5737. 4:34:12schedule option. So this one we get an
  5738. 4:34:15option how frequently we want to refresh
  5739. 4:34:17this dashboard. So if we are preparing
  5740. 4:34:20it for near real time so that we can
  5741. 4:34:22monitor the transactions at the minute
  5742. 4:34:25level. So the minimum refresh time we
  5743. 4:34:27get is every 1 minute. So if we do that
  5744. 4:34:31and if we create it so every 1 minute it
  5745. 4:34:34will start refreshing this dashboard. So
  5746. 4:34:36that is how we can orchestrate this
  5747. 4:34:38dashboard. And now the only piece that
  5748. 4:34:42is pending this one I canled it because
  5749. 4:34:44I don't want to actually do it now. And
  5750. 4:34:47the only pending piece is the batch
  5751. 4:34:49processing pipeline. So how do we
  5752. 4:34:52orchestrate the injection and then the
  5753. 4:34:55silver pipeline there. So for that we
  5754. 4:34:58will create a uh orchestration job. So
  5755. 4:35:01we will go to jobs and pipelines. We
  5756. 4:35:04will click on this jobs part.
  5757. 4:35:07So other than jobs the injection and ETL
  5758. 4:35:10pipeline we already covered. This was
  5759. 4:35:12the only pending piece. So here we will
  5760. 4:35:15say customer
  5761. 4:35:18injection
  5762. 4:35:22uh source to silver
  5763. 4:35:30and in this one there are going to be
  5764. 4:35:32two step. So first we will run a
  5765. 4:35:35injection pipeline that will inject the
  5766. 4:35:37data from source to branch
  5767. 4:35:42and type will be pipeline only
  5768. 4:35:47and here by default it is showing ETL
  5769. 4:35:49pipeline only but our pipeline it is
  5770. 4:35:52injection pipeline.
  5771. 4:35:54So here we will select our fine guard
  5772. 4:35:57customers injection pipeline that will
  5773. 4:36:00ingest the data and then we will save
  5774. 4:36:03this task.
  5775. 4:36:05After that we will add a new task. This
  5776. 4:36:08new task also it will be a pipeline.
  5777. 4:36:11This time it will be ETL pipeline. So
  5778. 4:36:14this one it will be bronze to silver.
  5779. 4:36:20And here we will select the pipeline.
  5780. 4:36:23And here we will select the pipeline
  5781. 4:36:25that we had created for customers table
  5782. 4:36:28bronze to silver injection. So this is
  5783. 4:36:30the pipeline and we will save it. So
  5784. 4:36:34that's it. These are the only two task
  5785. 4:36:36we need to do there
  5786. 4:36:39and then we can run it manually from
  5787. 4:36:41here so that it will first ingest the
  5788. 4:36:43data from source to bronze and then to
  5789. 4:36:45silver and after testing that we can add
  5790. 4:36:48a trigger here as well. So trigger type
  5791. 4:36:51it can be scheduled in this case because
  5792. 4:36:54we want to run it every 1 day that is
  5793. 4:36:57how we want to do it. So this is the
  5794. 4:37:00default one. If you want to select a
  5795. 4:37:02specific time when we want to run it. So
  5796. 4:37:04every day it will run at this time. So
  5797. 4:37:07time also we can select and then if we
  5798. 4:37:10save so every day it will do a batch
  5799. 4:37:12injection for this test for this table.
  5800. 4:37:15So the streaming part it will keep
  5801. 4:37:17running continuously and batch part
  5802. 4:37:20whatever latest data is available in our
  5803. 4:37:22silver customers table that will be used
  5804. 4:37:24and every day it will it will be
  5805. 4:37:26refreshing and new data will be used. So
  5806. 4:37:29that is how the end toend orchestration
  5807. 4:37:31of this project will look like. So
  5808. 4:37:34basically this process it will run once
  5809. 4:37:36a day. Then streaming injection it will
  5810. 4:37:39run continuously and dashboard refresh
  5811. 4:37:42that will happen every 1 minute. So then
  5812. 4:37:45it will be running end to end
  5813. 4:37:47continuously and uh and all the data
  5814. 4:37:51that that processing it will happen in
  5815. 4:37:54real time. So that covers the
  5816. 4:37:56orchestration piece of our architecture.
  5817. 4:38:00So now to summarize we have completed
  5818. 4:38:03each and every functionality in this
  5819. 4:38:05architecture we have done hands-on. We
  5820. 4:38:07started by streaming some data from
  5821. 4:38:09Kafka loading it through bronze and
  5822. 4:38:12silver layer. Then we brought in the
  5823. 4:38:15batch data the customer data from
  5824. 4:38:17Postgress SQL through lakeflow connect
  5825. 4:38:20and ingested into bronze and silver. And
  5826. 4:38:23after that we brought in the streaming
  5827. 4:38:26data using autoloader as well from our
  5828. 4:38:29volume. And after silver layer we did
  5829. 4:38:32all these types stream to stream join
  5830. 4:38:34stream static join fraud detection
  5831. 4:38:36everything in real time. And then we
  5832. 4:38:39sent the email alerts and prepared a
  5833. 4:38:42dashboard. And we did overall
  5834. 4:38:44orchestration using lakeflow job. And
  5835. 4:38:47then we uh used Unity catalog to prepare
  5836. 4:38:51all our tables in Unity catalog with
  5837. 4:38:54proper governance.
  5838. 4:38:56So these were all the details I wanted
  5839. 4:38:58to share in this video. I hope my
  5840. 4:39:01efforts that I put in to create this
  5841. 4:39:03video were worth it. So if you think
  5842. 4:39:06that those were worth it, please put it
  5843. 4:39:08in the comment section and let it out.
  5844. 4:39:10And if you have any doubt or if you come
  5845. 4:39:12across any issue related to this project
  5846. 4:39:15then also please put a comment and I
  5847. 4:39:18will suggest that you do a proper
  5848. 4:39:20hands-on on this project end to end so
  5849. 4:39:22that you are more comfortable if you
  5850. 4:39:25want to show it in an interview or
  5851. 4:39:26something and then only you will not
  5852. 4:39:29forget anything once you do a practical
  5853. 4:39:32and you can also get the PDF that I have
  5854. 4:39:35prepared that you can use as a revision
  5855. 4:39:37for this project whenever you want to
  5856. 4:39:39have a quick glance so you can go over
  5857. 4:39:41the PDF and use it so that you can show
  5858. 4:39:45it properly in the resume and you can be
  5859. 4:39:47ready for the interview whenever you
  5860. 4:39:49want to showcase this project. So that's
  5861. 4:39:52all for now. I hope you really liked it.
  5862. 4:39:55So let's stay in touch and let's see
  5863. 4:39:57what's coming in the next video. For now
  5864. 4:40:00that's all. Bye-bye. Happy learning.

About this transcript

This page contains the full transcript of End-to-End Spark Streaming Project | Databricks + Kafka + PostgreSQL + Real-Time Dashboard by DataBeli, generated from the public captions YouTube serves with the video. The transcript has 41,939 words across 5,864 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to choose a caption track available on the video.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, caption language selection, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.