Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ COPY migrations ./migrations
COPY setup_scripts ./setup_scripts
COPY ml ./ml
COPY tests ./tests
COPY streamlit ./streamlit

CMD ["python", "discogs_rec_api/main.py"]
9 changes: 9 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@ Complete endpoint documentation with request/response schemas is available at:
- http://localhost:8000/redoc
- http://localhost:8000/docs


## Streamlit App
I built a mini streamlit app which can be used to get recommendations via a UI. The app is very basic and does not include many of the features available directly via the API. To start streamlit run:
```bash
docker compose up streamlit -d
```

![alt text](assets/streamlit_preview.png)

## Entity Relationship Diagram
![alt text](assets/erd.png)

Expand Down
Binary file added assets/streamlit_preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 11 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ services:
command: ["uvicorn", "discogs_rec_api.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
depends_on:
- db


streamlit:
build: .
ports:
- 8501:8501
volumes:
- ./streamlit:/app/streamlit
command: ["streamlit", "run", "streamlit/app.py", "--server.port=8501", "--server.address=0.0.0.0"]
depends_on:
- discogs_rec_api

db:
image: postgres:16-alpine
environment:
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ email_validator==2.2.0
python-multipart==0.0.20
python-dotenv==1.1.1
httpx==0.28.1
huggingface-hub==0.34.4
huggingface-hub==0.34.4
streamlit==1.51.0
58 changes: 58 additions & 0 deletions streamlit/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import streamlit as st
import re
import requests


def validate_url(url: str) -> bool:
"""Check if URL matches Discogs release pattern."""
pattern = r"https?://www\.discogs\.com/release/\d+(-[a-zA-Z0-9\-]+)?"
return bool(re.match(pattern, url))


def display_recommendations(recs: list[dict]) -> None:
"""Render recommendation links with custom styling."""
for rec in recs:
st.markdown(
f"<a href='{rec.get('url')}' class='custom-font'>{rec.get('artist_name')} - {rec.get('release_title')}</a>",
unsafe_allow_html=True,
)


def get_recomendation(url: str, n_recs: int) -> dict:
"""Fetch recommendations from API endpoint."""
try:
response = requests.post(
"http://discogs_rec_api:8000/recommend",
json={"url": url, "n_recs": n_recs},
)
response.raise_for_status()
return response.json()
except Exception as e:
print(f"Error: {e}")


def main():
st.title("Discogs Rec")

url = st.text_input(
"Enter a Discogs URL", placeholder="https://www.discogs.com/release/123456"
)

is_valid = validate_url(url)
n_recs = st.slider("Number of Recommendations", 1, 20, 5)
if url:
if not is_valid:
st.error(
"Invalid URL, please make sure it takes "
"the form https://www.discogs.com/release/<release_id>"
)

recs = get_recomendation(url=url, n_recs=n_recs)

if "recommendations" not in recs:
st.error(recs.get("detail"))

display_recommendations(recs=recs.get("recommendations"))


main()