# # This file is part of gunicorn released under the MIT license. # See the NOTICE for more information. """ Example WSGI Application that uses Dirty Workers This demonstrates how HTTP workers can call dirty workers for heavy operations like ML inference. Run with: cd examples/dirty_example gunicorn wsgi_app:app -c gunicorn_conf.py """ import json import os from urllib.parse import parse_qs def get_dirty_client(): """Get the dirty client, with fallback for when dirty workers aren't enabled.""" try: from gunicorn.dirty import get_dirty_client as _get_dirty_client return _get_dirty_client() except Exception as e: return None def app(environ, start_response): """WSGI application that demonstrates dirty worker integration.""" path = environ.get('PATH_INFO', '/') method = environ.get('REQUEST_METHOD', 'GET') # Parse query string query = parse_qs(environ.get('QUERY_STRING', '')) # Get dirty client client = get_dirty_client() try: if path == '/': result = { "message": "Dirty Workers Demo", "dirty_enabled": client is not None, "pid": os.getpid(), "endpoints": { "/models": "List loaded models", "/load?name=MODEL": "Load a model", "/inference?model=NAME&data=INPUT": "Run inference", "/unload?name=MODEL": "Unload a model", "/fibonacci?n=NUMBER": "Compute fibonacci", "/prime?n=NUMBER": "Check if prime", "/stats": "Get dirty worker stats", "/session/login?user_id=ID&name=NAME": "Login user (stash demo)", "/session/get?user_id=ID": "Get session (stash demo)", "/session/list": "List all sessions (stash demo)", "/session/logout?user_id=ID": "Logout user (stash demo)", "/session/stats": "Get stash stats (stash demo)", } } elif path == '/models': if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:MLApp", "list_models" ) elif path == '/load': name = query.get('name', ['model1'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:MLApp", "load_model", name ) elif path == '/inference': model = query.get('model', ['default'])[0] data = query.get('data', ['test input'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:MLApp", "inference", model, data ) elif path == '/unload': name = query.get('name', ['model1'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:MLApp", "unload_model", name ) elif path == '/fibonacci': n = int(query.get('n', ['10'])[0]) if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:ComputeApp", "fibonacci", n ) elif path == '/prime': n = int(query.get('n', ['17'])[0]) if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:ComputeApp", "prime_check", n ) elif path == '/stats': if client is None: result = {"error": "Dirty workers not enabled"} else: ml_stats = client.execute( "examples.dirty_example.dirty_app:MLApp", "list_models" ) compute_stats = client.execute( "examples.dirty_example.dirty_app:ComputeApp", "stats" ) result = { "ml_app": ml_stats, "compute_app": compute_stats, "http_worker_pid": os.getpid(), } # ===================================================================== # Session endpoints (stash demo) # ===================================================================== elif path == '/session/login': user_id = query.get('user_id', ['1'])[0] name = query.get('name', ['Anonymous'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "login", user_id=user_id, user_data={"name": name} ) elif path == '/session/get': user_id = query.get('user_id', ['1'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "get_session", user_id=user_id ) elif path == '/session/list': if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "list_sessions" ) elif path == '/session/logout': user_id = query.get('user_id', ['1'])[0] if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "logout", user_id=user_id ) elif path == '/session/stats': if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "get_stats" ) elif path == '/session/clear': if client is None: result = {"error": "Dirty workers not enabled"} else: result = client.execute( "examples.dirty_example.dirty_app:SessionApp", "clear_all" ) else: start_response('404 Not Found', [('Content-Type', 'application/json')]) return [json.dumps({"error": "Not found"}).encode()] # Success response start_response('200 OK', [('Content-Type', 'application/json')]) return [json.dumps(result, indent=2).encode()] except Exception as e: start_response('500 Internal Server Error', [('Content-Type', 'application/json')]) return [json.dumps({ "error": str(e), "type": type(e).__name__ }).encode()]