DEV Community

Cover image for Get YouTube Channel Details API: Testing Connection
apiharbor
apiharbor

Posted on • Edited on

Get YouTube Channel Details API: Testing Connection

Hi,

In our previous post here, we built the framework for a Python package that communicates with the API at The Better YouTube Channel Details to retrieve YouTube channel details. If you haven't read the previous part, I highly recommend it!

Let's look at the roadmap to see where we are now:

  1. creating the package structure and coding for API communication.
  2. 👉 we are currently here: testing our solution
  3. next, we'll publish our work on pypi

Today, we're going to:

  • create a function that will connect to the API endpoint
  • test the implementation

Let's get started!

Everyone ready? Camera! ACTION! 🎬

📡 Get Youtube Channel details by using __get_request

Previously, we implemented the __get_request function, which connects to the API and returns data in JSON format. We'll use it to fetch the details of a YouTube channel from the API.

In the API documentation, we see that the endpoint is located at:
https://the-better-youtube-channel-details.p.rapidapi.com/GetChannelDetails
and it accepts a query parameter UrlOrUsername. The endpoint only supports the GET method.

With this knowledge of the API, let's write a function:

   async def get_channel_details(self, urlOrUsername) -> any:
        response = await self.__get_request("/GetChannelDetails", urlencode({'urlOrUsername': urlOrUsername}))
        print(response)
Enter fullscreen mode Exit fullscreen mode

In the previous post, when we were implementing __get_request, we explained why this function would take a query: dict parameter. Briefly, it's because urlencode, which is used for encoding special characters, returns them in the form of a dict.

👨‍💻 Let's test the code!

Phew, now we need to check if everything works correctly. We'll use tests for this task. Yes, I know, "test-first". But in such a project, let's be realistic - we write tests (like a BOSS) AFTER coding 😊 We write them only to check if we haven't made any mistakes and if the code works as it should.

We open a file tests/tests.py. At the very beginning of the file, we add an import line:

from src.youtube_channel_details_api_client_apiharbor.api_client import YouTubeChannelDetailsApiClient

print("it works!")
Enter fullscreen mode Exit fullscreen mode

It's very important! Pay attention to how the from construct looks, and then look at the structure of our project:

Running the tests

We open cmd and navigate to the directory \libs\youtube_channel_details_api, then write the command to run the test: python -m tests.tests
And we should see the message: "it works!"

When everything works we can move on. Let's write a simple test to check if data fetching from the API works.

api = YouTubeChannelDetailsApiClient("YOUR_RAPID_API_KEY")

async def test_get_channel_details():
  await api.get_channel_details('@MrBeast')

async def main():
  await test_get_channel_details()
  return None

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

We run it using the previously mentioned command:
python -m tests.tests
in the directory \libs\youtube_channel_details_api and here is the result:

{'description': 'OK', 'status': 200, 'data': {'channel_url': 'https://www.youtube.com/channel/UCX6OQ3DkcsbYNE6H8uQQuVA', 'channel_name': 'MrBeast', 'channel_id': 'UCX6OQ3DkcsbYNE6H8uQQuVA', 'joined_date_text': 'Joined Feb 20, 2012', 'channel_country': 'United States', 'rss_url': 
Enter fullscreen mode Exit fullscreen mode

🦾 We're the best! Everything works as it should, but we want to make our work easier in other projects. Therefore, we will do mapping from JSON to OBJECT.

🔄 Mapping plain JSON to python OBJECT

Let's go back to our get_channel_details function.

async def get_channel_details(self, urlOrUsername) -> any:
        response = await self.__get_request("/GetChannelDetails", urlencode({'urlOrUsername': urlOrUsername}))
        print(response)
Enter fullscreen mode Exit fullscreen mode

Everything is going well, but we still need to map JSON. We'll use the pydantic package for this task. Let's install it by running the command: pip install pydantic.

Now let's start coding the mapping. We add a directory src/schemas, where we'll put: base.py, which will be the main model from which every class in the schema will inherit.

from pydantic import BaseModel

class BaseModelORM(BaseModel):
    class Config:
        from_attributes = True
Enter fullscreen mode Exit fullscreen mode

We create a new schema schemas/channel_details.py.

from .base import BaseModelORM

class ChannelDetails(BaseModelORM):
    status: int
    description: str
Enter fullscreen mode Exit fullscreen mode

So far, we will only map these two fields: status and description. We need to make sure that everything works. Only then will we map all the fields.

Let's go back to api_client.py and import the ChannelDetails schema.

from .schemas.channel_details import ChannelDetails
Enter fullscreen mode Exit fullscreen mode

and modify the get_channel_details function so that it returns a ChannelDetails object created from the JSON received from the API.

async def get_channel_details(self, urlOrUsername) -> any:
 response = await self.__get_request("/GetChannelDetails", urlencode({'urlOrUsername': urlOrUsername}))
        return ChannelDetails.model_validate(response)

Enter fullscreen mode Exit fullscreen mode

The final step is to modify the test_get_channel_details test.

async def test_get_channel_details():
    r = await api.get_channel_details('@MrBeast')
    assert r.status == 200
Enter fullscreen mode Exit fullscreen mode

Run python -m tests.tests and... nothing appears. That means everything is working! Otherwise, we would have received an error. To confirm this theory, let's change the assert in the test to

    assert r.status != 200
Enter fullscreen mode Exit fullscreen mode

After running the test, we are greeted with a beautiful error:

assert r.status != 200
AssertionError
Enter fullscreen mode Exit fullscreen mode

All that's left for us to do is to complete the mapping for ChannelDetails.

One Eternity Later

Just kidding. We won't be doing this mapping manually; instead, we'll use a tool available at https://jsontopydantic.com/. You just need to input your JSON, and the tool will generate the schema for you.

Recap

Let's summarize what we managed to do today:

  • We wrote the get_channel_details function, which calls __get_request to fetch YouTube channel details.
  • We also wrote a test for it to check if everything works OK.
  • We implemented mapping from JSON to a Python object.

What will we do next time? Actually, the whole package is ready, and all that's left is to publish it on Packagist.

Thanks for your time and see you next time!

p.s. I hope you enjoyed the style and examples. If possible, please give a thumbs up, comment, or any kind of reaction! It fuels me for future posts. Follow me to make sure you don't miss anything 🚀

Top comments (0)