Backend-Übersicht¶
Audience: Dev
You will learn:
- Flask-Anwendungsarchitektur und Module
- API-Endpunkte und Datenfluss
- File-System-Integration und Metadaten-Verwaltung
- Backend-Services und Datenverarbeitung
Pre-requisites: - Architektur-Übersicht verstanden - Python und Flask Grundkenntnisse - Entwickler-Setup abgeschlossen
Anwendungsarchitektur¶
Flask-Application Structure¶
# app.py - Hauptanwendung
from flask import Flask, render_template, jsonify
import os
import json
app = Flask(__name__)
# Kernfunktionen:
# 1. Icon-Metadaten laden
# 2. File-System-Scanning
# 3. REST API bereitstellen
# 4. Web-Interface rendern
Evidenz: app.py:1-67
Module und Dependencies¶
# pyproject.toml
[project]
name = "repl-nix-workspace"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"flask>=3.1.1",
]
Core Dependencies: - Flask 3.1.1+: Web-Framework und Template-Engine - Python 3.11+: Runtime-Environment - JSON (stdlib): Metadata-Parsing - OS (stdlib): File-System-Operations
Evidenz: pyproject.toml:1-8
API-Endpunkte¶
1. Web-Interface Endpunkt¶
@app.route('/')
def index():
"""Main page showing icon grid"""
icons, categories = get_icon_list()
return render_template('index.html',
icons=icons,
categories=categories,
total_icons=len(icons))
Funktionalität: - Lädt komplette Icon-Liste mit Metadaten - Rendert HTML-Template mit Jinja2 - Übergibt Icon-Kategorien für Filterung
Performance: Template-Rendering + Icon-Scanning ~50-100ms
Evidenz: app.py:45-49
2. JSON API Endpunkt¶
@app.route('/api/icons')
def api_icons():
"""API endpoint to get icons as JSON"""
icons, categories = get_icon_list()
return jsonify({'icons': icons, 'categories': categories})
Response Format:
{
"icons": [
{
"name": "home",
"filename": "home.svg",
"path": "/static/icons/home.svg",
"display_name": "Home",
"category": "Navigation & Direction"
}
],
"categories": {
"Navigation & Direction": ["home.svg", "user.svg"]
}
}
Performance: JSON-Serialisierung ~10-30ms für 162 Icons
Evidenz: app.py:51-55
3. Single Icon Endpunkt¶
@app.route('/icon/<icon_name>')
def get_icon(icon_name):
"""Get individual icon details"""
icons, _ = get_icon_list()
icon = next((i for i in icons if i['name'] == icon_name), None)
if icon:
return jsonify(icon)
return jsonify({'error': 'Icon not found'}), 404
Use Cases: - Programmatischer Zugriff auf einzelne Icons - Icon-Validation vor Integration - Metadaten-Abfrage für specific Icons
Security: Input-Validation gegen verfügbare Icon-Liste
Evidenz: app.py:57-64
Datenverarbeitung¶
Icon-Metadaten Laden¶
def load_icon_categories():
"""Load icon categories from icons.json"""
try:
with open('icons.json', 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
Verhalten: - Erfolg: Lädt 20+ Kategorien mit Icon-Mappings - Fehler: Graceful fallback zu leeren Kategorien - Performance: File-read + JSON-parse ~1-5ms
Evidenz: app.py:7-13
File-System Integration¶
def get_icon_list():
"""Get list of all available icons from static/icons directory"""
icons_dir = os.path.join('static', 'icons')
if not os.path.exists(icons_dir):
return [], {}
# Create reverse mapping: filename -> category
filename_to_category = {}
for category, filenames in categories.items():
for filename in filenames:
filename_to_category[filename] = category
icons = []
for filename in os.listdir(icons_dir):
if filename.endswith('.svg'):
icon_name = filename[:-4] # Remove .svg extension
category = filename_to_category.get(filename, 'Uncategorized')
icons.append({
'name': icon_name,
'filename': filename,
'path': f'/static/icons/{filename}',
'display_name': icon_name.replace('-', ' ').title(),
'category': category
})
return sorted(icons, key=lambda x: x['name']), categories
Datenfluss:
1. Directory Scan: os.listdir('static/icons')
2. Metadata Merge: JSON-Kategorien + File-System-Realität
3. Icon Enrichment: Display-Namen und Pfade generieren
4. Sorting: Alphabetische Sortierung für UI
Performance Characteristics: - File Count: 162 SVG-Dateien - Directory Scan: ~1-5ms bei SSD - Metadata Processing: ~5-10ms - Total Time: ~10-20ms per request
Evidenz: app.py:15-43
Datenstrukturen¶
Icon Object Schema¶
{
'name': str, # 'home' (ohne .svg)
'filename': str, # 'home.svg'
'path': str, # '/static/icons/home.svg'
'display_name': str, # 'Home'
'category': str # 'Navigation & Direction'
}
Categories Schema¶
{
"Navigation & Direction": [
"arrow-up.svg",
"arrow-down.svg",
# ...
],
"UI Controls": [
"plus.svg",
"minus.svg",
# ...
]
}
Evidenz: icons.json:1-206, app.py:30-42
Services und Business Logic¶
Icon Discovery Service¶
class IconService:
"""Service for icon discovery and metadata management"""
@staticmethod
def get_all_icons():
"""Returns all icons with metadata"""
return get_icon_list()
@staticmethod
def find_icon(name):
"""Find specific icon by name"""
icons, _ = get_icon_list()
return next((i for i in icons if i['name'] == name), None)
@staticmethod
def get_categories():
"""Get all available categories"""
return load_icon_categories()
File System Service¶
class FileSystemService:
"""Service for file system operations"""
ICONS_DIR = 'static/icons'
METADATA_FILE = 'icons.json'
@classmethod
def scan_icons(cls):
"""Scan file system for available icons"""
if not os.path.exists(cls.ICONS_DIR):
return []
return [f for f in os.listdir(cls.ICONS_DIR) if f.endswith('.svg')]
@classmethod
def load_metadata(cls):
"""Load icon metadata from JSON"""
try:
with open(cls.METADATA_FILE, 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
Evidenz: app.py service logic patterns
Error Handling¶
Graceful Degradation¶
# Metadata loading mit fallback
def load_icon_categories():
try:
with open('icons.json', 'r') as f:
return json.load(f)
except FileNotFoundError:
app.logger.warning("icons.json not found, returning empty categories")
return {}
except json.JSONDecodeError:
app.logger.error("icons.json invalid JSON, returning empty categories")
return {}
# Directory scanning mit validation
def get_icon_list():
icons_dir = os.path.join('static', 'icons')
if not os.path.exists(icons_dir):
app.logger.error(f"Icons directory {icons_dir} does not exist")
return [], {}
HTTP Error Responses¶
# 404 für unbekannte Icons
@app.route('/icon/<icon_name>')
def get_icon(icon_name):
icon = find_icon_by_name(icon_name)
if not icon:
return jsonify({'error': 'Icon not found'}), 404
return jsonify(icon)
# 500 für System-Fehler (automatisch durch Flask)
Evidenz: app.py:57-64 error handling
Performance Optimierung¶
Caching Strategies¶
# In-Memory-Caching für Icon-Liste
from functools import lru_cache
@lru_cache(maxsize=1)
def get_cached_icon_list():
"""Cached version of icon list - invalidate on metadata changes"""
return get_icon_list()
# Cache-Invalidierung bei Updates
def invalidate_icon_cache():
get_cached_icon_list.cache_clear()
Database Migration Path¶
# Future: SQLite für größere Icon-Sammlungen
class IconRepository:
def __init__(self, db_path='icons.db'):
self.db_path = db_path
self._init_db()
def _init_db(self):
"""Initialize SQLite database for icons"""
# CREATE TABLE icons (name, filename, category, path, metadata)
pass
def get_all_icons(self):
"""Get all icons from database"""
# SELECT * FROM icons ORDER BY name
pass
Migration Trigger: >500 Icons oder Performance-Probleme bei Directory-Scanning
Evidenz: replit.md:91 (Development Considerations)
Integration Points¶
Static File Serving¶
# Flask automatisches Static-File-Serving
# /static/icons/*.svg → direkter File-Access
# Kein Backend-Processing für SVG-Delivery
# Optional: Custom static file handler
@app.route('/static/icons/<filename>')
def serve_icon(filename):
return send_from_directory('static/icons', filename,
mimetype='image/svg+xml')
Template Integration¶
# Jinja2 Template-Variables
@app.route('/')
def index():
context = {
'icons': icons,
'categories': categories,
'total_icons': len(icons),
'app_version': '1.0.0'
}
return render_template('index.html', **context)
Evidenz: app.py:45-49, templates/index.html integration
Development Tools¶
Debug Mode¶
Debug Features: - Auto-reload: Code-Änderungen triggern Neustart - Error Pages: Detaillierte Stack-Traces - Template Debugging: Jinja2-Variable-Inspection
Logging Configuration¶
import logging
# Optional: Structured logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
app.logger.setLevel(logging.INFO)
Health Checks¶
@app.route('/health')
def health_check():
"""System health check endpoint"""
try:
icons, categories = get_icon_list()
return jsonify({
'status': 'healthy',
'icon_count': len(icons),
'categories_count': len(categories),
'timestamp': time.time()
})
except Exception as e:
return jsonify({
'status': 'unhealthy',
'error': str(e)
}), 503
Evidenz: app.py:66-67 main execution
Testing Strategy¶
Unit Tests¶
import unittest
from app import load_icon_categories, get_icon_list
class TestIconService(unittest.TestCase):
def test_load_categories(self):
categories = load_icon_categories()
self.assertIsInstance(categories, dict)
self.assertGreater(len(categories), 10)
def test_icon_list_format(self):
icons, _ = get_icon_list()
if icons:
icon = icons[0]
self.assertIn('name', icon)
self.assertIn('filename', icon)
self.assertIn('category', icon)
Integration Tests¶
def test_api_endpoints():
with app.test_client() as client:
# Test main page
response = client.get('/')
assert response.status_code == 200
# Test API
response = client.get('/api/icons')
assert response.status_code == 200
data = response.get_json()
assert 'icons' in data
assert 'categories' in data
Nächste Schritte: - Frontend-Dokumentation für UI-Integration - API-Referenz für externe Nutzung - Operations-Runbook für Produktivbetrieb