<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cleaner Wrasse</title>
    <description>The latest articles on DEV Community by Cleaner Wrasse (@cleaner-wrasse).</description>
    <link>https://dev.to/cleaner-wrasse</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3890877%2Fd09f0944-9bf3-4613-98f5-d82f6eb663c0.png</url>
      <title>DEV Community: Cleaner Wrasse</title>
      <link>https://dev.to/cleaner-wrasse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cleaner-wrasse"/>
    <language>en</language>
    <item>
      <title>Building a YouTube Video View Count Ranking CLI Tool with Python and YouTube Data API</title>
      <dc:creator>Cleaner Wrasse</dc:creator>
      <pubDate>Thu, 27 Aug 2026 02:58:46 +0000</pubDate>
      <link>https://dev.to/cleaner-wrasse/building-a-youtube-video-view-count-ranking-cli-tool-with-python-and-youtube-data-api-236c</link>
      <guid>https://dev.to/cleaner-wrasse/building-a-youtube-video-view-count-ranking-cli-tool-with-python-and-youtube-data-api-236c</guid>
      <description>&lt;h1&gt;
  
  
  Building a Video View Count Ranking CLI with Python and the YouTube Data API
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I built a CLI tool using Python and the YouTube Data API v3.&lt;/p&gt;

&lt;p&gt;The tool takes a YouTube channel as input and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieves the latest 100 videos&lt;/li&gt;
&lt;li&gt;Retrieves the view count of each video&lt;/li&gt;
&lt;li&gt;Sorts the videos by view count in descending order&lt;/li&gt;
&lt;li&gt;Displays the top 10 videos in the terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Building a Minimal Working CLI Tool with Python
&lt;/h2&gt;

&lt;p&gt;The goal of this project is to build a CLI tool that retrieves video information from a specified YouTube channel.&lt;/p&gt;

&lt;p&gt;The tool can be launched from the terminal with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 youtube_cli.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 1. Install the Required Libraries
&lt;/h2&gt;

&lt;p&gt;First, install the libraries required to use the YouTube Data API from Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install &lt;/span&gt;google-api-python-client google-auth-oauthlib google-auth-httplib2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 2. Enable the API in Google Cloud Console
&lt;/h2&gt;

&lt;p&gt;To use the YouTube Data API, you first need to configure your project in Google Cloud.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new project&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;YouTube Data API v3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;OAuth 2.0 Client ID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Download &lt;code&gt;client_secret.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Place &lt;code&gt;client_secret.json&lt;/code&gt; in your Python project directory&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🧩 3. CLI Tool Implementation (&lt;code&gt;youtube_cli.py&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;Here is the Python CLI tool used in this project.&lt;/p&gt;

&lt;p&gt;The user enters a YouTube channel name or handle, and the tool retrieves the latest 100 videos from that channel and displays the top 10 videos with the highest view counts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;youtube_cli.py&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google_auth_oauthlib.flow&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;InstalledAppFlow&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;googleapiclient.discovery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;

&lt;span class="n"&gt;SCOPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.googleapis.com/auth/youtube.readonly&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_channel_id_from_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Search YouTube for the specified channel name or keyword
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Searching for a channel matching: 「&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;」&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;channel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;maxResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Channel 「&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;」 was not found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;channel_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;channelId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;channel_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Target channel: 【 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;channel_title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 】&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;channel_id&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;TOP_N&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="n"&gt;MAX_VIDEOS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;  &lt;span class="c1"&gt;# Maximum number of recent videos to retrieve
&lt;/span&gt;
    &lt;span class="c1"&gt;# OAuth authentication
&lt;/span&gt;    &lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;InstalledAppFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_client_secrets_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_secret.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SCOPES&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_local_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;youtube&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;youtube&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. Ask the user for a channel name or keyword
&lt;/span&gt;    &lt;span class="n"&gt;user_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the name of the YouTube channel you want to analyze: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No channel name was entered. Exiting.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="c1"&gt;# Get the channel ID
&lt;/span&gt;    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;channel_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_channel_id_from_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="c1"&gt;# Get the channel's uploads playlist ID
&lt;/span&gt;    &lt;span class="n"&gt;channel_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;channels&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contentDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;channel_id&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;uploads_playlist_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;channel_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contentDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;relatedPlaylists&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;uploads&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Retrieve up to 100 recent video IDs
&lt;/span&gt;    &lt;span class="n"&gt;video_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;next_page_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retrieving the latest videos...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;playlist_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;playlistItems&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contentDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;playlistId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;uploads_playlist_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;maxResults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;pageToken&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;next_page_token&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;playlist_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt;
            &lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contentDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;videoId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

            &lt;span class="c1"&gt;# Stop when the maximum number of videos is reached
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;MAX_VIDEOS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;MAX_VIDEOS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="n"&gt;next_page_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;playlist_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nextPageToken&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;next_page_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

    &lt;span class="n"&gt;videos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retrieving data for the latest &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; videos...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Process videos in batches of up to 50
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;chunk_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;ids_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;youtube&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statistics,snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ids_string&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snippet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;views&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;viewCount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;video_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="n"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;views&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;video_id&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;# Sort by view count
&lt;/span&gt;    &lt;span class="n"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;views&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Display the ranking
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- View Count Ranking for 【&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;】 &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(Top &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TOP_N&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;TOP_N&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;views&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; views &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(https://www.youtube.com/watch?v=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the CLI Tool
&lt;/h2&gt;

&lt;p&gt;Run the following command from the directory containing &lt;code&gt;youtube_cli.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;./scripts % python3 youtube_cli.py
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A browser window will open, and you will be asked to select a Google account.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhf5849x1ahdm4nxs4n6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhf5849x1ahdm4nxs4n6w.png" alt=" " width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the account you want to use for authentication.&lt;/p&gt;

&lt;p&gt;Then, click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7p9ak0nu4due0tofkap3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7p9ak0nu4due0tofkap3.png" alt=" " width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After authentication is completed, return to the terminal.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faqnl53y60x15vam23yx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faqnl53y60x15vam23yx0.png" alt="Screenshot 2026-08-27 at 9.21.55.png" width="800" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should then see the following prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter the name of the YouTube channel you want to analyze: 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter the name of the YouTube channel you want to analyze: @SaturdayNightLive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;The tool will search for the specified channel and retrieve its latest videos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Searching for a channel matching: 「@SaturdayNightLive」
Target channel: 【 Saturday Night Live 】

Retrieving the latest videos...
Retrieving data for the latest 100 videos...

--- View Count Ranking for 【@SaturdayNightLive】 (Top 10) ---
1. you know what this song needs? - 12,489,263 views (https://www.youtube.com/watch?v=Q1ZabPOA76w)
2. cast list reveal - 6,404,227 views (https://www.youtube.com/watch?v=Uw9ub2NnMYY)
3. Jeffrey Epstein Ghost Cold Open - SNL - 5,039,611 views (https://www.youtube.com/watch?v=YzqJh6WnQOM)
4. some wires were crossed - 4,867,443 views (https://www.youtube.com/watch?v=HZtZATonxw8)
5. weekend update! - 3,381,263 views (https://www.youtube.com/watch?v=gROY9_gPA4Q)
6. the american dream - 3,258,007 views (https://www.youtube.com/watch?v=wCSDinZYJEQ)
7. finale joke swap! - 3,054,821 views (https://www.youtube.com/watch?v=WMRcO1VuUhw)
8. Weekend Update: Colin Jost and Michael Che Swap Jokes for Season 51 Finale - SNL - 3,041,289 views (https://www.youtube.com/watch?v=WY8lNAmso1Y)
9. talking to a mechanic be like - 2,916,902 views (https://www.youtube.com/watch?v=-VAQxjvYxZ8)
10. now kiss - 2,871,220 views (https://www.youtube.com/watch?v=ruX5XweYnOI)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;The YouTube Data API CLI tool follows this flow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable the API in Google Cloud&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Create an OAuth 2.0 Client ID&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Place &lt;code&gt;client_secret.json&lt;/code&gt; in the Python project&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Authenticate with a Google account&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Call the YouTube Data API&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Receive the response in JSON format&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Process the required data with Python&lt;/strong&gt;&lt;br&gt;
↓&lt;br&gt;
&lt;strong&gt;Display the results in the terminal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Configure the API in Google Cloud, authenticate the Python application with OAuth, call the YouTube Data API, process the returned JSON data with Python, and display the results through a CLI.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>youtube</category>
      <category>api</category>
      <category>cli</category>
    </item>
    <item>
      <title>My Developer Profile</title>
      <dc:creator>Cleaner Wrasse</dc:creator>
      <pubDate>Sun, 26 Apr 2026 16:07:16 +0000</pubDate>
      <link>https://dev.to/cleaner-wrasse/my-developer-profile-223g</link>
      <guid>https://dev.to/cleaner-wrasse/my-developer-profile-223g</guid>
      <description>&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;I took the plunge into the IT industry in May 2023.&lt;br&gt;
In my career so far, I’ve had many opportunities to work with &lt;strong&gt;Java&lt;/strong&gt; and &lt;strong&gt;JavaScript (TypeScript)&lt;/strong&gt;. My current goal is to build a solid foundation in these two languages before exploring further career opportunities🏂&lt;/p&gt;

&lt;p&gt;As a junior engineer, I am learning something new every day, and I'm eager to gain broad and deep knowledge and experience in the tech field🧑‍💻&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
I haven't been able to travel lately, so I'm dying to go somewhere far away! ✈️&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffm0wut0x8irkxn2c3n6q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffm0wut0x8irkxn2c3n6q.jpeg" alt="Sandanbeki" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Sandanbeki Rock Cliff&lt;/strong&gt; | Shirahama, Wakayama&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngadtdg5e0bz51x4y88c.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngadtdg5e0bz51x4y88c.jpeg" alt="Yakatabune" width="473" height="843"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Yakatabune (Traditional Houseboat)&lt;/strong&gt; | Arashiyama, Kyoto&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs46ntfchrp49hg80yblg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs46ntfchrp49hg80yblg.jpeg" alt="Halloween" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Halloween Night&lt;/strong&gt; | Namba, Osaka&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7m1ols2rxcqy51evsa2i.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7m1ols2rxcqy51evsa2i.jpeg" alt="Kyudo" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Kyudo (Japanese Archery) Experience&lt;/strong&gt; | Shinsekai, Osaka&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a37wh1kf9dbk90vxr2g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a37wh1kf9dbk90vxr2g.jpeg" alt="Jakarta" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Bundaran HI (Welcome Monument)&lt;/strong&gt; | Jakarta, Indonesia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouyj8409tjpe11edxpt1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fouyj8409tjpe11edxpt1.jpeg" alt="Frankfurt" width="800" height="1062"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;strong&gt;Römerberg Square&lt;/strong&gt; | Frankfurt, Germany&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🛠 Tech Stack &amp;amp; Expertise
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JavaScript / TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links &amp;amp; Portfolio
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Flying-WhaleShark" rel="noopener noreferrer"&gt;Flying-WhaleShark&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 Featured Project: Hotel Booking System
&lt;/h3&gt;

&lt;p&gt;This is a full-stack project I developed to solidify my foundation in Java and TypeScript while mastering the end-to-end development process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://hotelbooking-ui-ds7l.onrender.com/" rel="noopener noreferrer"&gt;Hotel Booking UI (on Render)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Code:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/Flying-WhaleShark/HotelBooking_UI" rel="noopener noreferrer"&gt;HotelBooking_UI&lt;/a&gt; (Frontend / TypeScript)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Flying-WhaleShark/HotelBooking_API" rel="noopener noreferrer"&gt;HotelBooking_API&lt;/a&gt; (Backend / Java)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Words to Live By
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Done is better than perfect&lt;/strong&gt;&lt;br&gt;
This phrase by Mark Zuckerberg (similar to Steve Jobs' "Real artists ship") serves as a constant reminder for me. I used to be someone who had many ideas but struggled to bring them to fruition. This quote keeps me moving forward😅&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If you want to find the secrets of the universe, think in terms of energy, frequency and vibration&lt;/strong&gt;&lt;br&gt;
Nikola Tesla’s words. I believe there is profound truth in this that science has yet to fully prove. I hope to eventually understand its meaning deeply, either through future scientific breakthroughs or my own interpretation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amor Fati&lt;/strong&gt;&lt;br&gt;
"Love of Fate." I believe there are three main perspectives: oneself, others, and third parties. No matter how well I do, events and accidents occur out of my control. This concept is essential for maintaining the right mindset when they do. While phrases like "C'est la vie" or "Love your neighbor as yourself" are similar, "Amor Fati" resonates with me the most.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎬 Currently Into
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Watching classic movies (especially from the 80s)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Gremlins&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;They Live (1988)&lt;/em&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m fascinated by the cultural backgrounds of that era and enjoy comparing older filming techniques with modern ones. Exploring "how things were expressed" back then through cinematography is incredibly stimulating👀✨&lt;/p&gt;




&lt;h2&gt;
  
  
  🎨 Art &amp;amp; Design Favorites
&lt;/h2&gt;

&lt;p&gt;I am drawn to works that possess a powerful visual impact and overwhelming energy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Last Judgment&lt;/strong&gt; / Michelangelo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The School of Athens&lt;/strong&gt; / Raphael&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thirty-six Views of Mount Fuji&lt;/strong&gt; / Katsushika Hokusai&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Famous Mirror: The Spirit of Japan&lt;/strong&gt; / Kawanabe Kyosai&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morozumi Bungo no kami Masakiyo&lt;/strong&gt; / Utagawa Kuniyoshi&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎵 Favorite Artists
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kenshi Yonezu&lt;/strong&gt; (J-Pop / Electronic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;King Gnu&lt;/strong&gt; (J-Pop / Mixture Rock)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Taylor Swift&lt;/strong&gt; (Pop / Country)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏃 Hobbies &amp;amp; Lifestyle
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Habits:&lt;/strong&gt; English learning, Strength training, Swimming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activities:&lt;/strong&gt; Bouldering, Traveling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📍 Location
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hometown:&lt;/strong&gt; Tokyo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Based in:&lt;/strong&gt; Tokyo → Osaka → Tokyo&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>java</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Deploy a Spring Boot + React App for Free on Render: From Local to Production</title>
      <dc:creator>Cleaner Wrasse</dc:creator>
      <pubDate>Tue, 21 Apr 2026 14:35:08 +0000</pubDate>
      <link>https://dev.to/cleaner-wrasse/how-to-deploy-a-spring-boot-react-app-for-free-on-render-from-local-to-production-2d7b</link>
      <guid>https://dev.to/cleaner-wrasse/how-to-deploy-a-spring-boot-react-app-for-free-on-render-from-local-to-production-2d7b</guid>
      <description>&lt;p&gt;&lt;strong&gt;LIVE DEMO:&lt;/strong&gt; &lt;a href="https://hotelbooking-ui-ds7l.onrender.com/" rel="noopener noreferrer"&gt;https://hotelbooking-ui-ds7l.onrender.com/&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠 Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React, Tailwind CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Java, Spring Boot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL (H2)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; Render&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring:&lt;/strong&gt; UptimeRobot&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  1/9:
&lt;/h3&gt;

&lt;p&gt;I’d been wanting to build my portfolio using Spring Boot but wasn't sure where to start. While looking for a free hosting service, I came across Render and decided to use it to bring my project to life!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://render.com/docs/free" rel="noopener noreferrer"&gt;https://render.com/docs/free&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the same time, I realized that building the UI from scratch would be quite a challenge. I figured using a template might be a better approach, so I searched for 'booking application web templates react' and came across this website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/arnobt78/Hotel-Booking-Landing-Page--React-Frontend" rel="noopener noreferrer"&gt;https://github.com/arnobt78/Hotel-Booking-Landing-Page--React-Frontend&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I chose the following website for my base design, but I noticed the navigation bar wasn't working properly. To fix this, I also referred to the site below, as combining them allowed me to create a fully functional and reliable user interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qiita.com/midori-game/items/17357d46e3ed1281001c" rel="noopener noreferrer"&gt;https://qiita.com/midori-game/items/17357d46e3ed1281001c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To update the visuals, I used the three websites mentioned below along with Nano Banana 2 for image generation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;https://unsplash.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pexels.com/" rel="noopener noreferrer"&gt;https://www.pexels.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pixabay.com/" rel="noopener noreferrer"&gt;https://pixabay.com/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2/9:
&lt;/h3&gt;

&lt;p&gt;After that, I cloned the repository and set up the project locally. As a first step for the UI updates, I started by replacing the images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original UI:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzc6cwhve0l0sxhg326f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzc6cwhve0l0sxhg326f.png" alt="image.png" width="658" height="858"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My current UI:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm43cf5nq9oo3wjjwae6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frm43cf5nq9oo3wjjwae6.png" alt="image.png" width="652" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3/9:
&lt;/h3&gt;

&lt;p&gt;At this stage, I started working on the backend separately from the UI. I chose Spring Boot for the API development. After fine-tuning the integration between the UI and API, I refactored the image handling so that pictures are now managed via the backend database instead of being stored directly in the frontend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsir3u6dy3y5dhpon34y0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsir3u6dy3y5dhpon34y0.png" alt="Screenshot 2026-04-14 at 21.47.44.png" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4/9:
&lt;/h3&gt;

&lt;p&gt;↓After completing the UI and API development and verifying the local server setup, I pushed the code to GitHub.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20fqvon2namszmwigcip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20fqvon2namszmwigcip.png" alt="Screenshot 2026-04-14 at 22.37.17.png" width="664" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5/9:
&lt;/h3&gt;

&lt;p&gt;With the code ready, I started setting up my Render account. I referred to the guide below for the setup process. I chose to authenticate with GitHub as it’s much more efficient for linking repositories.&lt;br&gt;
&lt;a href="https://qiita.com/tks_00/items/73cf04c225e5f6113cd8" rel="noopener noreferrer"&gt;https://qiita.com/tks_00/items/73cf04c225e5f6113cd8&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x1f0sbwdr33r6uvkbqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x1f0sbwdr33r6uvkbqh.png" alt="Screenshot 2026-04-14 at 22.42.14.png" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6/9:
&lt;/h3&gt;

&lt;p&gt;I proceeded by setting up the API as a Web Service and the UI as a Static Site. It wasn't a smooth start—I ran into several deployment errors related to updated paths and database configurations. Some images also failed to load initially. I spent some time troubleshooting these configuration issues and eventually secured a successful deploy.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhzhx9hl837ytljcbt0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhzhx9hl837ytljcbt0d.png" alt="Screenshot 2026-04-15 at 1.34.39.png" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7/9:
&lt;/h3&gt;

&lt;p&gt;I've finally reached a point where I'm happy with the progress.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9rafcd9t3a7iqisparea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9rafcd9t3a7iqisparea.png" alt="Screenshot 2026-04-15 at 1.40.12.png" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8/9:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Optimizing Load Speed&lt;/strong&gt;&lt;br&gt;
I noticed that Render’s free tier spins down the instance after 15 minutes of inactivity, leading to a long 60-90s wait for the first user. To maintain faster response times, I integrated UptimeRobot to monitor the site and prevent it from sleeping. I referred to this article for the implementation:&lt;br&gt;
&lt;a href="https://qiita.com/yuto141592/items/cef9b50ea4557dfe1be7" rel="noopener noreferrer"&gt;https://qiita.com/yuto141592/items/cef9b50ea4557dfe1be7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After accessing the UptimeRobot site, I created an account using GitHub authentication. To start the monitoring, I pasted my website's URL into the 'URL to monitor' section.&lt;br&gt;
&lt;a href="https://dashboard.uptimerobot.com/monitors?ref=website-header" rel="noopener noreferrer"&gt;https://dashboard.uptimerobot.com/monitors?ref=website-header&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jnzfp2xzg724v2jgtb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jnzfp2xzg724v2jgtb5.png" alt="Screenshot 2026-04-18 at 16.19.18.png" width="558" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default monitoring interval is set to every 5 minutes. Since that's enough to keep the server from sleeping, I kept the default settings. With this, the initial loading problem is now solved.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqev0bu0bae6nr05p7hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqev0bu0bae6nr05p7hq.png" alt="for_blog_9.png" width="800" height="302"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyryznj6t0f38bzqk74p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyryznj6t0f38bzqk74p.png" alt="for_blog_10.png" width="800" height="411"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0quui10en45lkp3zidi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0quui10en45lkp3zidi5.png" alt="for_blog_11.png" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9/9:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;br&gt;
Through this project, I gained practical experience in integrating React with Spring Boot and learned a lot about server-side communication.&lt;/p&gt;

&lt;p&gt;While the current backend is a minimal setup, I plan to build upon it by implementing a booking system. I also aim to add more advanced features such as API fetching and PDF generation to further enhance the backend's functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Links&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://hotelbooking-ui-ds7l.onrender.com/" rel="noopener noreferrer"&gt;https://hotelbooking-ui-ds7l.onrender.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/Flying-WhaleShark/HotelBooking_UI" rel="noopener noreferrer"&gt;https://github.com/Flying-WhaleShark/HotelBooking_UI&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Flying-WhaleShark/HotelBooking_API" rel="noopener noreferrer"&gt;https://github.com/Flying-WhaleShark/HotelBooking_API&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>springboot</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
