Watch me Query Blockchain Data (on-chain) using Python + The Graph in Real Time!

Learn to query blockchain data using The Graph and Python. The presenter builds a Streamlit app that fetches recent ENS domain registrations in real time, using the Subgrounds library to write GraphQL queries and convert Unix timestamps into readable dates.
Chapters
All right, so welcome everyone.
I'm just going over some few things here today, um, something different from what I usually do here. I'm just sharing what I— I'm just sharing my work process, basically, what I'm trying to—
what I'm working on, a bunch of projects.
So if you want to stick around and want to learn a few things about the blockchain and how to get data from the blockchain, this is the place to be.
So I'll start by going to the website first of where I want to get the data from.
So, um, The Graph is basically, if you can think of it as they were—
people call it like the Google of blockchain.
So kind of like what Google does for, for the, for the Web2 side of things. And Web2, I mean, um, the current system that we use currently, uh, things like Google, right? So The Graph is like Google for Web2.
That's basically what it is.
So with that said, what I'll do next, I'll just go— I think I figured out what I want to do, so I'll go and explore, uh, I'll go here to hosted service. So it's like, and as you can see here, what they're talking about is the APIs for vibrant decentralized future. So it's basically, um, an API for the decentralized, um, Blockchain.
So what are, I guess, what are APIs to start off with, right?
So APIs are, think of it as, you know, and I think I've used this example before, you go to a restaurant and what happens? You usually sit down, you get a chair, they sit you down, then you give them your order. You tell them, hey, I want to, you know, I want whatever, but whatever you want to get from the restaurant, right? Maybe you want to get, um, Whatever food, let's say you're gonna get some rice and beans, for example, right? Maybe you're on a budget and you want to get some rice and beans. So what you do, you tell them, you tell the waiter, they go back there to the, the kitchen, they give it to them, to the cooks, the cooks make the food, or if it's ready, they already kind of like know, you know, here's rice, here's some beans, they serve it up and they bring it to you with the portions that you asked for, right? And you personally, you're sitting with a chair, probably on your phone doing whatever you need to do. You don't care about what's going on in the background. So they're cooking that food and they're bringing it to you. All you care for is whatever you ordered, you're getting it, right? So with that said, this means that as an API, in the technical— technological sense of it, the API does exactly the same thing. So the API You give it a query, tell it, hey, I want some this and this from the database. It goes back there, it does what it needs to do, sifts the data. Maybe you tell it, I want the data from this date to this date. It goes there, grabs that data and brings it over to you. So that's typically what it does. So with the Web3 side of things, there are things called subgraphs built by The Graph protocol. So what they do here is you can build, you can personally go build a subgraph for anything. So there's smart contracts that are built. And if you build a smart contract, you build a subgraph, which is an API that tracks what happens on that contract. Take for example, you create an NFT, right? An NFT collection and you sell it, you put it on exchange like a marketplace like OpenSea, right? And so you were able to, if you want to create like a subgraph, you can create a subgraph that kind of tracks what happens with that with your NFTs. So from that, you can get information like, you know, who bought what at what time and sold it to who, transferred to who for how much and things like that. So subgraphs help you maintain that. So a better example and a subgraph that I'll use today is called the ENS domains. It's Ethereum Name Service. I'm sure you've seen a lot of people on the webs Having especially on what's it called? Especially on especially on Twitter that are using they're using the names like .eth .eth behind their behind their name. That's because they're using they're getting the names from from the Ethereum name service. So .eth is basically like a .com but for the blockchain. So this is a subgraph that tracks what happens with this Ethereum Name Service names. So if you go and mint one or create a name, and I can show you an example of how you can do this.
Let me just share my screen again. I need to fix this entire screen window. It's going to the first one.
All right.
So we can go to one here.
Um, so let's go to ENS. We come to ENS here, Ethereum Name Service. Um, we can come to the app itself, go to app, and then from here you literally— you can—
well, let me trade up my MetaMask.
That's not what I want to do. So from here what you can do is You can search any name that you want to register to become your name. So for example, let's just search, I don't know, worldnews.eth.
Let's see if that's available.
So you can come here, register that name. Of course, it's owned by somebody. Somebody already registered that name a long time ago in 2017. That was quite a long time ago, but not a long time ago, but it also expires in this year, June 18th. So this is basically if it wasn't registered. So it says name registered already. So if it wasn't registered, you would be able to register that name. Let's just find something weird that maybe somebody has not registered. For example, that.
I don't think— I'd be surprised if somebody already registered that.
Okay, and Monks in Nairobi.
Okay, yeah, so it's available.
It's saying it's available.
So you can see it says it's available, and I'm not sure if it's pretty clear on my screen, but, um, hopefully it is.
You can let me know in the chat if it's not. Um, but from here you can register it. You click on that.
It will tell you, it will give you the price and everything that you need to pay to register it, like how you would register a .com.
Maybe this was like kenyanmonksinarabi.com, for example. You would have to pay a certain amount of money to register it. In this case, for if you want to register this name, for example, for 1 year it's worth—
well, for 2 years—
for 1 year it's worth 0.003 ETH. So that's just the price of buying the name itself. For one year, you could also, but you also need to pay fees, which is it's called gas. It's basically how much you're paying for. They used to call them miners, people that create make sure like include your transaction in the blockchain so that it registered and it's valid.
You have to pay them a fee, which is zero point zero eight, which is higher than the name registration actually.
And that's very obvious and common in the Ethereum space. So total comes up to 0.011 ETH that you have to pay them. So that's about $17.84 to register that name for 1 year only. I think there's a max of years you can register, maybe not, because I can keep going. Yeah, the more you keep going, the more, you know, like $97 for registered for 17 years. So you own it in your wallet is $97. So pretty interesting, but the gist of it really. So what I want to do— that's not what I wanted to do today. What I want to do is focus this on the data aspect of things. I'm going to focus on how we can get data and play with the data from this subgraph and create visualization and build an app, um, on using Streamlit.
So in this example right here, um, I really hope my screen is pretty clear. Let's see. So cool. So on this website, if you come to the Graph website, you can see that you're able to—
let me zoom that in a little bit. So there's a playground. If you come to the subgraph that you want, for example, this ENS, right? You come to this ENS subgraph. You're able to see some data here. So you can query data. There's an example query here. So that means— and this is in GraphQL. GraphQL is basically a language that communicates with— that you— GraphQL is like an API in a sense, but it's better than API because— that's my opinion anyway— because you're able to tell it exactly what you want in the data, and it will give you exactly that and nothing more. Nothing less. So compared to API, API, you're given an endpoint. So they can give you an endpoint for maybe just domains, an endpoint for transfers, an endpoint for block numbers and transaction IDs, for example, right? And that's the data you get from those. So that means you would have to call different, several endpoints to get the data, and you don't really have control over what data you get from those endpoints because it's already curated for you. You're just calling it and getting the data you want. But with GraphQL, you're able to structure it in a way that you get exactly the data that you need, which in this case is here. For example, I want domains, I want the first 5 domains.
This is just what this example query is saying.
I want the first 5 domains. I want from those first 5 domains, I want the ID, I want the name, I want the label name, I want the label hash, I want the transfer. I want the transfer entity as well, and I want the ID and domain and all this stuff. So let's run this and see the example of what it gives us. So you can see that it gives us some data, and this is null, most of it is null. And this is like the first names that were minted on the blockchain for ENS back in the day. It's just saying the first 5. We can do more here to refine it a little more. What I like about using this, so here's an example. So you can use this, you can edit this and write however you want. We can take out this label hash, for example, keep the label name, maybe just take out this transfer section of things because we don't need much of that.
And then just let's have the ID and the name, for example, or just the name, the first 5 names.
Example, let's just run that and you'll see that gives you the first 5 names that were created or minted on this platform. So what you want to do or what you can play around with this GraphQL query here as well, you can edit it. It says first 5, right? And some of them is null because it was the first one. So we can the first 5 and we can do by order by, so we can order by We can do orderBy, but we don't, we don't have anything really to orderBy because we— I mean, we could orderBy name, but that's kind of like not what we want to do at the same time because I don't think we would get anything important. But we can do orderBy order direction, and I want to do descending order. So that means I want the, the recent 5, right?
Um, and that's not working. Let's just do this, stick this out.
And it's—
oh, that's a lot.
Yeah, so order direction, we'll do descending.
Let's try different ones, right, and see what it gives us. So it only allows us to do first, first 5.
And also let me just do, um, descending, because I think that would make it much easier. But what I like using is— and see this one, this is hard to— it's not really hard, but it's like a little more complicated, just kind of like typing the manual queries here, right? So what I like to do, I usually come to this side here, um, where you have the Explorer, where you can just use it instead of just kind of going and doing all that extra stuff on the other side. So, so, um, the Explorer helps you because you get to pick exactly what you want. And nothing more. So I'd come here to domains, right? I'll pick the first 5 like it's already picked there. And the next thing that I would like to do as well from there, I want to order by— maybe let's order by created date, right? Because that's an important thing. I order by the created date and then order direction. And as I pick this stuff here, you can see like it's populating it on, uh, on our query here. And so I want to pick, let's take out the ID. I don't want the label name. I just want the name. Let's see if it's going to let me do that. I don't want that. I don't want that. I want the name and maybe I want the owner as well, who owns it. And that would be the owner ID that I want. And that's like, it was going to give us the hexadecimal address of the person that owns that name in this case. And I want the order to be descending so that way I can get the latest that got—
that's been registered here.
So let's run that and see what it gives us. And bam, you can see it gives us some interesting work, right? So here it's ordered by— so this person basically just registered this name like not so long ago, probably a few seconds ago, I would guess. Um, so beautymix.eth. And with the app that I'm going to create at the end of this session, hopefully, although I'm aiming to create this— I'm trying to create a Streamlit app which is built purely on Python. Everything's going to be done in Python and not so many lines of code. My goal is to create an app where it refreshes and every 30 seconds it gives us a new name that's being registered or the recent name that just got registered on the ENS domains. And that's really important. And I can do that by calling this subgraph and refreshing, calling it every 30 seconds to see what data is coming off of it. So with that idea in mind, let's just jump straight into the coding aspect of things. And please feel free to chat on the chat as well. Let me know what you're thinking as well, or if you want me to clarify some things. So with that said, I will fire up my IDE here, which is— I use VS Code for those who are familiar with.
VS Code, Visual Studio Code. So let me just share my screen. Let me share, share window. Which one? This one I want to share. All right, cool.
So I'll use VS Code to do my coding here. And if you don't have VS Code, or if you, if you're wondering what it is, you can just look up VS Code and you should be able to find some information on it online. And you can use it. It's really, it's real nice for coding. So from here, I'll open a new folder and I'll—
my desktop.
Let me just create something.
No, let me just create a folder here, a random folder. Um, ens_test. So yeah, let's call it ens_test.
And from here, what it would do We'll just go ahead and set up the environment.
It's a blank slate, so we'll start with first creating a, let's say, app, my app.py file. Oh, that's in caps. I don't want that.
I need to rename.
I'll name it app.py. All right, yeah, my app.py here.
And the next thing I want to do is start thinking about the query I want to get from the subgraph that, that I was working with, right? So what I'd like to do is go ahead and share that subgraph screen that I wanted to, to get the data from as well.
And let's do this. All right, cool.
So from here, I want to generate a script that it's of the data that we— that I want to gather from, from this subgraph itself. So the best thing to do is I want to get the registration dates, which is the important thing because If our app is going to be showing the most recent registrations every 30 seconds, we have to get it from registration. So who's registering a name right now and it's posting it every 30 seconds, it's posting like a list of names that I just got registered. So what I want to do, I want to go come here to the side and come to registration events.
That's where—
or registration, not registration events, registrations. And from registrations, And we'll do like a dry run here to see what, what it gives us, right? Um, so we'll go with, um, the first 20 probably, or the first 10.
Um, let's do the first 20, why not? Or the first 10 for, for test.
Then I want to order by—
in this case, um, I want to order by created Created date, or yeah, registration date. That means the time it got registered.
And the direction, I want it to be descending.
So from the soonest one to the— or the earliest one to—
and then from there, I also want some data from it. I want the domain name, of course. So I want the name. I want the label name as— I don't know if I want the label name.
Yeah, sure, let's take the label name.
The label name, label name is just going to be like this name, just the name without the dot, without the, without the .eth. So just the first name in the beginning. I also want to get the owner ID, so their address.
I want to get the address.
I also want to see how much they spent on this name registering the name, so cost. And I also want the expiry date for, for that, uh, for the name itself because it has expiry dates when, you know, when do they renew it. So let's run that and see what it's going to give us. So it's giving us some data. Cool. So it's giving us the name.
So this is the person that just got registered not so long ago. The first name is jabries.eth, Jabries.
And then the, the name of the person, uh, the address of the person that registered it, the costs. And this is in, um, Ether. So 1 Ether is, I think, is 8 to the power of 16.
I might be wrong. 10 to the power of 16.
I might be wrong, but we'll do the conversions when time comes. We'll just convert that to ETH. So Ether is basically the lowest denomination or the lowest, um, the smallest unit of Ethereum. If you think of 1 ETH, what is that like? The smallest, 0.01 ETH, that's like an Ether, like the smallest.
That's the name of it.
That's like how Bitcoin are called Satoshi.
Satoshi is like Satoshi.
Satoshi is like the Smallest unit of of an entire Bitcoin, for example. Then we have the expiry date. This one also is in Unix time time format. We need to convert this to like human readable time, and we'll also have to write a function to do that. So now that I have like the function that I want to convert, just copy that. Not the function, but more of like the I have the the query that I know I'm gonna, I'm gonna use to pull the data. Then I'll go ahead and let me share my coding screen.
Let's get started.
So from this screen right here, um, I'll just create another temporary file, um, or let me call it query.
And this is just—
this will just be random because it will just hold the data here for us.
Let me not call it JSON. Let me call it maybe MD or something. Yeah, so that way it's not throwing errors.
Yeah, so this is basically a rough draft of how it's going to look like.
And let me just skip the line. And let's just this be ENS query so we can appease the error errors that are showing up on our screen. But all right, cool. So from here we have a query that we We could definitely potentially use and get some data, right? So the next thing we want to do is just get started, download some of the— or import some of the stuff, some of the dependencies we'll need. But first, you know, we need to set up an interpreter because there's none here. So what I usually do is you create a virtual environment. In a virtual environment, if you're not familiar with virtual environments, they basically— so when you download Maybe you pip install whatever package, whatever module, right, that you want to use in your application. For the most part, those pip installs, they usually go to your main or your master on your system.
So they're just everywhere.
They're definitely global.
So if you build any other application, the versions could clash because maybe there's an app you built wants to use the, I guess, the pandas version, whatever. But then, and then I'm just picking an example, pandas module, right? Because it's very popular in people that are doing data, data analysis, data engineers, data scientists. So if you have different versions, it could crash your other app that doesn't use that version of that code, of that module. So the simple solution is to create virtual environments. So basically, it's basically like you're creating a box within a big box. And within that box, you're just using specific version. Maybe you have the same module in all the little boxes within the big box, but within each box you have different version of each of whatever it's in each box. So that hopefully that kind of helps you think of the reason of why you need a virtual environment. And in Python, to create that, you just need to do python-module, which M sensor module.
So why you tell Python, hey Python, use this module called venv, which is in short virtual environment, to create a virtual environment. And after the venv virtual environment, I just can name it anything. In this case, I want to name it maybe, uh, let's name it venv, why not. So Python, use module venv virtual environment to create a virtual environment called venv. And then you hit enter. It's gonna take a few minutes, a few seconds. It's pretty quick. What it's gonna do is create another file here, uh, um, a folder within your, within your work environment or directory, and it's gonna include, uh, basically that box. That's basically the box that I just created. And within this box right here, you need to activate it first before you start using that box. There's an activate script here. To do that, you need To just do one time, I want you to do venv. You need to just access the virtual environment and then go to scripts. There's scripts right here, and then you do activate, and you do a activate, then quit, and we are done. We are active. So to know that it's active, you can see up in front of your directory here, this line, you can see the venv, it's like in green. That shows you that, and it's in brackets, and the name of your virtual environment is within the brackets. That shows you that, you know, in this case, as I was referring to it, box is created, your box is ready to go. So now if you do any installs, if you do any install of any packages, it will go straight into this box. It won't pollute and contaminate your entire system's, um, packages. So let's go ahead and import the module we'll need in this, uh, for this to build this app, right?
The first one I need is Subgrounds.
Subgrounds is more of a package that wraps around this query itself and gives us the data without us doing it the manual way. Let's start with Subgrounds. The first thing we'll do is we need to do a piece of input.
Import Subgrounds.
As programs, and you can see it's already giving us errors because it's we don't have it already. And to fix that, you just come here, pip install programs. It's gonna start loading. And caveat to that as well: if you're running anything less than Python. 3.10, so 3.10. If you're running anything less than that or before that, it's not going to load Subgrounds because Subgrounds is built to only use Python 3.10 at this time unless something changes. But it's just Python 3.10, just so you're aware. And we will need Subgrounds, and on top of that, we also need other versions. Subgrounds within it. So import subgrounds. So grab import from here. We'll just do from because we're trying to grab something from this. So we'll make this synthetic field. And what synthetic field does, just to explain, synthetic field, what it does is basically you see those times that I was talking about, you know, a query here, we'll get the expiry date, the dates are going to be mixed. So we can use the synthetic fields to It's basically like a placeholder where we have a function and we put that function to do what we need it to do. And then that's like some type version of it. And then it's going to spew the data into a DataFrame in a way that we need it. So that's why we need that.
And let's go to the next one would be struct format.
So let's just clear here. Here our screen and we'll do pip install Streamlit. It's going to load Streamlit. And Streamlit here, what it does is it's a software, it's an open source tool that you can use to build data applications with just Python. You don't need to use any other programming language.
You don't need to know how to code front end.
You don't need to know React and any of that stuff. If you know Python, you can just build an app for free and get hosted for free with Struts. It allows you to build a web app that's very functional and you can share with other people to use. So I'll show you how that works and then we'll be able to deploy that app afterwards. That's an app that actually people can use and that's the important thing here.
So after we get that, the next thing—
oh, we need to import Streamlit up here. So, but we don't need like exactly Streamlit, we just need, um, a Streamlit item. Import Streamlit as st. I'm just gonna call it st. And as st, that if you're not familiar, st, or as you can name it as whatever. But in this case, it's gonna— a good naming convention going on here. And the next thing we want to do is datetime. We need datetime because we'll need to convert those, um, those Unix times into human-readable time. So import from datetime, import datetime as datetime. Let's save that. So, and we will also need pandas, right? Yes, those are good enough to start with. I'm sure we'll need some more packages, but for now those are good to start with. So the first thing we're going to do is we're going to build a function to just get the data and display it on the screen, right? So the first thing we want to do is instantiate or initialize Subgraphs first, which is Right up here that we will use. So let's just initialize. We'll just build everything out first and then we'll put them in functions later on once we figure out which needs to go where, what could be condensed, what is more usable, right? Because we want to make our code reusable. So sg, this will be a variable that will hold our instance of Sequence.
I need to zoom in to make sure that this is very clear.
All right, so initialize subgrounds, and then ens, which will be, um, which will hold the This could be a variable that holds our link to the subgraph, and I can just grab the link to the subgraph up here, and it should be in the subgraph that we were looking at in the website. So from there, we'll just do that. That's it, the EN subgraph that we want. Let's just do URL easier. So that's the URL to the ENS subgraph. And then the next thing I want to do is load that subgraph as ENS, just a variable called ens. I'm going to use the Subgraph instance that we have to load it, load the subgraph from there. And we can just use— Let me see. Click on it, it should give us. Doesn't need to give us anything. So load subgraph. That's a URL for it. When it's loaded, subgraph URL. And let's just give it a shot. Why not? Let's see. Print. Oh, it doesn't. It won't print anything for now. So try to be ahead of ourselves. I'm trying to be. I'm trying to run ahead of myself. So the next thing I want to do is, or that we would want to do here as well, is to make sure that, um, once we have this instances done, the next thing we want to do is, uh, create the synthetic fields for the registration dates that we, that we're trying to get.
Because here from our query, we're trying to get the registration dates, right?
So registrations, um, we'll use the reg Registration date as part of our filters because we'll use the registration date to order the data that we get back, the names that we get back. We'll use the registration date. Those dates, we'll need to convert them from Unix to human readable.
Let's create a synthetic field.
For registration date. So here we'll do ens.registration.registration. So in this case here, we're calling the registration field. Field that exists within, uh, the entity that exists within, uh, which is this one basically, but it's an entity that exists within the subgraph. So, and then we just name it as registration date. So this alias for it that we're using, what are we calling the data? So we're using a synthetic field and we'll use the lambda function. Lambda function, if you're not familiar with it, it's a type It's like a function, but it's very short. Registration date, we'll call it registration date, and we'll convert it to string. We use the date module. All right, my screen is getting a little crowded. We use the date module, and then from Timestamp. You're trying to convert timestamps.
Registration dates.
Let me just zoom out. My screen is losing some real estate here.
So.
Bear for moments, but to pick up where we left off from. So left off at synthetic, the synthetic field, synthetic field, or field, field. Do the string here because we're going to write. Let me clear the screen. And I can tab this. Then we also want to add the ENS, the name itself, the registration. And we want to do the registration date. And that should take care of the synthetic field for the registration date. Now we want to create another synthetic field for expiry date because we're going to have expiry date within our Data, and that's something that we want to make sure that we take care of. So from here as well, so we can just copy this one and then just edit what I don't need and replace it with expiry date. So big field for expiry. The expiry date, and for this case, instead of calling it that, we'll do instead of registration date, we'll do expiry. Then same things in type field, and instead of registration date, we're just doing expiry date. Date, and everything to expiry date. And everything, the expiry date. And then let's just save. Let's make sure that everything looks the way it's supposed to look. For more data monitoring this livestream as well, just make sure that there's no questions.
Cool.
All right, so we've gotten so far what we need for the synthetic fields. And just make sure we don't miss anything. Convert it to string, convert it to string.
Now the next thing would be handling the field paths.
And the field paths, you can think of them as the filters that we're going to have. So field paths are like folders, filters in this case. So, and we'll make it load maybe the first 20 names, DNS names or DNS domains. In descending order. Just writing that for comments so that I can remember that that's what I want to do. So we'll just come to registrations, another, um, array we could hold what we need here. So registrations, and we'll just call it ens. This time we just call the query itself. Not registrations.
Because if you think of it, we're calling this, so we're calling ens registrations.
We'll query first, see this query, and then registrations. And then we're going to be inputting this stuff in it now since we have most of the stuff done. We're going to have this stuff done afterwards. So on the registrations entity, we want specific things from there. The first thing we want is we want to get the first 20 names and we want to order by the entity registration date that we already created, the synthetic that we created up here. So DNS registration, registrations.registration_date. That's what we need to register that for. That's what we need to fulfill the order. Then the order direction, we want it to be descending. And in this case, we'll do descending. That's a string. That's why it has the stuff around it. So after this, what we want to do is the payload, and the payload itself is going to be this domain name, label name, owner, cost, and expiry date. Those are our payloads that we are sending so we can get back, which is the payload. In this case, we'll do field paths. And we'll put it in a list since it's going to be a good number of them. But in this case now, we'll start with registrations. And the first thing I'm going to do is registration date is the first thing I want to get. So you can see here, we're just going registrations. We're going to be getting exactly what we want.
Here we can add registration date as one of the things.
So basically we go to registrations dot and then we go to the next thing from there. So excuse me. All right, so we've gotten the first one, uh, but instead of using the one you can see here with a capital D for the date, instead of using that, we're using this synthetic one that we've already fixed up here. So the synthetic registration date, and we'll do the same thing for expiry date as well. But the next thing we want to do is also get Registration registrations at domain dot name. All right, so again, we're going to registrations dot next thing next level is domain dot name. So do that. We've got the name. Then we'll do the next one. Registrations dot domain dot label name registration dot domain dot owner dot ID.
And we'll just keep going like that until we finish all of them.
So this is like traversing tree in a way.
So domain label name.
We'll check out the domain for the label name because I don't think we need that. We'll just do registrations domain. We've got the domain name. The next one will be domain.owner.id. That's what we needed for to get the address for the person that's buying the name. And then the cost. We'll do the same thing, registration.cost.
And then the final one will be the expiry date, expiry date.
We want to do the domain, we'll do the synthetic field that we've created. So after that, what we want to do is we also Need to call now. We've gotten to the point where we can call the data. We can we can we can put it in a data frame. So df would for pandas just means df data frame. So we'll do in this case we'll do subgrounds and we'll tell we'll tell the query over df. So just so you know, you can use subgrounds to query the data into JSON as well. So we would have done sg.query JSON and we'll put the data in JSON. We want it in a DataFrame to make it easy for us to access and play around with. So, and we will probably put it in a DataFrame at the end of the day anyway. So we'll do field paths. We're telling, hey, we want to put this data in a DataFrame so that we want it to load the field paths. And I think we need a pagination strategy. Pagination strategy is, will help us In terms of like, because there's so many pages of this data, and we also want to make sure that it's going through them in a nice, fast way. So I want to use the shallow strategy. Shallow strategy. So in this case, we don't have it up here, so we need to import it. And the easiest way we would do is under support, Grounds here, we can just say again from grounds.page nation port. Oh, that helps take out that error.
Cool.
And that should be, that should be it really. And then from there, let's just do Let's print the DataFrame. Let's print the head of DataFrame. Print df.head just means print the first 5. And let me save that. All right, I'm going to test and see if I wrote some good code here. If it works, it should print out It didn't work. So module is not callable. Subgrams, sg_subgrams is not callable. So that's number 9. Line number 9 is failing. So let's troubleshoot that and see what the problem is. So initialize subgrams. Subgrants. See, put subgrants or subgrants. That is the problem. From subgrants report. I shouldn't be rushing. Good. That squashes that problem. So let's.
Rerun it again.
Let's see if we get another error. All right, so we didn't get any error. We got the data we needed. So we've gotten some data, and you can see it did print out here the query that he used, which was registrations, um, the data we gave it, ascending, ascending where That's interesting. Yes, so it did not print what we wanted. It gave us the direction as ascending, and I didn't want the direction as ascending. I wanted it as descending, where first skipped, and it did all that. So, but it gave us some data, so that's a good part. So the first The thing I'm going to do is come back here and see where the issue might have been. Registration, line 22. Let's just figure out what's going on with this here. Let me take out this. I'm back now. That was weird, but I'm back. Let's just make sure everything is supposed to be the way it's supposed to be. Ens_query registrations, and I wanted the first 20, order by registration.registration_date. I wanted descending, so it didn't pick up that part. Uh, very interesting because this was supposed to feed into this, which means it did work, but we just didn't get the data that we wanted.
Um, in this case, we didn't get The time frame that we wanted because I wanted it in order direction as descending, and it didn't seem to have taken that into into into consideration here.
So pagination strategy, we've got costs expiry date.
Trying to verify that we got the right name.
I'm just looking at the the so ground documentation here on the side as well just to make sure that I got it. All right, do some debugging in real time here. Field paths, pagination strategy, ENS query, registrations. Let me pump up the music a little bit because I think it's just too low volume-wise.
Okay, let me run it again just to make sure that— and this time I want to print out the columns as well so that way I get the names. The columns to make sure that I'm getting all the columns.
So to do that, I would just do df.columns. And make sure you have to save the file first before you run it again. Let's run it again. Let's see what we get this time around. All right, so we're still getting the data, but we're getting from like 2020. That's not what I wanted. And I don't know why it's still— That, but you can see that here that the columns we're getting registration, registration date, registration domain name, label name. We're getting everything that we want: domain registration cost, which expired date. We're getting everything that we need. The only thing here would be just we're getting not the right time, the right the right dates. So let me do the entire data frame and see.
All right, so with that, it doesn't seem to be— it did print out all the data that we need.
More from Tony

Summarize Videos and Research Companies with CrewAI + Gemini Models [Quickstart Guide]

How to Make Your AI Agents More Reliable with CrewAI Task Guardrails (Step-by-Step Tutorial)








