Commit 38dbddd2 authored by codey's avatar codey
Browse files

changes include: allow GET endpoints, redirect to codey.lol instead of...

changes include: allow GET endpoints, redirect to codey.lol instead of returning status 422, clean junk from ai endpoint, add misc endpoint, add methods to lyric_search_new.sources.cache, other misc/cleanup
parent e95ef3b0
Loading
Loading
Loading
Loading
+15 −5
Changes for base.py: 15 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ import importlib
import logging
import asyncio
from typing import Any
from fastapi import FastAPI
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from lyric_search_new.sources import redis_cache

@@ -34,7 +34,7 @@ origins = [
app.add_middleware(CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["POST"],
allow_methods=["POST", "GET", "HEAD"],
allow_headers=["*"])


@@ -49,9 +49,18 @@ Blacklisted routes
def disallow_get():
    return util.get_blocked_response()

@app.get("/{any:path}")
def disallow_get_any(var: Any = None): # pylint: disable=unused-argument
@app.get("/{path}")
def disallow_get_any(request: Request, var: Any = None): # pylint: disable=unused-argument
    path = request.path_params['path']
    if not (
        isinstance(path, str) 
            and
            path.split("/", maxsplit=1) == "widget"
        ):
        return util.get_blocked_response()
    else:
        logging.info("OK, %s",
                     path)

@app.post("/")
def disallow_base_post():
@@ -79,9 +88,10 @@ lastfm_endpoints = importlib.import_module("endpoints.lastfm").LastFM(app, util,
yt_endpoints = importlib.import_module("endpoints.yt").YT(app, util, constants, glob_state)
# Below: XC endpoint(s)
xc_endpoints = importlib.import_module("endpoints.xc").XC(app, util, constants, glob_state)

# Below: Karma endpoint(s)
karma_endpoints = importlib.import_module("endpoints.karma").Karma(app, util, constants, glob_state)
# Below: Misc endpoints
misc_endpoints = importlib.import_module("endpoints.misc").Misc(app, util, constants, glob_state)

"""
End Actionable Routes
+3 −1
Changes for endpoints/ai.py: 3 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
import logging
import traceback
import regex
import json

from aiohttp import ClientSession, ClientTimeout
from fastapi import FastAPI, Request, HTTPException, BackgroundTasks
@@ -49,7 +50,8 @@ class AI(FastAPI):
        }
        
        for endpoint, handler in self.endpoints.items():
            app.add_api_route(f"/{endpoint}/", handler, methods=["POST"])
            app.add_api_route(f"/{endpoint}/", handler, methods=["POST"] if not endpoint == "testy" else ["POST", "GET"])
            
    
    async def respond_via_webhook(self, data: ValidHookSongRequest, originalRequest: Request):
        """Respond via Webhook"""

endpoints/misc.py

0 → 100644
+77 −0
Changes for endpoints/misc.py: 77 added lines, 0 removed lines.
Original line number Diff line number Diff line
#!/usr/bin/env python3.12
# pylint: disable=bare-except, broad-exception-caught, invalid-name

import logging
import traceback
import time
from fastapi import FastAPI
import redis.asyncio as redis
from redis.commands.search.query import Query
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.field import TextField, TagField
from redis.commands.json.path import Path
from lyric_search_new.sources import private, cache as LyricsCache

class Misc(FastAPI):
    """Misc Endpoints"""
    def __init__(self, app: FastAPI, my_util, constants, glob_state):  # pylint: disable=super-init-not-called
        self.app = app
        self.util = my_util
        self.constants = constants
        self.glob_state = glob_state
        self.lyr_cache = LyricsCache.Cache()
        self.redis_client = redis.Redis(password=private.REDIS_PW)
        self.endpoints = {
            "widget/redis": self.homepage_redis_widget,
            "widget/sqlite": self.homepage_sqlite_widget,
        }
        
        for endpoint, handler in self.endpoints.items():
            app.add_api_route(f"/{endpoint}/", handler, methods=["GET"])
            
    async def homepage_redis_widget(self) -> dict:
        """
        /widget/redis/
        Homepage Widget Handler
        Args:
            None
        Returns:
            dict
        """
        
        # Measure response time w/ test lyric search
        time_start: float = time.time() # Start time for response_time
        test_lyrics_result = await self.redis_client.ft().search("@artist: test @song: test")
        time_end: float = time.time()
        # End response time test
        
        total_keys = await self.redis_client.dbsize()
        response_time: float = time_end - time_start   
        (_, ci_keys) = await self.redis_client.scan(cursor=0, match="ci_session*", count=10000000)
        num_ci_keys = len(ci_keys)
        index_info = await self.redis_client.ft().info()
        indexed_lyrics = index_info.get('num_docs')
        return {
            'responseTime': round(response_time, 7),
            'storedKeys': total_keys,
            'indexedLyrics': indexed_lyrics,
            'sessions': num_ci_keys,
        }
    
    async def homepage_sqlite_widget(self) -> dict:
        """
        /widget/sqlite/
        Homepage Widget Handler
        Args:
            None
        Returns:
            dict
        """        
        row_count = await self.lyr_cache.sqlite_rowcount()
        distinct_artists = await self.lyr_cache.sqlite_distinct("artist")
        lyrics_length = await self.lyr_cache.sqlite_lyrics_length()
        return {
            'storedRows': row_count,
            'distinctArtists': distinct_artists,
            'lyricsLength': lyrics_length,
        }
 No newline at end of file
+0 −3
Changes for lastfm_wrapper.py: 0 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -110,16 +110,13 @@ class LastFM:
                async with session.get(f"{self.api_base_url}artist.gettopalbums&artist={artist}&api_key={self.creds.get('key')}&autocorrect=1&format=json",
                                       timeout=ClientTimeout(connect=3, sock_read=8)) as request:
                    assert request.status in [200, 204]
                    # return request.text
                    data = await request.json()
                    data = data.get('topalbums').get('album')
                    # print(f"Data:\n{data}")
                    retObj = [
                        {
                            'title': item.get('name')
                        } for item in data if not(item.get('name').lower() == "(null)") and int(item.get('playcount')) >= 50
                    ]
                    # # print(f"Keys: {data[0].keys()}")
                    return retObj            
        except:
            traceback.print_exc()
+48 −2
Changes for lyric_search_new/sources/cache.py: 48 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ class Cache:
            for res in redis_results:
                (key, row) = res
                if key == matched_id:
                    logging.info("Matched row: %s", row)
                    return LyricsResult(
                        artist=row['artist'],
                        song=row['song'],
@@ -114,6 +113,53 @@ class Cache:
            await self.redis_cache.redis_store(sqlite_insert_id, lyr_result)
            
    
    async def sqlite_rowcount(self, where: Optional[str] = None, params: Optional[tuple] = None) -> int:
        """
        Get rowcount for cached_lyrics DB
        Args:
            where (Optional[str]): WHERE ext for query if needed
            params (Optional[tuple]): Parameters to query, if where is specified
        Returns:
            int: Number of rows found
        """
        async with sqlite3.connect(self.cache_db, timeout=2) as db_conn:
            db_conn.row_factory = sqlite3.Row
            query = f"SELECT count(id) AS rowcount FROM lyrics {where}".strip()
            async with await db_conn.execute(query, params) as db_cursor:
                result = await db_cursor.fetchone()
                return result['rowcount']
            
    async def sqlite_distinct(self, column: str) -> int:
        """
        Get count of distinct values for a column
        Args:
            column (str): The column to check
        Returns:
            int: Number of distinct values found
        """
        async with sqlite3.connect(self.cache_db, timeout=2) as db_conn:
            db_conn.row_factory = sqlite3.Row
            query = f"SELECT COUNT(DISTINCT {column}) as distinct_items FROM lyrics"
            async with await db_conn.execute(query) as db_cursor:
                result = await db_cursor.fetchone()
                return result['distinct_items']
            
    async def sqlite_lyrics_length(self) -> int:
        """
        Get total length of text stored for lyrics
        Args:
            None
        Returns:
            int: Total length of stored lyrics
        """
        async with sqlite3.connect(self.cache_db, timeout=2) as db_conn:
            db_conn.row_factory = sqlite3.Row
            query = "SELECT SUM(LENGTH(lyrics)) as lyrics_len FROM lyrics"
            async with await db_conn.execute(query) as db_cursor:
                result = await db_cursor.fetchone()
                return result['lyrics_len']
        
    
    async def sqlite_store(self, lyr_result: LyricsResult) -> int:
        """
        Store lyrics to SQLite Cache
@@ -188,7 +234,7 @@ class Cache:
            
            """Check Redis First"""

            logging.info("Checking redis cache for %s...",
            logging.debug("Checking redis cache for %s...",
                    f"{artist} - {song}")
            redis_result = await self.redis_cache.search(artist=artist,
                                                         song=song)
Loading