00Boobs00 commited on
Commit
180578f
Β·
verified Β·
1 Parent(s): 43cdfe9

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +317 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * DeepStudio Pro - Enhanced Production Server
3
+ * Built with anycoder β†’ https://huggingface.co/spaces/akhaliq/anycoder
4
+ *
5
+ * Features:
6
+ * - Graceful shutdown handling
7
+ * - Request logging and metrics
8
+ * - Health check endpoint
9
+ * - Memory and performance monitoring
10
+ * - Security headers
11
+ */
12
+
13
+ const path = require('path');
14
+ const http = require('http');
15
+ const { parse } = require('url');
16
+
17
+ const dir = path.join(__dirname);
18
+
19
+ // Set production environment
20
+ process.env.NODE_ENV = 'production';
21
+ process.chdir(__dirname);
22
+
23
+ // Configuration with sensible defaults
24
+ const config = {
25
+ port: parseInt(process.env.PORT, 10) || 7860,
26
+ hostname: process.env.HOSTNAME || '0.0.0.0',
27
+ keepAliveTimeout: parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10) || 65000,
28
+ requestTimeout: parseInt(process.env.REQUEST_TIMEOUT, 10) || 30000,
29
+ maxRequestsPerSocket: parseInt(process.env.MAX_REQUESTS_PER_SOCKET, 10) || 0,
30
+ };
31
+
32
+ // Next.js configuration - optimized for production
33
+ const nextConfig = {
34
+ env: {},
35
+ webpack: null,
36
+ eslint: { ignoreDuringBuilds: true },
37
+ typescript: {
38
+ ignoreBuildErrors: false,
39
+ tsconfigPath: 'tsconfig.json'
40
+ },
41
+ distDir: './.next',
42
+ cleanDistDir: true,
43
+ assetPrefix: '',
44
+ cacheMaxMemorySize: 52428800,
45
+ configOrigin: 'next.config.ts',
46
+ useFileSystemPublicRoutes: true,
47
+ generateEtags: true,
48
+ pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
49
+ poweredByHeader: false, // Security: disable X-Powered-By
50
+ compress: true,
51
+ images: {
52
+ deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
53
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
54
+ path: '/_next/image',
55
+ loader: 'default',
56
+ loaderFile: '',
57
+ domains: [],
58
+ disableStaticImages: false,
59
+ minimumCacheTTL: 60,
60
+ formats: ['image/webp', 'image/avif'],
61
+ dangerouslyAllowSVG: false,
62
+ contentSecurityPolicy: "script-src 'none'; frame-src 'none'; sandbox;",
63
+ contentDispositionType: 'attachment',
64
+ remotePatterns: [],
65
+ unoptimized: false,
66
+ },
67
+ devIndicators: { position: 'bottom-left' },
68
+ onDemandEntries: { maxInactiveAge: 60000, pagesBufferLength: 5 },
69
+ amp: { canonicalBase: '' },
70
+ basePath: '',
71
+ sassOptions: {},
72
+ trailingSlash: false,
73
+ i18n: null,
74
+ productionBrowserSourceMaps: false,
75
+ excludeDefaultMomentLocales: true,
76
+ serverRuntimeConfig: {},
77
+ publicRuntimeConfig: {},
78
+ reactProductionProfiling: false,
79
+ reactStrictMode: true,
80
+ reactMaxHeadersLength: 6000,
81
+ httpAgentOptions: { keepAlive: true },
82
+ logging: {},
83
+ expireTime: 31536000,
84
+ staticPageGenerationTimeout: 60,
85
+ output: 'standalone',
86
+ modularizeImports: {
87
+ '@mui/icons-material': { transform: '@mui/icons-material/{{member}}' },
88
+ 'lodash': { transform: 'lodash/{{member}}' },
89
+ },
90
+ outputFileTracingRoot: process.cwd(),
91
+ experimental: {
92
+ optimizeCss: true,
93
+ optimizePackageImports: [
94
+ 'lucide-react',
95
+ 'date-fns',
96
+ 'lodash-es',
97
+ 'ramda',
98
+ 'antd',
99
+ 'react-bootstrap',
100
+ 'ahooks',
101
+ '@ant-design/icons',
102
+ '@headlessui/react',
103
+ '@headlessui-float/react',
104
+ '@heroicons/react/20/solid',
105
+ '@heroicons/react/24/solid',
106
+ '@heroicons/react/24/outline',
107
+ '@visx/visx',
108
+ '@tremor/react',
109
+ 'rxjs',
110
+ '@mui/material',
111
+ '@mui/icons-material',
112
+ 'recharts',
113
+ 'react-use',
114
+ 'framer-motion',
115
+ '@radix-ui/react-icons',
116
+ ],
117
+ },
118
+ };
119
+
120
+ // Serialize config for Next.js
121
+ process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig);
122
+
123
+ // Metrics tracking
124
+ const metrics = {
125
+ startTime: Date.now(),
126
+ requests: { total: 0, success: 0, error: 0 },
127
+ activeConnections: 0,
128
+ };
129
+
130
+ // Request logging middleware
131
+ function logRequest(req, res, startTime) {
132
+ const duration = Date.now() - startTime;
133
+ const logEntry = {
134
+ timestamp: new Date().toISOString(),
135
+ method: req.method,
136
+ url: req.url,
137
+ status: res.statusCode,
138
+ duration: `${duration}ms`,
139
+ userAgent: req.headers['user-agent'],
140
+ ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress,
141
+ };
142
+
143
+ // Log errors with more detail
144
+ if (res.statusCode >= 400) {
145
+ console.error('[REQUEST ERROR]', JSON.stringify(logEntry));
146
+ metrics.requests.error++;
147
+ } else {
148
+ console.log('[REQUEST]', JSON.stringify(logEntry));
149
+ metrics.requests.success++;
150
+ }
151
+ metrics.requests.total++;
152
+ }
153
+
154
+ // Security headers middleware
155
+ function setSecurityHeaders(res) {
156
+ res.setHeader('X-DNS-Prefetch-Control', 'on');
157
+ res.setHeader('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
158
+ res.setHeader('X-Frame-Options', 'SAMEORIGIN');
159
+ res.setHeader('X-Content-Type-Options', 'nosniff');
160
+ res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
161
+ res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
162
+ }
163
+
164
+ // Health check handler
165
+ function healthCheck(req, res) {
166
+ const uptime = Date.now() - metrics.startTime;
167
+ const health = {
168
+ status: 'healthy',
169
+ timestamp: new Date().toISOString(),
170
+ uptime: `${Math.floor(uptime / 1000)}s`,
171
+ version: process.env.npm_package_version || '2.0.0',
172
+ nodejs: process.version,
173
+ memory: process.memoryUsage(),
174
+ metrics: {
175
+ requests: metrics.requests,
176
+ activeConnections: metrics.activeConnections,
177
+ },
178
+ };
179
+
180
+ res.writeHead(200, { 'Content-Type': 'application/json' });
181
+ res.end(JSON.stringify(health, null, 2));
182
+ }
183
+
184
+ // Metrics endpoint for monitoring
185
+ function metricsEndpoint(req, res) {
186
+ res.writeHead(200, { 'Content-Type': 'application/json' });
187
+ res.end(JSON.stringify({
188
+ ...metrics,
189
+ memory: process.memoryUsage(),
190
+ cpu: process.cpuUsage(),
191
+ uptime: process.uptime(),
192
+ }, null, 2));
193
+ }
194
+
195
+ // Main server startup
196
+ async function startServer() {
197
+ const { startServer: startNextServer } = require('next/dist/server/lib/start-server');
198
+
199
+ // Validate keep-alive timeout
200
+ let keepAliveTimeout = config.keepAliveTimeout;
201
+ if (
202
+ Number.isNaN(keepAliveTimeout) ||
203
+ !Number.isFinite(keepAliveTimeout) ||
204
+ keepAliveTimeout < 0
205
+ ) {
206
+ keepAliveTimeout = undefined;
207
+ }
208
+
209
+ console.log(`
210
+ ╔══════════════════════════════════════════════════════════════╗
211
+ β•‘ DeepStudio Pro - Starting Production Server β•‘
212
+ β•‘ Built with anycoder β†’ https://huggingface.co/spaces/akhaliq/anycoder β•‘
213
+ ╠══════════════════════════════════════════════════════════════╣
214
+ Port: ${config.port}
215
+ Hostname: ${config.hostname}
216
+ Node Env: ${process.env.NODE_ENV}
217
+ Node Ver: ${process.version}
218
+ Start Time: ${new Date().toISOString()}
219
+ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
220
+ `);
221
+
222
+ try {
223
+ // Start the Next.js server
224
+ const server = await startNextServer({
225
+ dir,
226
+ isDev: false,
227
+ config: nextConfig,
228
+ hostname: config.hostname,
229
+ port: config.port,
230
+ allowRetry: false,
231
+ keepAliveTimeout,
232
+ });
233
+
234
+ // Get the underlying HTTP server to add custom middleware
235
+ const httpServer = server.server;
236
+
237
+ // Track connections for graceful shutdown
238
+ httpServer.on('connection', (socket) => {
239
+ metrics.activeConnections++;
240
+ socket.on('close', () => {
241
+ metrics.activeConnections--;
242
+ });
243
+ });
244
+
245
+ // Custom request handling for health checks and metrics
246
+ const originalHandler = httpServer.listeners('request')[0];
247
+ httpServer.removeAllListeners('request');
248
+
249
+ httpServer.on('request', (req, res) => {
250
+ const startTime = Date.now();
251
+
252
+ // Set security headers on all responses
253
+ setSecurityHeaders(res);
254
+
255
+ // Intercept health check requests
256
+ const parsedUrl = parse(req.url, true);
257
+ if (parsedUrl.pathname === '/api/health') {
258
+ healthCheck(req, res);
259
+ return;
260
+ }
261
+
262
+ // Metrics endpoint (basic auth in production recommended)
263
+ if (parsedUrl.pathname === '/api/metrics') {
264
+ metricsEndpoint(req, res);
265
+ return;
266
+ }
267
+
268
+ // Log response when finished
269
+ res.on('finish', () => logRequest(req, res, startTime));
270
+
271
+ // Pass to Next.js handler
272
+ originalHandler(req, res);
273
+ });
274
+
275
+ // Graceful shutdown handling
276
+ const shutdown = (signal) => {
277
+ console.log(`\n[SHUTDOWN] Received ${signal}. Starting graceful shutdown...`);
278
+ console.log(`[SHUTDOWN] Active connections: ${metrics.activeConnections}`);
279
+
280
+ // Stop accepting new connections
281
+ httpServer.close(() => {
282
+ console.log('[SHUTDOWN] HTTP server closed');
283
+ process.exit(0);
284
+ });
285
+
286
+ // Force shutdown after timeout
287
+ setTimeout(() => {
288
+ console.error('[SHUTDOWN] Forced shutdown after timeout');
289
+ process.exit(1);
290
+ }, 30000);
291
+ };
292
+
293
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
294
+ process.on('SIGINT', () => shutdown('SIGINT'));
295
+
296
+ // Handle uncaught errors
297
+ process.on('uncaughtException', (err) => {
298
+ console.error('[FATAL] Uncaught exception:', err);
299
+ process.exit(1);
300
+ });
301
+
302
+ process.on('unhandledRejection', (reason, promise) => {
303
+ console.error('[FATAL] Unhandled rejection at:', promise, 'reason:', reason);
304
+ process.exit(1);
305
+ });
306
+
307
+ console.log(`[READY] Server running at http://${config.hostname}:${config.port}`);
308
+ return server;
309
+
310
+ } catch (err) {
311
+ console.error('[FATAL] Failed to start server:', err);
312
+ process.exit(1);
313
+ }
314
+ }
315
+
316
+ // Start the server
317
+ startServer();
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ # No additional dependencies required