Spaces:
Sleeping
Sleeping
Update README.md for deployment instructions and enhance project structure
Browse files- README.md +147 -25
- pyproject.toml +96 -0
- requirements.txt +2 -2
README.md
CHANGED
|
@@ -1,46 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
---
|
| 10 |
|
| 11 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
-
|
| 14 |
|
| 15 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
| Method | Endpoint | Description |
|
| 18 |
|--------|----------|-------------|
|
| 19 |
| GET | `/api/health` | Health check |
|
| 20 |
-
| GET | `/docs` | Swagger UI |
|
| 21 |
| POST | `/api/youtube/analyze` | Analyze YouTube video |
|
| 22 |
| POST | `/api/data/augment/audio` | Audio augmentation |
|
| 23 |
| POST | `/api/data/augment/image` | Image augmentation |
|
| 24 |
|
| 25 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
```bash
|
| 28 |
-
#
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
-
#
|
| 32 |
-
|
| 33 |
```
|
| 34 |
|
| 35 |
-
|
| 36 |
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
-
|
| 41 |
-
-
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
##
|
| 44 |
|
| 45 |
-
-
|
| 46 |
-
-
|
|
|
|
|
|
|
|
|
| 1 |
+
# CrownCode Backend
|
| 2 |
+
|
| 3 |
+
YouTube-first backend service for AI music detection workflows.
|
| 4 |
+
|
| 5 |
---
|
| 6 |
+
|
| 7 |
+
## Hugging Face Spaces Deployment
|
| 8 |
+
|
| 9 |
+
### Quick Deploy
|
| 10 |
+
|
| 11 |
+
1. **Hugging Face Space Olustur**
|
| 12 |
+
- [huggingface.co/new-space](https://huggingface.co/new-space) adresine git
|
| 13 |
+
- Space Name: `crowncode-backend`
|
| 14 |
+
- SDK: **Docker** (onemli!)
|
| 15 |
+
- Hardware: **CPU Basic (Free)**
|
| 16 |
+
|
| 17 |
+
2. **Dosyalari Yukle**
|
| 18 |
+
- Space sayfasinda "Files" sekmesine git
|
| 19 |
+
- "Add file" > "Upload files" tikla
|
| 20 |
+
- Su dosyalari yukle:
|
| 21 |
+
- `Dockerfile`
|
| 22 |
+
- `requirements.txt`
|
| 23 |
+
- `app/` klasoru (tum icerigi ile)
|
| 24 |
+
|
| 25 |
+
3. **Deploy**
|
| 26 |
+
- "Commit changes" butonuna bas
|
| 27 |
+
- 3-5 dakika icinde build tamamlanir
|
| 28 |
+
|
| 29 |
+
### URL Format
|
| 30 |
+
```
|
| 31 |
+
https://KULLANICI_ADI-crowncode-backend.hf.space
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
### Test Endpoints
|
| 35 |
+
```
|
| 36 |
+
GET /api/health -> {"status": "healthy"}
|
| 37 |
+
GET /docs -> Swagger UI
|
| 38 |
+
POST /api/youtube/analyze
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
---
|
| 42 |
|
| 43 |
+
## What This Service Does
|
| 44 |
+
|
| 45 |
+
- Accepts a YouTube URL
|
| 46 |
+
- Downloads audio via `yt-dlp`
|
| 47 |
+
- Optionally forwards the audio to external services:
|
| 48 |
+
- Music-AIDetector (`/predict`)
|
| 49 |
+
- Ses-Analizi (`/analyze`)
|
| 50 |
+
- Produces a deterministic preview decision if no model is available
|
| 51 |
|
| 52 |
+
---
|
| 53 |
|
| 54 |
+
## Structure
|
| 55 |
+
|
| 56 |
+
```
|
| 57 |
+
backend/
|
| 58 |
+
Dockerfile <- Hugging Face Spaces icin
|
| 59 |
+
requirements.txt <- CPU-compatible dependencies
|
| 60 |
+
app/
|
| 61 |
+
main.py
|
| 62 |
+
schemas.py
|
| 63 |
+
routes/
|
| 64 |
+
health.py
|
| 65 |
+
youtube.py
|
| 66 |
+
data_processing.py
|
| 67 |
+
services/
|
| 68 |
+
external_clients.py
|
| 69 |
+
url_parser.py
|
| 70 |
+
youtube_analysis.py
|
| 71 |
+
youtube_downloader.py
|
| 72 |
+
audio_processor.py
|
| 73 |
+
validation.py
|
| 74 |
+
logging_config.py
|
| 75 |
+
preview_model.py
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## API Endpoints
|
| 81 |
|
| 82 |
| Method | Endpoint | Description |
|
| 83 |
|--------|----------|-------------|
|
| 84 |
| GET | `/api/health` | Health check |
|
|
|
|
| 85 |
| POST | `/api/youtube/analyze` | Analyze YouTube video |
|
| 86 |
| POST | `/api/data/augment/audio` | Audio augmentation |
|
| 87 |
| POST | `/api/data/augment/image` | Image augmentation |
|
| 88 |
|
| 89 |
+
### POST /api/youtube/analyze
|
| 90 |
+
|
| 91 |
+
Request body:
|
| 92 |
+
```json
|
| 93 |
+
{
|
| 94 |
+
"url": "https://www.youtube.com/watch?v=VIDEO_ID",
|
| 95 |
+
"include_raw": false
|
| 96 |
+
}
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
Response:
|
| 100 |
+
```json
|
| 101 |
+
{
|
| 102 |
+
"summary": {
|
| 103 |
+
"decision": "ai_generated",
|
| 104 |
+
"confidence": 0.85,
|
| 105 |
+
"source": "preview_model"
|
| 106 |
+
},
|
| 107 |
+
"music_ai": { ... },
|
| 108 |
+
"ses_analizi": { ... },
|
| 109 |
+
"warnings": [],
|
| 110 |
+
"errors": []
|
| 111 |
+
}
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
---
|
| 115 |
+
|
| 116 |
+
## Environment Variables
|
| 117 |
+
|
| 118 |
+
| Variable | Default | Description |
|
| 119 |
+
|----------|---------|-------------|
|
| 120 |
+
| `CROWNCODE_CORS_ORIGINS` | `*` | Allowed CORS origins |
|
| 121 |
+
| `MUSIC_AI_API_URL` | - | Music-AIDetector service URL |
|
| 122 |
+
| `SES_ANALIZI_API_URL` | - | Ses-Analizi service URL |
|
| 123 |
+
| `CROWNCODE_API_TIMEOUT_SEC` | `30` | External service timeout |
|
| 124 |
+
| `SES_ANALIZI_THRESHOLD` | `0.5` | Authenticity score threshold |
|
| 125 |
+
| `LOG_LEVEL` | `INFO` | Logging level |
|
| 126 |
+
|
| 127 |
+
---
|
| 128 |
+
|
| 129 |
+
## Frontend Configuration
|
| 130 |
+
|
| 131 |
+
Backend deploy edildikten sonra frontend `.env` dosyasini guncelle:
|
| 132 |
+
|
| 133 |
+
```env
|
| 134 |
+
NEXT_PUBLIC_API_URL=https://kullaniciadi-crowncode-backend.hf.space
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
---
|
| 138 |
+
|
| 139 |
+
## Local Development
|
| 140 |
|
| 141 |
```bash
|
| 142 |
+
# Install dependencies
|
| 143 |
+
pip install -r requirements.txt
|
| 144 |
+
|
| 145 |
+
# Install PyTorch CPU
|
| 146 |
+
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
|
| 147 |
|
| 148 |
+
# Run server
|
| 149 |
+
uvicorn app.main:app --reload --port 8000
|
| 150 |
```
|
| 151 |
|
| 152 |
+
---
|
| 153 |
|
| 154 |
+
## Docker Local Build
|
| 155 |
+
|
| 156 |
+
```bash
|
| 157 |
+
docker build -t crowncode-backend .
|
| 158 |
+
docker run -p 7860:7860 crowncode-backend
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
---
|
| 162 |
|
| 163 |
+
## Notes
|
| 164 |
|
| 165 |
+
- `yt-dlp` requires network access and works best with `ffmpeg` installed
|
| 166 |
+
- When external services are not configured, returns preview decision
|
| 167 |
+
- Hugging Face free tier has 16GB RAM and 2 vCPU
|
| 168 |
+
- Build may take 5-10 minutes due to PyTorch installation
|
pyproject.toml
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CrownCode Backend - Linting and Formatting Configuration
|
| 2 |
+
|
| 3 |
+
[tool.black]
|
| 4 |
+
line-length = 100
|
| 5 |
+
target-version = ['py311']
|
| 6 |
+
include = '\.pyi?$'
|
| 7 |
+
extend-exclude = '''
|
| 8 |
+
/(
|
| 9 |
+
# directories
|
| 10 |
+
\.eggs
|
| 11 |
+
| \.git
|
| 12 |
+
| \.hg
|
| 13 |
+
| \.mypy_cache
|
| 14 |
+
| \.tox
|
| 15 |
+
| \.venv
|
| 16 |
+
| build
|
| 17 |
+
| dist
|
| 18 |
+
)/
|
| 19 |
+
'''
|
| 20 |
+
|
| 21 |
+
[tool.ruff]
|
| 22 |
+
line-length = 100
|
| 23 |
+
target-version = "py311"
|
| 24 |
+
select = [
|
| 25 |
+
"E", # pycodestyle errors
|
| 26 |
+
"W", # pycodestyle warnings
|
| 27 |
+
"F", # pyflakes
|
| 28 |
+
"I", # isort
|
| 29 |
+
"C", # flake8-comprehensions
|
| 30 |
+
"B", # flake8-bugbear
|
| 31 |
+
"UP", # pyupgrade
|
| 32 |
+
"N", # pep8-naming
|
| 33 |
+
"S", # bandit security
|
| 34 |
+
"A", # flake8-builtins
|
| 35 |
+
"T20", # flake8-print
|
| 36 |
+
]
|
| 37 |
+
ignore = [
|
| 38 |
+
"E501", # line too long (handled by black)
|
| 39 |
+
"B008", # do not perform function calls in argument defaults
|
| 40 |
+
"C901", # too complex
|
| 41 |
+
"S101", # use of assert
|
| 42 |
+
"T201", # print found (allowed in scripts)
|
| 43 |
+
]
|
| 44 |
+
|
| 45 |
+
[tool.ruff.per-file-ignores]
|
| 46 |
+
"__init__.py" = ["F401"] # unused imports
|
| 47 |
+
"tests/*" = ["S101"] # assert allowed in tests
|
| 48 |
+
|
| 49 |
+
[tool.mypy]
|
| 50 |
+
python_version = "3.11"
|
| 51 |
+
warn_return_any = true
|
| 52 |
+
warn_unused_configs = true
|
| 53 |
+
disallow_untyped_defs = true
|
| 54 |
+
disallow_incomplete_defs = true
|
| 55 |
+
check_untyped_defs = true
|
| 56 |
+
no_implicit_optional = true
|
| 57 |
+
warn_redundant_casts = true
|
| 58 |
+
warn_unused_ignores = true
|
| 59 |
+
warn_no_return = true
|
| 60 |
+
warn_unreachable = true
|
| 61 |
+
strict_equality = true
|
| 62 |
+
|
| 63 |
+
[[tool.mypy.overrides]]
|
| 64 |
+
module = "yt_dlp.*"
|
| 65 |
+
ignore_missing_imports = true
|
| 66 |
+
|
| 67 |
+
[[tool.mypy.overrides]]
|
| 68 |
+
module = "httpx.*"
|
| 69 |
+
ignore_missing_imports = true
|
| 70 |
+
|
| 71 |
+
[tool.pytest.ini_options]
|
| 72 |
+
minversion = "7.0"
|
| 73 |
+
addopts = "-ra -q --strict-markers --cov=app --cov-report=term-missing"
|
| 74 |
+
testpaths = [
|
| 75 |
+
"tests",
|
| 76 |
+
]
|
| 77 |
+
python_files = "test_*.py"
|
| 78 |
+
python_functions = "test_*"
|
| 79 |
+
|
| 80 |
+
[tool.coverage.run]
|
| 81 |
+
source = ["app"]
|
| 82 |
+
omit = [
|
| 83 |
+
"*/tests/*",
|
| 84 |
+
"*/test_*.py",
|
| 85 |
+
]
|
| 86 |
+
|
| 87 |
+
[tool.coverage.report]
|
| 88 |
+
exclude_lines = [
|
| 89 |
+
"pragma: no cover",
|
| 90 |
+
"def __repr__",
|
| 91 |
+
"raise AssertionError",
|
| 92 |
+
"raise NotImplementedError",
|
| 93 |
+
"if __name__ == .__main__.:",
|
| 94 |
+
"if TYPE_CHECKING:",
|
| 95 |
+
"@abstractmethod",
|
| 96 |
+
]
|
requirements.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
# === Core Framework ===
|
| 2 |
-
fastapi>=0.
|
| 3 |
-
uvicorn[standard]>=0.
|
| 4 |
pydantic>=2.5.3
|
| 5 |
python-multipart>=0.0.6
|
| 6 |
|
|
|
|
| 1 |
# === Core Framework ===
|
| 2 |
+
fastapi>=0.103.0,<0.104.0
|
| 3 |
+
uvicorn[standard]>=0.23.2,<0.24.0
|
| 4 |
pydantic>=2.5.3
|
| 5 |
python-multipart>=0.0.6
|
| 6 |
|