Skip to content

Commit 35ae00a

Browse files
committed
Update README with final project features and deployment details
1 parent e2128f3 commit 35ae00a

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

.streamlit/config.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[server]
2+
headless = true
3+
port = 8501
4+
enableCORS = false

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![Tests](https://github.com/Peippo1/Style-My-Text-API/actions/workflows/test.yml/badge.svg)](https://github.com/Peippo1/Style-My-Text-API/actions/workflows/test.yml)
77

88

9-
A playful FastAPI-powered microservice that transforms input text into various fun styles like **pirate**, **sarcastic**, and more.
9+
A playful FastAPI-powered microservice that transforms input text into various fun styles like **pirate**, **sarcastic**, and more — complete with a Streamlit frontend, CI testing, and rate limiting.
1010

1111
## ✨ Features
1212

@@ -46,4 +46,12 @@ Example input:
4646
This project is open-sourced under the MIT License. See `LICENSE` for details.
4747

4848
---
49-
🧠 Built with FastAPI for fun and learning.
49+
## ✅ Final Features
50+
51+
- FastAPI backend deployed on Render: [https://style-my-text-api.onrender.com](https://style-my-text-api.onrender.com)
52+
- Streamlit frontend for user interaction
53+
- GitHub Actions CI for automated testing
54+
- Rate limiting using `slowapi` to prevent spam
55+
56+
---
57+
🧠 Built with FastAPI and Streamlit for fun, learning, and production-ready API practice.

app/main.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
from fastapi import FastAPI, Form
1+
from fastapi import FastAPI, Form, Request, Depends
2+
from slowapi import Limiter, _rate_limit_exceeded_handler
3+
from slowapi.util import get_remote_address
4+
from fastapi.responses import JSONResponse
5+
from slowapi.errors import RateLimitExceeded
26

37
app = FastAPI()
48

9+
# Create a limiter instance using IP address for client identity
10+
limiter = Limiter(key_func=get_remote_address)
11+
12+
# Register the handler for rate limit errors
13+
app.state.limiter = limiter
14+
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
15+
516
def apply_style(text: str, style: str) -> str:
617
if style == "pirate":
718
return text.replace("my", "me").replace("you", "ye").replace(".", " arrr!").capitalize()
@@ -22,6 +33,11 @@ def apply_style(text: str, style: str) -> str:
2233
return text
2334

2435
@app.post("/style")
25-
async def style_text(text: str = Form(...), style: str = Form(...)):
36+
@limiter.limit("5/minute")
37+
async def style_text(
38+
request: Request,
39+
text: str = Form(...),
40+
style: str = Form(...)
41+
):
2642
styled = apply_style(text, style)
2743
return {"styled_text": styled}

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ uvicorn==0.35.0
44
streamlit==1.47.0
55
requests==2.32.4
66
python-multipart
7+
slowapi==0.1.6
78

89
# Dev & Testing
910
pytest

tests/test_api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ def test_invalid_style_fallback():
1717
response = client.post("/style", data={"text": "test", "style": "nonexistent"})
1818
assert response.status_code == 200
1919
assert response.json()["styled_text"] == "test"
20+
2021

0 commit comments

Comments
 (0)