WEBVTT

00:00:00.001 --> 00:00:04.620
Open source has permeated much of the software industry, but what about healthcare?

00:00:04.620 --> 00:00:09.880
This highly regulated and important industry might seem to be the domain of huge specialized

00:00:09.880 --> 00:00:14.480
software companies. On this episode, Fred Kingham is here to introduce us to a project called

00:00:14.480 --> 00:00:20.640
Opal. It was born out of NHS Hack Days in the UK and is a full-stack web framework for building

00:00:20.640 --> 00:00:25.320
healthcare applications. It's based on Django and has a ton of interesting features as a framework

00:00:25.320 --> 00:00:31.220
in general. This is Talk Python To Me, episode 241, recorded November 30th, 2019.

00:00:31.220 --> 00:00:49.520
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the ecosystem,

00:00:49.520 --> 00:00:54.200
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter where I'm at

00:00:54.200 --> 00:00:59.340
and Kennedy. Keep up with the show and listen to past episodes at talkpython.fm and follow the show

00:00:59.340 --> 00:01:04.900
on Twitter via at Talk Python. This episode is sponsored by Linode and the University of San

00:01:04.900 --> 00:01:09.040
Francisco. Please check out what they're offering during their segments. It really helps support the

00:01:09.040 --> 00:01:13.980
show. Hi there. Thanks for listening to this episode. Before we get to the interview, I have

00:01:13.980 --> 00:01:18.920
something to share with you. We just launched a new course. It's called Python for Decision Makers and

00:01:18.920 --> 00:01:24.000
Business Leaders. If you're a team lead or deciding whether to use Python for your next project,

00:01:24.080 --> 00:01:30.040
or even the next stage in your career, this course is a great fit for you. It's super unique. Most

00:01:30.040 --> 00:01:36.000
courses teach you how to program with Python. This course is a guided discussion and exploration of

00:01:36.000 --> 00:01:41.440
the Python ecosystem through the lens of your organization and your team. It's full of fact-based

00:01:41.440 --> 00:01:46.640
presentations for the Python ecosystem, covering things like frameworks, types of apps you can build,

00:01:46.640 --> 00:01:51.600
developer jobs, and more. And it explores some of the tools making Python so popular in the data

00:01:51.600 --> 00:01:57.540
science space. It's written both for developers and non-developers alike. So check it out at

00:01:57.540 --> 00:02:04.960
 talkpython.fm/decision or just click the link in the show notes. But wait, there's more. I'm working

00:02:04.960 --> 00:02:10.060
on a few interactive events as well. So I'm putting together this live event to help kick off the course.

00:02:10.060 --> 00:02:16.560
It's a free webcast on an interactive platform with lots of QA that's happening in January of 2020.

00:02:16.560 --> 00:02:23.320
Check that out at talkpython.fm/python dash decision dash webcast, or just click it in the show

00:02:23.320 --> 00:02:28.660
notes. Go ahead and register now. Hopefully you can make the live event. But if you can't, you can

00:02:28.660 --> 00:02:34.120
still ask questions, participate in polls and chat. All that stuff will be available on demand afterward

00:02:34.120 --> 00:02:39.480
once the recording is there on that platform. Super fun. So I hope you love both of these things,

00:02:39.480 --> 00:02:45.120
the course and the webcast. Now let's get onto that interview. Fred, welcome to Talk Python To Me.

00:02:45.120 --> 00:02:48.360
Hi. Hey, it's great to have you here. We're going to cover some stuff that, you know, I don't think

00:02:48.360 --> 00:02:53.060
we spent any time on the show before. Healthcare and open source. It'll be fun. Sounds great. Yeah.

00:02:53.060 --> 00:02:59.240
Yeah. Now you guys are working on this project called Opal, which has an interesting origin story

00:02:59.240 --> 00:03:06.920
out of the UK healthcare industry and whatnot, which is great. And lots of Python involved. But before we

00:03:06.920 --> 00:03:10.720
get into all that interesting stuff, let's start with your story. How'd you get into programming in Python?

00:03:10.720 --> 00:03:18.200
I started programming on the Atari ST, that venerable computer of the 1980s. I was using something

00:03:18.200 --> 00:03:22.060
called Stoff when I was sort of like seven or eight, you know, when you're creating little

00:03:22.060 --> 00:03:26.500
games, drive the L's through the X's, that kind of thing. Right.

00:03:26.500 --> 00:03:34.580
Full of go-tos, go-tubs and all the joys that come with it. Then I did a philosophy degree and I did a

00:03:34.580 --> 00:03:38.920
conversion course into a master's conversion course into computer science.

00:03:38.920 --> 00:03:42.060
Wow. Philosophy to computer science, huh? That's quite the transition.

00:03:42.060 --> 00:03:46.540
It is. But I don't know. A lot of people, I know a lot of people who've done it.

00:03:46.540 --> 00:03:46.760
Yeah.

00:03:46.760 --> 00:03:54.220
I think there's something about conceptualization, maybe formal logic. There's a whole branch philosophy

00:03:54.220 --> 00:04:00.500
called, what's it called? Logical atomism, I think. Which tries to structure, tries to work

00:04:00.500 --> 00:04:07.200
out Boolean responses to arguments based on conjunctions. Sort of like, if I like trees

00:04:07.200 --> 00:04:14.820
and people who like things are liked, somebody likes me. That kind of weird sort of set logic,

00:04:14.820 --> 00:04:16.560
very Russell-based.

00:04:16.560 --> 00:04:21.080
Right, right. Is it true that I do this or does it follow that I do this? Yeah. Yeah. I think

00:04:21.080 --> 00:04:26.500
actually, now that you say it, there's a lot of thinking. You know, I studied math. I didn't really

00:04:26.500 --> 00:04:31.220
do much programming. I took a couple, like two programming courses in college for little sub

00:04:31.220 --> 00:04:36.880
prerequisites. But I don't feel like I do math at all these days, even though I was in a PhD program

00:04:36.880 --> 00:04:43.860
working on it, right? But I feel like that process that I went through, the type of thinking and the

00:04:43.860 --> 00:04:48.280
way of approaching problems and all that, like, I use that every day. And that seems like it came straight

00:04:48.280 --> 00:04:51.840
out of there, even though I couldn't do math to save my life these days.

00:04:51.840 --> 00:04:52.880
Yeah, exactly.

00:04:52.880 --> 00:04:56.160
All right. Before we move on to philosophy, who's your favorite philosopher?

00:04:56.160 --> 00:05:04.920
David Hume, who is the father of empiricism, who, he writes very interesting books about

00:05:04.920 --> 00:05:10.500
skepticism and causality, the notion of how do you know if something is connected to that,

00:05:10.500 --> 00:05:15.600
to something else? You know, causality does causality equal causation, does correlation equal

00:05:15.600 --> 00:05:20.300
causation. And his books are very readable, and I highly recommend them. He writes them as a

00:05:20.300 --> 00:05:25.160
discourse between, like, two or three people quite often. Discourse is concerning natural religion,

00:05:25.160 --> 00:05:27.980
I think. Dialogue concerning natural religion, exactly.

00:05:27.980 --> 00:05:31.620
Yeah, that's a tough question. There's so many choices throughout the years. All right,

00:05:31.620 --> 00:05:35.500
so you studied philosophy, and then you did this conversion course over to computer science,

00:05:35.500 --> 00:05:35.640
huh?

00:05:35.720 --> 00:05:41.220
I finished my philosophy course, I went traveling for a bit, had a small little accident, ended

00:05:41.220 --> 00:05:45.400
up in a hospital for a bit, came out of that, did a master's conversion course, went into

00:05:45.400 --> 00:05:52.040
banking, because it seemed like a good thing for five odd years. Sort of Wall Street, I guess,

00:05:52.040 --> 00:05:57.500
the investment side, what we would call the city. And then I did some contracting for a few

00:05:57.500 --> 00:06:03.600
years for sort of marketing companies, you know, marketing websites, that kind of thing. And then

00:06:03.600 --> 00:06:11.880
I went to NHS Hack Day, which is a series of hack days that exists in the UK, where clinicians come up

00:06:11.880 --> 00:06:16.880
and they're like, we have this problem. At the moment, there's nothing available at our hospital.

00:06:16.880 --> 00:06:22.860
In a weekend, can you sort of push something out so that I can take it back to my hospital IT

00:06:22.860 --> 00:06:28.060
people who are saying, we can't have this and say, well, these guys have done something similar

00:06:28.060 --> 00:06:33.420
in a weekend, make it happen kind of thing. Yeah, exactly. Like, it's so funny that sometimes

00:06:33.420 --> 00:06:36.600
that's the way it is, right? Oh, you can't do that. There's no way. This is impractical. Do you

00:06:36.600 --> 00:06:41.320
know how long this will take? Yeah, it'll take a couple of weeks. Let's just do it. And you know,

00:06:41.320 --> 00:06:45.920
like, sometimes the debate about whether something is possible takes longer than actually doing it.

00:06:45.920 --> 00:06:50.940
But you need this sort of outside perspective, right? So this NHS Hack Days, what is the goal? I mean,

00:06:50.940 --> 00:06:55.200
you said the goal is to like, show what is possible. Is the goal to go there and try to like,

00:06:55.200 --> 00:07:00.000
learn what is needed to maybe I could do a startup? Is it a charitable thing? Like,

00:07:00.000 --> 00:07:04.520
I want to create the software and I want to give it back to the health industry in my country to just

00:07:04.520 --> 00:07:09.760
help everyone what's going on there? It's quite open source. It's not really about the businesses,

00:07:09.760 --> 00:07:14.420
people have tried to launch businesses based on the ideas that have come out of it. People,

00:07:14.420 --> 00:07:19.760
some people go there to learn, some people go there just to learn, you know, experiment in

00:07:19.760 --> 00:07:24.320
technology. It's quite a common reason to go to Hack Day anyway. The idea is definitely to make the NHS

00:07:24.320 --> 00:07:29.760
better in this country or healthcare better. But as I say, people have tried to make companies out of

00:07:29.760 --> 00:07:35.300
their stuff on one side. But on the other side, there's a one in one of the first one, a great

00:07:35.300 --> 00:07:42.520
example is people who essentially have to type in like a series of strings based on whether they see

00:07:42.520 --> 00:07:49.080
certain cells, certain things within a cell. And it was taking people ages. And the solution was

00:07:49.080 --> 00:07:55.720
literally, well, we'll just remap your keyboard, so that you press J and this weird string comes out.

00:07:55.720 --> 00:08:01.960
And suddenly what you've got is people who are taking days at something being able to do it in,

00:08:01.960 --> 00:08:08.920
less than an hour. And it's such a simple solution. And yeah, you could turn that into a business model.

00:08:08.920 --> 00:08:17.160
But realistically, this is just, it's just an easy way of making somebody's life so much easier. And

00:08:17.160 --> 00:08:20.360
it's not hard. Anyone can write that, right? It's not.

00:08:20.520 --> 00:08:26.760
Right. On the other hand, I think I know some people who they did. One of the big problems is

00:08:26.760 --> 00:08:31.720
people who don't take their medications, specifically if they're ill. I know some people who tried to

00:08:31.720 --> 00:08:37.720
create a company. I don't know how I was doing. I've lost track of them. But that was take your meds.

00:08:37.720 --> 00:08:42.360
So essentially people getting a text message when they should take their medication because

00:08:42.360 --> 00:08:48.600
people don't take their medication. It tends to make the whole system right because things, you know,

00:08:48.600 --> 00:08:53.320
suddenly what should be very cheap is super expensive because you then have to go in there

00:08:53.320 --> 00:08:54.840
and make, you know, real.

00:08:54.840 --> 00:09:01.160
Yeah. Do some kind of intervention. Yeah. So like schizophrenic stuff or medication or

00:09:01.160 --> 00:09:06.440
depression medication. I feel like people take that stuff and then they're like, oh, I feel better now.

00:09:06.440 --> 00:09:10.920
I'm better. I don't need my meds. Right. But maybe, you know, maybe it's because you're taking the

00:09:10.920 --> 00:09:14.920
medication. As soon as you stop, you're like, oh, my gosh, it's all back to beginning.

00:09:14.920 --> 00:09:20.360
It's often for like geriatric, well, geriatric, like old people who, you know, they're required

00:09:20.360 --> 00:09:25.560
to take medication once every three hours. And it's so easy to forget. And as soon as you don't,

00:09:25.560 --> 00:09:31.000
well, suddenly you haven't taken, I don't know, that medication and you're at risk of a heart attack.

00:09:31.000 --> 00:09:35.720
Yeah, of course. Yeah. I guess if the frequency is a couple of hours, it's tricky. Yeah.

00:09:35.720 --> 00:09:41.080
Yeah. Cool. So we've, you've got these NHS hack days, which sounds like a really good idea. I don't

00:09:41.080 --> 00:09:47.400
know if we have that in the US. Maybe we do, but I've never heard of it. You know, I probably one of

00:09:47.400 --> 00:09:53.480
these cool benefits of government healthcare. Interesting. So, so, you know, it's not all just

00:09:53.480 --> 00:09:59.880
for profit. Like who wants to go help? I don't know, like your local HMO make more money or that

00:09:59.880 --> 00:10:04.520
local health insurance company. Right. I'm not going to go do a hack day for any insurance company

00:10:04.520 --> 00:10:09.400
whatsoever. Right. Unless it's just weird. Anyway, this is cool. So you guys have these

00:10:09.400 --> 00:10:15.160
and you went there and, Opal was born out of it, huh? So yeah, Opal was born out of,

00:10:15.160 --> 00:10:20.840
out of that by, by my, my wife, a colleague, like a couple of years before,

00:10:20.840 --> 00:10:27.880
before I joined open healthcare. And then I was contracting. I was, I went to a couple of these

00:10:27.880 --> 00:10:33.000
hack days and been to a couple of years in a row. And then I went to work for, went to an interview at

00:10:33.000 --> 00:10:37.960
quite a sort of prestigious startup. it was quite as intense a process. Like, I don't know,

00:10:37.960 --> 00:10:42.360
six hours of continuous interviews. And then in the last one, the founder of the company said,

00:10:42.360 --> 00:10:48.520
where do you see yourself in 10 years? And I said, writing software for open source software for the

00:10:48.520 --> 00:10:55.880
NHS. So then I turned down their offer and went to work for open healthcare. Cause I realized by going

00:10:55.880 --> 00:10:59.240
through that process, that was actually what I wanted to do. So why not do it now?

00:10:59.240 --> 00:11:00.840
It's pretty grand.

00:11:00.840 --> 00:11:06.360
That's grand. So I think this is a good test. People should give themselves periodically,

00:11:06.360 --> 00:11:11.900
right? The five year, the 10 year test, you know, in this case, it was where do you see yourself? Like

00:11:11.900 --> 00:11:16.320
in the broad sense, but it could also be, you know, look at the people that are five or 10 years more

00:11:16.320 --> 00:11:21.440
senior than you and your company. What do they do? Do you, do you want to do that? If you don't want to

00:11:21.440 --> 00:11:26.580
be doing that, the time to like start finding a different path is now, right? Because that's,

00:11:26.700 --> 00:11:29.580
that could be right where you're headed. I think that's a great motivation.

00:11:29.580 --> 00:11:33.040
When you go into an interview and you see the people who are interviewing you,

00:11:33.040 --> 00:11:37.120
the first thing you should think is, do I want to be these people? Do these people

00:11:37.120 --> 00:11:39.740
seem happy with their lives and their life choices?

00:11:39.740 --> 00:11:46.580
Yeah, that's really great. I totally agree with that. All right. So that's a pretty big goal. And

00:11:46.580 --> 00:11:53.080
I think it's a very cool thing, but I also see it as challenging just as a career, right?

00:11:53.620 --> 00:11:59.220
I want to go write open source software for NHS. How did you tie that back to the career in your

00:11:59.220 --> 00:12:01.840
mind? Like, how are you going to pay the bills while doing that?

00:12:01.840 --> 00:12:07.160
The business model is essentially quite clearly there. Like if you can create a good service,

00:12:07.160 --> 00:12:14.740
medical software is big business. I don't see the open source as in any way a blocker to this.

00:12:14.740 --> 00:12:20.720
I want to, like the NHS are paying us money. We're not doing this out of the goodness of our hearts.

00:12:20.720 --> 00:12:26.580
the open source means that the quality of the software can be more rigorously tested,

00:12:26.580 --> 00:12:34.260
that there's not so much of a contractual lock-in because one of the problems that you get, I was

00:12:34.260 --> 00:12:41.560
talking to a hospital that will remain nameless and a lot of the medical data is with one system and

00:12:41.560 --> 00:12:46.020
they want to shift to another system. And they said, how much to move it across? And they were told 10

00:12:46.020 --> 00:12:51.320
million quid, 10 million pounds. Yeah. The hospital was like, we can't afford that.

00:12:51.320 --> 00:12:58.200
So we just dumped the data and the sort of computer proprietor said, well, it'll be 10 million pounds to

00:12:58.200 --> 00:13:00.300
delete the data. That's rough.

00:13:00.300 --> 00:13:06.040
Yeah. Right. There's a bad system of contractual lock-ins. So by being open source,

00:13:06.440 --> 00:13:11.840
we can provide great quality software, we can charge for great quality software, but if they

00:13:11.840 --> 00:13:16.580
don't like us, they're not locked into us because anyone can look at the source code that we've

00:13:16.580 --> 00:13:22.400
written and sort of take it over if necessary. Hopefully that's never happened so far and we'd

00:13:22.400 --> 00:13:23.020
like to think it won't.

00:13:23.020 --> 00:13:28.780
I think so. And you know, it's based on super popular stuff, right? Things that most people

00:13:28.780 --> 00:13:36.780
who know Python could walk in and get up to speed on in a week or so, at least. And you know, Python

00:13:36.780 --> 00:13:42.600
being the most popular language or at least contending not for that, that's a pretty solid

00:13:42.600 --> 00:13:45.960
statement that people can just pick this up. So tell us what Opal is.

00:13:45.960 --> 00:13:51.820
Opal is a web framework for building healthcare applications that store medical data about people.

00:13:51.820 --> 00:13:57.460
Cool. So we have Django, we have Flask, we have Pyramid, we have Starlet, we have these other

00:13:57.460 --> 00:14:05.160
frameworks. Why do we need Opal? What does it do in addition to just, you know, Django, you know,

00:14:05.160 --> 00:14:08.480
create app or cookie cutter, Pyramid or Flask?

00:14:08.480 --> 00:14:14.420
Yeah. So that's a super interesting question because in the levels, Opal is kind of, it's a domain

00:14:14.420 --> 00:14:21.360
specific framework. So you have Django, Django is do anything on the web. So Django,

00:14:21.360 --> 00:14:26.720
Django arrives on the scene. And I don't know if you're too young to remember this. But Django

00:14:26.720 --> 00:14:30.960
arrives on the scene and suddenly you were able to say, well, I want to create a polls app. And

00:14:30.960 --> 00:14:36.880
you know, I was able to do it in a lunch break. And I was able to do a week's work in a, in a

00:14:36.880 --> 00:14:43.120
lunch break. And that's, that's amazing. And it revolutionized things, right? And then from

00:14:43.120 --> 00:14:48.480
there, you don't have that too many sort of domain specific, I guess, blogging software is the,

00:14:48.480 --> 00:14:54.580
is the most domain specific where you have software, which is a framework, which are,

00:14:54.580 --> 00:14:57.980
I'm just going to build a blog. I'm going to do one thing. So you've taken, right?

00:14:57.980 --> 00:15:00.820
Got something like Django and then you're super specialized on top of that.

00:15:01.480 --> 00:15:05.720
Right. Like WordPress or ghost or something. I hadn't even really considered blogging,

00:15:05.720 --> 00:15:11.900
blog frameworks, platforms as, you know, domain specific. But yeah, you're right. They,

00:15:11.900 --> 00:15:14.940
they definitely are. And it makes a ton of sense, right? I'm just, you know,

00:15:14.940 --> 00:15:20.500
thinking about what you get. So this is built on Django, Opal is. So it's not like

00:15:20.500 --> 00:15:24.320
another framework in the sense of that it's trying to compete with those, but it's,

00:15:24.480 --> 00:15:30.220
let's take Django and let's, let's take all the boilerplate junk that you have to write

00:15:30.220 --> 00:15:37.080
to build something in the clinical domain, make that happen. And now get started, right?

00:15:37.080 --> 00:15:42.480
What we can do is we can say, we know you're going to have patients. We know you're going to have

00:15:42.480 --> 00:15:48.540
episodes of care. We know, yeah, we know you're probably going to have these bunch of clinical models.

00:15:50.400 --> 00:15:57.120
And we can therefore make loads of assumptions, which means that we can scaffold things out quite

00:15:57.120 --> 00:16:03.520
quickly. So we know that you're going to have a patient list page, patient detail pages of different

00:16:03.520 --> 00:16:09.380
types of episodes of care. We know that you're going to want forms for, forms for, for example,

00:16:09.380 --> 00:16:14.760
conditions for diagnoses that are going to hang off an episode of care. So we can say,

00:16:15.660 --> 00:16:22.820
we can scaffold you up forms for the condition. We can scaffold you display templates. We can give

00:16:22.820 --> 00:16:27.640
you a rest endpoint for an episode, which will give you all of the things which are hanging off that.

00:16:27.640 --> 00:16:33.680
So you've got that for your treatment, your diagnosis, maybe your treatments, maybe your blood cultures,

00:16:33.680 --> 00:16:39.400
maybe your lab tests. We can just do that super quickly because we know that's what the modeling

00:16:39.400 --> 00:16:40.860
structure that you're going to want.

00:16:41.660 --> 00:16:46.600
That's great. So you don't have to think about all those things. You just start using them. And these

00:16:46.600 --> 00:16:53.420
are all classes. These are Django entities, right? In the Django ORM. But you could create ones that are

00:16:53.420 --> 00:16:58.260
more specialized. You could create other ones that go in there, right? So it's, it sounds like a lot of

00:16:58.260 --> 00:17:01.740
the core data models already put together and, and things like that, right?

00:17:01.860 --> 00:17:10.720
We have sort of a specialized model called a sub record that we know that you, you can use, which we

00:17:10.720 --> 00:17:15.540
know will have a relationship to a patient or relationship to an episode. And because we know

00:17:15.540 --> 00:17:22.500
that model structure, we can automatically wire that into forms and stuff, as I said, but also into

00:17:22.500 --> 00:17:30.500
search, into data extract. We don't, Opal doesn't enforce like a model structure. It offers this. And this,

00:17:30.500 --> 00:17:37.220
uh, a lot of what these kinds of frameworks do is they, and what Opal tries to do is get you 80% of

00:17:37.220 --> 00:17:41.300
the way there. You know, once you're there, once you've done, once you've started prototyping, you

00:17:41.300 --> 00:17:46.580
might be like, Oh, I want to just use more sort of vanilla Django stuff. Opal doesn't stop any of that.

00:17:46.580 --> 00:17:51.300
It just gives you a helping hand in what we think the right direction.

00:17:51.540 --> 00:17:58.260
Yeah. I just that quick, quick boost. And even though this came out of those NHS hack

00:17:58.260 --> 00:18:03.540
weeks, I suspect somebody could take this as the starting point for another one of those and really

00:18:03.540 --> 00:18:07.680
bust out something pretty amazing, pretty quickly. It sounds like, cause it just puts all this stuff

00:18:07.680 --> 00:18:13.380
together for you. So one of the things that these episodes, sub records, which are the Django models

00:18:14.100 --> 00:18:20.740
do that. I don't know. It's kind of interesting to me is it creates a relationship between the

00:18:20.740 --> 00:18:26.580
entities already, right? Which is pretty cool. But it also creates a JSON API for creating and updating and

00:18:26.580 --> 00:18:32.980
searching them. It creates, make sure that the angular layer, we'll talk about angular in a little

00:18:32.980 --> 00:18:39.060
bit, the angular front end layer knows about it. bunch of stuff like that, right? That's pretty cool.

00:18:39.060 --> 00:18:43.380
Any modern develop web developer knows that you're probably going to want to have Django rest framework

00:18:43.380 --> 00:18:49.780
endpoints for a Django app. So exactly right at Spox, it gives you those. It does some schema

00:18:49.780 --> 00:18:56.100
description so that if you're looking for other developers to use to like programmatically read

00:18:56.100 --> 00:19:00.420
your endpoints, you can give them that description and they'll have an understanding of

00:19:00.420 --> 00:19:04.580
what data is going to be available. so yeah, I think, I think it's all right.

00:19:04.580 --> 00:19:08.420
That's pretty sweet. So it comes with batteries included, but these batteries are more like

00:19:08.420 --> 00:19:13.540
stethoscopes and tongue depressors. That's excellent. I'm stealing that. That's fine.

00:19:13.540 --> 00:19:17.220
Feel free to steal it. It's all good. I'm sure there's better, better,

00:19:17.220 --> 00:19:19.700
analogies in the health space, but that's a good start.

00:19:19.700 --> 00:19:27.300
This portion of Talk Python To Me is brought to you by Linode. Are you looking for hosting that's fast,

00:19:27.300 --> 00:19:31.860
simple, and incredibly affordable? Well, look past that bookstore and check out Linode at

00:19:31.860 --> 00:19:39.860
talkpython.fm/linode. That's L I N O D E plans start at just $5 a month for a dedicated server with a gig

00:19:39.860 --> 00:19:44.900
of RAM. They have 10 data centers across the globe. So no matter where you are or where your users are,

00:19:44.900 --> 00:19:48.900
there's a data center for you. Whether you want to run a Python web app, host a private

00:19:48.900 --> 00:19:55.620
Git server, or just a file server, you'll get native SSDs on all the machines, a newly upgraded 200 gigabit

00:19:55.620 --> 00:20:00.980
network, 24 seven friendly support, even on holidays and a seven day money back guarantee.

00:20:00.980 --> 00:20:05.460
Need a little help with your infrastructure. They even offer professional services to help you with

00:20:05.460 --> 00:20:10.340
architecture, migrations, and more. Do you want a dedicated server for free for the next four months?

00:20:10.340 --> 00:20:20.020
Just visit talkpython.fm/linode. When I think of this project, it sounds cool. Like if I, as a primarily

00:20:20.020 --> 00:20:25.540
web developer, when I'm writing code, when I'm thinking of like, how would I use this? Obviously,

00:20:25.540 --> 00:20:31.220
I would go out and I would build some cool healthcare app if that was the domain I wanted to spend some

00:20:31.220 --> 00:20:37.780
time on. But when you think about this project, who do you have in mind? Like, have you made this for

00:20:37.780 --> 00:20:43.460
people like me? Have you made this for the IT folks inside the company? Have you made it for doctors?

00:20:43.460 --> 00:20:47.860
Like, who do you have in mind using or who's ended up using Opal?

00:20:47.860 --> 00:20:55.060
That's a nice question. So in reality, we use this ourselves. Obviously, we exist in a number of

00:20:55.060 --> 00:21:03.540
major hospitals for sort of a whole bunch of teams. And I think that when building a framework, you know,

00:21:03.540 --> 00:21:08.660
you need to, what is it? Eat your dog food? Yeah, we are the dog. And this is designed for other

00:21:08.660 --> 00:21:15.300
dogs like us. So other developers being brought into hospitals or who already work in hospitals

00:21:15.300 --> 00:21:23.460
to develop healthcare applications. That being said, doctors, as it turns out, incredibly smart,

00:21:23.460 --> 00:21:30.500
technically minded individuals. And a number of them have picked up an experiment with Opal for their own

00:21:30.500 --> 00:21:37.220
sort of side project and for projects for their hospitals. I'm not sure a doctor has ever released an

00:21:37.220 --> 00:21:41.700
local application into a hospital. And maybe you'd want to give it a code review first.

00:21:41.700 --> 00:21:47.300
It's going to need some refactoring. I'm not so sure about this. But you know, I think that's really

00:21:47.300 --> 00:21:53.060
cool. And I do think that's one of the things that Python makes more possible for folks who are really

00:21:53.060 --> 00:21:57.860
smart and technically minded like doctors to just say, you know, I have this problem. And it's got to be

00:21:57.860 --> 00:22:03.460
frustrating to go to work, at least in the US, it's you never log into your computer, you log into like some

00:22:03.460 --> 00:22:09.860
Citrix, remote desktop thing. And you know, it just there's probably all these frustrating like layers.

00:22:09.860 --> 00:22:14.340
And they're just like, you know what, if I could just have this thing, it seems so easy.

00:22:14.340 --> 00:22:19.700
And you know, they probably just, you know, start busting something out, right. And then they can bring

00:22:19.700 --> 00:22:24.420
that in and be that proof that you talked about, like from the NHS hack days sort of example.

00:22:24.420 --> 00:22:26.580
Exactly. They can just say, look, it's not that hard.

00:22:26.580 --> 00:22:32.020
I have a funny story. I'll tell you real quick about a doctor and programming. I was at the doctor.

00:22:32.020 --> 00:22:36.020
I don't remember why it was nothing major, just some random thing with the doctor.

00:22:36.020 --> 00:22:44.420
Maybe 2010, something like that, quite a while ago. And the doctor said, what do you do?

00:22:44.420 --> 00:22:47.460
So I'm a programmer. And I said, what language do you program at the time? I'm like, well,

00:22:47.460 --> 00:22:50.260
programming this language called C#, which I was at the time.

00:22:50.260 --> 00:22:54.180
And he says, pauses for a second. He looks at me. And I thought he was just trying to make small

00:22:54.180 --> 00:22:57.700
talk. Right. So he could like, before he stabbed me with a needle or something, looks over, goes,

00:22:57.700 --> 00:23:03.700
you excited about the new release of Visual Studio? I'm like, excuse me? He's like, yeah,

00:23:03.700 --> 00:23:07.460
this new stuff they're doing is so great. I'm really, I'm like, are you a real doctor? Who are you?

00:23:07.460 --> 00:23:10.260
Like, who gave you that robe? I'm not sure I want that.

00:23:10.260 --> 00:23:14.740
Yeah. Did this make you trust him more or less? What's the,

00:23:14.740 --> 00:23:20.020
both, both, but it's so interesting because you like at the time, I'm like, oh, sure.

00:23:20.020 --> 00:23:23.700
They're surely they don't care. But the more I interact with doctors, the more I realize,

00:23:23.700 --> 00:23:27.860
you know, yeah, for sure. They, they have these challenges and you can bring in programming

00:23:27.860 --> 00:23:31.620
languages to solve those at some point, like the pressure gets too high. You're just like,

00:23:31.620 --> 00:23:34.980
I'm going to write this website. That's going to solve this problem. I do see it as an extra

00:23:34.980 --> 00:23:39.540
challenge in the healthcare space over, you know, some other, I said, say accounting or something,

00:23:39.540 --> 00:23:43.380
right? And then maybe it kind of is not even the best counter example, but in healthcare,

00:23:43.380 --> 00:23:47.620
you have to be a little more careful with your data and stuff. So you can't just like,

00:23:47.620 --> 00:23:51.540
I just threw it on like a random server on the internet and it's easy now. Like,

00:23:51.540 --> 00:23:53.300
well, maybe that's not going to fly.

00:23:53.300 --> 00:23:58.020
To me, one of the interesting things about the medical space in relation to other space. So

00:23:58.020 --> 00:24:01.220
as I say, I used to just sort of do some investment banking stuff.

00:24:01.220 --> 00:24:04.980
what you have there and what you have in a lot of places, you have things like stocks,

00:24:04.980 --> 00:24:12.420
stocks are essentially manmade inventions, right? And therefore they've already like a man's mind can

00:24:12.420 --> 00:24:17.220
comprehend what they were and, or a person's mind can comprehend what they were and draw the

00:24:17.220 --> 00:24:21.860
limitations around that. And there's, there are legal entity in that to describe. Whereas when you look

00:24:21.860 --> 00:24:30.980
at modeling in a medical sense, it's such a, a broad, we're just ascribing concepts to real world

00:24:30.980 --> 00:24:37.300
conditions. That means that modeling comes far, far fuzzier. Sort of when you're saying sort of like

00:24:37.300 --> 00:24:43.460
obesity, somebody's dying of like drowning, well, nobody dies of drowning. They die of like an oxygen

00:24:43.460 --> 00:24:45.300
deficit kind of thing. Right, right.

00:24:45.300 --> 00:24:50.100
So when you're filling in your medical notes, what do you do? Well, you know, like, which I think

00:24:50.100 --> 00:24:57.060
means and different doctors will put in different things because if you're a blood cancer specialist,

00:24:57.060 --> 00:25:03.140
then your concepts of dying of this, I don't, okay, maybe I don't know that. Maybe I don't know blood

00:25:03.140 --> 00:25:09.140
cancer for certain, but definitely when describing a blood cancer, describing a blood test, if you work

00:25:09.140 --> 00:25:13.620
in microbiology, your description is going to be different from a doctor who was another specialist,

00:25:14.260 --> 00:25:15.540
which I think is super interesting.

00:25:15.540 --> 00:25:21.300
It is. And, you know, I think it really makes the modeling challenging, right? And we already talked

00:25:21.300 --> 00:25:26.900
that there are some of the sub model, some episode, sub episode classes, like the Django model

00:25:26.900 --> 00:25:32.980
classes that model these things, but they're coming from a certain perspective, right? Like one of the

00:25:32.980 --> 00:25:37.460
things that you talked about on the, maybe on the tutorial, I can't remember where I saw this, but

00:25:37.460 --> 00:25:43.620
to, you know, a cough, it could be a symptom of a condition or the cough itself could be a

00:25:43.620 --> 00:25:47.700
condition. So if they come and say, Hey, I need you to treat me because I have a cough,

00:25:47.700 --> 00:25:54.020
then that's probably the condition. But if they have a cold, then it's just a symptom, right?

00:25:54.020 --> 00:25:56.820
So how do you record that in your database?

00:25:56.820 --> 00:26:01.780
Which is it a symptom or a condition, right? These are, these are challenging.

00:26:01.780 --> 00:26:07.860
I sat in a room with doctors having full blown arguments at each other about exactly this. And

00:26:07.860 --> 00:26:10.900
it's kind of like, well, if you don't know, how do you expect us to know that?

00:26:10.900 --> 00:26:17.060
Yeah. Well, that's the problem or the challenge of building something for a domain, especially if you're

00:26:17.060 --> 00:26:23.300
not yourself a doctor or you're a specialist in that domain, it makes it harder to model stuff in that

00:26:23.300 --> 00:26:27.540
domain as a programmer. But it's also the value, right?

00:26:27.540 --> 00:26:34.100
That is one of the things that I will try to say, you know, the programmers, I, well, I've been a

00:26:34.100 --> 00:26:40.260
programmer for 12 years now. I've been around the block. A doctor has had, what, at least five years

00:26:41.060 --> 00:26:46.340
a university, probably two years after that, still sort of learning the ropes, you know,

00:26:46.340 --> 00:26:52.260
they're going to be eight, nine years down the line. And so the, what Opal tries to do is trying to

00:26:52.260 --> 00:26:59.380
create through, essentially the, in some levels, the Django sort of modeling, Django models is to kind of

00:26:59.380 --> 00:27:05.700
create a bridge where two very, very complicated domains can kind of meet and discuss in a way that

00:27:05.700 --> 00:27:08.980
they can understand each other. I guess it's that shared experience, right?

00:27:08.980 --> 00:27:15.940
So maybe an interesting way to talk about, to give people a sense of what this is and how it works.

00:27:15.940 --> 00:27:23.060
Maybe we could talk through a getting started story. So you have a tutorial on the website and it says,

00:27:23.060 --> 00:27:27.620
as a doctor, you want to know what's going on with your patients under your care so you can treat them

00:27:27.620 --> 00:27:33.540
effectively and whatnot. So you need some kind of app or something to manage that. Let's build that in,

00:27:33.540 --> 00:27:38.580
in Opal, which is pretty interesting. So do you want to maybe just talk us through,

00:27:38.580 --> 00:27:45.060
like this whole getting started story here? Opal does similar thing to, I guess, Django app and start

00:27:45.060 --> 00:27:52.500
projects, but again, more specific for, for medical applications. So out of the box, we essentially

00:27:52.500 --> 00:27:58.260
give you some core clinical models that we think are pretty good and you might like, and we give you some

00:27:58.260 --> 00:28:04.900
reference data that you might want to change, but it's the kind of thing that you want loaded in this

00:28:04.900 --> 00:28:11.060
table. So we give you a list of conditions that doctors have given us in the past and said,

00:28:11.060 --> 00:28:17.220
these are the kind of conditions we want to record. We give you sort of basic sort of demographic lookup

00:28:17.220 --> 00:28:23.060
lists. So again, you know, like gender, ethnicity, you might want to change them, but out of the box,

00:28:23.060 --> 00:28:31.220
give me something sensible. When you run the create project, you get sensible defaults and it gives you a

00:28:31.220 --> 00:28:38.580
patient list and episode detail page and a way of adding patients because we know from the domain

00:28:38.580 --> 00:28:42.500
that these things that you're going to want. Yeah. And it feels very much like getting started with

00:28:42.500 --> 00:28:48.180
Django itself. So the way you get Opal is you just pip install it. That's cool. All right. You just pip

00:28:48.180 --> 00:28:53.220
install this or put it as a requirement. And then you say, Opal start project, and you give it a name,

00:28:53.220 --> 00:29:00.100
very Django-esque. Go in there and go in that folder and you say, Python manage that py run server,

00:29:00.100 --> 00:29:05.140
right? Like you could just replace Opal with Django. And so far you're on the same path, right?

00:29:05.140 --> 00:29:10.820
I mean, that might just be for a good reason. Exactly. We've taken what Django, we think Django did

00:29:10.820 --> 00:29:18.020
well and hopefully extended that. So yeah, exactly. So it gives you the Django settings, which are probably

00:29:18.020 --> 00:29:22.900
going to be the ones you want. It gives you an S you like, you know, it sets you up with a S you like.

00:29:22.900 --> 00:29:28.100
Right. So basically, if I'm a Django developer, it's super easy for me to drop in and get started with

00:29:28.100 --> 00:29:33.300
Opal. I just have to learn the new batteries that you've added, right? And the conventions that you

00:29:33.300 --> 00:29:38.580
follow. We've given you some sugar. But if you're a Django developer, it really shouldn't take you,

00:29:38.580 --> 00:29:43.780
it shouldn't be too difficult to figure out what we're doing. And I will say, once, you know,

00:29:43.780 --> 00:29:48.020
if you want, if you're a Django developer, you're like, I like what you've done with this,

00:29:48.020 --> 00:29:53.460
but I'd like to do this in vanilla Django. We don't stop you from defining your own views and

00:29:53.460 --> 00:29:59.220
doing what you like. How much of what Opal gives you in terms of this scaffolding business here,

00:29:59.220 --> 00:30:05.620
how much of it is a, at the beginning of my project, one time only, or is there a way to

00:30:06.260 --> 00:30:13.780
periodically add new entities and new views? Right. So maybe I have like, like I have demographics

00:30:13.780 --> 00:30:17.860
and treatments and diagnosis and all that stuff comes out of the box, but then say like, oh,

00:30:17.860 --> 00:30:22.980
I need a surgery and I'm going to add that. Is there a way to run like a command line option to,

00:30:22.980 --> 00:30:27.620
to do all that magic to add it in? Or do I, am I kind of on my own once I started?

00:30:27.620 --> 00:30:34.420
So you add in a carer model, for example, for a patient, for an episode, you add in your Django

00:30:34.420 --> 00:30:41.460
model and then you run managed applied scaffold. What we'll do is we will create you a form template

00:30:41.460 --> 00:30:48.900
and a display template. And then you have to go into your patient detail and which will already have

00:30:48.900 --> 00:30:54.420
a list of similar sort of record panels as we call them. And you can just add in that,

00:30:54.420 --> 00:31:03.300
but with care instead of what that gives you is a display template and a way of adding automatically

00:31:03.300 --> 00:31:08.100
wires you in like a modal form. So you click add one and it would bring you up a modal form.

00:31:08.100 --> 00:31:13.300
And then what we do is we look at a method called underscore is Singleton. We look at a property

00:31:13.300 --> 00:31:18.660
called underscore is Singleton on model. And that tells us if it's a one to one model or a one to many

00:31:18.660 --> 00:31:23.940
models. So obviously like demographics, you're only going to have one, but you're only going to have one

00:31:23.940 --> 00:31:28.500
name, right? Well, it's not be true. You're only going to have one demographics model related to

00:31:28.500 --> 00:31:33.540
a person, whereas you may have multiple treatments. And so that tells the record panel whether to allow,

00:31:33.540 --> 00:31:38.980
let me add many treatments or just let me edit the single demographics model.

00:31:38.980 --> 00:31:44.820
That is awesome because then you could just keep adding these Django models and then just rerun

00:31:44.820 --> 00:31:47.300
scaffold and it does all the stuff for you, right? All the magic.

00:31:47.300 --> 00:31:52.580
Exactly. So it just ellips your model and then creates your form, a whole bunch of point fields

00:31:52.580 --> 00:31:59.700
off the back of that. We are different from vanilla Django. We use a template tag for our form fields

00:31:59.700 --> 00:32:04.740
because under the covers, this is all, there's, there's a whole bunch of angular that's happening.

00:32:04.740 --> 00:32:09.140
So we're not refreshing the page. We're bringing up a model. We're editing it. We're changing it.

00:32:09.140 --> 00:32:13.940
We're saving it. Everything just working with the doctor the other day. And what was really lovely is

00:32:13.940 --> 00:32:22.820
they changed one of the models and then they looked at form. And personally, I really like API design.

00:32:23.380 --> 00:32:28.100
And when somebody like doesn't even need to look at the dots and they're like, oh, I just need to change

00:32:28.100 --> 00:32:33.620
this to this. And you're like, that's grand. Yeah. My work here is done. Yeah. You know,

00:32:33.620 --> 00:32:38.900
you build a good API when they're their first guess, their first intuition is exactly what you'd hope

00:32:38.900 --> 00:32:42.900
they would do. Exactly. Super cool. So one of the things I saw in the tutorial that was pretty

00:32:42.900 --> 00:32:48.740
interesting is you have these relationships like, you know, what problem or symptom did this person

00:32:48.740 --> 00:32:54.900
have, and there's probably a big pre-filled list, like a dropdown select. You can pull down and choose,

00:32:54.900 --> 00:32:59.460
you know, they've got a fever, their foot is broken, whatever their bone is broken.

00:32:59.460 --> 00:33:05.860
But it's, it also allows you to type in free text. So you have this column type field type,

00:33:05.860 --> 00:33:09.940
foreign key or free text. That was really interesting to me is that you guys came up with that,

00:33:09.940 --> 00:33:15.060
right? That's not part of Django. Yeah, that's all our pattern. I've seen like different people in

00:33:15.060 --> 00:33:20.260
different places, all of them having to roll their own sort of customized implementation of

00:33:20.260 --> 00:33:25.540
exactly the same thing. It's such a common thing that I want to put in a sort of a foreign key

00:33:25.540 --> 00:33:32.420
relationship or free text. And what this does is it does exactly that. It's a free text box,

00:33:32.420 --> 00:33:36.420
you can type in whatever you like, but there'll be an auto complete bunch of options. And you can

00:33:36.420 --> 00:33:41.220
select one of those and it'll save it as a relational, as a foreign key method. And one of the things

00:33:41.220 --> 00:33:50.580
that's nice is that they, it also supports symptoms. So say you can have a cough or a sore throat or,

00:33:50.580 --> 00:33:57.460
I don't know, a pain, pain throat. I don't know. Yeah. You kind of get the idea that quite often

00:33:57.460 --> 00:34:04.260
there's two terms for the same thing, symptoms and what the doctors can do or what they can tell us to do

00:34:04.260 --> 00:34:10.900
is say, wheezyness and breathlessness are the same thing. And it will reconcile those so that you have

00:34:10.900 --> 00:34:13.860
a consistent view of what the patient might have if they both fit in.

00:34:13.860 --> 00:34:17.780
Okay. That's a really cool feature. I love it. That's that's, I think that's great. And it seems

00:34:17.780 --> 00:34:23.780
like it shows up really nicely in the UI. So let's talk about, you know, you mentioned Angular and whatnot,

00:34:23.780 --> 00:34:26.660
we've obviously been talking about Django, but let's dig into some of the tech.

00:34:26.660 --> 00:34:30.100
Want to tell us what's involved? What, how you built it?

00:34:30.100 --> 00:34:34.660
We've got Django on the back end. And then at the moment, we've got AngularJS on the front end

00:34:34.660 --> 00:34:41.140
and Bootstrap. A lot of these, as I say, it's, it's framework for people who come to Opal aren't

00:34:41.140 --> 00:34:44.980
necessarily going to have a background with Opal and the technologies are very much well,

00:34:44.980 --> 00:34:49.620
just stack overflow will answer my question. That's super easy for that. So yes, we've got

00:34:49.620 --> 00:34:56.980
AngularJS and then there's a bunch of magic that wires things together for you. So as I say, there's

00:34:56.980 --> 00:35:03.940
a schema that you can get out for particular for each of your models, which describes the model and

00:35:03.940 --> 00:35:07.460
AngularJS consumes that and it uses that when constructing forms.

00:35:07.460 --> 00:35:09.540
Does it talk back over Django rest framework?

00:35:09.540 --> 00:35:15.620
Yeah. And then Angular, because we have the concept of form templates and display templates,

00:35:15.620 --> 00:35:20.980
and they're all scaffolded out for you. We can make reasonable assumptions and Angular can,

00:35:20.980 --> 00:35:28.260
ideally, you don't even have to like touch Angular that much, but you can. So we use a model for the

00:35:28.260 --> 00:35:35.860
front end, which I haven't really used that much before. It's one that my colleague sort of did,

00:35:35.860 --> 00:35:41.940
which is actually what I want is I want all of a patient. So whereas in previous projects I've worked

00:35:41.940 --> 00:35:48.740
on, I'd be like, well, the patient, they want treatments, they want diagnoses, do separate

00:35:48.740 --> 00:35:54.980
API endpoints for that. When you go for a patient or an episode, it's like using a DRF. I think they

00:35:54.980 --> 00:36:00.420
like using a nested serializer. We don't use a nested serializer. So essentially, you get an episode,

00:36:00.900 --> 00:36:06.580
then it serializes everything under it. So when you're doing front end code, you know what is

00:36:06.580 --> 00:36:11.300
available without having to worry about, well, this loaded, this didn't load, which is really nice.

00:36:11.300 --> 00:36:12.100
It's a lovely fact.

00:36:12.100 --> 00:36:16.900
I see. So it like traverses the foreign key relationships and it creates a hierarchical

00:36:16.900 --> 00:36:18.180
JSON response type of thing.

00:36:18.180 --> 00:36:18.980
Exactly. Exactly.

00:36:18.980 --> 00:36:24.740
Okay. And so we serialize everything for that episode in one go because experience is showing

00:36:24.740 --> 00:36:29.460
that's what doctors want. And that makes it a lot easier in the front end to know that the model is

00:36:29.460 --> 00:36:30.340
going to be similar to the back end.

00:36:30.340 --> 00:36:34.660
It's worth just saying, you know what, we'll pay the extra price and we'll ship the episode

00:36:34.660 --> 00:36:39.620
along with the patient and it's going to be fine because you don't have two ways to do it.

00:36:39.620 --> 00:36:44.100
You can pre-fetch related all of the things and the number of database queries you're doing is

00:36:44.100 --> 00:36:45.140
pretty efficient.

00:36:45.140 --> 00:36:51.380
This portion of Talk Python To Me is brought to you by the University of San Francisco.

00:36:51.380 --> 00:36:57.140
Learn how to use Python to analyze the digital economy in the new master's in applied economics

00:36:57.140 --> 00:37:01.380
at the University of San Francisco. Located at the epicenter of digital disruption,

00:37:01.380 --> 00:37:05.460
USF is the ideal launching pad for the next phase of your career.

00:37:05.460 --> 00:37:10.740
Their new STEM designated economics program doesn't just provide technical training in high demand

00:37:10.740 --> 00:37:15.620
skills like machine learning, causal inference, experimental design, and econometrics.

00:37:15.620 --> 00:37:20.740
It takes the next step, teaching you how to apply these techniques to understand the economics of

00:37:20.740 --> 00:37:25.700
platforms, auctions, pricing, and competitive business strategy in the world of big data.

00:37:25.700 --> 00:37:31.300
The program is open to beginner and to advanced coders looking to apply their skills in a new area.

00:37:31.300 --> 00:37:35.300
Applications are now open for the fall 2020 classes.

00:37:35.300 --> 00:37:41.300
To learn more and get an application fee waiver, go to talkpython.fm/usf.

00:37:41.300 --> 00:37:44.020
That's talkpython.fm/usf.

00:37:44.020 --> 00:37:48.020
Speaking of databases, it sounds like you're using Postgres.

00:37:48.020 --> 00:37:49.620
Yeah, we use Postgres.

00:37:49.620 --> 00:37:55.300
When you do the sort of tutorial app, vanilla, it gives you FDLite because if you're a hack day,

00:37:55.300 --> 00:38:00.340
you don't necessarily want to teach people how to install Postgres onto their computer.

00:38:00.340 --> 00:38:05.140
Yeah, SQLite's beautiful like that, right? You can just say you have basically a full database.

00:38:05.140 --> 00:38:09.300
But you don't have to do anything. Can you make a file? All right, let's go with that. You know what I mean?

00:38:09.300 --> 00:38:09.940
I love it.

00:38:09.940 --> 00:38:11.140
Yeah, I do too.

00:38:11.140 --> 00:38:16.100
I think it should be used more. A lot of the times when people are exchanging like CSBs in like big

00:38:16.100 --> 00:38:21.860
app institutions, I'm kind of like, oh, why don't you just stick it in an FDLite database and ship an FDLite database?

00:38:21.860 --> 00:38:23.140
Yeah, it's super great.

00:38:23.140 --> 00:38:23.620
For sure.

00:38:24.260 --> 00:38:28.580
So it sounds like it's a pretty good project in terms of how it's all put together, some of the technologies.

00:38:28.580 --> 00:38:38.740
What's the deployment story look like? Is this, you got to make sure you set up Postgres, you set up Celery, you set up, I don't know, Microwiskey or G-Unicorn or whatever it is you're going to set up.

00:38:38.740 --> 00:38:45.140
And then is it a bunch of steps or is there some pre-canned way that people can run a magic script and have the infrastructure?

00:38:45.140 --> 00:38:50.660
So at the moment, we don't have that pre-canned script. I mean, we do for our own deployments in-house.

00:38:50.660 --> 00:38:51.060
Sure.

00:38:51.060 --> 00:39:01.860
Obviously all scripted up. But the reason why we haven't is because hospitals vary quite a lot in the sort of VPN technologies.

00:39:01.860 --> 00:39:10.900
So what we tend to do is have boxes on the hospital sites that are running the software that sort of gets us around any sort of security issues.

00:39:11.700 --> 00:39:23.460
And depending on the VPN, sometimes you can only log in on the VPN via a Windows machine doing this, the other, whereas others you can wire together with Ansible and do your deploy scripts with Ansible.

00:39:23.460 --> 00:39:31.220
So sometimes you've got the fabric scripts, sometimes Ansible scripts. So we don't have that vanilla out of the box deployment scripts, which would be quite nice.

00:39:31.220 --> 00:39:37.620
What I've been hearing a lot lately for setups like this is what we're going to do is use Docker.

00:39:38.100 --> 00:39:46.580
I mean, I'm a fan of Docker, but I feel like that adds another layer of like, okay, you did have to know Python web frameworks and you have to know Postgres.

00:39:46.580 --> 00:39:50.500
Well, now you kind of sort of have to know this, but you also have to know Docker.

00:39:50.500 --> 00:39:57.140
You know what I mean? It's like, on one hand, it gets simpler. On the other, it like expands out the things you have to maintain and manage.

00:39:57.140 --> 00:39:59.180
So I don't know. It's tricky.

00:39:59.340 --> 00:40:06.420
No, I think that's great. I think we have been looking at that. I think I looked at it a while back and maybe I'm wrong. I could be wrong with my memory.

00:40:06.420 --> 00:40:14.320
But I think that the version of Ubuntu that they were running it on was not going to casually allow us to run Docker on it.

00:40:14.320 --> 00:40:14.760
Right.

00:40:14.760 --> 00:40:16.580
But maybe, maybe that's exactly.

00:40:16.580 --> 00:40:21.720
Yeah. Speaking more broadly, I mean, because this is healthcare, it has special constraints on where it can live.

00:40:21.800 --> 00:40:32.340
Right. But if you were building this kind of thing for something that wasn't so regulated, it might be cool to build some sort of Kubernetes thing and you could just plug it into one of these managed Kubernetes clusters.

00:40:32.340 --> 00:40:33.980
Yeah, that would be cool.

00:40:33.980 --> 00:40:39.180
Right. Like that, that would be cool. That seems like a pretty easy way to say, look, you don't have to actually worry about running it.

00:40:39.180 --> 00:40:44.240
You just get this service and you just jam it in there and you can scale it with these knobs. You're good.

00:40:44.640 --> 00:40:51.180
Right. But when it's down to you running the clusters, we talk to clinicians a lot because we deal with a lot of sort of like new services.

00:40:51.180 --> 00:40:55.960
And as I say, we're not the greatest judges of when we don't have a clinician's experience.

00:40:55.960 --> 00:41:05.180
So we do a lot of like just roll up a hierarchy box with this branch, roll up a hierarchy as well through this branch, send them both over to the doctors and say, try these, play both of these.

00:41:05.180 --> 00:41:09.200
But we haven't, we haven't branched out to Kubernetes, which is what the cool kids are using.

00:41:09.420 --> 00:41:19.440
For now, anyway, you never know. You chose a JavaScript front end framework. And, you know, what is the lifetime half-life maybe of one of those things?

00:41:19.440 --> 00:41:26.080
I mean, Angular has been going for a while, but we had Angular 1 and Angular 2. I feel like those are almost different things with different programming languages.

00:41:26.080 --> 00:41:30.080
And that's a big decision, but you got to pick one, right? Like that's how it goes.

00:41:31.080 --> 00:41:40.000
Well, I mean, we are, we are, we're now rolling, we're, we're now working on Opal 1. So previously been on zero point star releases.

00:41:40.000 --> 00:41:46.040
And as such, we are aiming to move off the AngularJS because it's end of life.

00:41:47.040 --> 00:41:56.740
And we are currently doing, we're essentially practicing experimenting with Vue, React, just, you know, to, it's just progressively building off sort of,

00:41:56.740 --> 00:41:58.960
the Angular forms with some, with some extra sugar.

00:41:58.960 --> 00:41:59.460
That's cool.

00:41:59.460 --> 00:42:04.800
It's the whole experimenting with those. I've heard you like Vue. I'm a big fan of Vue.

00:42:04.800 --> 00:42:05.140
Yeah.

00:42:05.380 --> 00:42:13.880
So I have a version of Opal that just runs Vue, but it's making sure that what we've got is easy and simple for the developer.

00:42:13.880 --> 00:42:19.980
And, you know, I can't make it, I, just because I like Vue, do well, have I experimented enough with React? It's tricky.

00:42:19.980 --> 00:42:23.060
And I mean, I think more of the problem is shipping it.

00:42:23.060 --> 00:42:29.100
So, you know, now what we've got at the moment and what's quite nice is static assets.

00:42:29.100 --> 00:42:39.420
You declare your static assets, the file names into, into either plugins or into an application and Django compressor just does it all for you.

00:42:39.420 --> 00:42:50.100
Whereas now, if you're looking at something like Vue or React commonly, you need to, you don't need to, but Webpack is kind of the assumed approach.

00:42:50.440 --> 00:43:03.820
And then you've got the Django webpack loader, but the Django webpack loader, based on what I've currently seen, I don't tend to be an expert at this, is doesn't necessarily load from packages.

00:43:03.820 --> 00:43:14.840
So, for example, you pit installed Opal, or you don't, if you want the static files, which are coming through with that, the Django webpack loader won't actually pick those up.

00:43:15.320 --> 00:43:20.500
So then you have to say, well, so do we then store the static files on NPM?

00:43:20.500 --> 00:43:32.820
And so we then put, you pip install Opal and through some magic, we'll bring in the static files from npm.

00:43:32.820 --> 00:43:36.900
But then obviously then you're supporting two different packages and you need to concentrate that.

00:43:36.900 --> 00:43:38.700
It's a super interesting problem.

00:43:39.340 --> 00:43:41.220
And I'm quite enjoying playing with it.

00:43:41.220 --> 00:43:42.180
It sounds challenging.

00:43:42.180 --> 00:43:45.900
It sounds a little bit, I don't know, in the UK, if you know the game Whack-A-Mole.

00:43:45.900 --> 00:43:49.980
It's like this arcade game where you be, you know, it reminds me of that, right?

00:43:49.980 --> 00:43:52.020
Like, I'm going to, bam, I solved this problem.

00:43:52.020 --> 00:43:53.440
Oh, it pops up over there.

00:43:53.440 --> 00:43:54.860
Whack, I solved that problem.

00:43:54.860 --> 00:43:55.600
Now it's back here.

00:43:55.600 --> 00:43:58.380
Like, you know, you squeeze on one side and it pops out the other.

00:43:58.380 --> 00:44:00.320
And, you know, it's challenging, right?

00:44:00.320 --> 00:44:01.320
It seems challenging.

00:44:01.320 --> 00:44:04.440
But yeah, to be honest, I don't know.

00:44:04.440 --> 00:44:07.540
Different programmers find different problems interesting.

00:44:07.540 --> 00:44:08.840
I do find this interesting.

00:44:08.840 --> 00:44:11.520
I do sometimes think it could all be simpler.

00:44:11.520 --> 00:44:14.920
But that is probably my own ignorance.

00:44:14.920 --> 00:44:23.640
Yeah, I feel like JavaScript went from being like, oh, it's the most easy, simple little thing to, oh, this is, there's a lot of stuff going on here.

00:44:23.640 --> 00:44:26.060
I'm not really sure why, how this is happening here.

00:44:26.060 --> 00:44:29.520
Yeah, well, it's like, oh, I'll just run npm install.

00:44:29.520 --> 00:44:31.400
Suddenly my computer gets hot.

00:44:31.400 --> 00:44:31.800
Yeah.

00:44:31.800 --> 00:44:32.180
Exactly.

00:44:32.180 --> 00:44:33.500
Yeah, interesting.

00:44:33.500 --> 00:44:35.400
Okay, well, I'm a big fan of you.

00:44:35.400 --> 00:44:37.640
I definitely think it's special.

00:44:37.640 --> 00:44:39.120
I like that as well.

00:44:39.120 --> 00:44:40.540
Now, let's see.

00:44:40.540 --> 00:44:42.200
Let me ask you a couple other questions.

00:44:42.200 --> 00:44:45.080
We're getting a little towards the end of the show here.

00:44:45.080 --> 00:44:52.260
One thing I guess it's interesting to talk about, just real briefly, is Opal is open source.

00:44:52.260 --> 00:44:53.780
Go to GitHub.

00:44:53.780 --> 00:44:55.440
I can get it, do whatever I want, right?

00:44:55.440 --> 00:44:56.200
I can pip install it.

00:44:56.380 --> 00:44:56.600
Yeah.

00:44:56.600 --> 00:45:04.860
But you work at Open Healthcare UK, which is that like a boutique app shop for the healthcare industry?

00:45:04.860 --> 00:45:05.960
Or how would you describe it?

00:45:06.100 --> 00:45:15.260
The way the healthcare in hospitals commonly works is that what you have is the productization,

00:45:15.260 --> 00:45:22.480
if that's a word, is massive, large-scale EPI are pumped in and it aims to be a data repository

00:45:22.480 --> 00:45:26.460
for all teams in the hospital doing all things.

00:45:26.460 --> 00:45:28.860
It's like the SAP of hospitals.

00:45:28.860 --> 00:45:30.280
It's going to do everything.

00:45:30.280 --> 00:45:32.240
Just install this and it'll be fine, right?

00:45:32.400 --> 00:45:32.840
Exactly.

00:45:32.840 --> 00:45:33.380
Okay.

00:45:33.380 --> 00:45:42.980
And what you find is that it does a pretty good job, but for, it does 80%, but for the

00:45:42.980 --> 00:45:49.860
extra 20%, what you've got is Word docs flying around, Excel spreadsheet, the occasional access

00:45:49.860 --> 00:45:52.300
database, or good old-fashioned pen and paper.

00:45:52.300 --> 00:45:52.660
Yeah.

00:45:52.660 --> 00:45:55.580
And sometimes this 20% is pretty darn useful.

00:45:55.580 --> 00:46:00.580
So we have, what we do is we fix up that 20%.

00:46:00.580 --> 00:46:06.960
So you're a, we do microbiology, for example, we do some of that sort of stuff, which is

00:46:06.960 --> 00:46:10.160
sort of teams which specialize in blood cultures.

00:46:10.160 --> 00:46:17.180
We go in there and we're like, and we talk to the doctors and we get their requirements and

00:46:17.180 --> 00:46:21.200
we tailor stuff as sort of kind of specific to them.

00:46:21.200 --> 00:46:23.540
And yeah, we cover that 20%.

00:46:23.540 --> 00:46:23.880
That's cool.

00:46:23.880 --> 00:46:29.880
So basically the role of Opal is this thing that you guys have built, it'll let you quickly,

00:46:29.880 --> 00:46:35.360
it'll, you know, supercharge your creation of these apps to cover that 20% that you talk

00:46:35.360 --> 00:46:39.180
about, but it's also awesome that it's open source and other people can take it and run

00:46:39.180 --> 00:46:39.440
with it.

00:46:39.440 --> 00:46:39.780
Is that right?

00:46:39.780 --> 00:46:40.260
That's right.

00:46:40.260 --> 00:46:41.260
That's exactly right.

00:46:41.260 --> 00:46:44.340
This is not that much of a specific problem.

00:46:44.340 --> 00:46:45.240
This is a general problem.

00:46:45.240 --> 00:46:49.720
I think worldwide, I don't think, I don't think in the States they've kind of got a magical

00:46:49.720 --> 00:46:51.520
EPR that fixes all problems either, right?

00:46:51.600 --> 00:46:53.040
No, no, no, no, of course not.

00:46:53.040 --> 00:46:53.340
Yeah.

00:46:53.340 --> 00:46:53.680
Cool.

00:46:53.680 --> 00:46:59.420
So it seems like a solid blend of here's this open source thing that people can work on and

00:46:59.420 --> 00:47:02.680
they can use, but is also there to support your business.

00:47:02.680 --> 00:47:08.800
And, you know, one of the things I feel like just doesn't seem to work really well is the

00:47:08.800 --> 00:47:12.220
PayPal donate button on open source projects, right?

00:47:12.220 --> 00:47:16.580
It's just my experience of hearing folks who seem like they have pretty popular projects

00:47:16.580 --> 00:47:20.740
is like, you know, it's definitely not a career at that point.

00:47:20.780 --> 00:47:21.600
There's got to be something else.

00:47:21.600 --> 00:47:24.200
And this seems like a really nice synergy around that.

00:47:24.200 --> 00:47:24.720
So that's cool.

00:47:24.720 --> 00:47:27.020
Our motivation for open source isn't.

00:47:27.020 --> 00:47:35.440
It's open source because healthcare applications deserve the rigor that being open source allows

00:47:35.440 --> 00:47:37.700
you to have and the inspection.

00:47:37.700 --> 00:47:44.900
Open source is kind of like a function for you should buy our software because it's open source

00:47:44.900 --> 00:47:47.140
and therefore hopefully you can trust it more.

00:47:47.140 --> 00:47:50.500
And yeah, that's the sales feel, I guess.

00:47:50.500 --> 00:47:54.840
It's the antidote to that 10 million quid problem.

00:47:54.840 --> 00:47:58.480
10 million to convert and 10 million to delete.

00:47:58.480 --> 00:47:59.760
Which one do you prefer?

00:47:59.760 --> 00:48:01.280
Exactly.

00:48:01.380 --> 00:48:05.040
Well, I guess on that, are you looking for contributors to this project?

00:48:05.040 --> 00:48:08.960
You know, are there restrictions that people want to take it and run with it and do something else?

00:48:08.960 --> 00:48:14.620
I'll sort of, what we would like is, as I say, we're moving front-end framework.

00:48:14.960 --> 00:48:19.320
I don't think, I think everyone has, I think every developer right now probably has experience

00:48:19.320 --> 00:48:21.580
between moving between different jobs for front-end framework.

00:48:21.580 --> 00:48:23.620
We'd love some opinions on that.

00:48:23.620 --> 00:48:26.140
We'd love anyone to come and have a look.

00:48:26.140 --> 00:48:31.520
Come and have a look at the GitHub repo, offer suggestions, any breaks in docs, any breaks in

00:48:31.520 --> 00:48:32.400
anything really.

00:48:32.400 --> 00:48:33.980
That would be super interesting.

00:48:33.980 --> 00:48:38.880
Also, you know, we've come at this from having years of experience with building healthcare

00:48:38.880 --> 00:48:40.520
applications in the UK.

00:48:40.520 --> 00:48:45.980
Well, does that necessarily create an international, something that's internationally applicable?

00:48:45.980 --> 00:48:46.520
Sure.

00:48:46.520 --> 00:48:50.840
At the moment, we have NHS number as a field on a model.

00:48:50.840 --> 00:48:52.760
That will not be happening soon.

00:48:52.760 --> 00:48:54.440
We are going to move off that.

00:48:54.440 --> 00:49:01.220
But that kind of thing, you know, this should be a global solution to a global problem, not

00:49:01.220 --> 00:49:02.980
a UK solution.

00:49:02.980 --> 00:49:04.680
Congratulations on this project, Fred.

00:49:04.680 --> 00:49:07.420
It looks really useful for folks out there.

00:49:07.420 --> 00:49:08.340
Thank you very much.

00:49:08.520 --> 00:49:09.600
It's been quite short to you.

00:49:09.600 --> 00:49:10.480
It's quite a little grand.

00:49:10.480 --> 00:49:10.820
Yeah.

00:49:10.820 --> 00:49:15.280
Now, before you get out of here, though, I've got the two final questions I've got to ask

00:49:15.280 --> 00:49:15.460
you.

00:49:15.460 --> 00:49:20.120
So if you're going to work on Opal and write some code over there, what editor do you use?

00:49:20.120 --> 00:49:26.160
I use the Vim plugin on VS Code, which is interesting.

00:49:26.160 --> 00:49:29.360
I occasionally go back into pure Vim.

00:49:29.360 --> 00:49:33.100
Before VS Code, I used Sublime.

00:49:33.100 --> 00:49:38.160
I used IntelliJ when I was a Java programmer or using the Vim plugin.

00:49:38.160 --> 00:49:38.600
Vim plugin.

00:49:38.600 --> 00:49:45.040
And so I think I feel like I've spent my life doing this sort of weird hybrid of helpful

00:49:45.040 --> 00:49:48.920
Vim versus a more integrated environment.

00:49:48.920 --> 00:49:49.740
A constant pool.

00:49:49.740 --> 00:49:50.020
Yeah.

00:49:50.020 --> 00:49:52.260
But VS Code sounds like a good one these days.

00:49:52.260 --> 00:49:53.800
It's got a lot of momentum for sure.

00:49:54.320 --> 00:49:56.000
And then notable PyPI baggage?

00:49:56.000 --> 00:50:01.960
I really like cache properties in Django, which are, if you've never used them, essentially

00:50:01.960 --> 00:50:05.140
it's an annotation that says, here's a method.

00:50:05.140 --> 00:50:08.780
Store the results of this method on the object.

00:50:09.460 --> 00:50:15.120
And then whenever I call this method, first time I call it, calculate it and return the

00:50:15.120 --> 00:50:15.380
answer.

00:50:15.380 --> 00:50:17.660
Subsequently, store the results of the method.

00:50:17.660 --> 00:50:20.260
I just think it's a beautiful pattern.

00:50:20.260 --> 00:50:25.680
It's been something that's been discussed as part of core Python for some time.

00:50:26.480 --> 00:50:28.160
Danny Greenfield, I think.

00:50:28.160 --> 00:50:29.000
Hi, Danny.

00:50:29.000 --> 00:50:34.100
He has a package on PyPy that does this because it's such a common function.

00:50:34.100 --> 00:50:41.600
And then in Python 3.8, just a few weeks ago, we now have functools cache property.

00:50:42.280 --> 00:50:44.020
So it's been moved into core.

00:50:44.020 --> 00:50:49.660
So I was hoping to have functools.cache property as my notable package, which is potentially

00:50:49.660 --> 00:50:51.240
cheating because part of the core library.

00:50:51.240 --> 00:50:52.380
But it's super useful.

00:50:52.380 --> 00:50:53.580
It's new enough, right?

00:50:53.580 --> 00:50:54.320
It just got shipped.

00:50:54.320 --> 00:50:55.060
I think that's cool.

00:50:55.060 --> 00:50:58.480
I think that's one of the really easy ways to speed up things.

00:50:58.480 --> 00:51:03.580
The only challenge with that is you have to be careful on what cache invalidation means,

00:51:03.580 --> 00:51:04.100
right?

00:51:04.100 --> 00:51:06.260
That can be challenging to deal whenever you're doing caching.

00:51:06.260 --> 00:51:09.440
And if you look at the pet, there's a long discussion about it.

00:51:09.440 --> 00:51:10.180
I can imagine.

00:51:10.820 --> 00:51:15.140
But, you know, it can just dramatically, it can just completely change the way the performance

00:51:15.140 --> 00:51:15.680
looks, right?

00:51:15.680 --> 00:51:18.960
So it's so easy to do those types of things.

00:51:18.960 --> 00:51:19.560
Pretty cool.

00:51:19.560 --> 00:51:19.960
Good one.

00:51:19.960 --> 00:51:20.760
All right.

00:51:20.760 --> 00:51:21.480
Final call to action.

00:51:21.480 --> 00:51:22.640
People want to get started with Opal.

00:51:22.640 --> 00:51:23.260
What do they do?

00:51:23.260 --> 00:51:24.180
Pick and install it.

00:51:24.180 --> 00:51:25.260
Take a look at the docs.

00:51:25.260 --> 00:51:27.200
We've kind of covered them a little bit today.

00:51:27.200 --> 00:51:29.020
I think they're pretty good.

00:51:29.020 --> 00:51:30.140
So pick and install it.

00:51:30.140 --> 00:51:33.440
Go through the tutorial and let us know what you think.

00:51:33.440 --> 00:51:37.740
The code is all at openhealthcare.com on GitHub.

00:51:37.740 --> 00:51:38.940
GitHub.com.

00:51:40.300 --> 00:51:43.180
So, yeah, you can go and just browse the code as well.

00:51:43.180 --> 00:51:43.740
Sounds good.

00:51:43.740 --> 00:51:44.700
Thanks for being on the show.

00:51:44.700 --> 00:51:45.440
It was great to talk with you.

00:51:45.440 --> 00:51:45.960
Great, Michael.

00:51:45.960 --> 00:51:46.620
Thanks very much.

00:51:46.620 --> 00:51:47.120
Yeah, bye.

00:51:47.900 --> 00:51:50.560
This has been another episode of Talk Python To Me.

00:51:50.560 --> 00:51:54.980
Our guest on this episode was Fred Kingham, and it's been brought to you by Linode and the

00:51:54.980 --> 00:51:56.300
University of San Francisco.

00:51:56.300 --> 00:52:00.720
Linode is your go-to hosting for whatever you're building with Python.

00:52:00.720 --> 00:52:04.260
Get four months free at talkpython.fm/linode.

00:52:04.260 --> 00:52:06.160
That's L-I-N-O-D-E.

00:52:06.840 --> 00:52:12.140
Learn how to use Python to analyze the digital economy in the Masters of Applied Economics at

00:52:12.140 --> 00:52:13.440
the University of San Francisco.

00:52:13.440 --> 00:52:18.280
Just go to talkpython.fm/USF to find out more.

00:52:18.280 --> 00:52:20.540
Want to level up your Python?

00:52:20.540 --> 00:52:25.340
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.

00:52:25.340 --> 00:52:30.440
Or if you're looking for something more advanced, check out our new async course that digs into

00:52:30.440 --> 00:52:33.500
all the different types of async programming you can do in Python.

00:52:33.500 --> 00:52:37.460
And of course, if you're interested in more than one of these, be sure to check out our

00:52:37.460 --> 00:52:38.160
Everything Bundle.

00:52:38.160 --> 00:52:40.060
It's like a subscription that never expires.

00:52:40.060 --> 00:52:42.200
Be sure to subscribe to the show.

00:52:42.200 --> 00:52:44.600
Open your favorite podcatcher and search for Python.

00:52:44.600 --> 00:52:45.840
We should be right at the top.

00:52:45.840 --> 00:52:51.380
You can also find the iTunes feed at /itunes, the Google Play feed at /play, and the

00:52:51.380 --> 00:52:54.820
direct RSS feed at /rss on talkpython.fm.

00:52:54.820 --> 00:52:56.900
This is your host, Michael Kennedy.

00:52:56.900 --> 00:52:58.400
Thanks so much for listening.

00:52:58.400 --> 00:52:59.440
I really appreciate it.

00:52:59.440 --> 00:53:01.220
Now get out there and write some Python code.

00:53:01.220 --> 00:53:02.220
Bye.

00:53:02.220 --> 00:53:03.220
Bye.

00:53:03.220 --> 00:53:03.220
Bye.

00:53:03.220 --> 00:53:03.220
Bye.

00:53:03.220 --> 00:53:04.220
Bye.

00:53:04.220 --> 00:53:34.200
Thank you.