├── README.md
├── requirements.txt
├── vercel.json
├── app.py
└── templates
└── status.html
/README.md:
--------------------------------------------------------------------------------
1 | ## SOON GUYS
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask
2 | spotipy
3 | requests
4 | beautifulsoup4
5 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | {
5 | "src": "app.py",
6 | "use": "@vercel/python"
7 | }
8 | ],
9 | "routes": [
10 | {
11 | "src": "/(.*)",
12 | "dest": "app.py"
13 | }
14 | ],
15 | "env": {
16 | "PYTHON_VERSION": "3.9"
17 | }
18 | }
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, jsonify, render_template
2 | import spotipy
3 | from spotipy.oauth2 import SpotifyClientCredentials
4 | import requests
5 | from bs4 import BeautifulSoup
6 | import re
7 |
8 | app = Flask(__name__)
9 |
10 | # Spotify credentials
11 | CLIENT_ID = ''
12 | CLIENT_SECRET = ''
13 |
14 | # Initialize Spotify client
15 | sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET))
16 |
17 | def is_spotify_url(input_string):
18 | """Check if input is a Spotify track URL."""
19 | return bool(re.match(r'^https://open\.spotify\.com/track/[a-zA-Z0-9]+', input_string))
20 |
21 | def get_spotmate_download(spotify_url):
22 | """Get download link from spotmate.online."""
23 | try:
24 | headers = {
25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
26 | 'Accept': 'text/html',
27 | }
28 | response = requests.get('https://spotmate.online', headers=headers, timeout=10)
29 | response.raise_for_status()
30 |
31 | soup = BeautifulSoup(response.text, 'html.parser')
32 | csrf_token = soup.find('meta', {'name': 'csrf-token'})
33 | if not csrf_token:
34 | raise ValueError("CSRF token not found")
35 | csrf_token = csrf_token['content']
36 |
37 | session_cookie = response.cookies.get('spotmateonline_session')
38 | if not session_cookie:
39 | raise ValueError("Session cookie not found")
40 |
41 | headers.update({
42 | 'Content-Type': 'application/json',
43 | 'x-csrf-token': csrf_token,
44 | 'cookie': f'spotmateonline_session={session_cookie}',
45 | 'referer': 'https://spotmate.online/en',
46 | 'origin': 'https://spotmate.online',
47 | })
48 | convert_response = requests.post(
49 | 'https://spotmate.online/convert',
50 | json={'urls': str(spotify_url)},
51 | headers=headers,
52 | timeout=10
53 | )
54 | convert_response.raise_for_status()
55 | data = convert_response.json()
56 |
57 | if data.get('error') or not data.get('url'):
58 | raise ValueError("Failed to get download link")
59 |
60 | return data['url']
61 | except Exception:
62 | return None
63 |
64 | def get_track_metadata(track_id):
65 | """Get track metadata from Spotify, including cover art."""
66 | try:
67 | track = sp.track(track_id)
68 | # Get the largest available cover art (usually at index 0)
69 | cover_art = track['album']['images'][0]['url'] if track['album']['images'] else None
70 | return {
71 | 'id': track['id'],
72 | 'title': track['name'],
73 | 'artists': ", ".join(artist['name'] for artist in track['artists']),
74 | 'album': track['album']['name'],
75 | 'release_date': track['album']['release_date'],
76 | 'duration': f"{track['duration_ms'] // 60000}:{(track['duration_ms'] % 60000) // 1000:02d}",
77 | 'isrc': track['external_ids'].get('isrc', 'N/A'),
78 | 'cover_art': cover_art
79 | }
80 | except Exception:
81 | return None
82 |
83 | def search_spotify(query, limit=5):
84 | """Search Spotify for tracks."""
85 | try:
86 | results = sp.search(q=query, type='track', limit=limit)
87 | return [(track['name'], ", ".join(artist['name'] for artist in track['artists']), track['id']) for track in results['tracks']['items']]
88 | except Exception:
89 | return []
90 |
91 | @app.route('/')
92 | def home():
93 | """Render the status.html template."""
94 | return render_template('status.html')
95 |
96 | @app.route('/sp/dl', methods=['GET'])
97 | def download_track():
98 | """Download track by Spotify URL."""
99 | spotify_url = request.args.get('url')
100 | if not spotify_url or not is_spotify_url(spotify_url):
101 | return jsonify({
102 | 'status': False,
103 | 'message': 'Valid Spotify track URL required ❌',
104 | 'example': '/sp/dl?url=https://open.spotify.com/track/TRACK_ID'
105 | }), 400
106 |
107 | try:
108 | track_id = spotify_url.split('/track/')[1].split('?')[0]
109 | metadata = get_track_metadata(track_id)
110 | if not metadata:
111 | return jsonify({
112 | 'status': False,
113 | 'message': 'Failed to fetch metadata ❌'
114 | }), 500
115 |
116 | download_url = get_spotmate_download(spotify_url)
117 | if not download_url:
118 | return jsonify({
119 | 'status': False,
120 | 'message': 'Sorry Song Not Available ❌'
121 | }), 500
122 |
123 | return jsonify({
124 | 'status': True,
125 | 'title': metadata['title'],
126 | 'artist': metadata['artists'],
127 | 'track_id': track_id,
128 | 'track_url': f"https://open.spotify.com/track/{track_id}",
129 | 'download_url': download_url,
130 | 'album': metadata['album'],
131 | 'release_date': metadata['release_date'],
132 | 'duration': metadata['duration'],
133 | 'isrc': metadata['isrc'],
134 | 'cover_art': metadata['cover_art'],
135 | 'credit': 'Downloaded By @TheSmartDev And API Developer @TheSmartDev Organization github.com/TheSmartDevs'
136 | })
137 |
138 | except Exception as e:
139 | return jsonify({
140 | 'status': False,
141 | 'message': f'Error: {str(e)} ❌'
142 | }), 500
143 |
144 | @app.route('/sp/search', methods=['GET'])
145 | def search_tracks():
146 | """Search tracks by query."""
147 | query = request.args.get('q')
148 | if not query:
149 | return jsonify({
150 | 'status': False,
151 | 'message': 'Search query required ❌',
152 | 'example': '/sp/search?q=Tomake+Chai'
153 | }), 400
154 |
155 | try:
156 | tracks = search_spotify(query)
157 | if not tracks:
158 | return jsonify({
159 | 'status': False,
160 | 'message': 'No tracks found ❌'
161 | }), 404
162 |
163 | results = []
164 | for name, artist, track_id in tracks:
165 | track_url = f"https://open.spotify.com/track/{track_id}"
166 | metadata = get_track_metadata(track_id)
167 | if not metadata:
168 | continue
169 |
170 | download_url = get_spotmate_download(track_url)
171 | results.append({
172 | 'title': name,
173 | 'artist': artist,
174 | 'track_id': track_id,
175 | 'track_url': track_url,
176 | 'download_url': download_url if download_url else None,
177 | 'album': metadata['album'],
178 | 'release_date': metadata['release_date'],
179 | 'duration': metadata['duration'],
180 | 'isrc': metadata['isrc'],
181 | 'cover_art': metadata['cover_art'],
182 | 'credit': 'Downloaded By @TheSmartDev And API Developer @TheSmartDev Organization github.com/TheSmartDevs' if download_url else ''
183 | })
184 |
185 | return jsonify({
186 | 'status': True,
187 | 'results': results
188 | })
189 |
190 | except Exception as e:
191 | return jsonify({
192 | 'status': False,
193 | 'message': f'Error: {str(e)} ❌'
194 | }), 500
195 |
196 | if __name__ == '__main__':
197 | app.run(host='0.0.0.0', port=5000)
198 |
--------------------------------------------------------------------------------
/templates/status.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | TheSmartDev's Spotify API
7 |
8 |
9 |
10 |
11 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | TheSmartDev's Spotify API
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Welcome to TheSmartDev's Spotify API ! 🚀 This API allows you to download Spotify tracks or search for songs with ease. Explore the endpoints below to get started.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
GET /sp/dl
77 |
78 |
Description: Retrieve a download link for a Spotify track using its URL.
79 |
80 |
Parameters:
81 |
82 | url: A valid Spotify track URL (required)
83 |
84 |
85 |
86 |
Example:
87 |
/sp/dl?url=https://open.spotify.com/track/2QbFklmXzH2C8dS8U8U1PS
88 |
89 |
90 |
Response Format:
91 |
92 | {
93 | "status": boolean,
94 | "title": string,
95 | "artist": string,
96 | "track_id": string,
97 | "track_url": string,
98 | "download_url": string,
99 | "album": string,
100 | "release_date": string,
101 | "duration": string,
102 | "isrc": string,
103 | "credit": string
104 | }
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
GET /sp/search
116 |
117 |
Description: Search for tracks on Spotify (returns up to 5 results).
118 |
119 |
Parameters:
120 |
121 | q: Search query for the track (required)
122 |
123 |
124 |
125 |
Example:
126 |
/sp/search?q=Tomake+Chai
127 |
128 |
129 |
Response Format:
130 |
131 | {
132 | "status": boolean,
133 | "results": [
134 | {
135 | "title": string,
136 | "artist": string,
137 | "track_id": string,
138 | "track_url": string,
139 | "download_url": string or null,
140 | "album": string,
141 | "release_date": string,
142 | "duration": string,
143 | "isrc": string,
144 | "credit": string
145 | }
146 | ]
147 | }
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
Developed By @TheSmartDev | API Developer
158 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------