Transcript

Managing Airflow at Scale using the Flowrs TUI

Download

1 00:00:01,083 --> 00:00:04,958 You open up your laptop and it's time to check the overnight data pipelines.

2 00:00:04,958 --> 00:00:08,000 You open up a browser, you log in and check the pipelines.

3 00:00:08,000 --> 00:00:12,583 You open up another tab, you log in again, different environment, same thing.

4 00:00:12,875 --> 00:00:18,541 12 environments, dev production, that's 24 environments every single morning.

5 00:00:18,625 --> 00:00:28,125 My colleague Jan got tired of that, so he built a terminal user interface called Flowers that allows him to manage all of his environments at once, from his keyboard, no mouse, no

6 00:00:28,125 --> 00:00:30,208 browser, no nonsense.

7 00:00:30,250 --> 00:00:36,083 And in this episode, Jan is going to show us how that works and how you can build something like this yourself in Rust.

8 00:00:36,416 --> 00:00:41,208 I am Jonny, knowledge theory at Dataminded, and welcome to Technology Explorations.

9 00:00:49,708 --> 00:00:54,791 Hi everyone, today we'll have a look at text user interfaces or terminal user interfaces.

10 00:00:54,791 --> 00:00:56,166 For that, I've invited Jan.

11 00:00:56,166 --> 00:00:56,833 Welcome Jan.

12 00:00:56,833 --> 00:00:57,458 Thank you, Jonny.

13 00:00:57,458 --> 00:01:00,666 Could you tell us a bit more about yourself and your role at Dataminded?

14 00:01:00,666 --> 00:01:04,583 I'm working here at Dataminded as a data engineer.

15 00:01:04,833 --> 00:01:11,458 I'm a team lead currently at one of our clients and I'm also heading uh our academy.

16 00:01:11,500 --> 00:01:14,750 Okay Jan, so you have been building a terminal user interface.

17 00:01:14,750 --> 00:01:17,083 Maybe show us what you built

18 00:01:17,083 --> 00:01:17,458 Sure.

19 00:01:17,458 --> 00:01:23,458 I'm in my terminal and in my case the tui is called Flowrs and you can start Flowrs by just typing Flowrs.

20 00:01:23,875 --> 00:01:33,208 The name Flowrs is a pun on Apache airflow and flow Flowrs and Because it is written in rust a lot of rust projects.

21 00:01:33,208 --> 00:01:37,916 They have this RS suffix So that's where the name comes from Flowrs

22 00:01:37,916 --> 00:01:41,958 And so for our viewers, Airflow is an orchestrator for data engineers.

23 00:01:41,958 --> 00:01:44,875 Could we maybe have a look at what the UI looks like normally?

24 00:01:44,875 --> 00:01:45,333 Sure,

25 00:01:45,333 --> 00:01:47,250 So this is the Airflow UI.

26 00:01:47,250 --> 00:01:54,333 And in Airflow, you have your DAGs, your directed acyclic graphs, which represent your workflow, your data pipelines.

27 00:01:54,333 --> 00:01:58,083 And you can inspect them and see how they are running, what they are doing.

28 00:01:58,083 --> 00:02:01,291 So here you have an overview of all of your DAG runs.

29 00:02:01,291 --> 00:02:01,791 Each...

30 00:02:01,791 --> 00:02:03,791 vertical line is a DAG run.

31 00:02:03,791 --> 00:02:07,333 Each square here is a task your pipeline.

32 00:02:07,333 --> 00:02:15,208 You can also visualize it as this DAG, as this directed acyclic graph of all these operations that will get scheduled by Airflow.

33 00:02:15,208 --> 00:02:19,583 And so Airflow is basically the babysitter of these DAGs, of these pipelines.

34 00:02:19,583 --> 00:02:23,583 And as you can already see, to navigate in this UI,

35 00:02:23,583 --> 00:02:25,375 First of all, there's a lot going on.

36 00:02:25,375 --> 00:02:27,041 There's a lot of things that I can click.

37 00:02:27,041 --> 00:02:30,250 There's a lot of different buttons and tabs.

38 00:02:30,250 --> 00:02:39,500 What you've now seen was one Airflow environment, one Airflow instance, and that's still manageable if you need to navigate through the DAGs and through all of the pipelines to

39 00:02:39,500 --> 00:02:45,250 see after a night of batch runs, which pipelines have failed, where do you need to take action.

40 00:02:45,250 --> 00:02:53,541 But if you have 10 or tens of these environments, it quite quickly becomes a hassle to do this through the UI by just clicking.

41 00:02:53,541 --> 00:02:56,750 And I got sick and tired of doing that, and that's why I built the Tui.

42 00:02:57,166 --> 00:02:57,583 Yeah.

43 00:02:57,583 --> 00:03:03,500 So you hate clicking around and jumping across all these environments because it takes a lot of time.

44 00:03:03,875 --> 00:03:06,666 And as a data engineer, you manage multiple ones of these.

45 00:03:06,666 --> 00:03:13,500 Like in this case, we see 12 environments, and you have a development production, you need to check all of them.

46 00:03:13,500 --> 00:03:15,833 So that would require 12 tabs being opened.

47 00:03:15,833 --> 00:03:20,625 And then even in those environments, you manage multiple DAGs, lots of work.

48 00:03:20,625 --> 00:03:26,250 lots of clicking, of exactly, lots of digging deeper to figure out what happened.

49 00:03:26,250 --> 00:03:27,791 And I wanted to make this easier.

50 00:03:27,791 --> 00:03:32,750 Yeah, so you built your own terminal user interface called Flowrs to navigate it.

51 00:03:32,750 --> 00:03:36,916 So could you show us around a bit in the terminal user interface on how you use it?

52 00:03:36,916 --> 00:03:37,791 Yeah, sure.

53 00:03:38,000 --> 00:03:39,833 So let's drill down on an environment.

54 00:03:39,833 --> 00:03:44,250 So when you go into an environment, you have, first of all, the list of DAGs.

55 00:03:44,250 --> 00:03:51,458 So these are your pipelines, your workflows, and then you can navigate through the DAGs just using your keyboard.

56 00:03:51,458 --> 00:03:53,125 can use VIM key bindings.

57 00:03:53,125 --> 00:03:56,375 So meaning J is going down, K is going up.

58 00:03:56,375 --> 00:04:03,916 You can also jump to the top of the table by using gg, or you can go to the bottom with capital G.

59 00:04:03,916 --> 00:04:12,000 And you can also filter if you just quickly want to find a DAG that you're interested in by using the slash command and then you see a filter popping up.

60 00:04:12,000 --> 00:04:18,041 at the bottom and then you can look for your favorite DAG and in my case I want to have a look at this DAG.

61 00:04:18,041 --> 00:04:23,333 If you then select the DAG, you get to see all of the DAG runs of the DAG.

62 00:04:23,333 --> 00:04:29,208 So a DAG run is an instantiation of a DAG and DAG is this concept of a workflow or pipeline.

63 00:04:29,208 --> 00:04:31,125 DAG run is a run of this pipeline.

64 00:04:31,125 --> 00:04:33,000 You get some information about this DAG.

65 00:04:33,000 --> 00:04:33,791 When did it run?

66 00:04:33,791 --> 00:04:35,125 How long did it take?

67 00:04:35,125 --> 00:04:35,750 There's

68 00:04:35,750 --> 00:04:40,000 a line gauge to show how long it took in comparison to other DAG runs.

69 00:04:40,000 --> 00:04:48,250 And if you then drill down, you can see all of the individual tasks of your DAG run to see how long did they take, did they run successfully.

70 00:04:48,250 --> 00:04:56,333 And then even at the run or the task level, you can drill down and see all of the logs of that specific run.

71 00:04:56,333 --> 00:04:58,000 I also see a follow mode here.

72 00:04:58,000 --> 00:05:04,375 So you would be able to have a trail and follow along when the pod is running in this case, where the task is running.

73 00:05:04,375 --> 00:05:12,916 Exactly, So it basically continuously polls for new logs and then it will follow along so you don't have to do anything.

74 00:05:12,916 --> 00:05:22,916 while you did the drill down, I saw these tabs at Every time you went a bit deeper and you go from the top level where you have all your instances to your DAGs, to the runs, to the

75 00:05:22,916 --> 00:05:24,416 tasks, to the logs.

76 00:05:24,458 --> 00:05:28,375 And how do you effectively do use this in your day to day?

77 00:05:28,375 --> 00:05:36,083 In my case, what I typically do, there's a few workflows, but we typically get alerted of important pipelines when they fail.

78 00:05:36,083 --> 00:05:38,666 This is happening in our alerting system.

79 00:05:38,666 --> 00:05:49,208 It's pager duty, And then I just look at the name of the DAG in the alert and I navigate to the right environment and I start searching for that DAG to see uh it failed.

80 00:05:49,208 --> 00:05:52,083 And then I drill down to see what failed, why did it fail?

81 00:05:52,083 --> 00:05:57,250 And as I mentioned before, you get the application logs for a failed task instance.

82 00:05:57,250 --> 00:05:58,083 So I can easily

83 00:05:58,083 --> 00:06:00,083 figure out what went wrong and try to fix it.

84 00:06:00,083 --> 00:06:00,500 Yeah.

85 00:06:00,500 --> 00:06:03,375 your trigger is an error from a pipeline.

86 00:06:03,375 --> 00:06:05,291 You get an alert, there's something wrong.

87 00:06:05,291 --> 00:06:11,375 And this allows you to immediately dive deep into that error without opening a browser, opening the right environment.

88 00:06:11,375 --> 00:06:13,583 So it saves you a bit of time, I guess.

89 00:06:13,583 --> 00:06:14,541 Yeah, it does.

90 00:06:14,541 --> 00:06:16,625 can also, if I know which DAG it is,

91 00:06:16,625 --> 00:06:21,500 Here there's a bunch of successful tasks, but I know that there's also a couple of failed ones.

92 00:06:21,500 --> 00:06:23,833 And then I can also filter on the state.

93 00:06:23,833 --> 00:06:27,166 You also see hopefully that there's like this autocomplete.

94 00:06:27,166 --> 00:06:32,375 It will also cycle if I start typing failed, it already knows.

95 00:06:32,375 --> 00:06:36,125 And then I just have an overview of the failed tasks of my...

96 00:06:36,125 --> 00:06:44,000 DAG run in this case and then I can have a look at the logs and see okay here's some a dbt job is running and one of the tests actually failed

97 00:06:44,000 --> 00:06:44,416 Yeah.

98 00:06:44,416 --> 00:06:48,958 And also these things like this auto-complete, you built that yourself in this UI.

99 00:06:48,958 --> 00:06:53,291 yeah, the autocomplete is basically a state machine.

100 00:06:53,291 --> 00:06:59,208 It generates the possible attributes of a DAG run or of a task that you can filter on.

101 00:06:59,791 --> 00:07:00,416 very nice.

102 00:07:00,416 --> 00:07:03,750 I think this looks quite slick actually, this UI.

103 00:07:04,208 --> 00:07:06,166 Anything else you'd like to show

104 00:07:06,625 --> 00:07:11,500 Actually, yes, on the UI side, Jonny, I recently added something based on a request of a user.

105 00:07:11,500 --> 00:07:22,125 So we all know, and you also know that any self-respecting developer uses a dark mode terminal, but there are some people that have maybe some color issues, color blindness,

106 00:07:22,125 --> 00:07:26,500 and they sometimes prefer a light mode terminal.

107 00:07:26,500 --> 00:07:35,666 So when you would open Flowrs in a light mode terminal, looks at your terminal, tries to figure out are you in a light mode terminal or in a dark mode terminal.

108 00:07:35,666 --> 00:07:37,375 uh

109 00:07:37,375 --> 00:07:40,958 Because terminals, do they pass on the information in the environment?

110 00:07:40,958 --> 00:07:45,958 well, I cannot give you the full details because I used a dependency to do this.

111 00:07:45,958 --> 00:07:51,500 There is a crate called Terminal ColorSaurus and I like the name already, but that does it for you.

112 00:07:51,500 --> 00:08:01,083 And if you look at the readme of the project, it seems like it's people really knowing what they're doing and really knowing terminals inside out, looking at specific escape

113 00:08:01,083 --> 00:08:02,916 sequences and C codes.

114 00:08:02,916 --> 00:08:04,291 It just works in my case.

115 00:08:04,291 --> 00:08:07,416 It correctly can figure out that this is a light mode terminal.

116 00:08:07,416 --> 00:08:11,166 So the extra feature is light mode where we used to see dark modes.

117 00:08:11,166 --> 00:08:13,708 You have a light mode as a new feature.

118 00:08:13,708 --> 00:08:14,500 exactly.

119 00:08:14,500 --> 00:08:22,916 And not only light modes, you can also, because of course we have to over engineer everything, you can also select these Catppucin themes.

120 00:08:23,125 --> 00:08:24,708 like latte, frappe, macchiato.

121 00:08:24,708 --> 00:08:28,375 And they each have a slightly different color scheme.

122 00:08:28,375 --> 00:08:29,958 And you can also enable

123 00:08:30,000 --> 00:08:41,958 uh Flower supports both Airflow V2 and V3, which is something that was quite useful for us because we have many of these environments and we were migrating these environments from

124 00:08:41,958 --> 00:08:43,250 V2 to V3.

125 00:08:43,250 --> 00:08:46,125 But we still wanted to manage our DAGs in the same way, right?

126 00:08:46,125 --> 00:08:50,208 We still wanted to navigate through our DAGs, find the failed task instances.

127 00:08:50,208 --> 00:08:54,916 And it kind of looks the same for both V2 and V3 Airflow.

128 00:08:55,166 --> 00:08:55,416 So

129 00:08:55,416 --> 00:08:59,125 So you provide more UI stability than Airflow itself at this point.

130 00:08:59,208 --> 00:09:01,541 Yes, but also less features.

131 00:09:01,541 --> 00:09:04,500 In the Airflow UI, apparently now you can play Doom.

132 00:09:04,500 --> 00:09:06,625 That's something you cannot do with Flowrs.

133 00:09:06,625 --> 00:09:07,541 nice not yet at least.

134 00:09:07,541 --> 00:09:12,000 I wanted to show this escape hatch maybe not everything you want is visible

135 00:09:12,000 --> 00:09:13,375 within Flowrs.

136 00:09:13,458 --> 00:09:22,958 So you can press O on any object on the DAG, on the DAG run or on task instance, and it will open the Airflow UI of that environment.

137 00:09:22,958 --> 00:09:29,666 you can easily, if you need more features or more graphical features, you can easily dive in.

138 00:09:29,666 --> 00:09:30,166 Nice.

139 00:09:30,166 --> 00:09:33,791 if you press V, it shows you the code of the DAG and you can

140 00:09:33,791 --> 00:09:45,041 one last thing I would like to show, which I think is quite cool, is if you have a bunch of failed DAGs, for example, and you want to all mark them as successful, you typically

141 00:09:45,041 --> 00:09:48,416 would do this if there's nothing really actionable about your failed DAG.

142 00:09:48,416 --> 00:09:56,625 Maybe your DAG has failed because there was a timeout or something, but you know that it's fixed now, and so you just want to mark your DAG as successful.

143 00:09:56,916 --> 00:10:06,125 You can press shift V, you go into visual mode, just like in vim, you can navigate and that basically selects a bunch of these, in this case, DAG runs.

144 00:10:06,125 --> 00:10:11,916 And you can then press the button to mark them as success, failed I want to mark them as successful.

145 00:10:11,916 --> 00:10:18,250 So in terms of managing such a large workload or multiple environments, this is a lot faster than going to the UI.

146 00:10:18,666 --> 00:10:21,250 I see tuis popping up everywhere.

147 00:10:21,250 --> 00:10:22,833 Where is this coming from?

148 00:10:22,833 --> 00:10:25,250 that's a good question.

149 00:10:25,250 --> 00:10:30,458 terminal user interfaces were the OG interfaces of our computers, right?

150 00:10:30,458 --> 00:10:35,250 You used to have only a terminal and some text on it.

151 00:10:35,250 --> 00:10:38,791 This is a VT100, one of the first tele typewriters.

152 00:10:38,791 --> 00:10:40,958 That's what you got, black screen and some text.

153 00:10:40,958 --> 00:10:45,208 And that used to be more than enough for a lot of use cases.

154 00:10:45,208 --> 00:10:48,166 You also have an example of MS-DOS.

155 00:10:49,000 --> 00:10:57,041 Also the first games, I really like this kind of trivia, the first games were also just text-based games And I think as a developer,

156 00:10:57,041 --> 00:10:59,625 Yeah, you kind of like working in a terminal.

157 00:10:59,625 --> 00:11:02,291 You feel efficient, you feel fast.

158 00:11:02,291 --> 00:11:08,416 If you have to navigate through a file system, I think most developers would say they prefer doing that than clicking around

159 00:11:08,416 --> 00:11:11,583 You have this element of speed, of being efficient.

160 00:11:11,583 --> 00:11:12,875 it's a lot less.

161 00:11:12,875 --> 00:11:17,208 convoluted and a lot less busy than the typical web UI.

162 00:11:17,208 --> 00:11:22,583 Although of course, if people properly design web UIs, they can also be simple and focused.

163 00:11:22,958 --> 00:11:25,833 And then there's also these retro aesthetics.

164 00:11:25,833 --> 00:11:27,875 It's more of a personal thing, but I like it.

165 00:11:27,875 --> 00:11:30,833 and it's also available on many systems, right?

166 00:11:30,833 --> 00:11:35,208 Like there's always like a bash terminal available that you can use.

167 00:11:35,500 --> 00:11:36,083 Indeed.

168 00:11:36,083 --> 00:11:43,416 Where I also think it shines is in for these kinds of applications where you have a big surface and like Airflow is a good example.

169 00:11:43,416 --> 00:11:48,583 You have a lot of things you can do with Airflow with the UI.

170 00:11:48,583 --> 00:11:52,166 There's also an Airflow CLI, which is also quite a big CLI.

171 00:11:52,166 --> 00:11:53,166 You can do a lot of things.

172 00:11:53,166 --> 00:11:57,125 What is then the difference between CLIs and TUIs according to you?

173 00:11:57,125 --> 00:11:59,625 When would you opt for each of them?

174 00:11:59,625 --> 00:12:01,125 a very good question.

175 00:12:01,125 --> 00:12:07,041 And also it can be tied to this new wave of agentic AI and agents doing things for us.

176 00:12:07,041 --> 00:12:10,875 A tui is a very visual thing, right?

177 00:12:10,875 --> 00:12:14,500 We humans are very visual creatures, right?

178 00:12:14,500 --> 00:12:17,416 And we easily spot small changes in uh

179 00:12:17,416 --> 00:12:23,666 in a visual thing, reading a bunch of text, which is typically what comes out of a shell command that takes time for us.

180 00:12:23,666 --> 00:12:25,083 We don't read that fast.

181 00:12:25,083 --> 00:12:27,916 Now agents do read very fast, right?

182 00:12:27,916 --> 00:12:34,833 So you have all of these agent skills and a lot of agent skills wrap around the CLI, they use CLIs.

183 00:12:34,833 --> 00:12:37,958 And I really think that's a beautiful marriage between the two.

184 00:12:37,958 --> 00:12:42,041 Agents can read super fast, the CLIs just give text back.

185 00:12:42,041 --> 00:12:46,666 But as a human, you are, I think, more efficient by just having something visual.

186 00:12:46,666 --> 00:12:56,333 In the case of Airflow, it's way easier to spot one red dot on your screen to show that something has failed, and then read the output of one CLI command.

187 00:12:56,333 --> 00:13:01,833 Yeah, so your Flowrs TUI does it mean it's not as suited for Agents to use?

188 00:13:01,833 --> 00:13:03,625 Yeah, maybe it could be used.

189 00:13:03,625 --> 00:13:06,250 I'm not sure if it just will be very efficient.

190 00:13:07,083 --> 00:13:10,500 And so what is then the reason you designed Flowrs?

191 00:13:10,500 --> 00:13:14,875 Because now we have agents, they can talk to CLIs, you could just ask a question.

192 00:13:14,875 --> 00:13:20,083 Do you still have the need for a speed up that you cannot achieve with agents?

193 00:13:20,416 --> 00:13:31,000 Well, first of all, I started developing Flowrs before there were agents and it was born out of frustration with having to click in the UI and also curiosity.

194 00:13:31,000 --> 00:13:33,583 I like to know how things tick.

195 00:13:33,583 --> 00:13:35,583 Like how does it actually work?

196 00:13:35,583 --> 00:13:37,791 What does it do?

197 00:13:37,791 --> 00:13:42,458 So I started building this before the whole agentic revolution,

198 00:13:42,458 --> 00:13:46,333 agents already replacing Flowrs in my day-to-day workflow?

199 00:13:46,333 --> 00:13:51,458 Not yet, but I also don't really have a good reason or argumentation of why they couldn't.

200 00:13:51,458 --> 00:14:00,041 But what I think you're still faster when doing it on your keyboard because if you know your Flowrs then you can easily jump into things that you know.

201 00:14:00,041 --> 00:14:02,875 So it's like second nature to you, seems.

202 00:14:04,000 --> 00:14:06,291 You still win of the AI in this case.

203 00:14:06,375 --> 00:14:09,041 Still out competing the bots.

204 00:14:09,041 --> 00:14:09,916 Yes, that's true.

205 00:14:09,916 --> 00:14:17,666 But if cost is not of a concern, because in the end you can indeed tell an agent, hey, here's the airflow CLI, figure it out.

206 00:14:17,666 --> 00:14:22,708 And it might take half an hour to figure it out and burn a bunch of tokens to do it.

207 00:14:22,708 --> 00:14:24,958 that might be a trade off you're willing to make.

208 00:14:24,958 --> 00:14:26,458 how do you build such a system?

209 00:14:26,458 --> 00:14:27,875 Where do you start?

210 00:14:27,916 --> 00:14:34,458 Yeah, so when I started building Flowrs, I started first looking for frameworks that people are using to build these tuis.

211 00:14:34,458 --> 00:14:36,666 I quickly found these three.

212 00:14:36,666 --> 00:14:45,875 You have Bubble Tea, Textual and Ratatui and each are written in a different language which is also quite nice if you're very familiar with a specific language With a colleague

213 00:14:45,875 --> 00:14:47,958 we experimented a bit with Bubble Tea.

214 00:14:47,958 --> 00:14:48,958 It's written in Go.

215 00:14:48,958 --> 00:14:50,750 It's very easy to use.

216 00:14:50,750 --> 00:14:52,708 It's very elegant as well.

217 00:14:52,708 --> 00:14:59,833 You also, by default, get a nice UI if you just take the default templates of Bubble Tea.

218 00:14:59,833 --> 00:15:01,333 But I didn't choose Bubble Tea.

219 00:15:01,333 --> 00:15:04,333 I thought, well, let's do something more challenging.

220 00:15:04,333 --> 00:15:08,666 And I wanted also to improve my Rust knowledge So that's why I went with Ratatui.

221 00:15:08,666 --> 00:15:11,208 Textual, I think it's also quite good.

222 00:15:11,208 --> 00:15:19,250 despite Python having this connotation of not being a very performant language, I think textual UIs can be also very interactive.

223 00:15:19,250 --> 00:15:20,708 and very performant.

224 00:15:20,750 --> 00:15:24,291 and what is the reason for you that you're so hyped about Rust?

225 00:15:24,291 --> 00:15:25,250 I hear this a lot.

226 00:15:25,250 --> 00:15:26,625 I haven't looked into Rust myself.

227 00:15:26,625 --> 00:15:29,375 It's still somewhere on the backlog for me.

228 00:15:29,375 --> 00:15:37,000 I think one of the main reasons is that it's fun to get hyped about stuff, In the end, it's just a programming language, they're all Turing complete.

229 00:15:37,000 --> 00:15:39,500 But it's fun to get hyped about things.

230 00:15:39,500 --> 00:15:44,708 And the other reason is that I like the expressiveness of the type system.

231 00:15:44,708 --> 00:15:54,375 I come from a scientific background, physics and mathematics, and I always liked the rigidity of proofs of logic.

232 00:15:54,375 --> 00:15:57,458 And then with Python, it's kind of the opposite.

233 00:15:57,458 --> 00:16:00,666 You can write a lot of things and nobody will complain.

234 00:16:00,666 --> 00:16:08,458 And at some point they might crash and burn in production and you will look at the wreckage and then see, ah, yeah, okay, that went wrong.

235 00:16:08,458 --> 00:16:09,958 I need to fix this in this way.

236 00:16:09,958 --> 00:16:12,166 With Rust, you have

237 00:16:12,208 --> 00:16:13,458 kind of the opposite.

238 00:16:13,458 --> 00:16:21,125 You are developing your application and for the first, in my case it was many days, the damn thing doesn't even compile.

239 00:16:21,125 --> 00:16:23,250 Some people say the compiler shouts at you.

240 00:16:23,250 --> 00:16:31,625 I now look at it as the compiler teaches you why what you wrote doesn't make sense, is not fault tolerant, has some issues with it.

241 00:16:31,625 --> 00:16:36,333 So I like the expressiveness of the type system and the guarantees that it provides.

242 00:16:36,333 --> 00:16:42,083 Okay, so it's a static compiled language, I assume, and you get a lot more safety.

243 00:16:42,083 --> 00:16:42,416 yeah.

244 00:16:42,416 --> 00:16:46,083 And one of the selling points and the tagline is always blazingly fast.

245 00:16:46,083 --> 00:16:50,041 You could do a benchmark with some other tuis and you would probably find that it's faster.

246 00:16:50,041 --> 00:16:55,166 All right, so you have these different frameworks, but under the hood, they're all actually quite similar.

247 00:16:55,166 --> 00:16:58,541 In the end, it's just one big event loop, and it just...

248 00:16:58,541 --> 00:17:00,166 does three different things.

249 00:17:00,166 --> 00:17:08,416 It listens for input events, when you press a key on your keyboard, or you get a response from an API call.

250 00:17:08,416 --> 00:17:11,166 And then based on the event, typically updates some state.

251 00:17:11,166 --> 00:17:16,125 And then after the state has been updated, there's a render phase and you display them on the screen.

252 00:17:16,125 --> 00:17:18,750 And for the rendering phase, you often have...

253 00:17:18,750 --> 00:17:23,833 built-in widgets like a table, a bar graph, and that just repeats in an infinite loop.

254 00:17:23,833 --> 00:17:32,583 So most of these frameworks give you either built-in widgets that you can easily configure yourself or you can create your own widgets and they typically have a few functions that

255 00:17:32,583 --> 00:17:33,500 you need to implement.

256 00:17:33,500 --> 00:17:41,625 So an example of some of these widgets, this is like the demo or the showcase project of Ratatui.

257 00:17:41,625 --> 00:17:44,250 So you can create these kind of tabs with it.

258 00:17:44,250 --> 00:17:48,333 You can have maps, you can have sparklines, gauges, whatever you want.

259 00:17:48,333 --> 00:17:53,458 This is really good for in the movies to put on screen and show something really cool is happening, right?

260 00:17:53,458 --> 00:17:57,958 This is the basic gist of it.

261 00:17:57,958 --> 00:18:00,791 You have your application, which is basically a loop

262 00:18:00,791 --> 00:18:07,041 which first draws or renders to the terminal, and then it starts processing events.

263 00:18:07,041 --> 00:18:08,250 See if something has changed.

264 00:18:08,250 --> 00:18:12,791 In this case, the only thing that can happen is you press a key and then it will break.

265 00:18:12,791 --> 00:18:15,041 And then basically your app will shut down.

266 00:18:15,041 --> 00:18:22,125 But what you would do is here, put all of the logic, like if people press the J key or the down key, that means you

267 00:18:22,125 --> 00:18:23,916 to go to the next item in a table.

268 00:18:23,916 --> 00:18:38,250 em If there's a tick event, like this clock ticking every 200 milliseconds, for every 2000 milliseconds, make an API call to the Airflow REST API to get the latest DAGs.

269 00:18:38,250 --> 00:18:44,583 You update your state with that, and then the next loop starts basically, terminal.draw, and it will render.

270 00:18:44,833 --> 00:18:48,250 actually my main takeaway message is go forth and mulTUIply.

271 00:18:48,250 --> 00:18:51,583 It's very easy to build your own Tui and to wrap around it.

272 00:18:51,583 --> 00:18:54,000 And how long were you working on this?

273 00:18:54,000 --> 00:18:55,000 that's a good question.

274 00:18:55,000 --> 00:18:58,750 in the beginning, of course, I didn't know the language, so I had to learn Rust.

275 00:18:58,750 --> 00:19:01,083 I made a lot of stupid rookie mistakes

276 00:19:01,083 --> 00:19:02,250 So I think it took me.

277 00:19:02,250 --> 00:19:08,666 on and off about a year to get like a first UI where I could just see the DAGs and the DAG runs in the task instances.

278 00:19:08,666 --> 00:19:19,333 But then this filtering, for example, with the state machine, this theming stuff that became a lot easier because I feel comfortable with the language and we have agents to

279 00:19:19,333 --> 00:19:19,750 help us.

280 00:19:19,750 --> 00:19:20,458 Okay, nice.

281 00:19:20,458 --> 00:19:22,625 And so people can actually use this, right?

282 00:19:22,625 --> 00:19:25,250 Can they brew install Flowrs or how does that work?

283 00:19:25,250 --> 00:19:27,250 Actually that's also a nice thing.

284 00:19:27,250 --> 00:19:33,750 there was a contribution from somebody from the community last week and they added it to the brew core taps.

285 00:19:33,750 --> 00:19:37,125 So now anybody can just install brew install Flowrs.

286 00:19:37,125 --> 00:19:41,541 So when you open Flowrs for the first time, actually don't see that much, right?

287 00:19:41,541 --> 00:19:47,666 Because works with airflow instances and you need to tell Flowrs where to find those airflow instances.

288 00:19:47,666 --> 00:19:52,708 Airflow is an open source project, which means you can just host it yourself.

289 00:19:52,708 --> 00:19:57,875 can basically deploy it on any cloud environment on AWS, for example, with some EC2 machines.

290 00:19:57,875 --> 00:20:02,250 But you also have a bunch of managed services.

291 00:20:02,333 --> 00:20:05,708 So actually before you would even uh open Flowrs, you would do something

292 00:20:05,708 --> 00:20:11,916 like Flowrs, config enable -m for managed service and then you can type a managed service.

293 00:20:11,916 --> 00:20:15,041 There are a bunch of managed services as I already mentioned.

294 00:20:15,041 --> 00:20:16,833 There's conveyor which is

295 00:20:16,833 --> 00:20:25,708 Dataminded's own managed airflow offering, but you also have MWAA, which is managed Workflows for Apache Airflow on the AWS cloud.

296 00:20:25,708 --> 00:20:27,458 You have Google Cloud Composer.

297 00:20:27,458 --> 00:20:34,625 You have Astronomer, which we all know now because of the CEO news story.

298 00:20:34,625 --> 00:20:38,250 um managed service.

299 00:20:38,250 --> 00:20:40,750 have and then it generates a config for you.

300 00:20:40,750 --> 00:20:43,125 Exactly, so you enable it.

301 00:20:43,125 --> 00:20:55,041 In this case, it was already enabled and there is a config file If it doesn't exist, it will get created and it basically contains some configuration that the TUI manages for

302 00:20:55,041 --> 00:20:55,541 you.

303 00:20:55,541 --> 00:20:58,416 And then you can start Flowrs and it will actually.

304 00:20:58,416 --> 00:20:59,583 uh

305 00:20:59,625 --> 00:21:01,666 find all of the Airflow environments.

306 00:21:01,666 --> 00:21:05,250 If you don't want to use a managed service, you just have your own Airflow instance.

307 00:21:05,250 --> 00:21:08,750 You can also just provide a host name and credentials.

308 00:21:08,750 --> 00:21:17,958 If you use basic authentication like a username and a password or OAuth 2 with the JWT token, those are all also valid options.

309 00:21:17,958 --> 00:21:21,791 Also in this case you have conveyor, but conveyor manages multiple of these environments.

310 00:21:21,791 --> 00:21:24,666 So it also discovers even the environments that you have.

311 00:21:24,666 --> 00:21:27,000 Cause that depends on the managed service, right?

312 00:21:27,000 --> 00:21:27,541 Exactly.

313 00:21:27,541 --> 00:21:40,666 And on MWAA so on Amazon, it also auto-discovers the environments that you have within your region, On GCP, you can also select a region and a GCP project, and it will also

314 00:21:40,666 --> 00:21:44,416 auto-discover the composer environments that you have available.

315 00:21:44,416 --> 00:21:46,208 oh Sure.

316 00:21:46,208 --> 00:21:47,458 So here's the repo.

317 00:21:47,458 --> 00:21:48,250 Yeah, exactly.

318 00:21:48,250 --> 00:21:50,666 143 stars!

319 00:21:50,666 --> 00:21:52,666 Exactly and of course it's self-starred.

320 00:21:52,666 --> 00:22:01,958 So this already existed since 2023 and I was mainly using it myself, And I was constantly poking some colleagues like, hey, have you tried Flowrs already?

321 00:22:01,958 --> 00:22:04,291 I know that you have to work with 10 airflow environments.

322 00:22:04,291 --> 00:22:05,750 Maybe you want to try Flowrs.

323 00:22:05,750 --> 00:22:08,916 And then at some point I got an email

324 00:22:08,916 --> 00:22:13,083 Mentioning like, your TUI is the TUI of the week.

325 00:22:13,083 --> 00:22:19,333 And then also the maintainer of the Ratatui project also shared it on his LinkedIn, I think.

326 00:22:19,333 --> 00:22:21,083 And also some more people found it.

327 00:22:21,083 --> 00:22:25,166 And I recently posted it in the Apache Airflow community Slack.

328 00:22:25,166 --> 00:22:28,583 So there's some community interaction now, which I actually like.

329 00:22:28,583 --> 00:22:30,250 It's also a first for me.

330 00:22:30,291 --> 00:22:33,375 I built some stuff, but usually just for myself.

331 00:22:33,375 --> 00:22:36,375 What did you learn about this whole TUI process

332 00:22:36,375 --> 00:22:40,875 I learned that I really like Rust as a programming language.

333 00:22:40,875 --> 00:22:45,750 I also learned that it's fun to just sometimes take a peek under the cover.

334 00:22:45,750 --> 00:22:51,541 We all use these applications, figuring out how they tick is a fun and rewarding experience on its own.

335 00:22:51,541 --> 00:23:00,833 I've also learned that agentic AI, especially the last couple of months, can really speed up the frequency at which you can push out new features.

336 00:23:00,833 --> 00:23:10,833 And I also learned that you sometimes also need to push people, like you have to be the annoying marketeer in order for people to start using your app.

337 00:23:10,833 --> 00:23:12,291 Even if you think it's amazing.

338 00:23:12,291 --> 00:23:14,250 I mean, I use it on a daily basis.

339 00:23:14,250 --> 00:23:15,416 I like using it.

340 00:23:15,416 --> 00:23:18,833 Just building it and making it public on GitHub.

341 00:23:18,833 --> 00:23:22,458 That doesn't result in people finding it and actually using it.

342 00:23:22,458 --> 00:23:26,791 You have to push it out and go after your audience yourself a bit.

343 00:23:27,083 --> 00:23:27,875 Yeah, okay.

344 00:23:27,875 --> 00:23:35,416 Yeah, I think it's a very nice tool you showed us, So thanks a lot for sharing what TUIs are, how you build them, and put them in the market.

345 00:23:35,416 --> 00:23:37,291 if you're using Airflow, check out the tool of Jan.

346 00:23:37,291 --> 00:23:40,500 We'll share the link in the description and in the comments.

347 00:23:40,500 --> 00:23:43,166 So Jan, thanks a lot for explaining this.

348 00:23:43,166 --> 00:23:44,875 Thank you everybody for watching.

349 00:23:44,875 --> 00:23:47,083 Check out Jan's tool and we'll see you next time.

350 00:23:47,083 --> 00:23:47,750 Bye bye!

351 00:23:47,750 --> 00:23:48,375 Bye!