LogicGoInfotechSpaces commited on
Commit
60c56d7
·
0 Parent(s):

Initial commit: Colorize API with Firebase App Check integration

Browse files
Files changed (42) hide show
  1. .dockerignore +22 -0
  2. .gitignore +28 -0
  3. .history/.dockerignore_20251111094015 +22 -0
  4. .history/.gitignore_20251111094027 +26 -0
  5. .history/DEPLOYMENT_20251111094442.md +143 -0
  6. .history/Dockerfile_20251111094013 +41 -0
  7. .history/Dockerfile_20251111094238 +42 -0
  8. .history/Dockerfile_20251111094448 +46 -0
  9. .history/Dockerfile_20251111094450 +49 -0
  10. .history/Dockerfile_20251111094456 +49 -0
  11. .history/Dockerfile_20251111094522 +49 -0
  12. .history/README_20251111094025.md +135 -0
  13. .history/README_20251111094115.md +135 -0
  14. .history/README_20251111094339.md +114 -0
  15. .history/README_20251111094352.md +114 -0
  16. .history/README_20251111094522.md +114 -0
  17. .history/README_HF_20251111094029.md +40 -0
  18. .history/SETUP_20251111094412.md +193 -0
  19. .history/app/__init___20251111094026.py +2 -0
  20. .history/app/colorize_model_20251111094002.py +154 -0
  21. .history/app/colorize_model_20251111094219.py +176 -0
  22. .history/app/colorize_model_20251111094231.py +195 -0
  23. .history/app/config_20251111094005.py +33 -0
  24. .history/app/main_20251111093950.py +265 -0
  25. .history/app/main_20251111094327.py +273 -0
  26. .history/app/main_20251111094522.py +273 -0
  27. .history/deploy_20251111094342.sh +24 -0
  28. .history/requirements_20251111094007.txt +17 -0
  29. .history/requirements_20251111094419.txt +16 -0
  30. .history/requirements_20251111094503.txt +17 -0
  31. .history/requirements_20251111094522.txt +17 -0
  32. DEPLOYMENT.md +143 -0
  33. Dockerfile +49 -0
  34. README.md +114 -0
  35. README_HF.md +40 -0
  36. SETUP.md +193 -0
  37. app/__init__.py +2 -0
  38. app/colorize_model.py +195 -0
  39. app/config.py +33 -0
  40. app/main.py +273 -0
  41. deploy.sh +24 -0
  42. requirements.txt +17 -0
.dockerignore ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .Python
6
+ env/
7
+ venv/
8
+ .venv/
9
+ *.egg-info/
10
+ dist/
11
+ build/
12
+ .git
13
+ .gitignore
14
+ *.md
15
+ .DS_Store
16
+ uploads/*
17
+ results/*
18
+ *.log
19
+ .env
20
+ .vscode
21
+ .idea
22
+
.gitignore ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ env/
7
+ venv/
8
+ ENV/
9
+ .venv/
10
+ *.egg-info/
11
+ dist/
12
+ build/
13
+ .eggs/
14
+ *.log
15
+ .env
16
+ .venv
17
+ uploads/
18
+ results/
19
+ *.jpg
20
+ *.jpeg
21
+ *.png
22
+ .vscode/
23
+ .idea/
24
+ .DS_Store
25
+ colorize-662df-firebase-adminsdk-fbsvc-e080668793.json
26
+ text-guided-image-colorization/
27
+ .history/
28
+
.history/.dockerignore_20251111094015 ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .Python
6
+ env/
7
+ venv/
8
+ .venv/
9
+ *.egg-info/
10
+ dist/
11
+ build/
12
+ .git
13
+ .gitignore
14
+ *.md
15
+ .DS_Store
16
+ uploads/*
17
+ results/*
18
+ *.log
19
+ .env
20
+ .vscode
21
+ .idea
22
+
.history/.gitignore_20251111094027 ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ env/
7
+ venv/
8
+ ENV/
9
+ .venv/
10
+ *.egg-info/
11
+ dist/
12
+ build/
13
+ .eggs/
14
+ *.log
15
+ .env
16
+ .venv
17
+ uploads/
18
+ results/
19
+ *.jpg
20
+ *.jpeg
21
+ *.png
22
+ .vscode/
23
+ .idea/
24
+ .DS_Store
25
+ colorize-662df-firebase-adminsdk-fbsvc-e080668793.json
26
+
.history/DEPLOYMENT_20251111094442.md ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Deployment Guide
2
+
3
+ ## Quick Start
4
+
5
+ ### 1. Copy Firebase Credentials
6
+
7
+ Copy your Firebase Admin SDK JSON file to the project root:
8
+ ```bash
9
+ # Windows
10
+ copy C:\Colorize\colorize-662df-firebase-adminsdk-fbsvc-e080668793.json .
11
+
12
+ # Linux/Mac
13
+ cp /path/to/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json .
14
+ ```
15
+
16
+ **Important**: For Hugging Face Spaces, you should add this as a secret instead of committing it to the repository.
17
+
18
+ ### 2. Deploy to Hugging Face Spaces
19
+
20
+ ```bash
21
+ # Initialize git repository
22
+ git init
23
+ git add .
24
+ git commit -m "Deploy Colorize API"
25
+
26
+ # Add Hugging Face remote
27
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
28
+
29
+ # Push to Hugging Face
30
+ git push -u origin main
31
+ ```
32
+
33
+ ### 3. Configure Hugging Face Space Secrets
34
+
35
+ 1. Go to your Space: https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
36
+ 2. Navigate to Settings → Secrets
37
+ 3. Add a new secret:
38
+ - **Name**: `FIREBASE_CREDENTIALS`
39
+ - **Value**: Paste the entire contents of your Firebase Admin SDK JSON file
40
+
41
+ ### 4. Update Dockerfile for Secrets (Optional)
42
+
43
+ If you want to use the secret, you can modify the Dockerfile to create the file from the secret:
44
+
45
+ ```dockerfile
46
+ # Add this before the CMD line
47
+ RUN if [ -n "$FIREBASE_CREDENTIALS" ]; then \
48
+ echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; \
49
+ fi
50
+ ```
51
+
52
+ ## Testing Locally
53
+
54
+ ### Run with Docker
55
+
56
+ ```bash
57
+ # Build image
58
+ docker build -t colorize-api .
59
+
60
+ # Run container
61
+ docker run -p 7860:7860 \
62
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
63
+ colorize-api
64
+ ```
65
+
66
+ ### Run without Docker
67
+
68
+ ```bash
69
+ # Install dependencies
70
+ pip install -r requirements.txt
71
+
72
+ # Run API
73
+ uvicorn app.main:app --host 0.0.0.0 --port 7860
74
+ ```
75
+
76
+ ## API Endpoints
77
+
78
+ Once deployed, your API will be available at:
79
+ - `https://logicgoinfotechspaces-colorize.hf.space/health` - Health check
80
+ - `https://logicgoinfotechspaces-colorize.hf.space/colorize` - Colorize image
81
+ - `https://logicgoinfotechspaces-colorize.hf.space/upload` - Upload image
82
+
83
+ ## Frontend Integration Example
84
+
85
+ ```javascript
86
+ // Initialize Firebase
87
+ import { initializeApp } from "firebase/app";
88
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
89
+
90
+ const firebaseConfig = {
91
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
92
+ authDomain: "colorize-662df.firebaseapp.com",
93
+ projectId: "colorize-662df",
94
+ storageBucket: "colorize-662df.firebasestorage.app",
95
+ messagingSenderId: "69166278311",
96
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
97
+ measurementId: "G-58CC2J8XKX"
98
+ };
99
+
100
+ const app = initializeApp(firebaseConfig);
101
+ const appCheck = initializeAppCheck(app, {
102
+ provider: new ReCaptchaEnterpriseProvider('YOUR_RECAPTCHA_SITE_KEY'),
103
+ isTokenAutoRefreshEnabled: true
104
+ });
105
+
106
+ // Colorize image function
107
+ async function colorizeImage(file) {
108
+ const { getToken } = await import('firebase/app-check');
109
+ const token = await getToken(appCheck);
110
+
111
+ const formData = new FormData();
112
+ formData.append('file', file);
113
+
114
+ const response = await fetch('https://logicgoinfotechspaces-colorize.hf.space/colorize', {
115
+ method: 'POST',
116
+ headers: {
117
+ 'X-Firebase-AppCheck': token.token
118
+ },
119
+ body: formData
120
+ });
121
+
122
+ return await response.json();
123
+ }
124
+ ```
125
+
126
+ ## Troubleshooting
127
+
128
+ ### Model Not Loading
129
+
130
+ - Check Hugging Face Space logs
131
+ - Verify model ID: `rsortino/ColorizeNet`
132
+ - Ensure sufficient disk space (models can be large)
133
+
134
+ ### Firebase App Check Failing
135
+
136
+ - Verify credentials are correctly set as a secret
137
+ - Check that App Check is enabled in Firebase Console
138
+ - Ensure reCAPTCHA Enterprise is set up
139
+
140
+ ### Port Issues
141
+
142
+ Hugging Face Spaces automatically handles port 7860. The Dockerfile is configured for this.
143
+
.history/Dockerfile_20251111094013 ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ && rm -rf /var/lib/apt/lists/*
15
+
16
+ # Copy requirements first for better caching
17
+ COPY requirements.txt .
18
+
19
+ # Install Python dependencies
20
+ RUN pip install --no-cache-dir -r requirements.txt
21
+
22
+ # Copy application code
23
+ COPY . .
24
+
25
+ # Create directories for uploads and results
26
+ RUN mkdir -p uploads results
27
+
28
+ # Expose port
29
+ EXPOSE 8000
30
+
31
+ # Set environment variables
32
+ ENV PYTHONUNBUFFERED=1
33
+ ENV BASE_URL=http://localhost:8000
34
+
35
+ # Health check
36
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
37
+ CMD python -c "import requests; requests.get('http://localhost:8000/health')" || exit 1
38
+
39
+ # Run the application
40
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
41
+
.history/Dockerfile_20251111094238 ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Expose port (Hugging Face Spaces uses port 7860)
30
+ EXPOSE 7860
31
+
32
+ # Set environment variables
33
+ ENV PYTHONUNBUFFERED=1
34
+ ENV BASE_URL=${SPACE_HOST}
35
+ ENV PORT=7860
36
+
37
+ # Health check
38
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
39
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
40
+
41
+ # Run the application
42
+ CMD uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}
.history/Dockerfile_20251111094448 ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Handle Firebase credentials from environment variable (for Hugging Face Spaces secrets)
30
+ # This allows the credentials to be passed as a secret and written to file at runtime
31
+ RUN echo '#!/bin/bash\nif [ -n "$FIREBASE_CREDENTIALS" ]; then echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; fi\nexec "$@"' > /entrypoint.sh && chmod +x /entrypoint.sh
32
+
33
+ # Expose port (Hugging Face Spaces uses port 7860)
34
+ EXPOSE 7860
35
+
36
+ # Set environment variables
37
+ ENV PYTHONUNBUFFERED=1
38
+ ENV BASE_URL=${SPACE_HOST}
39
+ ENV PORT=7860
40
+
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
44
+
45
+ # Run the application
46
+ CMD uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}
.history/Dockerfile_20251111094450 ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Handle Firebase credentials from environment variable (for Hugging Face Spaces secrets)
30
+ # This allows the credentials to be passed as a secret and written to file at runtime
31
+ RUN echo '#!/bin/bash\nif [ -n "$FIREBASE_CREDENTIALS" ]; then echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; fi\nexec "$@"' > /entrypoint.sh && chmod +x /entrypoint.sh
32
+
33
+ # Expose port (Hugging Face Spaces uses port 7860)
34
+ EXPOSE 7860
35
+
36
+ # Set environment variables
37
+ ENV PYTHONUNBUFFERED=1
38
+ ENV BASE_URL=${SPACE_HOST}
39
+ ENV PORT=7860
40
+
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
44
+
45
+ # Set entrypoint
46
+ ENTRYPOINT ["/entrypoint.sh"]
47
+
48
+ # Run the application
49
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "${PORT:-7860}"]
.history/Dockerfile_20251111094456 ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Handle Firebase credentials from environment variable (for Hugging Face Spaces secrets)
30
+ # This allows the credentials to be passed as a secret and written to file at runtime
31
+ RUN echo '#!/bin/bash\nif [ -n "$FIREBASE_CREDENTIALS" ]; then echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; fi\nexec "$@"' > /entrypoint.sh && chmod +x /entrypoint.sh
32
+
33
+ # Expose port (Hugging Face Spaces uses port 7860)
34
+ EXPOSE 7860
35
+
36
+ # Set environment variables
37
+ ENV PYTHONUNBUFFERED=1
38
+ ENV BASE_URL=${SPACE_HOST}
39
+ ENV PORT=7860
40
+
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
44
+
45
+ # Set entrypoint
46
+ ENTRYPOINT ["/entrypoint.sh"]
47
+
48
+ # Run the application (port will be set via environment variable)
49
+ CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}"]
.history/Dockerfile_20251111094522 ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Handle Firebase credentials from environment variable (for Hugging Face Spaces secrets)
30
+ # This allows the credentials to be passed as a secret and written to file at runtime
31
+ RUN echo '#!/bin/bash\nif [ -n "$FIREBASE_CREDENTIALS" ]; then echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; fi\nexec "$@"' > /entrypoint.sh && chmod +x /entrypoint.sh
32
+
33
+ # Expose port (Hugging Face Spaces uses port 7860)
34
+ EXPOSE 7860
35
+
36
+ # Set environment variables
37
+ ENV PYTHONUNBUFFERED=1
38
+ ENV BASE_URL=${SPACE_HOST}
39
+ ENV PORT=7860
40
+
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
44
+
45
+ # Set entrypoint
46
+ ENTRYPOINT ["/entrypoint.sh"]
47
+
48
+ # Run the application (port will be set via environment variable)
49
+ CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}"]
.history/README_20251111094025.md ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Colorize Image API
2
+
3
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
4
+
5
+ ## Features
6
+
7
+ - 🖼️ Image upload and colorization
8
+ - 🔒 Firebase App Check authentication
9
+ - 🐳 Docker support
10
+ - 🚀 Hugging Face Spaces deployment ready
11
+ - 📥 Download URLs for browser access
12
+
13
+ ## API Endpoints
14
+
15
+ ### Health Check
16
+ ```
17
+ GET /health
18
+ ```
19
+ Returns the health status of the API and model.
20
+
21
+ ### Upload Image
22
+ ```
23
+ POST /upload
24
+ Headers: X-Firebase-AppCheck: <token>
25
+ Body: multipart/form-data with image file
26
+ ```
27
+ Uploads an image and returns the image URL.
28
+
29
+ ### Colorize Image
30
+ ```
31
+ POST /colorize
32
+ Headers: X-Firebase-AppCheck: <token>
33
+ Body: multipart/form-data with image file
34
+ ```
35
+ Colorizes a grayscale image and returns the result URL.
36
+
37
+ ### Download Result
38
+ ```
39
+ GET /download/{file_id}
40
+ Headers: X-Firebase-AppCheck: <token>
41
+ ```
42
+ Downloads the colorized image by file ID.
43
+
44
+ ### Get Result (Public)
45
+ ```
46
+ GET /results/{filename}
47
+ ```
48
+ Public endpoint to access colorized images in browser.
49
+
50
+ ## Setup
51
+
52
+ ### Local Development
53
+
54
+ 1. Install dependencies:
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ 2. Place Firebase credentials file:
60
+ ```
61
+ colorize-662df-firebase-adminsdk-fbsvc-e080668793.json
62
+ ```
63
+
64
+ 3. Run the application:
65
+ ```bash
66
+ uvicorn app.main:app --reload
67
+ ```
68
+
69
+ ### Docker
70
+
71
+ 1. Build the image:
72
+ ```bash
73
+ docker build -t colorize-api .
74
+ ```
75
+
76
+ 2. Run the container:
77
+ ```bash
78
+ docker run -p 8000:8000 \
79
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
80
+ colorize-api
81
+ ```
82
+
83
+ ### Hugging Face Spaces
84
+
85
+ 1. Push to Hugging Face Space:
86
+ ```bash
87
+ git init
88
+ git add .
89
+ git commit -m "Initial commit"
90
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
91
+ git push -u origin main
92
+ ```
93
+
94
+ ## Environment Variables
95
+
96
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
97
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file
98
+ - `BASE_URL`: Base URL for the API (for generating download URLs)
99
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
100
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
101
+
102
+ ## Firebase App Check Setup
103
+
104
+ 1. Initialize Firebase App Check in your frontend:
105
+ ```javascript
106
+ import { initializeApp } from "firebase/app";
107
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
108
+
109
+ const app = initializeApp(firebaseConfig);
110
+ const appCheck = initializeAppCheck(app, {
111
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
112
+ isTokenAutoRefreshEnabled: true
113
+ });
114
+ ```
115
+
116
+ 2. Include the token in API requests:
117
+ ```javascript
118
+ const token = await appCheck.getToken();
119
+ fetch('/colorize', {
120
+ method: 'POST',
121
+ headers: {
122
+ 'X-Firebase-AppCheck': token.token
123
+ },
124
+ body: formData
125
+ });
126
+ ```
127
+
128
+ ## Model
129
+
130
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
131
+
132
+ ## License
133
+
134
+ MIT
135
+
.history/README_20251111094115.md ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Colorize Image API
2
+
3
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
4
+
5
+ ## Features
6
+
7
+ - 🖼️ Image upload and colorization
8
+ - 🔒 Firebase App Check authentication
9
+ - 🐳 Docker support
10
+ - 🚀 Hugging Face Spaces deployment ready
11
+ - 📥 Download URLs for browser access
12
+
13
+ ## API Endpoints
14
+
15
+ ### Health Check
16
+ ```
17
+ GET /health
18
+ ```
19
+ Returns the health status of the API and model.
20
+
21
+ ### Upload Image
22
+ ```
23
+ POST /upload
24
+ Headers: X-Firebase-AppCheck: <token>
25
+ Body: multipart/form-data with image file
26
+ ```
27
+ Uploads an image and returns the image URL.
28
+
29
+ ### Colorize Image
30
+ ```
31
+ POST /colorize
32
+ Headers: X-Firebase-AppCheck: <token>
33
+ Body: multipart/form-data with image file
34
+ ```
35
+ Colorizes a grayscale image and returns the result URL.
36
+
37
+ ### Download Result
38
+ ```
39
+ GET /download/{file_id}
40
+ Headers: X-Firebase-AppCheck: <token>
41
+ ```
42
+ Downloads the colorized image by file ID.
43
+
44
+ ### Get Result (Public)
45
+ ```
46
+ GET /results/{filename}
47
+ ```
48
+ Public endpoint to access colorized images in browser.
49
+
50
+ ## Setup
51
+
52
+ ### Local Development
53
+
54
+ 1. Install dependencies:
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ 2. Place Firebase credentials file:
60
+ ```
61
+ colorize-662df-firebase-adminsdk-fbsvc-e080668793.json
62
+ ```
63
+
64
+ 3. Run the application:
65
+ ```bash
66
+ uvicorn app.main:app --reload
67
+ ```
68
+
69
+ ### Docker
70
+
71
+ 1. Build the image:
72
+ ```bash
73
+ docker build -t colorize-api .
74
+ ```
75
+
76
+ 2. Run the container:
77
+ ```bash
78
+ docker run -p 8000:8000 \
79
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
80
+ colorize-api
81
+ ```
82
+
83
+ ### Hugging Face Spaces
84
+
85
+ 1. Push to Hugging Face Space:
86
+ ```bash
87
+ git init
88
+ git add .
89
+ git commit -m "Initial commit"
90
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
91
+ git push -u origin main
92
+ ```
93
+
94
+ ## Environment Variables
95
+
96
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
97
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file
98
+ - `BASE_URL`: Base URL for the API (for generating download URLs)
99
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
100
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
101
+
102
+ ## Firebase App Check Setup
103
+
104
+ 1. Initialize Firebase App Check in your frontend:
105
+ ```javascript
106
+ import { initializeApp } from "firebase/app";
107
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
108
+
109
+ const app = initializeApp(firebaseConfig);
110
+ const appCheck = initializeAppCheck(app, {
111
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
112
+ isTokenAutoRefreshEnabled: true
113
+ });
114
+ ```
115
+
116
+ 2. Include the token in API requests:
117
+ ```javascript
118
+ const token = await appCheck.getToken();
119
+ fetch('/colorize', {
120
+ method: 'POST',
121
+ headers: {
122
+ 'X-Firebase-AppCheck': token.token
123
+ },
124
+ body: formData
125
+ });
126
+ ```
127
+
128
+ ## Model
129
+
130
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
131
+
132
+ ## License
133
+
134
+ MIT
135
+
.history/README_20251111094339.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - 🖼️ Image upload and colorization
20
+ - 🔒 Firebase App Check authentication
21
+ - 🐳 Docker deployment
22
+ - 📥 Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ ### Health Check
27
+ ```
28
+ GET /health
29
+ ```
30
+ Returns the health status of the API and model.
31
+
32
+ ### Upload Image
33
+ ```
34
+ POST /upload
35
+ Headers: X-Firebase-AppCheck: <token>
36
+ Body: multipart/form-data with image file
37
+ ```
38
+ Uploads an image and returns the image URL.
39
+
40
+ ### Colorize Image
41
+ ```
42
+ POST /colorize
43
+ Headers: X-Firebase-AppCheck: <token>
44
+ Body: multipart/form-data with image file
45
+ ```
46
+ Colorizes a grayscale image and returns the result URL.
47
+
48
+ ### Download Result
49
+ ```
50
+ GET /download/{file_id}
51
+ Headers: X-Firebase-AppCheck: <token>
52
+ ```
53
+ Downloads the colorized image by file ID.
54
+
55
+ ### Get Result (Public)
56
+ ```
57
+ GET /results/{filename}
58
+ ```
59
+ Public endpoint to access colorized images in browser.
60
+
61
+ ## Setup
62
+
63
+ ### Environment Variables
64
+
65
+ Set these in your Hugging Face Space secrets:
66
+
67
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file (or set as secret)
68
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
69
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
70
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
71
+
72
+ ### Firebase App Check Setup
73
+
74
+ 1. Initialize Firebase App Check in your frontend:
75
+ ```javascript
76
+ import { initializeApp } from "firebase/app";
77
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
78
+
79
+ const firebaseConfig = {
80
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
81
+ authDomain: "colorize-662df.firebaseapp.com",
82
+ projectId: "colorize-662df",
83
+ storageBucket: "colorize-662df.firebasestorage.app",
84
+ messagingSenderId: "69166278311",
85
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
86
+ measurementId: "G-58CC2J8XKX"
87
+ };
88
+
89
+ const app = initializeApp(firebaseConfig);
90
+ const appCheck = initializeAppCheck(app, {
91
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
92
+ isTokenAutoRefreshEnabled: true
93
+ });
94
+ ```
95
+
96
+ 2. Include the token in API requests:
97
+ ```javascript
98
+ const token = await appCheck.getToken();
99
+ fetch('https://your-space.hf.space/colorize', {
100
+ method: 'POST',
101
+ headers: {
102
+ 'X-Firebase-AppCheck': token.token
103
+ },
104
+ body: formData
105
+ });
106
+ ```
107
+
108
+ ## Model
109
+
110
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
111
+
112
+ ## License
113
+
114
+ MIT
.history/README_20251111094352.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - 🖼️ Image upload and colorization
20
+ - 🔒 Firebase App Check authentication
21
+ - 🐳 Docker deployment
22
+ - 📥 Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ ### Health Check
27
+ ```
28
+ GET /health
29
+ ```
30
+ Returns the health status of the API and model.
31
+
32
+ ### Upload Image
33
+ ```
34
+ POST /upload
35
+ Headers: X-Firebase-AppCheck: <token>
36
+ Body: multipart/form-data with image file
37
+ ```
38
+ Uploads an image and returns the image URL.
39
+
40
+ ### Colorize Image
41
+ ```
42
+ POST /colorize
43
+ Headers: X-Firebase-AppCheck: <token>
44
+ Body: multipart/form-data with image file
45
+ ```
46
+ Colorizes a grayscale image and returns the result URL.
47
+
48
+ ### Download Result
49
+ ```
50
+ GET /download/{file_id}
51
+ Headers: X-Firebase-AppCheck: <token>
52
+ ```
53
+ Downloads the colorized image by file ID.
54
+
55
+ ### Get Result (Public)
56
+ ```
57
+ GET /results/{filename}
58
+ ```
59
+ Public endpoint to access colorized images in browser.
60
+
61
+ ## Setup
62
+
63
+ ### Environment Variables
64
+
65
+ Set these in your Hugging Face Space secrets:
66
+
67
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file (or set as secret)
68
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
69
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
70
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
71
+
72
+ ### Firebase App Check Setup
73
+
74
+ 1. Initialize Firebase App Check in your frontend:
75
+ ```javascript
76
+ import { initializeApp } from "firebase/app";
77
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
78
+
79
+ const firebaseConfig = {
80
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
81
+ authDomain: "colorize-662df.firebaseapp.com",
82
+ projectId: "colorize-662df",
83
+ storageBucket: "colorize-662df.firebasestorage.app",
84
+ messagingSenderId: "69166278311",
85
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
86
+ measurementId: "G-58CC2J8XKX"
87
+ };
88
+
89
+ const app = initializeApp(firebaseConfig);
90
+ const appCheck = initializeAppCheck(app, {
91
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
92
+ isTokenAutoRefreshEnabled: true
93
+ });
94
+ ```
95
+
96
+ 2. Include the token in API requests:
97
+ ```javascript
98
+ const token = await appCheck.getToken();
99
+ fetch('https://your-space.hf.space/colorize', {
100
+ method: 'POST',
101
+ headers: {
102
+ 'X-Firebase-AppCheck': token.token
103
+ },
104
+ body: formData
105
+ });
106
+ ```
107
+
108
+ ## Model
109
+
110
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
111
+
112
+ ## License
113
+
114
+ MIT
.history/README_20251111094522.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - 🖼️ Image upload and colorization
20
+ - 🔒 Firebase App Check authentication
21
+ - 🐳 Docker deployment
22
+ - 📥 Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ ### Health Check
27
+ ```
28
+ GET /health
29
+ ```
30
+ Returns the health status of the API and model.
31
+
32
+ ### Upload Image
33
+ ```
34
+ POST /upload
35
+ Headers: X-Firebase-AppCheck: <token>
36
+ Body: multipart/form-data with image file
37
+ ```
38
+ Uploads an image and returns the image URL.
39
+
40
+ ### Colorize Image
41
+ ```
42
+ POST /colorize
43
+ Headers: X-Firebase-AppCheck: <token>
44
+ Body: multipart/form-data with image file
45
+ ```
46
+ Colorizes a grayscale image and returns the result URL.
47
+
48
+ ### Download Result
49
+ ```
50
+ GET /download/{file_id}
51
+ Headers: X-Firebase-AppCheck: <token>
52
+ ```
53
+ Downloads the colorized image by file ID.
54
+
55
+ ### Get Result (Public)
56
+ ```
57
+ GET /results/{filename}
58
+ ```
59
+ Public endpoint to access colorized images in browser.
60
+
61
+ ## Setup
62
+
63
+ ### Environment Variables
64
+
65
+ Set these in your Hugging Face Space secrets:
66
+
67
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file (or set as secret)
68
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
69
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
70
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
71
+
72
+ ### Firebase App Check Setup
73
+
74
+ 1. Initialize Firebase App Check in your frontend:
75
+ ```javascript
76
+ import { initializeApp } from "firebase/app";
77
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
78
+
79
+ const firebaseConfig = {
80
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
81
+ authDomain: "colorize-662df.firebaseapp.com",
82
+ projectId: "colorize-662df",
83
+ storageBucket: "colorize-662df.firebasestorage.app",
84
+ messagingSenderId: "69166278311",
85
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
86
+ measurementId: "G-58CC2J8XKX"
87
+ };
88
+
89
+ const app = initializeApp(firebaseConfig);
90
+ const appCheck = initializeAppCheck(app, {
91
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
92
+ isTokenAutoRefreshEnabled: true
93
+ });
94
+ ```
95
+
96
+ 2. Include the token in API requests:
97
+ ```javascript
98
+ const token = await appCheck.getToken();
99
+ fetch('https://your-space.hf.space/colorize', {
100
+ method: 'POST',
101
+ headers: {
102
+ 'X-Firebase-AppCheck': token.token
103
+ },
104
+ body: formData
105
+ });
106
+ ```
107
+
108
+ ## Model
109
+
110
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
111
+
112
+ ## License
113
+
114
+ MIT
.history/README_HF_20251111094029.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - Image upload and colorization
20
+ - Firebase App Check authentication
21
+ - Docker deployment
22
+ - Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ - `GET /health` - Health check
27
+ - `POST /upload` - Upload image
28
+ - `POST /colorize` - Colorize image
29
+ - `GET /download/{file_id}` - Download result
30
+ - `GET /results/{filename}` - Public result access
31
+
32
+ ## Setup
33
+
34
+ The API requires Firebase credentials. Place your Firebase Admin SDK JSON file in the root directory as:
35
+ `colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
36
+
37
+ ## Model
38
+
39
+ Uses `rsortino/ColorizeNet` from Hugging Face for image colorization.
40
+
.history/SETUP_20251111094412.md ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Setup Guide for Colorize API
2
+
3
+ ## Prerequisites
4
+
5
+ 1. Python 3.10+
6
+ 2. Docker (for containerized deployment)
7
+ 3. Firebase Admin SDK credentials file
8
+ 4. Hugging Face account with access to the Colorize Space
9
+
10
+ ## Local Development Setup
11
+
12
+ ### 1. Install Dependencies
13
+
14
+ ```bash
15
+ pip install -r requirements.txt
16
+ ```
17
+
18
+ ### 2. Firebase Credentials
19
+
20
+ Copy your Firebase Admin SDK JSON file to the project root:
21
+ - Source: `C:\Colorize\colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
22
+ - Destination: `colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
23
+
24
+ Or set the path in environment variable:
25
+ ```bash
26
+ export FIREBASE_CREDENTIALS_PATH=/path/to/your/firebase-credentials.json
27
+ ```
28
+
29
+ ### 3. Run the API
30
+
31
+ ```bash
32
+ uvicorn app.main:app --reload --port 7860
33
+ ```
34
+
35
+ The API will be available at `http://localhost:7860`
36
+
37
+ ## Docker Setup
38
+
39
+ ### 1. Build the Docker Image
40
+
41
+ ```bash
42
+ docker build -t colorize-api .
43
+ ```
44
+
45
+ ### 2. Run the Container
46
+
47
+ ```bash
48
+ docker run -p 7860:7860 \
49
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
50
+ -e BASE_URL=http://localhost:7860 \
51
+ colorize-api
52
+ ```
53
+
54
+ ## Hugging Face Spaces Deployment
55
+
56
+ ### 1. Prepare Your Repository
57
+
58
+ ```bash
59
+ # Initialize git repository
60
+ git init
61
+ git add .
62
+ git commit -m "Initial commit: Colorize API with Firebase App Check"
63
+ ```
64
+
65
+ ### 2. Set Up Hugging Face Space
66
+
67
+ 1. Go to https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
68
+ 2. If the space doesn't exist, create a new Docker space
69
+
70
+ ### 3. Add Firebase Credentials as Secret
71
+
72
+ In Hugging Face Space settings:
73
+ 1. Go to Settings → Secrets
74
+ 2. Add a new secret:
75
+ - Name: `FIREBASE_CREDENTIALS`
76
+ - Value: Contents of your Firebase Admin SDK JSON file
77
+
78
+ ### 4. Update Dockerfile for Secrets (if needed)
79
+
80
+ The Dockerfile will automatically use the credentials file if it exists. For Hugging Face Spaces, you may need to create the file from secrets:
81
+
82
+ ```dockerfile
83
+ # Add this to Dockerfile if using HF secrets
84
+ RUN echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json || true
85
+ ```
86
+
87
+ ### 5. Push to Hugging Face
88
+
89
+ ```bash
90
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
91
+ git push -u origin main
92
+ ```
93
+
94
+ ## Testing the API
95
+
96
+ ### Health Check
97
+
98
+ ```bash
99
+ curl http://localhost:7860/health
100
+ ```
101
+
102
+ ### Upload Image (with App Check token)
103
+
104
+ ```bash
105
+ curl -X POST http://localhost:7860/upload \
106
+ -H "X-Firebase-AppCheck: YOUR_APP_CHECK_TOKEN" \
107
+ -F "file=@path/to/image.jpg"
108
+ ```
109
+
110
+ ### Colorize Image (with App Check token)
111
+
112
+ ```bash
113
+ curl -X POST http://localhost:7860/colorize \
114
+ -H "X-Firebase-AppCheck: YOUR_APP_CHECK_TOKEN" \
115
+ -F "file=@path/to/grayscale_image.jpg"
116
+ ```
117
+
118
+ ## Frontend Integration
119
+
120
+ ### Initialize Firebase App Check
121
+
122
+ ```javascript
123
+ import { initializeApp } from "firebase/app";
124
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
125
+
126
+ const firebaseConfig = {
127
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
128
+ authDomain: "colorize-662df.firebaseapp.com",
129
+ projectId: "colorize-662df",
130
+ storageBucket: "colorize-662df.firebasestorage.app",
131
+ messagingSenderId: "69166278311",
132
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
133
+ measurementId: "G-58CC2J8XKX"
134
+ };
135
+
136
+ const app = initializeApp(firebaseConfig);
137
+
138
+ // Initialize App Check
139
+ const appCheck = initializeAppCheck(app, {
140
+ provider: new ReCaptchaEnterpriseProvider('YOUR_RECAPTCHA_SITE_KEY'),
141
+ isTokenAutoRefreshEnabled: true
142
+ });
143
+
144
+ // Get token and make API call
145
+ async function colorizeImage(imageFile) {
146
+ const token = await appCheck.getToken();
147
+
148
+ const formData = new FormData();
149
+ formData.append('file', imageFile);
150
+
151
+ const response = await fetch('https://your-space.hf.space/colorize', {
152
+ method: 'POST',
153
+ headers: {
154
+ 'X-Firebase-AppCheck': token.token
155
+ },
156
+ body: formData
157
+ });
158
+
159
+ const result = await response.json();
160
+ console.log('Colorized image URL:', result.download_url);
161
+ return result;
162
+ }
163
+ ```
164
+
165
+ ## Troubleshooting
166
+
167
+ ### Model Loading Issues
168
+
169
+ If the ColorizeNet model fails to load:
170
+ 1. Check your internet connection (model downloads from Hugging Face)
171
+ 2. Verify you have sufficient disk space
172
+ 3. Check logs for specific error messages
173
+
174
+ ### Firebase App Check Issues
175
+
176
+ If App Check verification fails:
177
+ 1. Verify your Firebase credentials file is correct
178
+ 2. Check that App Check is enabled in Firebase Console
179
+ 3. Ensure the token is being sent in the `X-Firebase-AppCheck` header
180
+
181
+ ### Port Issues
182
+
183
+ Hugging Face Spaces uses port 7860 by default. Make sure your Dockerfile exposes this port.
184
+
185
+ ## Environment Variables
186
+
187
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase Admin SDK JSON file
188
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (true/false)
189
+ - `BASE_URL`: Base URL for generating download URLs
190
+ - `PORT`: Port to run the API on (default: 7860)
191
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
192
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
193
+
.history/app/__init___20251111094026.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # Colorize API Package
2
+
.history/app/colorize_model_20251111094002.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ColorizeNet model wrapper for image colorization
3
+ """
4
+ import logging
5
+ import torch
6
+ import numpy as np
7
+ from PIL import Image
8
+ import cv2
9
+ from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
10
+ from diffusers.utils import load_image
11
+ from transformers import pipeline
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class ColorizeModel:
16
+ """Wrapper for ColorizeNet model"""
17
+
18
+ def __init__(self, model_id: str = "rsortino/ColorizeNet"):
19
+ """
20
+ Initialize the ColorizeNet model
21
+
22
+ Args:
23
+ model_id: Hugging Face model ID for ColorizeNet
24
+ """
25
+ self.model_id = model_id
26
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
27
+ logger.info("Using device: %s", self.device)
28
+
29
+ try:
30
+ # Load ControlNet model
31
+ self.controlnet = ControlNetModel.from_pretrained(
32
+ model_id,
33
+ torch_dtype=torch.float16 if self.device == "cuda" else torch.float32
34
+ )
35
+
36
+ # Load Stable Diffusion pipeline with ControlNet
37
+ self.pipe = StableDiffusionControlNetPipeline.from_pretrained(
38
+ "runwayml/stable-diffusion-v1-5",
39
+ controlnet=self.controlnet,
40
+ torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
41
+ safety_checker=None,
42
+ requires_safety_checker=False
43
+ )
44
+
45
+ self.pipe.to(self.device)
46
+
47
+ # Enable memory efficient attention if available
48
+ if hasattr(self.pipe, "enable_xformers_memory_efficient_attention"):
49
+ try:
50
+ self.pipe.enable_xformers_memory_efficient_attention()
51
+ except:
52
+ pass
53
+
54
+ logger.info("ColorizeNet model loaded successfully")
55
+ except Exception as e:
56
+ logger.error("Error loading ColorizeNet model: %s", str(e))
57
+ # Fallback: try alternative loading method
58
+ try:
59
+ self.pipe = pipeline(
60
+ "image-to-image",
61
+ model=model_id,
62
+ device=0 if self.device == "cuda" else -1
63
+ )
64
+ logger.info("ColorizeNet model loaded using pipeline")
65
+ except Exception as e2:
66
+ logger.error("Failed to load model with pipeline: %s", str(e2))
67
+ raise
68
+
69
+ def preprocess_image(self, image: Image.Image) -> Image.Image:
70
+ """
71
+ Preprocess image for colorization
72
+
73
+ Args:
74
+ image: PIL Image
75
+
76
+ Returns:
77
+ Preprocessed PIL Image
78
+ """
79
+ # Convert to grayscale if needed
80
+ if image.mode != "L":
81
+ # Convert to grayscale
82
+ image = image.convert("L")
83
+
84
+ # Convert back to RGB (grayscale image with 3 channels)
85
+ image = image.convert("RGB")
86
+
87
+ # Resize to standard size (512x512 for SD models)
88
+ image = image.resize((512, 512), Image.Resampling.LANCZOS)
89
+
90
+ return image
91
+
92
+ def colorize(self, image: Image.Image, num_inference_steps: int = 20) -> Image.Image:
93
+ """
94
+ Colorize a grayscale image
95
+
96
+ Args:
97
+ image: PIL Image (grayscale or color)
98
+ num_inference_steps: Number of inference steps
99
+
100
+ Returns:
101
+ Colorized PIL Image
102
+ """
103
+ try:
104
+ # Preprocess image
105
+ control_image = self.preprocess_image(image)
106
+ original_size = image.size
107
+
108
+ # Prepare prompt for colorization
109
+ prompt = "colorize this black and white image, high quality, detailed, vibrant colors"
110
+ negative_prompt = "black and white, grayscale, monochrome, low quality, blurry"
111
+
112
+ # Generate colorized image
113
+ if hasattr(self.pipe, "__call__"):
114
+ # Use ControlNet pipeline
115
+ result = self.pipe(
116
+ prompt=prompt,
117
+ image=control_image,
118
+ negative_prompt=negative_prompt,
119
+ num_inference_steps=num_inference_steps,
120
+ guidance_scale=7.5,
121
+ controlnet_conditioning_scale=1.0
122
+ )
123
+
124
+ if isinstance(result, dict) and "images" in result:
125
+ colorized = result["images"][0]
126
+ elif isinstance(result, list) and len(result) > 0:
127
+ colorized = result[0]
128
+ else:
129
+ colorized = result
130
+ else:
131
+ # Use pipeline directly
132
+ colorized = self.pipe(
133
+ control_image,
134
+ prompt=prompt,
135
+ num_inference_steps=num_inference_steps
136
+ )
137
+
138
+ # Ensure we have a PIL Image
139
+ if not isinstance(colorized, Image.Image):
140
+ if isinstance(colorized, np.ndarray):
141
+ colorized = Image.fromarray(colorized)
142
+ else:
143
+ raise ValueError("Unexpected output type from model")
144
+
145
+ # Resize back to original size
146
+ if original_size != (512, 512):
147
+ colorized = colorized.resize(original_size, Image.Resampling.LANCZOS)
148
+
149
+ return colorized
150
+
151
+ except Exception as e:
152
+ logger.error("Error during colorization: %s", str(e))
153
+ raise
154
+
.history/app/colorize_model_20251111094219.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ColorizeNet model wrapper for image colorization
3
+ """
4
+ import logging
5
+ import torch
6
+ import numpy as np
7
+ from PIL import Image
8
+ import cv2
9
+ from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, StableDiffusionXLControlNetPipeline
10
+ from diffusers.utils import load_image
11
+ from transformers import pipeline
12
+ from huggingface_hub import hf_hub_download
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ class ColorizeModel:
17
+ """Wrapper for ColorizeNet model"""
18
+
19
+ def __init__(self, model_id: str = "rsortino/ColorizeNet"):
20
+ """
21
+ Initialize the ColorizeNet model
22
+
23
+ Args:
24
+ model_id: Hugging Face model ID for ColorizeNet
25
+ """
26
+ self.model_id = model_id
27
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
28
+ logger.info("Using device: %s", self.device)
29
+ self.dtype = torch.float16 if self.device == "cuda" else torch.float32
30
+
31
+ try:
32
+ # Try loading as ControlNet with Stable Diffusion
33
+ logger.info("Attempting to load ColorizeNet as ControlNet...")
34
+ try:
35
+ # Load ControlNet model
36
+ self.controlnet = ControlNetModel.from_pretrained(
37
+ model_id,
38
+ torch_dtype=self.dtype
39
+ )
40
+
41
+ # Try SDXL first, fallback to SD 1.5
42
+ try:
43
+ self.pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
44
+ "stabilityai/stable-diffusion-xl-base-1.0",
45
+ controlnet=self.controlnet,
46
+ torch_dtype=self.dtype,
47
+ safety_checker=None,
48
+ requires_safety_checker=False
49
+ )
50
+ logger.info("Loaded with SDXL base model")
51
+ except:
52
+ self.pipe = StableDiffusionControlNetPipeline.from_pretrained(
53
+ "runwayml/stable-diffusion-v1-5",
54
+ controlnet=self.controlnet,
55
+ torch_dtype=self.dtype,
56
+ safety_checker=None,
57
+ requires_safety_checker=False
58
+ )
59
+ logger.info("Loaded with SD 1.5 base model")
60
+
61
+ self.pipe.to(self.device)
62
+
63
+ # Enable memory efficient attention if available
64
+ if hasattr(self.pipe, "enable_xformers_memory_efficient_attention"):
65
+ try:
66
+ self.pipe.enable_xformers_memory_efficient_attention()
67
+ logger.info("XFormers memory efficient attention enabled")
68
+ except Exception as e:
69
+ logger.warning("Could not enable XFormers: %s", str(e))
70
+
71
+ logger.info("ColorizeNet model loaded successfully as ControlNet")
72
+ self.model_type = "controlnet"
73
+
74
+ except Exception as e:
75
+ logger.warning("Failed to load as ControlNet: %s", str(e))
76
+ # Fallback: try as image-to-image pipeline
77
+ logger.info("Trying to load as image-to-image pipeline...")
78
+ self.pipe = pipeline(
79
+ "image-to-image",
80
+ model=model_id,
81
+ device=0 if self.device == "cuda" else -1,
82
+ torch_dtype=self.dtype
83
+ )
84
+ logger.info("ColorizeNet model loaded using image-to-image pipeline")
85
+ self.model_type = "pipeline"
86
+
87
+ except Exception as e:
88
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
89
+ raise RuntimeError(f"Could not load ColorizeNet model: {str(e)}")
90
+
91
+ def preprocess_image(self, image: Image.Image) -> Image.Image:
92
+ """
93
+ Preprocess image for colorization
94
+
95
+ Args:
96
+ image: PIL Image
97
+
98
+ Returns:
99
+ Preprocessed PIL Image
100
+ """
101
+ # Convert to grayscale if needed
102
+ if image.mode != "L":
103
+ # Convert to grayscale
104
+ image = image.convert("L")
105
+
106
+ # Convert back to RGB (grayscale image with 3 channels)
107
+ image = image.convert("RGB")
108
+
109
+ # Resize to standard size (512x512 for SD models)
110
+ image = image.resize((512, 512), Image.Resampling.LANCZOS)
111
+
112
+ return image
113
+
114
+ def colorize(self, image: Image.Image, num_inference_steps: int = 20) -> Image.Image:
115
+ """
116
+ Colorize a grayscale image
117
+
118
+ Args:
119
+ image: PIL Image (grayscale or color)
120
+ num_inference_steps: Number of inference steps
121
+
122
+ Returns:
123
+ Colorized PIL Image
124
+ """
125
+ try:
126
+ # Preprocess image
127
+ control_image = self.preprocess_image(image)
128
+ original_size = image.size
129
+
130
+ # Prepare prompt for colorization
131
+ prompt = "colorize this black and white image, high quality, detailed, vibrant colors"
132
+ negative_prompt = "black and white, grayscale, monochrome, low quality, blurry"
133
+
134
+ # Generate colorized image
135
+ if hasattr(self.pipe, "__call__"):
136
+ # Use ControlNet pipeline
137
+ result = self.pipe(
138
+ prompt=prompt,
139
+ image=control_image,
140
+ negative_prompt=negative_prompt,
141
+ num_inference_steps=num_inference_steps,
142
+ guidance_scale=7.5,
143
+ controlnet_conditioning_scale=1.0
144
+ )
145
+
146
+ if isinstance(result, dict) and "images" in result:
147
+ colorized = result["images"][0]
148
+ elif isinstance(result, list) and len(result) > 0:
149
+ colorized = result[0]
150
+ else:
151
+ colorized = result
152
+ else:
153
+ # Use pipeline directly
154
+ colorized = self.pipe(
155
+ control_image,
156
+ prompt=prompt,
157
+ num_inference_steps=num_inference_steps
158
+ )
159
+
160
+ # Ensure we have a PIL Image
161
+ if not isinstance(colorized, Image.Image):
162
+ if isinstance(colorized, np.ndarray):
163
+ colorized = Image.fromarray(colorized)
164
+ else:
165
+ raise ValueError("Unexpected output type from model")
166
+
167
+ # Resize back to original size
168
+ if original_size != (512, 512):
169
+ colorized = colorized.resize(original_size, Image.Resampling.LANCZOS)
170
+
171
+ return colorized
172
+
173
+ except Exception as e:
174
+ logger.error("Error during colorization: %s", str(e))
175
+ raise
176
+
.history/app/colorize_model_20251111094231.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ColorizeNet model wrapper for image colorization
3
+ """
4
+ import logging
5
+ import torch
6
+ import numpy as np
7
+ from PIL import Image
8
+ import cv2
9
+ from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, StableDiffusionXLControlNetPipeline
10
+ from diffusers.utils import load_image
11
+ from transformers import pipeline
12
+ from huggingface_hub import hf_hub_download
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ class ColorizeModel:
17
+ """Wrapper for ColorizeNet model"""
18
+
19
+ def __init__(self, model_id: str = "rsortino/ColorizeNet"):
20
+ """
21
+ Initialize the ColorizeNet model
22
+
23
+ Args:
24
+ model_id: Hugging Face model ID for ColorizeNet
25
+ """
26
+ self.model_id = model_id
27
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
28
+ logger.info("Using device: %s", self.device)
29
+ self.dtype = torch.float16 if self.device == "cuda" else torch.float32
30
+
31
+ try:
32
+ # Try loading as ControlNet with Stable Diffusion
33
+ logger.info("Attempting to load ColorizeNet as ControlNet...")
34
+ try:
35
+ # Load ControlNet model
36
+ self.controlnet = ControlNetModel.from_pretrained(
37
+ model_id,
38
+ torch_dtype=self.dtype
39
+ )
40
+
41
+ # Try SDXL first, fallback to SD 1.5
42
+ try:
43
+ self.pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
44
+ "stabilityai/stable-diffusion-xl-base-1.0",
45
+ controlnet=self.controlnet,
46
+ torch_dtype=self.dtype,
47
+ safety_checker=None,
48
+ requires_safety_checker=False
49
+ )
50
+ logger.info("Loaded with SDXL base model")
51
+ except:
52
+ self.pipe = StableDiffusionControlNetPipeline.from_pretrained(
53
+ "runwayml/stable-diffusion-v1-5",
54
+ controlnet=self.controlnet,
55
+ torch_dtype=self.dtype,
56
+ safety_checker=None,
57
+ requires_safety_checker=False
58
+ )
59
+ logger.info("Loaded with SD 1.5 base model")
60
+
61
+ self.pipe.to(self.device)
62
+
63
+ # Enable memory efficient attention if available
64
+ if hasattr(self.pipe, "enable_xformers_memory_efficient_attention"):
65
+ try:
66
+ self.pipe.enable_xformers_memory_efficient_attention()
67
+ logger.info("XFormers memory efficient attention enabled")
68
+ except Exception as e:
69
+ logger.warning("Could not enable XFormers: %s", str(e))
70
+
71
+ logger.info("ColorizeNet model loaded successfully as ControlNet")
72
+ self.model_type = "controlnet"
73
+
74
+ except Exception as e:
75
+ logger.warning("Failed to load as ControlNet: %s", str(e))
76
+ # Fallback: try as image-to-image pipeline
77
+ logger.info("Trying to load as image-to-image pipeline...")
78
+ self.pipe = pipeline(
79
+ "image-to-image",
80
+ model=model_id,
81
+ device=0 if self.device == "cuda" else -1,
82
+ torch_dtype=self.dtype
83
+ )
84
+ logger.info("ColorizeNet model loaded using image-to-image pipeline")
85
+ self.model_type = "pipeline"
86
+
87
+ except Exception as e:
88
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
89
+ raise RuntimeError(f"Could not load ColorizeNet model: {str(e)}")
90
+
91
+ def preprocess_image(self, image: Image.Image) -> Image.Image:
92
+ """
93
+ Preprocess image for colorization
94
+
95
+ Args:
96
+ image: PIL Image
97
+
98
+ Returns:
99
+ Preprocessed PIL Image
100
+ """
101
+ # Convert to grayscale if needed
102
+ if image.mode != "L":
103
+ # Convert to grayscale
104
+ image = image.convert("L")
105
+
106
+ # Convert back to RGB (grayscale image with 3 channels)
107
+ image = image.convert("RGB")
108
+
109
+ # Resize to standard size (512x512 for SD models)
110
+ image = image.resize((512, 512), Image.Resampling.LANCZOS)
111
+
112
+ return image
113
+
114
+ def colorize(self, image: Image.Image, num_inference_steps: int = 20) -> Image.Image:
115
+ """
116
+ Colorize a grayscale image
117
+
118
+ Args:
119
+ image: PIL Image (grayscale or color)
120
+ num_inference_steps: Number of inference steps
121
+
122
+ Returns:
123
+ Colorized PIL Image
124
+ """
125
+ try:
126
+ # Preprocess image
127
+ control_image = self.preprocess_image(image)
128
+ original_size = image.size
129
+
130
+ # Prepare prompt for colorization
131
+ prompt = "colorize this black and white image, high quality, detailed, vibrant colors, natural colors"
132
+ negative_prompt = "black and white, grayscale, monochrome, low quality, blurry, desaturated"
133
+
134
+ # Generate colorized image based on model type
135
+ if self.model_type == "controlnet":
136
+ # Use ControlNet pipeline
137
+ result = self.pipe(
138
+ prompt=prompt,
139
+ image=control_image,
140
+ negative_prompt=negative_prompt,
141
+ num_inference_steps=num_inference_steps,
142
+ guidance_scale=7.5,
143
+ controlnet_conditioning_scale=1.0,
144
+ generator=torch.Generator(device=self.device).manual_seed(42)
145
+ )
146
+
147
+ if isinstance(result, dict) and "images" in result:
148
+ colorized = result["images"][0]
149
+ elif isinstance(result, list) and len(result) > 0:
150
+ colorized = result[0]
151
+ else:
152
+ colorized = result
153
+ else:
154
+ # Use pipeline directly
155
+ result = self.pipe(
156
+ control_image,
157
+ prompt=prompt,
158
+ num_inference_steps=num_inference_steps
159
+ )
160
+
161
+ if isinstance(result, dict) and "images" in result:
162
+ colorized = result["images"][0]
163
+ elif isinstance(result, list) and len(result) > 0:
164
+ colorized = result[0]
165
+ else:
166
+ colorized = result
167
+
168
+ # Ensure we have a PIL Image
169
+ if not isinstance(colorized, Image.Image):
170
+ if isinstance(colorized, np.ndarray):
171
+ # Handle numpy array
172
+ if colorized.dtype != np.uint8:
173
+ colorized = (colorized * 255).astype(np.uint8)
174
+ if len(colorized.shape) == 3 and colorized.shape[2] == 3:
175
+ colorized = Image.fromarray(colorized, 'RGB')
176
+ else:
177
+ colorized = Image.fromarray(colorized)
178
+ elif torch.is_tensor(colorized):
179
+ # Handle torch tensor
180
+ colorized = colorized.cpu().permute(1, 2, 0).numpy()
181
+ colorized = (colorized * 255).astype(np.uint8)
182
+ colorized = Image.fromarray(colorized, 'RGB')
183
+ else:
184
+ raise ValueError(f"Unexpected output type: {type(colorized)}")
185
+
186
+ # Resize back to original size
187
+ if original_size != (512, 512):
188
+ colorized = colorized.resize(original_size, Image.Resampling.LANCZOS)
189
+
190
+ return colorized
191
+
192
+ except Exception as e:
193
+ logger.error("Error during colorization: %s", str(e))
194
+ raise
195
+
.history/app/config_20251111094005.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Configuration settings for the application
3
+ """
4
+ import os
5
+ from pydantic_settings import BaseSettings
6
+
7
+ class Settings(BaseSettings):
8
+ """Application settings"""
9
+
10
+ # Firebase settings
11
+ ENABLE_APP_CHECK: bool = os.getenv("ENABLE_APP_CHECK", "true").lower() == "true"
12
+ FIREBASE_CREDENTIALS_PATH: str = os.getenv(
13
+ "FIREBASE_CREDENTIALS_PATH",
14
+ "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json"
15
+ )
16
+
17
+ # API settings
18
+ BASE_URL: str = os.getenv("BASE_URL", "http://localhost:8000")
19
+
20
+ # Model settings
21
+ MODEL_ID: str = os.getenv("MODEL_ID", "rsortino/ColorizeNet")
22
+ NUM_INFERENCE_STEPS: int = int(os.getenv("NUM_INFERENCE_STEPS", "20"))
23
+
24
+ # Storage settings
25
+ UPLOAD_DIR: str = os.getenv("UPLOAD_DIR", "uploads")
26
+ RESULT_DIR: str = os.getenv("RESULT_DIR", "results")
27
+
28
+ class Config:
29
+ env_file = ".env"
30
+ case_sensitive = False
31
+
32
+ settings = Settings()
33
+
.history/app/main_20251111093950.py ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FastAPI application for image colorization using ColorizeNet model
3
+ with Firebase App Check integration
4
+ """
5
+ import os
6
+ import uuid
7
+ import logging
8
+ from pathlib import Path
9
+ from typing import Optional
10
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Depends, Request
11
+ from fastapi.responses import FileResponse, JSONResponse
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from fastapi.staticfiles import StaticFiles
14
+ import firebase_admin
15
+ from firebase_admin import credentials, app_check
16
+ import cv2
17
+ import numpy as np
18
+ import torch
19
+ from PIL import Image
20
+ import io
21
+
22
+ from app.colorize_model import ColorizeModel
23
+ from app.config import settings
24
+
25
+ # Configure logging
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
29
+ )
30
+ logger = logging.getLogger(__name__)
31
+
32
+ # Initialize FastAPI app
33
+ app = FastAPI(
34
+ title="Colorize API",
35
+ description="Image colorization API using ColorizeNet model",
36
+ version="1.0.0"
37
+ )
38
+
39
+ # CORS middleware
40
+ app.add_middleware(
41
+ CORSMiddleware,
42
+ allow_origins=["*"], # Configure appropriately for production
43
+ allow_credentials=True,
44
+ allow_methods=["*"],
45
+ allow_headers=["*"],
46
+ )
47
+
48
+ # Initialize Firebase Admin SDK
49
+ firebase_cred_path = os.getenv("FIREBASE_CREDENTIALS_PATH", "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json")
50
+ if os.path.exists(firebase_cred_path):
51
+ cred = credentials.Certificate(firebase_cred_path)
52
+ firebase_admin.initialize_app(cred)
53
+ logger.info("Firebase Admin SDK initialized")
54
+ else:
55
+ logger.warning("Firebase credentials file not found. App Check will be disabled.")
56
+ firebase_admin.initialize_app()
57
+
58
+ # Create directories
59
+ UPLOAD_DIR = Path("uploads")
60
+ RESULT_DIR = Path("results")
61
+ UPLOAD_DIR.mkdir(exist_ok=True)
62
+ RESULT_DIR.mkdir(exist_ok=True)
63
+
64
+ # Mount static files for serving results
65
+ app.mount("/results", StaticFiles(directory="results"), name="results")
66
+
67
+ # Initialize ColorizeNet model
68
+ colorize_model = None
69
+
70
+ @app.on_event("startup")
71
+ async def startup_event():
72
+ """Initialize the colorization model on startup"""
73
+ global colorize_model
74
+ try:
75
+ logger.info("Loading ColorizeNet model...")
76
+ colorize_model = ColorizeModel()
77
+ logger.info("ColorizeNet model loaded successfully")
78
+ except Exception as e:
79
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
80
+ raise
81
+
82
+ @app.on_event("shutdown")
83
+ async def shutdown_event():
84
+ """Cleanup on shutdown"""
85
+ global colorize_model
86
+ if colorize_model:
87
+ del colorize_model
88
+ logger.info("Application shutdown")
89
+
90
+ # Firebase App Check verification
91
+ async def verify_app_check(request: Request):
92
+ """Verify Firebase App Check token"""
93
+ if not settings.ENABLE_APP_CHECK:
94
+ return True
95
+
96
+ app_check_token = request.headers.get("X-Firebase-AppCheck")
97
+ if not app_check_token:
98
+ raise HTTPException(
99
+ status_code=401,
100
+ detail="Missing App Check token"
101
+ )
102
+
103
+ try:
104
+ # Verify the App Check token
105
+ app_check_claims = app_check.verify_token(app_check_token)
106
+ logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
107
+ return True
108
+ except Exception as e:
109
+ logger.warning("App Check token verification failed: %s", str(e))
110
+ raise HTTPException(
111
+ status_code=401,
112
+ detail="Invalid App Check token"
113
+ )
114
+
115
+ @app.get("/health")
116
+ async def health_check():
117
+ """Health check endpoint"""
118
+ return {
119
+ "status": "healthy",
120
+ "model_loaded": colorize_model is not None
121
+ }
122
+
123
+ @app.post("/upload")
124
+ async def upload_image(
125
+ file: UploadFile = File(...),
126
+ verified: bool = Depends(verify_app_check)
127
+ ):
128
+ """
129
+ Upload an image and return the uploaded image URL
130
+ """
131
+ if not file.content_type or not file.content_type.startswith("image/"):
132
+ raise HTTPException(status_code=400, detail="File must be an image")
133
+
134
+ # Generate unique filename
135
+ file_id = str(uuid.uuid4())
136
+ file_extension = Path(file.filename).suffix or ".jpg"
137
+ filename = f"{file_id}{file_extension}"
138
+ filepath = UPLOAD_DIR / filename
139
+
140
+ # Save uploaded file
141
+ try:
142
+ contents = await file.read()
143
+ with open(filepath, "wb") as f:
144
+ f.write(contents)
145
+ logger.info("Image uploaded: %s", filename)
146
+
147
+ # Return the URL to access the uploaded image
148
+ base_url = os.getenv("BASE_URL", "http://localhost:8000")
149
+ image_url = f"{base_url}/uploads/{filename}"
150
+
151
+ return {
152
+ "success": True,
153
+ "image_id": file_id,
154
+ "image_url": image_url,
155
+ "filename": filename
156
+ }
157
+ except Exception as e:
158
+ logger.error("Error uploading image: %s", str(e))
159
+ raise HTTPException(status_code=500, detail=f"Error uploading image: {str(e)}")
160
+
161
+ @app.post("/colorize")
162
+ async def colorize_image(
163
+ file: UploadFile = File(...),
164
+ verified: bool = Depends(verify_app_check)
165
+ ):
166
+ """
167
+ Colorize an uploaded grayscale image using ColorizeNet
168
+ Returns the colorized image URL
169
+ """
170
+ if colorize_model is None:
171
+ raise HTTPException(status_code=503, detail="Colorization model not loaded")
172
+
173
+ if not file.content_type or not file.content_type.startswith("image/"):
174
+ raise HTTPException(status_code=400, detail="File must be an image")
175
+
176
+ try:
177
+ # Read image
178
+ contents = await file.read()
179
+ image = Image.open(io.BytesIO(contents))
180
+
181
+ # Convert to RGB if needed
182
+ if image.mode != "RGB":
183
+ image = image.convert("RGB")
184
+
185
+ # Colorize the image
186
+ logger.info("Colorizing image...")
187
+ colorized_image = colorize_model.colorize(image)
188
+
189
+ # Save colorized image
190
+ file_id = str(uuid.uuid4())
191
+ result_filename = f"{file_id}.jpg"
192
+ result_filepath = RESULT_DIR / result_filename
193
+
194
+ colorized_image.save(result_filepath, "JPEG", quality=95)
195
+ logger.info("Colorized image saved: %s", result_filename)
196
+
197
+ # Return URLs
198
+ base_url = os.getenv("BASE_URL", "http://localhost:8000")
199
+ download_url = f"{base_url}/results/{result_filename}"
200
+ api_download_url = f"{base_url}/download/{file_id}"
201
+
202
+ return {
203
+ "success": True,
204
+ "result_id": file_id,
205
+ "download_url": download_url,
206
+ "api_download_url": api_download_url,
207
+ "filename": result_filename
208
+ }
209
+ except Exception as e:
210
+ logger.error("Error colorizing image: %s", str(e))
211
+ raise HTTPException(status_code=500, detail=f"Error colorizing image: {str(e)}")
212
+
213
+ @app.get("/download/{file_id}")
214
+ async def download_result(
215
+ file_id: str,
216
+ verified: bool = Depends(verify_app_check)
217
+ ):
218
+ """
219
+ Download the colorized image by file ID
220
+ """
221
+ result_filepath = RESULT_DIR / f"{file_id}.jpg"
222
+
223
+ if not result_filepath.exists():
224
+ raise HTTPException(status_code=404, detail="Result not found")
225
+
226
+ return FileResponse(
227
+ result_filepath,
228
+ media_type="image/jpeg",
229
+ filename=f"colorized_{file_id}.jpg"
230
+ )
231
+
232
+ @app.get("/results/{filename}")
233
+ async def get_result_file(filename: str):
234
+ """
235
+ Serve result files directly (public endpoint for browser access)
236
+ """
237
+ result_filepath = RESULT_DIR / filename
238
+
239
+ if not result_filepath.exists():
240
+ raise HTTPException(status_code=404, detail="File not found")
241
+
242
+ return FileResponse(
243
+ result_filepath,
244
+ media_type="image/jpeg"
245
+ )
246
+
247
+ @app.get("/uploads/{filename}")
248
+ async def get_upload_file(filename: str):
249
+ """
250
+ Serve uploaded files directly
251
+ """
252
+ upload_filepath = UPLOAD_DIR / filename
253
+
254
+ if not upload_filepath.exists():
255
+ raise HTTPException(status_code=404, detail="File not found")
256
+
257
+ return FileResponse(
258
+ upload_filepath,
259
+ media_type="image/jpeg"
260
+ )
261
+
262
+ if __name__ == "__main__":
263
+ import uvicorn
264
+ uvicorn.run(app, host="0.0.0.0", port=8000)
265
+
.history/app/main_20251111094327.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FastAPI application for image colorization using ColorizeNet model
3
+ with Firebase App Check integration
4
+ """
5
+ import os
6
+ import uuid
7
+ import logging
8
+ from pathlib import Path
9
+ from typing import Optional
10
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Depends, Request
11
+ from fastapi.responses import FileResponse, JSONResponse
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from fastapi.staticfiles import StaticFiles
14
+ import firebase_admin
15
+ from firebase_admin import credentials, app_check
16
+ import cv2
17
+ import numpy as np
18
+ import torch
19
+ from PIL import Image
20
+ import io
21
+
22
+ from app.colorize_model import ColorizeModel
23
+ from app.config import settings
24
+
25
+ # Configure logging
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
29
+ )
30
+ logger = logging.getLogger(__name__)
31
+
32
+ # Initialize FastAPI app
33
+ app = FastAPI(
34
+ title="Colorize API",
35
+ description="Image colorization API using ColorizeNet model",
36
+ version="1.0.0"
37
+ )
38
+
39
+ # CORS middleware
40
+ app.add_middleware(
41
+ CORSMiddleware,
42
+ allow_origins=["*"], # Configure appropriately for production
43
+ allow_credentials=True,
44
+ allow_methods=["*"],
45
+ allow_headers=["*"],
46
+ )
47
+
48
+ # Initialize Firebase Admin SDK
49
+ firebase_cred_path = os.getenv("FIREBASE_CREDENTIALS_PATH", "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json")
50
+ if os.path.exists(firebase_cred_path):
51
+ try:
52
+ cred = credentials.Certificate(firebase_cred_path)
53
+ firebase_admin.initialize_app(cred)
54
+ logger.info("Firebase Admin SDK initialized")
55
+ except Exception as e:
56
+ logger.warning("Failed to initialize Firebase: %s", str(e))
57
+ firebase_admin.initialize_app()
58
+ else:
59
+ logger.warning("Firebase credentials file not found. App Check will be disabled.")
60
+ try:
61
+ firebase_admin.initialize_app()
62
+ except:
63
+ pass
64
+
65
+ # Create directories
66
+ UPLOAD_DIR = Path("uploads")
67
+ RESULT_DIR = Path("results")
68
+ UPLOAD_DIR.mkdir(exist_ok=True)
69
+ RESULT_DIR.mkdir(exist_ok=True)
70
+
71
+ # Mount static files for serving results
72
+ app.mount("/results", StaticFiles(directory="results"), name="results")
73
+ app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
74
+
75
+ # Initialize ColorizeNet model
76
+ colorize_model = None
77
+
78
+ @app.on_event("startup")
79
+ async def startup_event():
80
+ """Initialize the colorization model on startup"""
81
+ global colorize_model
82
+ try:
83
+ logger.info("Loading ColorizeNet model...")
84
+ colorize_model = ColorizeModel()
85
+ logger.info("ColorizeNet model loaded successfully")
86
+ except Exception as e:
87
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
88
+ # Don't raise - allow health check to work even if model fails
89
+
90
+ @app.on_event("shutdown")
91
+ async def shutdown_event():
92
+ """Cleanup on shutdown"""
93
+ global colorize_model
94
+ if colorize_model:
95
+ del colorize_model
96
+ logger.info("Application shutdown")
97
+
98
+ # Firebase App Check verification
99
+ async def verify_app_check(request: Request):
100
+ """Verify Firebase App Check token"""
101
+ if not settings.ENABLE_APP_CHECK:
102
+ return True
103
+
104
+ app_check_token = request.headers.get("X-Firebase-AppCheck")
105
+ if not app_check_token:
106
+ raise HTTPException(
107
+ status_code=401,
108
+ detail="Missing App Check token"
109
+ )
110
+
111
+ try:
112
+ # Verify the App Check token
113
+ app_check_claims = app_check.verify_token(app_check_token)
114
+ logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
115
+ return True
116
+ except Exception as e:
117
+ logger.warning("App Check token verification failed: %s", str(e))
118
+ raise HTTPException(
119
+ status_code=401,
120
+ detail="Invalid App Check token"
121
+ )
122
+
123
+ @app.get("/health")
124
+ async def health_check():
125
+ """Health check endpoint"""
126
+ return {
127
+ "status": "healthy",
128
+ "model_loaded": colorize_model is not None
129
+ }
130
+
131
+ @app.post("/upload")
132
+ async def upload_image(
133
+ file: UploadFile = File(...),
134
+ verified: bool = Depends(verify_app_check)
135
+ ):
136
+ """
137
+ Upload an image and return the uploaded image URL
138
+ """
139
+ if not file.content_type or not file.content_type.startswith("image/"):
140
+ raise HTTPException(status_code=400, detail="File must be an image")
141
+
142
+ # Generate unique filename
143
+ file_id = str(uuid.uuid4())
144
+ file_extension = Path(file.filename).suffix or ".jpg"
145
+ filename = f"{file_id}{file_extension}"
146
+ filepath = UPLOAD_DIR / filename
147
+
148
+ # Save uploaded file
149
+ try:
150
+ contents = await file.read()
151
+ with open(filepath, "wb") as f:
152
+ f.write(contents)
153
+ logger.info("Image uploaded: %s", filename)
154
+
155
+ # Return the URL to access the uploaded image
156
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
157
+ image_url = f"{base_url}/uploads/{filename}"
158
+
159
+ return {
160
+ "success": True,
161
+ "image_id": file_id,
162
+ "image_url": image_url,
163
+ "filename": filename
164
+ }
165
+ except Exception as e:
166
+ logger.error("Error uploading image: %s", str(e))
167
+ raise HTTPException(status_code=500, detail=f"Error uploading image: {str(e)}")
168
+
169
+ @app.post("/colorize")
170
+ async def colorize_image(
171
+ file: UploadFile = File(...),
172
+ verified: bool = Depends(verify_app_check)
173
+ ):
174
+ """
175
+ Colorize an uploaded grayscale image using ColorizeNet
176
+ Returns the colorized image URL
177
+ """
178
+ if colorize_model is None:
179
+ raise HTTPException(status_code=503, detail="Colorization model not loaded")
180
+
181
+ if not file.content_type or not file.content_type.startswith("image/"):
182
+ raise HTTPException(status_code=400, detail="File must be an image")
183
+
184
+ try:
185
+ # Read image
186
+ contents = await file.read()
187
+ image = Image.open(io.BytesIO(contents))
188
+
189
+ # Convert to RGB if needed
190
+ if image.mode != "RGB":
191
+ image = image.convert("RGB")
192
+
193
+ # Colorize the image
194
+ logger.info("Colorizing image...")
195
+ colorized_image = colorize_model.colorize(image)
196
+
197
+ # Save colorized image
198
+ file_id = str(uuid.uuid4())
199
+ result_filename = f"{file_id}.jpg"
200
+ result_filepath = RESULT_DIR / result_filename
201
+
202
+ colorized_image.save(result_filepath, "JPEG", quality=95)
203
+ logger.info("Colorized image saved: %s", result_filename)
204
+
205
+ # Return URLs
206
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
207
+ download_url = f"{base_url}/results/{result_filename}"
208
+ api_download_url = f"{base_url}/download/{file_id}"
209
+
210
+ return {
211
+ "success": True,
212
+ "result_id": file_id,
213
+ "download_url": download_url,
214
+ "api_download_url": api_download_url,
215
+ "filename": result_filename
216
+ }
217
+ except Exception as e:
218
+ logger.error("Error colorizing image: %s", str(e))
219
+ raise HTTPException(status_code=500, detail=f"Error colorizing image: {str(e)}")
220
+
221
+ @app.get("/download/{file_id}")
222
+ async def download_result(
223
+ file_id: str,
224
+ verified: bool = Depends(verify_app_check)
225
+ ):
226
+ """
227
+ Download the colorized image by file ID
228
+ """
229
+ result_filepath = RESULT_DIR / f"{file_id}.jpg"
230
+
231
+ if not result_filepath.exists():
232
+ raise HTTPException(status_code=404, detail="Result not found")
233
+
234
+ return FileResponse(
235
+ result_filepath,
236
+ media_type="image/jpeg",
237
+ filename=f"colorized_{file_id}.jpg"
238
+ )
239
+
240
+ @app.get("/results/{filename}")
241
+ async def get_result_file(filename: str):
242
+ """
243
+ Serve result files directly (public endpoint for browser access)
244
+ """
245
+ result_filepath = RESULT_DIR / filename
246
+
247
+ if not result_filepath.exists():
248
+ raise HTTPException(status_code=404, detail="File not found")
249
+
250
+ return FileResponse(
251
+ result_filepath,
252
+ media_type="image/jpeg"
253
+ )
254
+
255
+ @app.get("/uploads/{filename}")
256
+ async def get_upload_file(filename: str):
257
+ """
258
+ Serve uploaded files directly
259
+ """
260
+ upload_filepath = UPLOAD_DIR / filename
261
+
262
+ if not upload_filepath.exists():
263
+ raise HTTPException(status_code=404, detail="File not found")
264
+
265
+ return FileResponse(
266
+ upload_filepath,
267
+ media_type="image/jpeg"
268
+ )
269
+
270
+ if __name__ == "__main__":
271
+ import uvicorn
272
+ port = int(os.getenv("PORT", "7860"))
273
+ uvicorn.run(app, host="0.0.0.0", port=port)
.history/app/main_20251111094522.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FastAPI application for image colorization using ColorizeNet model
3
+ with Firebase App Check integration
4
+ """
5
+ import os
6
+ import uuid
7
+ import logging
8
+ from pathlib import Path
9
+ from typing import Optional
10
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Depends, Request
11
+ from fastapi.responses import FileResponse, JSONResponse
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from fastapi.staticfiles import StaticFiles
14
+ import firebase_admin
15
+ from firebase_admin import credentials, app_check
16
+ import cv2
17
+ import numpy as np
18
+ import torch
19
+ from PIL import Image
20
+ import io
21
+
22
+ from app.colorize_model import ColorizeModel
23
+ from app.config import settings
24
+
25
+ # Configure logging
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
29
+ )
30
+ logger = logging.getLogger(__name__)
31
+
32
+ # Initialize FastAPI app
33
+ app = FastAPI(
34
+ title="Colorize API",
35
+ description="Image colorization API using ColorizeNet model",
36
+ version="1.0.0"
37
+ )
38
+
39
+ # CORS middleware
40
+ app.add_middleware(
41
+ CORSMiddleware,
42
+ allow_origins=["*"], # Configure appropriately for production
43
+ allow_credentials=True,
44
+ allow_methods=["*"],
45
+ allow_headers=["*"],
46
+ )
47
+
48
+ # Initialize Firebase Admin SDK
49
+ firebase_cred_path = os.getenv("FIREBASE_CREDENTIALS_PATH", "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json")
50
+ if os.path.exists(firebase_cred_path):
51
+ try:
52
+ cred = credentials.Certificate(firebase_cred_path)
53
+ firebase_admin.initialize_app(cred)
54
+ logger.info("Firebase Admin SDK initialized")
55
+ except Exception as e:
56
+ logger.warning("Failed to initialize Firebase: %s", str(e))
57
+ firebase_admin.initialize_app()
58
+ else:
59
+ logger.warning("Firebase credentials file not found. App Check will be disabled.")
60
+ try:
61
+ firebase_admin.initialize_app()
62
+ except:
63
+ pass
64
+
65
+ # Create directories
66
+ UPLOAD_DIR = Path("uploads")
67
+ RESULT_DIR = Path("results")
68
+ UPLOAD_DIR.mkdir(exist_ok=True)
69
+ RESULT_DIR.mkdir(exist_ok=True)
70
+
71
+ # Mount static files for serving results
72
+ app.mount("/results", StaticFiles(directory="results"), name="results")
73
+ app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
74
+
75
+ # Initialize ColorizeNet model
76
+ colorize_model = None
77
+
78
+ @app.on_event("startup")
79
+ async def startup_event():
80
+ """Initialize the colorization model on startup"""
81
+ global colorize_model
82
+ try:
83
+ logger.info("Loading ColorizeNet model...")
84
+ colorize_model = ColorizeModel()
85
+ logger.info("ColorizeNet model loaded successfully")
86
+ except Exception as e:
87
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
88
+ # Don't raise - allow health check to work even if model fails
89
+
90
+ @app.on_event("shutdown")
91
+ async def shutdown_event():
92
+ """Cleanup on shutdown"""
93
+ global colorize_model
94
+ if colorize_model:
95
+ del colorize_model
96
+ logger.info("Application shutdown")
97
+
98
+ # Firebase App Check verification
99
+ async def verify_app_check(request: Request):
100
+ """Verify Firebase App Check token"""
101
+ if not settings.ENABLE_APP_CHECK:
102
+ return True
103
+
104
+ app_check_token = request.headers.get("X-Firebase-AppCheck")
105
+ if not app_check_token:
106
+ raise HTTPException(
107
+ status_code=401,
108
+ detail="Missing App Check token"
109
+ )
110
+
111
+ try:
112
+ # Verify the App Check token
113
+ app_check_claims = app_check.verify_token(app_check_token)
114
+ logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
115
+ return True
116
+ except Exception as e:
117
+ logger.warning("App Check token verification failed: %s", str(e))
118
+ raise HTTPException(
119
+ status_code=401,
120
+ detail="Invalid App Check token"
121
+ )
122
+
123
+ @app.get("/health")
124
+ async def health_check():
125
+ """Health check endpoint"""
126
+ return {
127
+ "status": "healthy",
128
+ "model_loaded": colorize_model is not None
129
+ }
130
+
131
+ @app.post("/upload")
132
+ async def upload_image(
133
+ file: UploadFile = File(...),
134
+ verified: bool = Depends(verify_app_check)
135
+ ):
136
+ """
137
+ Upload an image and return the uploaded image URL
138
+ """
139
+ if not file.content_type or not file.content_type.startswith("image/"):
140
+ raise HTTPException(status_code=400, detail="File must be an image")
141
+
142
+ # Generate unique filename
143
+ file_id = str(uuid.uuid4())
144
+ file_extension = Path(file.filename).suffix or ".jpg"
145
+ filename = f"{file_id}{file_extension}"
146
+ filepath = UPLOAD_DIR / filename
147
+
148
+ # Save uploaded file
149
+ try:
150
+ contents = await file.read()
151
+ with open(filepath, "wb") as f:
152
+ f.write(contents)
153
+ logger.info("Image uploaded: %s", filename)
154
+
155
+ # Return the URL to access the uploaded image
156
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
157
+ image_url = f"{base_url}/uploads/{filename}"
158
+
159
+ return {
160
+ "success": True,
161
+ "image_id": file_id,
162
+ "image_url": image_url,
163
+ "filename": filename
164
+ }
165
+ except Exception as e:
166
+ logger.error("Error uploading image: %s", str(e))
167
+ raise HTTPException(status_code=500, detail=f"Error uploading image: {str(e)}")
168
+
169
+ @app.post("/colorize")
170
+ async def colorize_image(
171
+ file: UploadFile = File(...),
172
+ verified: bool = Depends(verify_app_check)
173
+ ):
174
+ """
175
+ Colorize an uploaded grayscale image using ColorizeNet
176
+ Returns the colorized image URL
177
+ """
178
+ if colorize_model is None:
179
+ raise HTTPException(status_code=503, detail="Colorization model not loaded")
180
+
181
+ if not file.content_type or not file.content_type.startswith("image/"):
182
+ raise HTTPException(status_code=400, detail="File must be an image")
183
+
184
+ try:
185
+ # Read image
186
+ contents = await file.read()
187
+ image = Image.open(io.BytesIO(contents))
188
+
189
+ # Convert to RGB if needed
190
+ if image.mode != "RGB":
191
+ image = image.convert("RGB")
192
+
193
+ # Colorize the image
194
+ logger.info("Colorizing image...")
195
+ colorized_image = colorize_model.colorize(image)
196
+
197
+ # Save colorized image
198
+ file_id = str(uuid.uuid4())
199
+ result_filename = f"{file_id}.jpg"
200
+ result_filepath = RESULT_DIR / result_filename
201
+
202
+ colorized_image.save(result_filepath, "JPEG", quality=95)
203
+ logger.info("Colorized image saved: %s", result_filename)
204
+
205
+ # Return URLs
206
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
207
+ download_url = f"{base_url}/results/{result_filename}"
208
+ api_download_url = f"{base_url}/download/{file_id}"
209
+
210
+ return {
211
+ "success": True,
212
+ "result_id": file_id,
213
+ "download_url": download_url,
214
+ "api_download_url": api_download_url,
215
+ "filename": result_filename
216
+ }
217
+ except Exception as e:
218
+ logger.error("Error colorizing image: %s", str(e))
219
+ raise HTTPException(status_code=500, detail=f"Error colorizing image: {str(e)}")
220
+
221
+ @app.get("/download/{file_id}")
222
+ async def download_result(
223
+ file_id: str,
224
+ verified: bool = Depends(verify_app_check)
225
+ ):
226
+ """
227
+ Download the colorized image by file ID
228
+ """
229
+ result_filepath = RESULT_DIR / f"{file_id}.jpg"
230
+
231
+ if not result_filepath.exists():
232
+ raise HTTPException(status_code=404, detail="Result not found")
233
+
234
+ return FileResponse(
235
+ result_filepath,
236
+ media_type="image/jpeg",
237
+ filename=f"colorized_{file_id}.jpg"
238
+ )
239
+
240
+ @app.get("/results/{filename}")
241
+ async def get_result_file(filename: str):
242
+ """
243
+ Serve result files directly (public endpoint for browser access)
244
+ """
245
+ result_filepath = RESULT_DIR / filename
246
+
247
+ if not result_filepath.exists():
248
+ raise HTTPException(status_code=404, detail="File not found")
249
+
250
+ return FileResponse(
251
+ result_filepath,
252
+ media_type="image/jpeg"
253
+ )
254
+
255
+ @app.get("/uploads/{filename}")
256
+ async def get_upload_file(filename: str):
257
+ """
258
+ Serve uploaded files directly
259
+ """
260
+ upload_filepath = UPLOAD_DIR / filename
261
+
262
+ if not upload_filepath.exists():
263
+ raise HTTPException(status_code=404, detail="File not found")
264
+
265
+ return FileResponse(
266
+ upload_filepath,
267
+ media_type="image/jpeg"
268
+ )
269
+
270
+ if __name__ == "__main__":
271
+ import uvicorn
272
+ port = int(os.getenv("PORT", "7860"))
273
+ uvicorn.run(app, host="0.0.0.0", port=port)
.history/deploy_20251111094342.sh ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Deployment script for Hugging Face Spaces
3
+
4
+ echo "Deploying to Hugging Face Space..."
5
+
6
+ # Initialize git if not already
7
+ if [ ! -d ".git" ]; then
8
+ git init
9
+ fi
10
+
11
+ # Add all files
12
+ git add .
13
+
14
+ # Commit changes
15
+ git commit -m "Deploy Colorize API with Firebase App Check"
16
+
17
+ # Add Hugging Face remote (replace with your space URL)
18
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize || git remote set-url origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
19
+
20
+ # Push to Hugging Face
21
+ git push -u origin main
22
+
23
+ echo "Deployment complete!"
24
+
.history/requirements_20251111094007.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ python-multipart==0.0.6
4
+ pillow==10.1.0
5
+ torch==2.1.0
6
+ torchvision==0.16.0
7
+ transformers==4.35.0
8
+ diffusers==0.24.0
9
+ accelerate==0.25.0
10
+ opencv-python==4.8.1.78
11
+ numpy==1.24.3
12
+ firebase-admin==6.2.0
13
+ pydantic-settings==2.1.0
14
+ huggingface-hub==0.19.4
15
+ safetensors==0.4.2
16
+ xformers==0.0.23.post1; sys_platform != "darwin"
17
+
.history/requirements_20251111094419.txt ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ python-multipart==0.0.6
4
+ pillow==10.1.0
5
+ torch>=2.0.0
6
+ torchvision>=0.15.0
7
+ transformers>=4.30.0
8
+ diffusers>=0.21.0
9
+ accelerate>=0.20.0
10
+ opencv-python-headless==4.8.1.78
11
+ numpy>=1.24.0
12
+ firebase-admin>=6.0.0
13
+ pydantic-settings>=2.0.0
14
+ huggingface-hub>=0.16.0
15
+ safetensors>=0.3.0
16
+
.history/requirements_20251111094503.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ python-multipart==0.0.6
4
+ requests>=2.31.0
5
+ pillow==10.1.0
6
+ torch>=2.0.0
7
+ torchvision>=0.15.0
8
+ transformers>=4.30.0
9
+ diffusers>=0.21.0
10
+ accelerate>=0.20.0
11
+ opencv-python-headless==4.8.1.78
12
+ numpy>=1.24.0
13
+ firebase-admin>=6.0.0
14
+ pydantic-settings>=2.0.0
15
+ huggingface-hub>=0.16.0
16
+ safetensors>=0.3.0
17
+
.history/requirements_20251111094522.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ python-multipart==0.0.6
4
+ requests>=2.31.0
5
+ pillow==10.1.0
6
+ torch>=2.0.0
7
+ torchvision>=0.15.0
8
+ transformers>=4.30.0
9
+ diffusers>=0.21.0
10
+ accelerate>=0.20.0
11
+ opencv-python-headless==4.8.1.78
12
+ numpy>=1.24.0
13
+ firebase-admin>=6.0.0
14
+ pydantic-settings>=2.0.0
15
+ huggingface-hub>=0.16.0
16
+ safetensors>=0.3.0
17
+
DEPLOYMENT.md ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Deployment Guide
2
+
3
+ ## Quick Start
4
+
5
+ ### 1. Copy Firebase Credentials
6
+
7
+ Copy your Firebase Admin SDK JSON file to the project root:
8
+ ```bash
9
+ # Windows
10
+ copy C:\Colorize\colorize-662df-firebase-adminsdk-fbsvc-e080668793.json .
11
+
12
+ # Linux/Mac
13
+ cp /path/to/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json .
14
+ ```
15
+
16
+ **Important**: For Hugging Face Spaces, you should add this as a secret instead of committing it to the repository.
17
+
18
+ ### 2. Deploy to Hugging Face Spaces
19
+
20
+ ```bash
21
+ # Initialize git repository
22
+ git init
23
+ git add .
24
+ git commit -m "Deploy Colorize API"
25
+
26
+ # Add Hugging Face remote
27
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
28
+
29
+ # Push to Hugging Face
30
+ git push -u origin main
31
+ ```
32
+
33
+ ### 3. Configure Hugging Face Space Secrets
34
+
35
+ 1. Go to your Space: https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
36
+ 2. Navigate to Settings → Secrets
37
+ 3. Add a new secret:
38
+ - **Name**: `FIREBASE_CREDENTIALS`
39
+ - **Value**: Paste the entire contents of your Firebase Admin SDK JSON file
40
+
41
+ ### 4. Update Dockerfile for Secrets (Optional)
42
+
43
+ If you want to use the secret, you can modify the Dockerfile to create the file from the secret:
44
+
45
+ ```dockerfile
46
+ # Add this before the CMD line
47
+ RUN if [ -n "$FIREBASE_CREDENTIALS" ]; then \
48
+ echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; \
49
+ fi
50
+ ```
51
+
52
+ ## Testing Locally
53
+
54
+ ### Run with Docker
55
+
56
+ ```bash
57
+ # Build image
58
+ docker build -t colorize-api .
59
+
60
+ # Run container
61
+ docker run -p 7860:7860 \
62
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
63
+ colorize-api
64
+ ```
65
+
66
+ ### Run without Docker
67
+
68
+ ```bash
69
+ # Install dependencies
70
+ pip install -r requirements.txt
71
+
72
+ # Run API
73
+ uvicorn app.main:app --host 0.0.0.0 --port 7860
74
+ ```
75
+
76
+ ## API Endpoints
77
+
78
+ Once deployed, your API will be available at:
79
+ - `https://logicgoinfotechspaces-colorize.hf.space/health` - Health check
80
+ - `https://logicgoinfotechspaces-colorize.hf.space/colorize` - Colorize image
81
+ - `https://logicgoinfotechspaces-colorize.hf.space/upload` - Upload image
82
+
83
+ ## Frontend Integration Example
84
+
85
+ ```javascript
86
+ // Initialize Firebase
87
+ import { initializeApp } from "firebase/app";
88
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
89
+
90
+ const firebaseConfig = {
91
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
92
+ authDomain: "colorize-662df.firebaseapp.com",
93
+ projectId: "colorize-662df",
94
+ storageBucket: "colorize-662df.firebasestorage.app",
95
+ messagingSenderId: "69166278311",
96
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
97
+ measurementId: "G-58CC2J8XKX"
98
+ };
99
+
100
+ const app = initializeApp(firebaseConfig);
101
+ const appCheck = initializeAppCheck(app, {
102
+ provider: new ReCaptchaEnterpriseProvider('YOUR_RECAPTCHA_SITE_KEY'),
103
+ isTokenAutoRefreshEnabled: true
104
+ });
105
+
106
+ // Colorize image function
107
+ async function colorizeImage(file) {
108
+ const { getToken } = await import('firebase/app-check');
109
+ const token = await getToken(appCheck);
110
+
111
+ const formData = new FormData();
112
+ formData.append('file', file);
113
+
114
+ const response = await fetch('https://logicgoinfotechspaces-colorize.hf.space/colorize', {
115
+ method: 'POST',
116
+ headers: {
117
+ 'X-Firebase-AppCheck': token.token
118
+ },
119
+ body: formData
120
+ });
121
+
122
+ return await response.json();
123
+ }
124
+ ```
125
+
126
+ ## Troubleshooting
127
+
128
+ ### Model Not Loading
129
+
130
+ - Check Hugging Face Space logs
131
+ - Verify model ID: `rsortino/ColorizeNet`
132
+ - Ensure sufficient disk space (models can be large)
133
+
134
+ ### Firebase App Check Failing
135
+
136
+ - Verify credentials are correctly set as a secret
137
+ - Check that App Check is enabled in Firebase Console
138
+ - Ensure reCAPTCHA Enterprise is set up
139
+
140
+ ### Port Issues
141
+
142
+ Hugging Face Spaces automatically handles port 7860. The Dockerfile is configured for this.
143
+
Dockerfile ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Install system dependencies
7
+ RUN apt-get update && apt-get install -y \
8
+ libgl1-mesa-glx \
9
+ libglib2.0-0 \
10
+ libsm6 \
11
+ libxext6 \
12
+ libxrender-dev \
13
+ libgomp1 \
14
+ git \
15
+ && rm -rf /var/lib/apt/lists/*
16
+
17
+ # Copy requirements first for better caching
18
+ COPY requirements.txt .
19
+
20
+ # Install Python dependencies
21
+ RUN pip install --no-cache-dir -r requirements.txt
22
+
23
+ # Copy application code
24
+ COPY . .
25
+
26
+ # Create directories for uploads and results
27
+ RUN mkdir -p uploads results
28
+
29
+ # Handle Firebase credentials from environment variable (for Hugging Face Spaces secrets)
30
+ # This allows the credentials to be passed as a secret and written to file at runtime
31
+ RUN echo '#!/bin/bash\nif [ -n "$FIREBASE_CREDENTIALS" ]; then echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json; fi\nexec "$@"' > /entrypoint.sh && chmod +x /entrypoint.sh
32
+
33
+ # Expose port (Hugging Face Spaces uses port 7860)
34
+ EXPOSE 7860
35
+
36
+ # Set environment variables
37
+ ENV PYTHONUNBUFFERED=1
38
+ ENV BASE_URL=${SPACE_HOST}
39
+ ENV PORT=7860
40
+
41
+ # Health check
42
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
43
+ CMD python -c "import requests; requests.get('http://localhost:7860/health', timeout=5)" || exit 1
44
+
45
+ # Set entrypoint
46
+ ENTRYPOINT ["/entrypoint.sh"]
47
+
48
+ # Run the application (port will be set via environment variable)
49
+ CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}"]
README.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - 🖼️ Image upload and colorization
20
+ - 🔒 Firebase App Check authentication
21
+ - 🐳 Docker deployment
22
+ - 📥 Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ ### Health Check
27
+ ```
28
+ GET /health
29
+ ```
30
+ Returns the health status of the API and model.
31
+
32
+ ### Upload Image
33
+ ```
34
+ POST /upload
35
+ Headers: X-Firebase-AppCheck: <token>
36
+ Body: multipart/form-data with image file
37
+ ```
38
+ Uploads an image and returns the image URL.
39
+
40
+ ### Colorize Image
41
+ ```
42
+ POST /colorize
43
+ Headers: X-Firebase-AppCheck: <token>
44
+ Body: multipart/form-data with image file
45
+ ```
46
+ Colorizes a grayscale image and returns the result URL.
47
+
48
+ ### Download Result
49
+ ```
50
+ GET /download/{file_id}
51
+ Headers: X-Firebase-AppCheck: <token>
52
+ ```
53
+ Downloads the colorized image by file ID.
54
+
55
+ ### Get Result (Public)
56
+ ```
57
+ GET /results/{filename}
58
+ ```
59
+ Public endpoint to access colorized images in browser.
60
+
61
+ ## Setup
62
+
63
+ ### Environment Variables
64
+
65
+ Set these in your Hugging Face Space secrets:
66
+
67
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase credentials JSON file (or set as secret)
68
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (default: true)
69
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
70
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
71
+
72
+ ### Firebase App Check Setup
73
+
74
+ 1. Initialize Firebase App Check in your frontend:
75
+ ```javascript
76
+ import { initializeApp } from "firebase/app";
77
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
78
+
79
+ const firebaseConfig = {
80
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
81
+ authDomain: "colorize-662df.firebaseapp.com",
82
+ projectId: "colorize-662df",
83
+ storageBucket: "colorize-662df.firebasestorage.app",
84
+ messagingSenderId: "69166278311",
85
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
86
+ measurementId: "G-58CC2J8XKX"
87
+ };
88
+
89
+ const app = initializeApp(firebaseConfig);
90
+ const appCheck = initializeAppCheck(app, {
91
+ provider: new ReCaptchaEnterpriseProvider('your-recaptcha-site-key'),
92
+ isTokenAutoRefreshEnabled: true
93
+ });
94
+ ```
95
+
96
+ 2. Include the token in API requests:
97
+ ```javascript
98
+ const token = await appCheck.getToken();
99
+ fetch('https://your-space.hf.space/colorize', {
100
+ method: 'POST',
101
+ headers: {
102
+ 'X-Firebase-AppCheck': token.token
103
+ },
104
+ body: formData
105
+ });
106
+ ```
107
+
108
+ ## Model
109
+
110
+ This API uses the `rsortino/ColorizeNet` model from Hugging Face for image colorization.
111
+
112
+ ## License
113
+
114
+ MIT
README_HF.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Colorize Image API
3
+ emoji: 🎨
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ sdk_version: 1.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Colorize Image API
14
+
15
+ FastAPI-based image colorization service using ColorizeNet model with Firebase App Check integration.
16
+
17
+ ## Features
18
+
19
+ - Image upload and colorization
20
+ - Firebase App Check authentication
21
+ - Docker deployment
22
+ - Download URLs for browser access
23
+
24
+ ## API Endpoints
25
+
26
+ - `GET /health` - Health check
27
+ - `POST /upload` - Upload image
28
+ - `POST /colorize` - Colorize image
29
+ - `GET /download/{file_id}` - Download result
30
+ - `GET /results/{filename}` - Public result access
31
+
32
+ ## Setup
33
+
34
+ The API requires Firebase credentials. Place your Firebase Admin SDK JSON file in the root directory as:
35
+ `colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
36
+
37
+ ## Model
38
+
39
+ Uses `rsortino/ColorizeNet` from Hugging Face for image colorization.
40
+
SETUP.md ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Setup Guide for Colorize API
2
+
3
+ ## Prerequisites
4
+
5
+ 1. Python 3.10+
6
+ 2. Docker (for containerized deployment)
7
+ 3. Firebase Admin SDK credentials file
8
+ 4. Hugging Face account with access to the Colorize Space
9
+
10
+ ## Local Development Setup
11
+
12
+ ### 1. Install Dependencies
13
+
14
+ ```bash
15
+ pip install -r requirements.txt
16
+ ```
17
+
18
+ ### 2. Firebase Credentials
19
+
20
+ Copy your Firebase Admin SDK JSON file to the project root:
21
+ - Source: `C:\Colorize\colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
22
+ - Destination: `colorize-662df-firebase-adminsdk-fbsvc-e080668793.json`
23
+
24
+ Or set the path in environment variable:
25
+ ```bash
26
+ export FIREBASE_CREDENTIALS_PATH=/path/to/your/firebase-credentials.json
27
+ ```
28
+
29
+ ### 3. Run the API
30
+
31
+ ```bash
32
+ uvicorn app.main:app --reload --port 7860
33
+ ```
34
+
35
+ The API will be available at `http://localhost:7860`
36
+
37
+ ## Docker Setup
38
+
39
+ ### 1. Build the Docker Image
40
+
41
+ ```bash
42
+ docker build -t colorize-api .
43
+ ```
44
+
45
+ ### 2. Run the Container
46
+
47
+ ```bash
48
+ docker run -p 7860:7860 \
49
+ -v $(pwd)/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json:/app/colorize-662df-firebase-adminsdk-fbsvc-e080668793.json \
50
+ -e BASE_URL=http://localhost:7860 \
51
+ colorize-api
52
+ ```
53
+
54
+ ## Hugging Face Spaces Deployment
55
+
56
+ ### 1. Prepare Your Repository
57
+
58
+ ```bash
59
+ # Initialize git repository
60
+ git init
61
+ git add .
62
+ git commit -m "Initial commit: Colorize API with Firebase App Check"
63
+ ```
64
+
65
+ ### 2. Set Up Hugging Face Space
66
+
67
+ 1. Go to https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
68
+ 2. If the space doesn't exist, create a new Docker space
69
+
70
+ ### 3. Add Firebase Credentials as Secret
71
+
72
+ In Hugging Face Space settings:
73
+ 1. Go to Settings → Secrets
74
+ 2. Add a new secret:
75
+ - Name: `FIREBASE_CREDENTIALS`
76
+ - Value: Contents of your Firebase Admin SDK JSON file
77
+
78
+ ### 4. Update Dockerfile for Secrets (if needed)
79
+
80
+ The Dockerfile will automatically use the credentials file if it exists. For Hugging Face Spaces, you may need to create the file from secrets:
81
+
82
+ ```dockerfile
83
+ # Add this to Dockerfile if using HF secrets
84
+ RUN echo "$FIREBASE_CREDENTIALS" > colorize-662df-firebase-adminsdk-fbsvc-e080668793.json || true
85
+ ```
86
+
87
+ ### 5. Push to Hugging Face
88
+
89
+ ```bash
90
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
91
+ git push -u origin main
92
+ ```
93
+
94
+ ## Testing the API
95
+
96
+ ### Health Check
97
+
98
+ ```bash
99
+ curl http://localhost:7860/health
100
+ ```
101
+
102
+ ### Upload Image (with App Check token)
103
+
104
+ ```bash
105
+ curl -X POST http://localhost:7860/upload \
106
+ -H "X-Firebase-AppCheck: YOUR_APP_CHECK_TOKEN" \
107
+ -F "file=@path/to/image.jpg"
108
+ ```
109
+
110
+ ### Colorize Image (with App Check token)
111
+
112
+ ```bash
113
+ curl -X POST http://localhost:7860/colorize \
114
+ -H "X-Firebase-AppCheck: YOUR_APP_CHECK_TOKEN" \
115
+ -F "file=@path/to/grayscale_image.jpg"
116
+ ```
117
+
118
+ ## Frontend Integration
119
+
120
+ ### Initialize Firebase App Check
121
+
122
+ ```javascript
123
+ import { initializeApp } from "firebase/app";
124
+ import { initializeAppCheck, ReCaptchaEnterpriseProvider } from "firebase/app-check";
125
+
126
+ const firebaseConfig = {
127
+ apiKey: "AIzaSyBIB6rcfyyqy5niERTXWvVD714Ter4Vx68",
128
+ authDomain: "colorize-662df.firebaseapp.com",
129
+ projectId: "colorize-662df",
130
+ storageBucket: "colorize-662df.firebasestorage.app",
131
+ messagingSenderId: "69166278311",
132
+ appId: "1:69166278311:web:0e8c50b8dd8627aaeadd82",
133
+ measurementId: "G-58CC2J8XKX"
134
+ };
135
+
136
+ const app = initializeApp(firebaseConfig);
137
+
138
+ // Initialize App Check
139
+ const appCheck = initializeAppCheck(app, {
140
+ provider: new ReCaptchaEnterpriseProvider('YOUR_RECAPTCHA_SITE_KEY'),
141
+ isTokenAutoRefreshEnabled: true
142
+ });
143
+
144
+ // Get token and make API call
145
+ async function colorizeImage(imageFile) {
146
+ const token = await appCheck.getToken();
147
+
148
+ const formData = new FormData();
149
+ formData.append('file', imageFile);
150
+
151
+ const response = await fetch('https://your-space.hf.space/colorize', {
152
+ method: 'POST',
153
+ headers: {
154
+ 'X-Firebase-AppCheck': token.token
155
+ },
156
+ body: formData
157
+ });
158
+
159
+ const result = await response.json();
160
+ console.log('Colorized image URL:', result.download_url);
161
+ return result;
162
+ }
163
+ ```
164
+
165
+ ## Troubleshooting
166
+
167
+ ### Model Loading Issues
168
+
169
+ If the ColorizeNet model fails to load:
170
+ 1. Check your internet connection (model downloads from Hugging Face)
171
+ 2. Verify you have sufficient disk space
172
+ 3. Check logs for specific error messages
173
+
174
+ ### Firebase App Check Issues
175
+
176
+ If App Check verification fails:
177
+ 1. Verify your Firebase credentials file is correct
178
+ 2. Check that App Check is enabled in Firebase Console
179
+ 3. Ensure the token is being sent in the `X-Firebase-AppCheck` header
180
+
181
+ ### Port Issues
182
+
183
+ Hugging Face Spaces uses port 7860 by default. Make sure your Dockerfile exposes this port.
184
+
185
+ ## Environment Variables
186
+
187
+ - `FIREBASE_CREDENTIALS_PATH`: Path to Firebase Admin SDK JSON file
188
+ - `ENABLE_APP_CHECK`: Enable/disable Firebase App Check (true/false)
189
+ - `BASE_URL`: Base URL for generating download URLs
190
+ - `PORT`: Port to run the API on (default: 7860)
191
+ - `MODEL_ID`: Hugging Face model ID (default: rsortino/ColorizeNet)
192
+ - `NUM_INFERENCE_STEPS`: Number of inference steps (default: 20)
193
+
app/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # Colorize API Package
2
+
app/colorize_model.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ ColorizeNet model wrapper for image colorization
3
+ """
4
+ import logging
5
+ import torch
6
+ import numpy as np
7
+ from PIL import Image
8
+ import cv2
9
+ from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, StableDiffusionXLControlNetPipeline
10
+ from diffusers.utils import load_image
11
+ from transformers import pipeline
12
+ from huggingface_hub import hf_hub_download
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ class ColorizeModel:
17
+ """Wrapper for ColorizeNet model"""
18
+
19
+ def __init__(self, model_id: str = "rsortino/ColorizeNet"):
20
+ """
21
+ Initialize the ColorizeNet model
22
+
23
+ Args:
24
+ model_id: Hugging Face model ID for ColorizeNet
25
+ """
26
+ self.model_id = model_id
27
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
28
+ logger.info("Using device: %s", self.device)
29
+ self.dtype = torch.float16 if self.device == "cuda" else torch.float32
30
+
31
+ try:
32
+ # Try loading as ControlNet with Stable Diffusion
33
+ logger.info("Attempting to load ColorizeNet as ControlNet...")
34
+ try:
35
+ # Load ControlNet model
36
+ self.controlnet = ControlNetModel.from_pretrained(
37
+ model_id,
38
+ torch_dtype=self.dtype
39
+ )
40
+
41
+ # Try SDXL first, fallback to SD 1.5
42
+ try:
43
+ self.pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
44
+ "stabilityai/stable-diffusion-xl-base-1.0",
45
+ controlnet=self.controlnet,
46
+ torch_dtype=self.dtype,
47
+ safety_checker=None,
48
+ requires_safety_checker=False
49
+ )
50
+ logger.info("Loaded with SDXL base model")
51
+ except:
52
+ self.pipe = StableDiffusionControlNetPipeline.from_pretrained(
53
+ "runwayml/stable-diffusion-v1-5",
54
+ controlnet=self.controlnet,
55
+ torch_dtype=self.dtype,
56
+ safety_checker=None,
57
+ requires_safety_checker=False
58
+ )
59
+ logger.info("Loaded with SD 1.5 base model")
60
+
61
+ self.pipe.to(self.device)
62
+
63
+ # Enable memory efficient attention if available
64
+ if hasattr(self.pipe, "enable_xformers_memory_efficient_attention"):
65
+ try:
66
+ self.pipe.enable_xformers_memory_efficient_attention()
67
+ logger.info("XFormers memory efficient attention enabled")
68
+ except Exception as e:
69
+ logger.warning("Could not enable XFormers: %s", str(e))
70
+
71
+ logger.info("ColorizeNet model loaded successfully as ControlNet")
72
+ self.model_type = "controlnet"
73
+
74
+ except Exception as e:
75
+ logger.warning("Failed to load as ControlNet: %s", str(e))
76
+ # Fallback: try as image-to-image pipeline
77
+ logger.info("Trying to load as image-to-image pipeline...")
78
+ self.pipe = pipeline(
79
+ "image-to-image",
80
+ model=model_id,
81
+ device=0 if self.device == "cuda" else -1,
82
+ torch_dtype=self.dtype
83
+ )
84
+ logger.info("ColorizeNet model loaded using image-to-image pipeline")
85
+ self.model_type = "pipeline"
86
+
87
+ except Exception as e:
88
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
89
+ raise RuntimeError(f"Could not load ColorizeNet model: {str(e)}")
90
+
91
+ def preprocess_image(self, image: Image.Image) -> Image.Image:
92
+ """
93
+ Preprocess image for colorization
94
+
95
+ Args:
96
+ image: PIL Image
97
+
98
+ Returns:
99
+ Preprocessed PIL Image
100
+ """
101
+ # Convert to grayscale if needed
102
+ if image.mode != "L":
103
+ # Convert to grayscale
104
+ image = image.convert("L")
105
+
106
+ # Convert back to RGB (grayscale image with 3 channels)
107
+ image = image.convert("RGB")
108
+
109
+ # Resize to standard size (512x512 for SD models)
110
+ image = image.resize((512, 512), Image.Resampling.LANCZOS)
111
+
112
+ return image
113
+
114
+ def colorize(self, image: Image.Image, num_inference_steps: int = 20) -> Image.Image:
115
+ """
116
+ Colorize a grayscale image
117
+
118
+ Args:
119
+ image: PIL Image (grayscale or color)
120
+ num_inference_steps: Number of inference steps
121
+
122
+ Returns:
123
+ Colorized PIL Image
124
+ """
125
+ try:
126
+ # Preprocess image
127
+ control_image = self.preprocess_image(image)
128
+ original_size = image.size
129
+
130
+ # Prepare prompt for colorization
131
+ prompt = "colorize this black and white image, high quality, detailed, vibrant colors, natural colors"
132
+ negative_prompt = "black and white, grayscale, monochrome, low quality, blurry, desaturated"
133
+
134
+ # Generate colorized image based on model type
135
+ if self.model_type == "controlnet":
136
+ # Use ControlNet pipeline
137
+ result = self.pipe(
138
+ prompt=prompt,
139
+ image=control_image,
140
+ negative_prompt=negative_prompt,
141
+ num_inference_steps=num_inference_steps,
142
+ guidance_scale=7.5,
143
+ controlnet_conditioning_scale=1.0,
144
+ generator=torch.Generator(device=self.device).manual_seed(42)
145
+ )
146
+
147
+ if isinstance(result, dict) and "images" in result:
148
+ colorized = result["images"][0]
149
+ elif isinstance(result, list) and len(result) > 0:
150
+ colorized = result[0]
151
+ else:
152
+ colorized = result
153
+ else:
154
+ # Use pipeline directly
155
+ result = self.pipe(
156
+ control_image,
157
+ prompt=prompt,
158
+ num_inference_steps=num_inference_steps
159
+ )
160
+
161
+ if isinstance(result, dict) and "images" in result:
162
+ colorized = result["images"][0]
163
+ elif isinstance(result, list) and len(result) > 0:
164
+ colorized = result[0]
165
+ else:
166
+ colorized = result
167
+
168
+ # Ensure we have a PIL Image
169
+ if not isinstance(colorized, Image.Image):
170
+ if isinstance(colorized, np.ndarray):
171
+ # Handle numpy array
172
+ if colorized.dtype != np.uint8:
173
+ colorized = (colorized * 255).astype(np.uint8)
174
+ if len(colorized.shape) == 3 and colorized.shape[2] == 3:
175
+ colorized = Image.fromarray(colorized, 'RGB')
176
+ else:
177
+ colorized = Image.fromarray(colorized)
178
+ elif torch.is_tensor(colorized):
179
+ # Handle torch tensor
180
+ colorized = colorized.cpu().permute(1, 2, 0).numpy()
181
+ colorized = (colorized * 255).astype(np.uint8)
182
+ colorized = Image.fromarray(colorized, 'RGB')
183
+ else:
184
+ raise ValueError(f"Unexpected output type: {type(colorized)}")
185
+
186
+ # Resize back to original size
187
+ if original_size != (512, 512):
188
+ colorized = colorized.resize(original_size, Image.Resampling.LANCZOS)
189
+
190
+ return colorized
191
+
192
+ except Exception as e:
193
+ logger.error("Error during colorization: %s", str(e))
194
+ raise
195
+
app/config.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Configuration settings for the application
3
+ """
4
+ import os
5
+ from pydantic_settings import BaseSettings
6
+
7
+ class Settings(BaseSettings):
8
+ """Application settings"""
9
+
10
+ # Firebase settings
11
+ ENABLE_APP_CHECK: bool = os.getenv("ENABLE_APP_CHECK", "true").lower() == "true"
12
+ FIREBASE_CREDENTIALS_PATH: str = os.getenv(
13
+ "FIREBASE_CREDENTIALS_PATH",
14
+ "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json"
15
+ )
16
+
17
+ # API settings
18
+ BASE_URL: str = os.getenv("BASE_URL", "http://localhost:8000")
19
+
20
+ # Model settings
21
+ MODEL_ID: str = os.getenv("MODEL_ID", "rsortino/ColorizeNet")
22
+ NUM_INFERENCE_STEPS: int = int(os.getenv("NUM_INFERENCE_STEPS", "20"))
23
+
24
+ # Storage settings
25
+ UPLOAD_DIR: str = os.getenv("UPLOAD_DIR", "uploads")
26
+ RESULT_DIR: str = os.getenv("RESULT_DIR", "results")
27
+
28
+ class Config:
29
+ env_file = ".env"
30
+ case_sensitive = False
31
+
32
+ settings = Settings()
33
+
app/main.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ FastAPI application for image colorization using ColorizeNet model
3
+ with Firebase App Check integration
4
+ """
5
+ import os
6
+ import uuid
7
+ import logging
8
+ from pathlib import Path
9
+ from typing import Optional
10
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Depends, Request
11
+ from fastapi.responses import FileResponse, JSONResponse
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from fastapi.staticfiles import StaticFiles
14
+ import firebase_admin
15
+ from firebase_admin import credentials, app_check
16
+ import cv2
17
+ import numpy as np
18
+ import torch
19
+ from PIL import Image
20
+ import io
21
+
22
+ from app.colorize_model import ColorizeModel
23
+ from app.config import settings
24
+
25
+ # Configure logging
26
+ logging.basicConfig(
27
+ level=logging.INFO,
28
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
29
+ )
30
+ logger = logging.getLogger(__name__)
31
+
32
+ # Initialize FastAPI app
33
+ app = FastAPI(
34
+ title="Colorize API",
35
+ description="Image colorization API using ColorizeNet model",
36
+ version="1.0.0"
37
+ )
38
+
39
+ # CORS middleware
40
+ app.add_middleware(
41
+ CORSMiddleware,
42
+ allow_origins=["*"], # Configure appropriately for production
43
+ allow_credentials=True,
44
+ allow_methods=["*"],
45
+ allow_headers=["*"],
46
+ )
47
+
48
+ # Initialize Firebase Admin SDK
49
+ firebase_cred_path = os.getenv("FIREBASE_CREDENTIALS_PATH", "colorize-662df-firebase-adminsdk-fbsvc-e080668793.json")
50
+ if os.path.exists(firebase_cred_path):
51
+ try:
52
+ cred = credentials.Certificate(firebase_cred_path)
53
+ firebase_admin.initialize_app(cred)
54
+ logger.info("Firebase Admin SDK initialized")
55
+ except Exception as e:
56
+ logger.warning("Failed to initialize Firebase: %s", str(e))
57
+ firebase_admin.initialize_app()
58
+ else:
59
+ logger.warning("Firebase credentials file not found. App Check will be disabled.")
60
+ try:
61
+ firebase_admin.initialize_app()
62
+ except:
63
+ pass
64
+
65
+ # Create directories
66
+ UPLOAD_DIR = Path("uploads")
67
+ RESULT_DIR = Path("results")
68
+ UPLOAD_DIR.mkdir(exist_ok=True)
69
+ RESULT_DIR.mkdir(exist_ok=True)
70
+
71
+ # Mount static files for serving results
72
+ app.mount("/results", StaticFiles(directory="results"), name="results")
73
+ app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
74
+
75
+ # Initialize ColorizeNet model
76
+ colorize_model = None
77
+
78
+ @app.on_event("startup")
79
+ async def startup_event():
80
+ """Initialize the colorization model on startup"""
81
+ global colorize_model
82
+ try:
83
+ logger.info("Loading ColorizeNet model...")
84
+ colorize_model = ColorizeModel()
85
+ logger.info("ColorizeNet model loaded successfully")
86
+ except Exception as e:
87
+ logger.error("Failed to load ColorizeNet model: %s", str(e))
88
+ # Don't raise - allow health check to work even if model fails
89
+
90
+ @app.on_event("shutdown")
91
+ async def shutdown_event():
92
+ """Cleanup on shutdown"""
93
+ global colorize_model
94
+ if colorize_model:
95
+ del colorize_model
96
+ logger.info("Application shutdown")
97
+
98
+ # Firebase App Check verification
99
+ async def verify_app_check(request: Request):
100
+ """Verify Firebase App Check token"""
101
+ if not settings.ENABLE_APP_CHECK:
102
+ return True
103
+
104
+ app_check_token = request.headers.get("X-Firebase-AppCheck")
105
+ if not app_check_token:
106
+ raise HTTPException(
107
+ status_code=401,
108
+ detail="Missing App Check token"
109
+ )
110
+
111
+ try:
112
+ # Verify the App Check token
113
+ app_check_claims = app_check.verify_token(app_check_token)
114
+ logger.info("App Check token verified for: %s", app_check_claims.get("app_id"))
115
+ return True
116
+ except Exception as e:
117
+ logger.warning("App Check token verification failed: %s", str(e))
118
+ raise HTTPException(
119
+ status_code=401,
120
+ detail="Invalid App Check token"
121
+ )
122
+
123
+ @app.get("/health")
124
+ async def health_check():
125
+ """Health check endpoint"""
126
+ return {
127
+ "status": "healthy",
128
+ "model_loaded": colorize_model is not None
129
+ }
130
+
131
+ @app.post("/upload")
132
+ async def upload_image(
133
+ file: UploadFile = File(...),
134
+ verified: bool = Depends(verify_app_check)
135
+ ):
136
+ """
137
+ Upload an image and return the uploaded image URL
138
+ """
139
+ if not file.content_type or not file.content_type.startswith("image/"):
140
+ raise HTTPException(status_code=400, detail="File must be an image")
141
+
142
+ # Generate unique filename
143
+ file_id = str(uuid.uuid4())
144
+ file_extension = Path(file.filename).suffix or ".jpg"
145
+ filename = f"{file_id}{file_extension}"
146
+ filepath = UPLOAD_DIR / filename
147
+
148
+ # Save uploaded file
149
+ try:
150
+ contents = await file.read()
151
+ with open(filepath, "wb") as f:
152
+ f.write(contents)
153
+ logger.info("Image uploaded: %s", filename)
154
+
155
+ # Return the URL to access the uploaded image
156
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
157
+ image_url = f"{base_url}/uploads/{filename}"
158
+
159
+ return {
160
+ "success": True,
161
+ "image_id": file_id,
162
+ "image_url": image_url,
163
+ "filename": filename
164
+ }
165
+ except Exception as e:
166
+ logger.error("Error uploading image: %s", str(e))
167
+ raise HTTPException(status_code=500, detail=f"Error uploading image: {str(e)}")
168
+
169
+ @app.post("/colorize")
170
+ async def colorize_image(
171
+ file: UploadFile = File(...),
172
+ verified: bool = Depends(verify_app_check)
173
+ ):
174
+ """
175
+ Colorize an uploaded grayscale image using ColorizeNet
176
+ Returns the colorized image URL
177
+ """
178
+ if colorize_model is None:
179
+ raise HTTPException(status_code=503, detail="Colorization model not loaded")
180
+
181
+ if not file.content_type or not file.content_type.startswith("image/"):
182
+ raise HTTPException(status_code=400, detail="File must be an image")
183
+
184
+ try:
185
+ # Read image
186
+ contents = await file.read()
187
+ image = Image.open(io.BytesIO(contents))
188
+
189
+ # Convert to RGB if needed
190
+ if image.mode != "RGB":
191
+ image = image.convert("RGB")
192
+
193
+ # Colorize the image
194
+ logger.info("Colorizing image...")
195
+ colorized_image = colorize_model.colorize(image)
196
+
197
+ # Save colorized image
198
+ file_id = str(uuid.uuid4())
199
+ result_filename = f"{file_id}.jpg"
200
+ result_filepath = RESULT_DIR / result_filename
201
+
202
+ colorized_image.save(result_filepath, "JPEG", quality=95)
203
+ logger.info("Colorized image saved: %s", result_filename)
204
+
205
+ # Return URLs
206
+ base_url = os.getenv("BASE_URL", os.getenv("SPACE_HOST", "http://localhost:7860"))
207
+ download_url = f"{base_url}/results/{result_filename}"
208
+ api_download_url = f"{base_url}/download/{file_id}"
209
+
210
+ return {
211
+ "success": True,
212
+ "result_id": file_id,
213
+ "download_url": download_url,
214
+ "api_download_url": api_download_url,
215
+ "filename": result_filename
216
+ }
217
+ except Exception as e:
218
+ logger.error("Error colorizing image: %s", str(e))
219
+ raise HTTPException(status_code=500, detail=f"Error colorizing image: {str(e)}")
220
+
221
+ @app.get("/download/{file_id}")
222
+ async def download_result(
223
+ file_id: str,
224
+ verified: bool = Depends(verify_app_check)
225
+ ):
226
+ """
227
+ Download the colorized image by file ID
228
+ """
229
+ result_filepath = RESULT_DIR / f"{file_id}.jpg"
230
+
231
+ if not result_filepath.exists():
232
+ raise HTTPException(status_code=404, detail="Result not found")
233
+
234
+ return FileResponse(
235
+ result_filepath,
236
+ media_type="image/jpeg",
237
+ filename=f"colorized_{file_id}.jpg"
238
+ )
239
+
240
+ @app.get("/results/{filename}")
241
+ async def get_result_file(filename: str):
242
+ """
243
+ Serve result files directly (public endpoint for browser access)
244
+ """
245
+ result_filepath = RESULT_DIR / filename
246
+
247
+ if not result_filepath.exists():
248
+ raise HTTPException(status_code=404, detail="File not found")
249
+
250
+ return FileResponse(
251
+ result_filepath,
252
+ media_type="image/jpeg"
253
+ )
254
+
255
+ @app.get("/uploads/{filename}")
256
+ async def get_upload_file(filename: str):
257
+ """
258
+ Serve uploaded files directly
259
+ """
260
+ upload_filepath = UPLOAD_DIR / filename
261
+
262
+ if not upload_filepath.exists():
263
+ raise HTTPException(status_code=404, detail="File not found")
264
+
265
+ return FileResponse(
266
+ upload_filepath,
267
+ media_type="image/jpeg"
268
+ )
269
+
270
+ if __name__ == "__main__":
271
+ import uvicorn
272
+ port = int(os.getenv("PORT", "7860"))
273
+ uvicorn.run(app, host="0.0.0.0", port=port)
deploy.sh ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Deployment script for Hugging Face Spaces
3
+
4
+ echo "Deploying to Hugging Face Space..."
5
+
6
+ # Initialize git if not already
7
+ if [ ! -d ".git" ]; then
8
+ git init
9
+ fi
10
+
11
+ # Add all files
12
+ git add .
13
+
14
+ # Commit changes
15
+ git commit -m "Deploy Colorize API with Firebase App Check"
16
+
17
+ # Add Hugging Face remote (replace with your space URL)
18
+ git remote add origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize || git remote set-url origin https://huggingface.co/spaces/LogicGoInfotechSpaces/Colorize
19
+
20
+ # Push to Hugging Face
21
+ git push -u origin main
22
+
23
+ echo "Deployment complete!"
24
+
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ python-multipart==0.0.6
4
+ requests>=2.31.0
5
+ pillow==10.1.0
6
+ torch>=2.0.0
7
+ torchvision>=0.15.0
8
+ transformers>=4.30.0
9
+ diffusers>=0.21.0
10
+ accelerate>=0.20.0
11
+ opencv-python-headless==4.8.1.78
12
+ numpy>=1.24.0
13
+ firebase-admin>=6.0.0
14
+ pydantic-settings>=2.0.0
15
+ huggingface-hub>=0.16.0
16
+ safetensors>=0.3.0
17
+