Download space_app.py from Chungulus/brain-lab: direct link, hf CLI and curl.
- Browser
- Download file 6.14 kB
-
https://huggingface.co/spaces/Chungulus/brain-lab/resolve/main/space_app.py
- Command line
-
hf download hf://spaces/Chungulus/brain-lab/space_app.py
-
curl -L -o space_app.py https://huggingface.co/spaces/Chungulus/brain-lab/resolve/main/space_app.py
6.14 kB
| """CPU Space adapter for the existing classroom app and saved research outputs.""" | |
| import json | |
| import os | |
| from pathlib import Path | |
| import shutil | |
| import sys | |
| import time | |
| from shared_usage import SharedUsage,SharedLimit | |
| ROOT=Path(__file__).resolve().parent/'brain_lab' | |
| sys.path.insert(0,str(ROOT)) | |
| import server as lab | |
| from fastapi import Request,HTTPException | |
| from fastapi.responses import FileResponse,JSONResponse | |
| from backend import credentials,mario,ml,mindeye_live | |
| app=lab.app | |
| ml.torch.set_num_threads(int(os.environ.get('BRAIN_LAB_THREADS','2'))) | |
| ml.DEVICE='cpu' | |
| if sys.platform!='darwin' or not mario.JAVA.is_file(): | |
| mario.JAVA=Path(shutil.which('java') or '/unavailable-java') | |
| mario.JAVAC=Path(shutil.which('javac') or '/unavailable-javac') | |
| # Owner-authorized shared keys are provided only through encrypted Space secrets. | |
| # Standard workstation environment variables and Keychain are never consulted. | |
| def space_key(provider): | |
| name={'openrouter':'BRAIN_LAB_OPENROUTER_API_KEY','perplexity':'BRAIN_LAB_PERPLEXITY_API_KEY'}.get(provider) | |
| return os.environ.get(name,'').strip() if name else '' | |
| credentials.get_key=space_key | |
| lab.sketch_provider.get_key=credentials.get_key | |
| shared_usage=SharedUsage(ROOT/'data/shared_recognition_usage.sqlite3', | |
| daily=max(1,min(2000,int(os.environ.get('BRAIN_LAB_SHARED_DAILY','200')))), | |
| per_minute=max(1,min(60,int(os.environ.get('BRAIN_LAB_SHARED_PER_MINUTE','20'))))) | |
| _seen={} | |
| def owner_key_needed(config): | |
| keys=config.get('api_keys',{});provider=config.get('provider','openrouter') | |
| return bool((not keys.get(provider) and space_key(provider)) or | |
| (not keys.get('openrouter') and space_key('openrouter'))) | |
| async def cpu_space_policy(request,call_next): | |
| path=request.url.path | |
| if request.method=='POST' and (path=='/api/tribe/jobs' or path=='/api/tribe/demo' or | |
| path.startswith('/api/mindeye/live/') or path=='/api/cinema'): | |
| return JSONResponse({'detail':'New large-model predictions are not enabled on this CPU Space. The saved Cinema clips and published MindEye2 replay are ready to use.'},status_code=503) | |
| # Expire unused game sessions and their Java processes; live requests keep | |
| # the visitor's session. No private histories are copied into the Space. | |
| if path.startswith('/api/'): | |
| sid=request.headers.get('X-Lab-Session','classroom');now=time.monotonic() | |
| with lab.STATE_LOCK: | |
| for old,stamp in list(_seen.items()): | |
| if old!=sid and now-stamp>1800: | |
| state=lab.STATES.pop(old,None);_seen.pop(old,None) | |
| if state and state.get('mario'): | |
| try:state['mario'].close() | |
| except OSError:pass | |
| _seen[sid]=now | |
| response=await call_next(request) | |
| response.headers['X-Brain-Lab-Edition']='spaces-cpu' | |
| return response | |
| def health(): | |
| return {'app':'Brain Lab','edition':'spaces-cpu','saved_clips':len(lab.clip_library._clips()), | |
| 'large_model_jobs_enabled':False, | |
| 'api_keys':'owner-space-secrets' if space_key('openrouter') else 'visitor-session-only'} | |
| # Serve already-computed model outputs as immutable compressed JSON, without | |
| # repeatedly converting the large prediction arrays on a shared CPU. | |
| app.router.routes=[r for r in app.router.routes if getattr(r,'path','') not in | |
| ['/api/tribe/results/{ident}','/api/mindeye/live/status','/api/sketch/config','/api/sketch']] | |
| def cached_response(ident:str): | |
| if not ident.isalnum() or len(ident)!=32: | |
| return JSONResponse({'detail':'Saved prediction not found.'},status_code=404) | |
| path=ROOT/'data/space_results'/(ident+'.json.gz') | |
| if not path.is_file():return JSONResponse({'detail':'Saved prediction not found.'},status_code=404) | |
| return FileResponse(path,media_type='application/json',headers={'Content-Encoding':'gzip'}) | |
| def live_status(): | |
| result=mindeye_live.status() | |
| result.update(hosted_cpu=True,installed=False,recorded_scan_tested=False,recorded_examples=[], | |
| note='Fresh fMRI decoding is not configured on this CPU Space. Published research comparisons remain available.') | |
| return result | |
| def sketch_config(request:Request): | |
| config=lab.session(request)[1]['sketch_config'] | |
| result=lab.sketch_provider.config_status(config) | |
| shared=bool(result['key_configured'] and owner_key_needed(config)) | |
| result.update(hosted=True,global_storage_available=False,shared_key_enabled=shared, | |
| key_source='classroom' if shared else 'visitor' if result['key_configured'] else 'missing', | |
| shared_allowance=shared_usage.summary() if shared else None) | |
| return result | |
| def set_sketch_config(body:lab.SketchConfig,request:Request): | |
| if body.save_globally: | |
| return JSONResponse({'detail':'Keys can be used only for this visitor session; global key storage is disabled on the public site.'},status_code=400) | |
| _,state=lab.session(request);state['sketch_config']['provider']=body.provider | |
| if body.api_key:state['sketch_config'].setdefault('api_keys',{})[body.provider]=body.api_key | |
| return sketch_config(request) | |
| def recognize(body:lab.SketchRequest,request:Request): | |
| _,state=lab.session(request);lab.require(state,'occipital','thalamus') | |
| if body.hint:lab.require(state,'wernicke','association','frontal') | |
| image=ml.decode_image(body.image);config=state['sketch_config'] | |
| # Blank previews never make a provider request or consume the shared quota. | |
| blank=lab.np.count_nonzero(lab.np.asarray(image.convert('L'))<220)<8 | |
| if owner_key_needed(config) and not blank: | |
| try: | |
| with shared_usage.lease():return lab.sketch_provider.recognize(image,config,body.hint) | |
| except SharedLimit as error:raise HTTPException(429,str(error)) from None | |
| return lab.sketch_provider.recognize(image,config,body.hint) | |