openrunner-sdk 2.8.0__tar.gz → 2.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/PKG-INFO +1 -1
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/__init__.py +1 -1
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/session.py +77 -55
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/pyproject.toml +1 -1
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/.gitignore +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/=6.0 +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/=8.1 +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/README.md +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/api_client.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/artifact.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/buffer.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cache.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cli.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/config.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/cost.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/dataset.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/environment.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/evaluation.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/feedback.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/git_info.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/guardrails.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/install_commands.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/__init__.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/accelerate.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/anthropic_tracer.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/catboost.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/diffusers.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/fastai.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/forced_alignment.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/gladia.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/gymnasium.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/huggingface.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/hydra.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/ignite.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/jax.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/keras.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/langchain.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/lightgbm.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/lightning.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/llamaindex.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/openai_finetune.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/openai_tracer.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/optuna.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/pytorch.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/sb3.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/sklearn.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/tensorflow.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/trl.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/tts.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/ultralytics.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/voice_agent.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/whisper.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/integration/xgboost.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/launch.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/media.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/migrate.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/model.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/offline.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/pii.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/plot.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/prompt.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/query_api.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/redact.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/run.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/scorers.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/sender.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/settings.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/summary.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/sweep.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/system_metrics.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/tensorboard.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/trace.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/transcript_formatter.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wal.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wandb_compat/__init__.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wandb_compat/_shim.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/openrunner/wer.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/__init__.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/conftest.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_alert.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_aliases.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_api_client.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_artifact.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_buffer.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_cache.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_class_scorers.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_cli.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_config.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_evaluation.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_finish.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_git_info.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_init.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_fastai.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_huggingface.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_keras.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_langchain.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_lightning.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_pytorch.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_sklearn.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_integration_xgboost.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_launch.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_log.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_log_code.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_media.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_migrate.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_offline.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_offline_sync.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_pii.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_plot.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_query_api.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_resume.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sdk_features.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sender.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_summary.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_sweep.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_system_metrics.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_trace.py +0 -0
- {openrunner_sdk-2.8.0 → openrunner_sdk-2.9.0}/tests/test_wandb_compat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openrunner-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: OpenRunner SDK - W&B-compatible ML experiment tracking client
|
|
5
5
|
Project-URL: Homepage, https://github.com/jqueguiner/openrunner
|
|
6
6
|
Project-URL: Repository, https://github.com/jqueguiner/openrunner
|
|
@@ -120,7 +120,7 @@ launch.from_run = _launch_from_run # type: ignore[attr-defined]
|
|
|
120
120
|
# openrunner.trace.patch_openai() syntax
|
|
121
121
|
trace.patch_openai = _patch_openai # type: ignore[attr-defined]
|
|
122
122
|
|
|
123
|
-
__version__ = "2.
|
|
123
|
+
__version__ = "2.9.0"
|
|
124
124
|
|
|
125
125
|
logger = logging.getLogger("openrunner")
|
|
126
126
|
|
|
@@ -506,80 +506,102 @@ def sync_session_to_openrunner(
|
|
|
506
506
|
|
|
507
507
|
client = APIClient(base_url=base_url, api_key=api_key)
|
|
508
508
|
|
|
509
|
-
#
|
|
509
|
+
# Resolve project_id from "org/project" format
|
|
510
|
+
project_id = None
|
|
511
|
+
try:
|
|
512
|
+
projects = client.list_projects()
|
|
513
|
+
for p in projects:
|
|
514
|
+
org_name = p.get("org_name", "")
|
|
515
|
+
proj_name = p.get("name", "")
|
|
516
|
+
full_name = f"{org_name}/{proj_name}" if org_name else proj_name
|
|
517
|
+
if full_name == project or proj_name == project:
|
|
518
|
+
project_id = p.get("id")
|
|
519
|
+
break
|
|
520
|
+
except Exception:
|
|
521
|
+
pass
|
|
522
|
+
|
|
523
|
+
if not project_id:
|
|
524
|
+
# Fallback: try creating as a run (backward compat with older servers)
|
|
525
|
+
logger.warning(f"Could not resolve project '{project}', falling back to run creation")
|
|
526
|
+
return _sync_as_run_fallback(client, parsed, project, visibility)
|
|
527
|
+
|
|
528
|
+
# Build AI session data
|
|
529
|
+
source = parsed["source"]
|
|
530
|
+
project_hint = parsed.get("project_hint", "")
|
|
531
|
+
timestamp = parsed.get("ended_at", "")[:16].replace("T", " ")
|
|
532
|
+
|
|
533
|
+
if project_hint:
|
|
534
|
+
short_hint = project_hint.rsplit("/", 1)[-1] if "/" in project_hint else project_hint
|
|
535
|
+
title = f"{source}/{short_hint}/{timestamp}"
|
|
536
|
+
else:
|
|
537
|
+
title = f"{source}/{timestamp}"
|
|
538
|
+
|
|
539
|
+
group_key = f"{source}:{project_hint}" if project_hint else f"{source}:default"
|
|
540
|
+
|
|
541
|
+
session_data = {
|
|
542
|
+
"title": title,
|
|
543
|
+
"source": source,
|
|
544
|
+
"worktree": project_hint,
|
|
545
|
+
"group_key": group_key,
|
|
546
|
+
"summary": parsed.get("summary"),
|
|
547
|
+
"notes": _format_session_notes(parsed),
|
|
548
|
+
"first_message": parsed.get("first_message"),
|
|
549
|
+
"messages": parsed.get("messages"),
|
|
550
|
+
"message_count": parsed.get("message_count", 0),
|
|
551
|
+
"user_message_count": parsed.get("user_message_count", 0),
|
|
552
|
+
"total_tokens": parsed.get("total_tokens", 0),
|
|
553
|
+
"tools_used": parsed.get("tools_used", []),
|
|
554
|
+
"files_touched": parsed.get("files_touched", []),
|
|
555
|
+
"visibility": visibility,
|
|
556
|
+
"tags": [f"source:{source}", f"worktree:{group_key}"],
|
|
557
|
+
"redacted": bool(parsed.get("_redaction")),
|
|
558
|
+
"redaction_mode": parsed.get("_redaction", {}).get("mode") if parsed.get("_redaction") else None,
|
|
559
|
+
"session_file": parsed.get("session_file"),
|
|
560
|
+
"started_at": parsed.get("started_at"),
|
|
561
|
+
"ended_at": parsed.get("ended_at"),
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
# POST to /projects/{project_id}/ai-sessions
|
|
565
|
+
try:
|
|
566
|
+
resp = client._request("post", f"/projects/{project_id}/ai-sessions", json=session_data)
|
|
567
|
+
if resp.status_code in (200, 201):
|
|
568
|
+
result = resp.json()
|
|
569
|
+
client.close()
|
|
570
|
+
return result.get("id")
|
|
571
|
+
else:
|
|
572
|
+
# Server doesn't have AI sessions endpoint yet — fall back to run
|
|
573
|
+
logger.info("AI sessions endpoint not available, falling back to run")
|
|
574
|
+
return _sync_as_run_fallback(client, parsed, project, visibility)
|
|
575
|
+
except Exception as e:
|
|
576
|
+
logger.warning(f"AI session sync failed: {e}")
|
|
577
|
+
client.close()
|
|
578
|
+
return None
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
def _sync_as_run_fallback(client, parsed: dict, project: str, visibility: str) -> str | None:
|
|
582
|
+
"""Fallback: create a run if AI sessions endpoint not available."""
|
|
510
583
|
source = parsed["source"]
|
|
511
584
|
timestamp = parsed.get("ended_at", "")[:16].replace("T", " ")
|
|
512
585
|
project_hint = parsed.get("project_hint", "")
|
|
513
586
|
|
|
514
|
-
# Build display name: include worktree/project context
|
|
515
587
|
if project_hint:
|
|
516
|
-
# Shorten: /home/ubuntu/openrun → openrun
|
|
517
588
|
short_hint = project_hint.rsplit("/", 1)[-1] if "/" in project_hint else project_hint
|
|
518
589
|
run_name = f"{source}/{short_hint}/{timestamp}"
|
|
519
590
|
else:
|
|
520
591
|
run_name = f"{source}/{timestamp}"
|
|
521
592
|
|
|
522
|
-
# Group sessions by source project (worktree)
|
|
523
|
-
group_name = f"{source}:{project_hint}" if project_hint else f"{source}:default"
|
|
524
|
-
|
|
525
593
|
run_data = {
|
|
526
594
|
"project": project,
|
|
527
595
|
"display_name": run_name,
|
|
528
|
-
"group_name":
|
|
529
|
-
"
|
|
530
|
-
"source": source,
|
|
531
|
-
"session_file": parsed.get("session_file", ""),
|
|
532
|
-
"project_hint": project_hint,
|
|
533
|
-
"message_count": parsed.get("message_count", 0),
|
|
534
|
-
"user_message_count": parsed.get("user_message_count", 0),
|
|
535
|
-
"tools_used": parsed.get("tools_used", []),
|
|
536
|
-
"total_tokens": parsed.get("total_tokens", 0),
|
|
537
|
-
},
|
|
538
|
-
"tags": [f"source:{source}", "ai-session", f"visibility:{visibility}", f"worktree:{group_name}"],
|
|
596
|
+
"group_name": f"{source}:{project_hint}" if project_hint else f"{source}:default",
|
|
597
|
+
"tags": [f"source:{source}", "ai-session"],
|
|
539
598
|
"notes": _format_session_notes(parsed),
|
|
540
599
|
"state": "finished",
|
|
541
600
|
}
|
|
542
601
|
|
|
543
|
-
# Add redaction metadata if applied
|
|
544
|
-
if parsed.get("_redaction"):
|
|
545
|
-
run_data["config"]["redacted"] = True
|
|
546
|
-
run_data["config"]["redaction_mode"] = parsed["_redaction"]["mode"]
|
|
547
|
-
run_data["config"]["entities_redacted"] = parsed["_redaction"]["entities_redacted"]
|
|
548
|
-
|
|
549
602
|
result = client.create_run(run_data)
|
|
550
|
-
if not result:
|
|
551
|
-
logger.warning("Failed to create session run")
|
|
552
|
-
client.close()
|
|
553
|
-
return None
|
|
554
|
-
|
|
555
|
-
run_id = result.get("id")
|
|
556
|
-
|
|
557
|
-
# Log metrics
|
|
558
|
-
metrics = []
|
|
559
|
-
if parsed.get("total_tokens"):
|
|
560
|
-
metrics.append({"key": "tokens", "value": parsed["total_tokens"], "step": 1})
|
|
561
|
-
if parsed.get("message_count"):
|
|
562
|
-
metrics.append({"key": "messages", "value": parsed["message_count"], "step": 1})
|
|
563
|
-
if parsed.get("user_message_count"):
|
|
564
|
-
metrics.append({"key": "user_messages", "value": parsed["user_message_count"], "step": 1})
|
|
565
|
-
if parsed.get("files_touched"):
|
|
566
|
-
metrics.append({"key": "files_touched", "value": len(parsed["files_touched"]), "step": 1})
|
|
567
|
-
|
|
568
|
-
if metrics and run_id:
|
|
569
|
-
client.post_metrics(run_id, metrics)
|
|
570
|
-
|
|
571
|
-
# Log files touched as summary
|
|
572
|
-
if parsed.get("files_touched") and run_id:
|
|
573
|
-
client.update_run(run_id, {
|
|
574
|
-
"summary": {
|
|
575
|
-
"files_touched": len(parsed["files_touched"]),
|
|
576
|
-
"tools_used": len(parsed.get("tools_used", [])),
|
|
577
|
-
"tokens": parsed.get("total_tokens", 0),
|
|
578
|
-
}
|
|
579
|
-
})
|
|
580
|
-
|
|
581
603
|
client.close()
|
|
582
|
-
return
|
|
604
|
+
return result.get("id") if result else None
|
|
583
605
|
|
|
584
606
|
|
|
585
607
|
def _format_session_notes(parsed: dict) -> str:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|