async def project_activity_api(request: Request, factory=Depends(object_factory)): project = Project() if not project.exists(): raise HTTPException(status_code=404) try: timezone = request.cookies.get('__AIMDE__:TIMEZONE') if timezone: timezone = pytz.timezone(parse.unquote(timezone)) except Exception: timezone = None if not timezone: timezone = pytz.timezone('gmt') num_runs = 0 activity_counter = Counter() for run in factory.runs(): creation_time = run.created_at.replace( tzinfo=pytz.utc).astimezone(timezone) activity_counter[creation_time.strftime('%Y-%m-%d')] += 1 num_runs += 1 return { 'num_experiments': len(factory.experiments()), 'num_runs': num_runs, 'activity_map': dict(activity_counter), }
def figure_blobs_batch_api(uri_batch: URIBatchIn): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) return StreamingResponse(figure_batch_result_streamer(uri_batch, project.repo))
async def run_metric_search_api(q: Optional[str] = '', p: Optional[int] = 50, x_axis: Optional[str] = None): steps_num = p if x_axis: x_axis = x_axis.strip() # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) query = q.strip() try: syntax_error_check(query) except SyntaxError as se: raise HTTPException(status_code=400, detail={ 'name': 'SyntaxError', 'statement': se.text, 'line': se.lineno, 'offset': se.offset }) traces = project.repo.query_metrics(query=query) streamer = metric_search_result_streamer(traces, steps_num, x_axis) return StreamingResponse(streamer)
async def run_figures_search_api(q: Optional[str] = '', record_range: Optional[str] = '', record_density: Optional[int] = 50, calc_ranges: Optional[bool] = False): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) query = q.strip() try: syntax_error_check(query) except SyntaxError as se: raise HTTPException(status_code=400, detail={ 'name': 'SyntaxError', 'statement': se.text, 'line': se.lineno, 'offset': se.offset }) traces = project.repo.query_figure_objects(query=query) try: record_range = str_to_range(record_range) except ValueError: raise HTTPException(status_code=400, detail='Invalid range format') streamer = figure_search_result_streamer(traces, record_range, record_density, calc_ranges) return StreamingResponse(streamer)
def object_factory(): from aim.web.api.projects.project import Project project = Project() if not project.exists(): raise HTTPException(status_code=404) return project.repo.structured_db
async def project_params_api(): project = Project() if not project.exists(): raise HTTPException(status_code=404) return { 'params': project.repo.collect_params(), 'metrics': project.repo.collect_metrics(), }
async def run_search_api(q: Optional[str] = ''): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) query = q.strip() runs = project.repo.query_runs(query=query) streamer = run_search_result_streamer(runs) return StreamingResponse(streamer)
def run_metric_custom_align_api(request_data: MetricAlignApiIn): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) x_axis_metric_name = request_data.align_by requested_runs = request_data.runs streamer = custom_aligned_metrics_streamer(requested_runs, x_axis_metric_name, project.repo) return StreamingResponse(streamer)
async def project_api(): project = Project() if not project.exists(): raise HTTPException(status_code=404) return { 'name': project.name, 'path': project.path, 'description': project.description, 'telemetry_enabled': os.getenv(AIM_UI_TELEMETRY_KEY, '1'), }
async def run_metric_batch_api(run_id: str, requested_traces: RunTracesBatchApiIn): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) run = project.repo.get_run(run_id) if not run: raise HTTPException(status_code=404) traces_data = collect_requested_metric_traces(run, requested_traces) return JSONResponse(traces_data)
async def delete_runs_batch_api(runs_batch: RunsBatchIn): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) success, remaining_runs = project.repo.delete_runs(runs_batch) if not success: raise HTTPException(400, detail={'message': 'Error while deleting runs.', 'remaining_runs': remaining_runs}) return { 'status': 'OK' }
async def delete_run_api(run_id: str): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) success = project.repo.delete_run(run_id) if not success: raise HTTPException(400, detail=f'Error while deleting run {run_id}.') return { 'id': run_id, 'status': 'OK' }
async def run_params_api(run_id: str): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) run = project.repo.get_run(hashname=run_id) if not run: raise HTTPException(status_code=404) response = { 'params': run[...], 'traces': run.get_traces_overview(), 'props': get_run_props(run) } return JSONResponse(response)
async def run_metric_search_api(q: Optional[str] = '', p: int = 50, x_axis: Optional[str] = None): steps_num = p if x_axis: x_axis = x_axis.strip() # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) search_statement = q.strip() traces = project.repo.traces(query=search_statement) streamer = metric_search_result_streamer(traces, steps_num, x_axis) return StreamingResponse(streamer)
async def project_params_api(sequence: Optional[Tuple[str, ...]] = Query(())): project = Project() if not project.exists(): raise HTTPException(status_code=404) if sequence != (): try: project.repo.validate_sequence_types(sequence) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) else: sequence = project.repo.available_sequence_types() response = { 'params': project.repo.collect_params_info(), } response.update(**project.repo.collect_sequence_info(sequence)) return response
async def run_distributions_batch_api(run_id: str, requested_traces: RunTracesBatchApiIn, record_range: Optional[str] = '', record_density: Optional[int] = 50): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) run = project.repo.get_run(run_id) if not run: raise HTTPException(status_code=404) try: record_range = str_to_range(record_range) except ValueError: raise HTTPException(status_code=400, detail='Invalid range format') traces_streamer = requested_distribution_traces_streamer(run, requested_traces, record_range, record_density) return StreamingResponse(traces_streamer)
def run_search_api(q: Optional[str] = '', limit: Optional[int] = 0, offset: Optional[str] = None): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) query = q.strip() try: syntax_error_check(query) except SyntaxError as se: raise HTTPException(status_code=400, detail={ 'name': 'SyntaxError', 'statement': se.text, 'line': se.lineno, 'offset': se.offset }) runs = project.repo.query_runs(query=query, paginated=bool(limit), offset=offset) streamer = run_search_result_streamer(runs, limit) return StreamingResponse(streamer)
async def run_params_api(run_id: str, sequence: Optional[Tuple[str, ...]] = Query(())): # Get project project = Project() if not project.exists(): raise HTTPException(status_code=404) run = project.repo.get_run(run_id) if not run: raise HTTPException(status_code=404) if sequence != (): try: project.repo.validate_sequence_types(sequence) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) else: sequence = project.repo.available_sequence_types() response = { 'params': run.get(...), 'traces': run.collect_sequence_info(sequence, skip_last_value=True), 'props': get_run_props(run) } return JSONResponse(response)
async def get_experiment_runs_api(exp_id: str, limit: Optional[int] = None, offset: Optional[str] = None, factory=Depends(object_factory)): project = Project() exp = factory.find_experiment(exp_id) if not exp: raise HTTPException(status_code=404) from aim.sdk.run import Run cache_name = 'exp_runs' project.repo.run_props_cache_hint = cache_name project.repo.structured_db.invalidate_cache(cache_name) project.repo.structured_db.init_cache(cache_name, exp.get_runs, lambda run_: run_.hash) exp_runs = [] run_hashes = [run.hash for run in exp.runs] offset_idx = 0 if offset: try: offset_idx = run_hashes.index(offset) + 1 except ValueError: pass if limit: run_hashes = run_hashes[offset_idx:offset_idx + limit] for run_hash in run_hashes: run = Run(run_hash, repo=project.repo, read_only=True) exp_runs.append({ 'run_id': run.hash, 'name': run.name, 'creation_time': run.creation_time, 'end_time': run.end_time }) project.repo.structured_db.invalidate_cache(cache_name) project.repo.run_props_cache_hint = None response = {'id': exp.uuid, 'runs': exp_runs} return response
async def get_tagged_runs_api(tag_id: str, factory=Depends(object_factory)): project = Project() tag = factory.find_tag(tag_id) if not tag: raise HTTPException from aim.sdk.run import Run cache_name = 'tag_runs' project.repo.run_props_cache_hint = cache_name project.repo.structured_db.invalidate_cache(cache_name) project.repo.structured_db.init_cache(cache_name, tag.get_runs, lambda run_: run_.hash) tag_runs = [] for tagged_run in tag.runs: run = Run(tagged_run.hash, repo=project.repo, read_only=True) tag_runs.append({ 'run_id': tagged_run.hash, 'name': tagged_run.name, 'creation_time': run.creation_time, 'end_time': run.end_time, 'experiment': tagged_run.experiment if tagged_run.experiment else None }) project.repo.structured_db.invalidate_cache(cache_name) project.repo.run_props_cache_hint = None response = {'id': tag.uuid, 'runs': tag_runs} return response
async def serve_images(exp_name, commit_hash, path): project = Project() image_file = os.path.join(project.repo_path, exp_name, commit_hash, 'objects', 'media', 'images', path) return FileResponse(image_file)