<?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: Aran Services</title>
    <description>The latest articles on DEV Community by Aran Services (@aran404).</description>
    <link>https://dev.to/aran404</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%2F2000871%2Fd2c74e5f-6667-4f81-a4af-d3caa05e0263.png</url>
      <title>DEV Community: Aran Services</title>
      <link>https://dev.to/aran404</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aran404"/>
    <language>en</language>
    <item>
      <title>I wrote a Python library at 16. Here are 5 things I'd fix in the async rewrite</title>
      <dc:creator>Aran Services</dc:creator>
      <pubDate>Sat, 14 Nov 2026 14:43:12 +0000</pubDate>
      <link>https://dev.to/aran404/i-wrote-a-python-library-at-16-here-are-5-things-id-fix-in-the-async-rewrite-4p62</link>
      <guid>https://dev.to/aran404/i-wrote-a-python-library-at-16-here-are-5-things-id-fix-in-the-async-rewrite-4p62</guid>
      <description>&lt;p&gt;My first Python library has nearly 500 GitHub stars. To get a track's name out of it, you wrote this:&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="k"&gt;print&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="s2"&gt;"item"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one line explains most of what I'd do differently.&lt;/p&gt;

&lt;p&gt;I started SpotAPI when I was 16. I'd spent a long time working with Spotify's unofficial web-player API, and I had a pile of code that worked, so I bundled it into a library and put it on GitHub. Over the next two years it picked up nearly 500 stars while the code barely changed. I didn't maintain it as well as I should have, and other people sent most of the fixes that kept it alive.&lt;/p&gt;

&lt;p&gt;Version 2 is a typed, async rewrite. Here's what I changed. None of it is specific to Spotify.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Return models, not nested dicts
&lt;/h2&gt;

&lt;p&gt;Version 1 handed back whatever the server sent:&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="c1"&gt;# v1&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate_songs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"weezer"&lt;/span&gt;&lt;span class="p"&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;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&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="s2"&gt;"item"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With an undocumented API, that couples every user's script to a response shape nobody promised to keep. Now results are typed models:&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="c1"&gt;# v2&lt;/span&gt;
&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;Public&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="s2"&gt;"weezer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&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;track&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tracks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;track&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get autocomplete and type checking, and when Spotify changes a response, the fix lives in the library instead of in every script that depends on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reading an attribute should never make a network call
&lt;/h2&gt;

&lt;p&gt;In v2, reading a model never triggers a hidden HTTP request. If Spotify didn't send a field, it stays optional and you decide whether to go and fetch it.&lt;/p&gt;

&lt;p&gt;Lazy-loading attributes feel convenient until you hit the N+1 problem in a loop. In async code it's worse, because a property can't &lt;code&gt;await&lt;/code&gt;. Network access should look like network access.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Offer a one-shot call and a context manager
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# One call: cleans up after itself&lt;/span&gt;
&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;Public&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="s2"&gt;"Daft Punk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Many calls: share one session&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;Catalogue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;spotify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;spotify&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="s2"&gt;"Daft Punk"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;artist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;spotify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_artist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;artists&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="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;artist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The one-shot covers the common case without leaking connections. The context manager makes ownership explicit when you're making several calls. Resource lifetime is where async libraries tend to go wrong, so I wanted both paths to be hard to misuse.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A row is not the thing it points to
&lt;/h2&gt;

&lt;p&gt;A playlist can contain the same track twice. If your API says &lt;code&gt;remove(track_uri)&lt;/code&gt;, which copy goes?&lt;/p&gt;

&lt;p&gt;SpotAPI models each &lt;em&gt;occurrence&lt;/em&gt; of a track in a playlist, with its own ID. &lt;code&gt;Playlist.items()&lt;/code&gt; returns occurrences, and &lt;code&gt;remove_occurrences()&lt;/code&gt; and &lt;code&gt;move_occurrences()&lt;/code&gt; act on them, so you can edit one copy without touching its twin.&lt;/p&gt;

&lt;p&gt;The same bug shows up in shopping carts, queues and to-do lists. Model what the user is actually pointing at, not the entity it refers to.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. If you wrap something unofficial, plan for it to break
&lt;/h2&gt;

&lt;p&gt;SpotAPI uses the same web-player endpoints as open.spotify.com, and Spotify can change them without telling anyone. Here's how I design around that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discover at runtime, cache by build.&lt;/strong&gt; The first request finds Spotify's current web-player queries, and later runs reuse them for the same Spotify build. The tradeoff is a slower first run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One exception to catch.&lt;/strong&gt; Library failures are &lt;code&gt;SpotAPIError&lt;/code&gt;, so your code can tell "the library broke" from "my code broke".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opt-in live tests.&lt;/strong&gt; The default test run (441 passing) doesn't depend on a third party's uptime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Written-down boundaries.&lt;/strong&gt; The docs list what I verified and what I didn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I got wrong the first time
&lt;/h2&gt;

&lt;p&gt;Stars aren't maintenance. I was slow to answer issues and cut releases, and people sometimes had to ask me to update the PyPI package.&lt;/p&gt;

&lt;p&gt;Releases now go out from GitHub Actions with PyPI attestations, so you can verify where a package came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in 30 seconds
&lt;/h2&gt;

&lt;p&gt;You don't need to care about Spotify to see what a typed async client feels like. You need Python 3.11+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip install spotapi
spotapi search &lt;span class="s2"&gt;"Ca$h YP"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no API key, login or config. The first run is slower while it discovers queries. For something nicer to look at, there's a terminal UI with artwork:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip install &lt;span class="s2"&gt;"spotapi[demo]"&lt;/span&gt;
spotapi discover &lt;span class="s2"&gt;"Ca$h YP"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0rjsu81mvpw8pycdsxup.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0rjsu81mvpw8pycdsxup.gif" alt="SpotAPI Discover in the terminal" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd like feedback on
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Layering:&lt;/strong&gt; Is &lt;code&gt;Public&lt;/code&gt; vs &lt;code&gt;Catalogue&lt;/code&gt; (one-shot vs shared session) clear, or did I over-split it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden I/O:&lt;/strong&gt; Do you agree that models shouldn't do hidden I/O, or have you found a case where lazy loading was worth it?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unofficial APIs:&lt;/strong&gt; How do you keep a client for an unofficial API maintainable?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SpotAPI uses unofficial endpoints, may conflict with Spotify's terms, and doesn't stream or download audio. See the legal notice before using it. It's GPL-3.0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;https://github.com/Aran404/SpotAPI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://spotapi.readthedocs.io/" rel="noopener noreferrer"&gt;https://spotapi.readthedocs.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>asyncio</category>
      <category>showdev</category>
    </item>
    <item>
      <title>🚀 Introducing SpotAPI: A Python Library for Effortless Spotify Integration 🚀</title>
      <dc:creator>Aran Services</dc:creator>
      <pubDate>Fri, 30 Aug 2024 03:00:22 +0000</pubDate>
      <link>https://dev.to/aran404/introducing-spotapi-a-python-library-for-effortless-spotify-integration-1g29</link>
      <guid>https://dev.to/aran404/introducing-spotapi-a-python-library-for-effortless-spotify-integration-1g29</guid>
      <description>&lt;p&gt;Hey DEV Community! 👋&lt;/p&gt;

&lt;p&gt;I'm excited to introduce &lt;strong&gt;&lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI&lt;/a&gt;&lt;/strong&gt;, a powerful and easy-to-use Python library designed to simplify your interactions with Spotify's private and public APIs. Whether you're building a music app or just experimenting with Spotify data, SpotAPI offers a seamless way to access Spotify's rich features programmatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SpotAPI? 🎵
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI&lt;/a&gt;&lt;/strong&gt; is a Python library that emulates the requests made through a web browser to interact with Spotify's APIs. It provides an intuitive interface to work with both public and private Spotify data, making it easier to integrate Spotify features into your applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features ✨
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Premium Required&lt;/strong&gt;: Access Spotify’s features without needing a Premium account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public API Access&lt;/strong&gt;: Retrieve and manage public Spotify data like playlists, albums, and tracks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private API Access&lt;/strong&gt;: Explore private endpoints for tailored application needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy Integration&lt;/strong&gt;: Start using &lt;strong&gt;&lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI&lt;/a&gt;&lt;/strong&gt; with minimal setup—no API key required!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser-like Requests&lt;/strong&gt;: Replicate Spotify's web requests for a true-to-web experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Start Guide 🚀
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Without User Authentication:&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;spotapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Song&lt;/span&gt;

&lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Song&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;gen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate_songs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weezer&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;batch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;gen&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;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&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;batch&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;idx&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;item&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;data&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;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Import Cookies 🛠️
&lt;/h3&gt;

&lt;p&gt;Prefer not to use a CAPTCHA solver? You can import cookies to manage your session. Simply follow the &lt;a href="https://github.com/Aran404/SpotAPI#import-cookies" rel="noopener noreferrer"&gt;steps in our documentation&lt;/a&gt; to use &lt;strong&gt;&lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI&lt;/a&gt;&lt;/strong&gt; with a fully functional session.&lt;/p&gt;




&lt;h3&gt;
  
  
  License 📝
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI&lt;/a&gt;&lt;/strong&gt; is licensed under the &lt;strong&gt;GPL 3.0&lt;/strong&gt; License. &lt;a href="https://choosealicense.com/licenses/gpl-3.0/" rel="noopener noreferrer"&gt;Learn more about the license&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Feel free to check out the &lt;a href="https://github.com/Aran404/SpotAPI" rel="noopener noreferrer"&gt;SpotAPI GitHub repository&lt;/a&gt; for more details and to get started. Let me know if you have any questions or feedback!&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>spotify</category>
      <category>api</category>
    </item>
  </channel>
</rss>
