diff --git a/README.md b/README.md
index f4c442e..b70bff1 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ Type "help", "copyright", "credits" or "license" for more information.
 
 ## Quick Start
 
-The most basic usage is to record what data files you read and write, and maybe to declare some summary statistics about how well the job went.
+The most basic usage is to record what data files you read and write, and maybe to declare some metrics about how well the job went.
 
 ```python
 import dotscience as ds
@@ -61,8 +61,8 @@ df = pd.read_csv(ds.input('input_file.csv'))
 # Likewise with files you write to:
 df.to_csv(ds.output('output_file.csv'))
 
-# Record a summary statistic about how well your job went
-ds.add_summary('f-score', f_score)
+# Record a metric about how well your job went
+ds.add_metric('f-score', f_score)
 
 ds.publish('Did some awesome data science!')
 ```
@@ -118,7 +118,7 @@ ds.publish("trained mnist model", deploy=True)
 
 ## All the things you can record
 
-There's a lot more than just data files and summary stats that Dotscience will keep track of for you - and there's a choice of convenient ways to specify each thing, so it can fit neatly into your code. Here's the full list:
+There's a lot more than just data files and metrics that Dotscience will keep track of for you - and there's a choice of convenient ways to specify each thing, so it can fit neatly into your code. Here's the full list:
 
 ### Start and end time
 
@@ -377,11 +377,11 @@ ds.add_labels(experimental=True, mode="test")
 ds.publish('Did some awesome data science!')
 ```
 
-### Summary statistics
+### Metrics
 
-Often, your job will be able to measure its own performance in some way - perhaps testing how well a model trained on some training data works when tested on some test data. If you declare those summary statistics to Dotscience, it can help you keep track of which runs produced the best results.
+Often, your job will be able to measure its own performance in some way - perhaps testing how well a model trained on some training data works when tested on some test data. If you declare those metrics to Dotscience, it can help you keep track of which runs produced the best results.
 
-As usual, this can be done while returning the summary value with `summary()`, explicitly with `add_summary()`, or en mass with `add_summaries()`:
+As usual, this can be done while returning the metric with `metric()`, explicitly with `add_metric()`, or en mass with `add_metrics()`:
 
 ```python
 import dotscience as ds
@@ -389,11 +389,11 @@ import dotscience as ds
 ds.script()
 ds.start()
 
-print('Fit: %f%%' % (ds.summary('fit%', fit),))
+print('Fit: %f%%' % (ds.metric('fit%', fit),))
 
-ds.add_summary('fit%', fit)
+ds.add_metric('fit%', fit)
 
-ds.add_summaries(fit=computeFit(), error=computeMeanError())
+ds.add_metrics(fit=computeFit(), error=computeMeanError())
 
 ds.publish('Did some awesome data science!')
 ```
@@ -439,7 +439,7 @@ ds.publish('Trained the model')
 ds.start()
 test_data = load_csv(ds.input('test.csv'))
 accuracy = test_model(model, test_data)
-ds.add_summary('accuracy', accuracy)
+ds.add_metric('accuracy', accuracy)
 ds.publish('Tested the model')
 ```
 
@@ -467,7 +467,7 @@ for smoothing in [1.0, 1.5, 2.0]:
     accuracy = test_model(model, test_data)
 
     # Inform Dotscience of the accuracy
-    ds.add_summary('accuracy', accuracy)
+    ds.add_metric('accuracy', accuracy)
 
     # Publish this run
     ds.publish('Tested the model with smoothing %s' % (smoothing,))
diff --git a/dotscience/__init__.py b/dotscience/__init__.py
index 00096f0..5455d5c 100644
--- a/dotscience/__init__.py
+++ b/dotscience/__init__.py
@@ -39,7 +39,7 @@ class Run:
         self._inputs = set()
         self._outputs = set()
         self._labels = {}
-        self._summary = {}
+        self._metric = {}
         self._parameters = {}
         self._start = None
         self._end = None
@@ -173,22 +173,27 @@ class Run:
         self.model(kind, name, *args, **kwargs)
         return None
 
-    def add_summary(self, label, value):
-        self._summary[str(label)] = str(value)
+    def add_metric(self, label, value):
+        self._metric[str(label)] = str(value)
 
     # Supports any combination of ("a", "val of a", "b", "val of b") and (c="val of c")
-    def add_summaries(self, *args, **kwargs):
+    def add_metrics(self, *args, **kwargs):
         if kwargs is not None:
             for key, value in kwargs.items():
-                self.add_summary(key, value)
+                self.add_metric(key, value)
         for key, value in [args[i:i+2] for i  in range(0, len(args), 2)]:
-            self.add_summary(key, value)
+            self.add_metric(key, value)
 
     # Binds a single value, but returns it unchanged
-    def summary(self, label, value):
-        self.add_summary(label, value)
+    def metric(self, label, value):
+        self.add_metric(label, value)
         return value
 
+    # Backwards compatability:
+    summary = metric
+    add_summary = add_metric
+    add_summaries = add_metrics
+
     def add_parameter(self, label, value):
         self._parameters[str(label)] = str(value)
 
@@ -220,7 +225,7 @@ class Run:
             "input": sorted(self._inputs),
             "output": sorted(expanded_outputs),
             "labels": self._labels,
-            "summary": self._summary,
+            "summary": self._metric,
             "parameters": self._parameters
         }
 
@@ -371,7 +376,7 @@ class Dotscience:
         # up with multiple runs with the same times (calling end() twice has no
         # effect the second time otherwise). If the user doesn't explicitly
         # call start(), it will get implicitly called after the next
-        # interaction with the python library anyway (e.g. ds.summary(), etc),
+        # interaction with the python library anyway (e.g. ds.metric(), etc),
         # via _check_started which does a lazy_start to cover resetting the
         # start timer in this case.
         self.currentRun.forget_times()
@@ -587,8 +592,8 @@ class Dotscience:
         run.452521f7-c069-4271-b06e-dcd55635b871.output-files: ["linear_regressor.pkl"]
         run.452521f7-c069-4271-b06e-dcd55635b871.parameters.features: finishedsqft
         run.452521f7-c069-4271-b06e-dcd55635b871.start: 20190924T112352.843016
-        run.452521f7-c069-4271-b06e-dcd55635b871.summary.lin_rmse: 855408.5050370345
-        run.452521f7-c069-4271-b06e-dcd55635b871.summary.regressor_score: 0.35677710327221
+        run.452521f7-c069-4271-b06e-dcd55635b871.metric.lin_rmse: 855408.5050370345
+        run.452521f7-c069-4271-b06e-dcd55635b871.metric.regressor_score: 0.35677710327221
         run.452521f7-c069-4271-b06e-dcd55635b871.workload-file: hello-dotscience.ipynb
         runner.cpu: ["1x Intel(R) Xeon(R) CPU @ 2.30GHz"]
         runner.name: 6ddeae52-untitled
@@ -655,7 +660,7 @@ class Dotscience:
         branch = dot.getBranch("master")
         result = branch.commit("Remote dotscience run", commit)
         # construct URL
-        runURL = f"{self._hostname}/project/{project['id']}/runs/summary/{self.currentRun._id}"
+        runURL = f"{self._hostname}/project/{project['id']}/runs/metric/{self.currentRun._id}"
         return runURL
 
     def _find_model_id(self, run_id):
@@ -888,17 +893,22 @@ class Dotscience:
         self._check_started()
         self.currentRun.add_labels(*args, **kwargs)
 
-    def add_summary(self, label, value):
+    def add_metric(self, label, value):
         self._check_started()
-        self.currentRun.add_summary(label, value)
+        self.currentRun.add_metric(label, value)
 
-    def add_summaries(self, *args, **kwargs):
+    def add_metrics(self, *args, **kwargs):
         self._check_started()
-        self.currentRun.add_summaries(*args, **kwargs)
+        self.currentRun.add_metrics(*args, **kwargs)
 
-    def summary(self, label, value):
+    def metric(self, label, value):
         self._check_started()
-        return self.currentRun.summary(label, value)
+        return self.currentRun.metric(label, value)
+
+    # Backwards compatibility:
+    add_summary = add_metric
+    add_summaries = add_metrics
+    summary = metric
 
     def add_parameter(self, label, value):
         self._check_started()
@@ -982,14 +992,14 @@ def add_labels(*args, **kwargs):
 def label(label, value):
     return _defaultDS.label(label, value)
 
-def add_summary(label, value):
-    _defaultDS.add_summary(label, value)
+def add_metric(label, value):
+    _defaultDS.add_metric(label, value)
 
-def add_summaries(*args, **kwargs):
-    _defaultDS.add_summaries(*args, **kwargs)
+def add_metrics(*args, **kwargs):
+    _defaultDS.add_metrics(*args, **kwargs)
 
-def summary(label, value):
-    return _defaultDS.summary(label, value)
+def metric(label, value):
+    return _defaultDS.metric(label, value)
 
 def model(kind, name, *args, **kwargs):
     return _defaultDS.model(kind, name, *args, **kwargs)
@@ -1006,9 +1016,9 @@ def parameter(label, value):
 def remove_prefix(text, prefix):
     return text[text.startswith(prefix) and len(prefix):]
 
-add_metric = add_summary
-add_metrics = add_summaries
-metric = summary
+add_metric = add_metric
+add_metrics = add_metrics
+metric = metric
 param = parameter
 
 def debug():
@@ -1022,3 +1032,7 @@ def connect(username, apikey, project, hostname=""):
         username, apikey, project, hostname,
     )
 
+# Backwards compatibility:
+summary = metric
+add_summary = add_metric
+add_summaries = add_metrics

ds.summary -> ds.metric
Rename ds.summary to ds.metric (leave ds.summary as an alias for backward compatibility).
diff --git a/dotscience/test_dotscience.py b/dotscience/test_dotscience.py
index ccf8902..9a4ff38 100644
--- a/dotscience/test_dotscience.py
+++ b/dotscience/test_dotscience.py
@@ -11,6 +11,27 @@ import shutil
 from hypothesis import given, assume, note
 from hypothesis.strategies import text, lists, sampled_from
 
+
+def test_metric_to_summary_backwards_compatibility():
+    """summary()/add_summary()/add_summaries() backwards compatibility."""
+    # Run level:
+    r = dotscience.Run("/workspace-root")
+    assert r.summary == r.metric
+    assert r.add_summary == r.add_metric
+    assert r.add_summaries == r.add_metrics
+
+    # Dotscience level:
+    d = dotscience.Dotscience()
+    assert d.summary == d.metric
+    assert d.add_summary == d.add_metric
+    assert d.add_summaries == d.add_metrics
+
+    # Module level:
+    assert dotscience.summary == dotscience.metric
+    assert dotscience.add_summary == dotscience.add_metric
+    assert dotscience.add_summaries == dotscience.add_metrics
+
+
 ###
 ### Test the Run class
 ###
@@ -28,7 +49,7 @@ def test_run_null():
 
 input_files=["test.csv","/workspace-root/test.csv","data/test.csv"]
 output_files=["test.csv","/workspace-root/test.csv","data/test.csv"]
-    
+
 @given(text(),text())
 def test_run_basics(error, description):
     r = dotscience.Run("/workspace-root")
@@ -305,7 +326,7 @@ def test_run_labels_multi(a,b,c,d):
 @given(text())
 def test_run_summary_1(x):
     r = dotscience.Run("/workspace-root")
-    assert r.summary("food", x) == x
+    assert r.metric("food", x) == x
     assert str(r) == """[[DOTSCIENCE-RUN:%s]]%s[[/DOTSCIENCE-RUN:%s]]""" % \
     (r._id, json.dumps({"version": "1",
                         "labels": {},
@@ -318,9 +339,9 @@ def test_run_summary_1(x):
 @given(text(),text(),text(),text())
 def test_run_summary_multi(a,b,c,d):
     r = dotscience.Run("/workspace-root")
-    r.add_summaries("a", a)
-    r.add_summaries(b=b)
-    r.add_summaries("c", c, d=d)
+    r.add_metrics("a", a)
+    r.add_metrics(b=b)
+    r.add_metrics("c", c, d=d)
     assert str(r) == """[[DOTSCIENCE-RUN:%s]]%s[[/DOTSCIENCE-RUN:%s]]""" % \
     (r._id, json.dumps({"version": "1",
                         "labels": {},
@@ -509,7 +530,7 @@ def test_default_script_name():
     m1 = _parse(s1.getvalue())
 
     # This might be a fragile assertion...
-    assert m1["workload-file"].endswith("/usr/local/bin/pytest")
+    assert m1["workload-file"].endswith("/bin/pytest") or m1["workload-file"].endswith("/bin/py.test")
 
 def test_explicit_script_name():
     ds = dotscience.Dotscience()
@@ -770,7 +791,7 @@ def test_label_n(a, b):
 def test_summary_1a(d):
     s=io.StringIO()
     dotscience.start()
-    dotscience.add_summary("test", d)
+    dotscience.add_metric("test", d)
     dotscience.publish(stream=s)
     m = _parse(s.getvalue())
     assert m["output"] == []
@@ -784,7 +805,7 @@ def test_summary_1a(d):
 def test_summary_1b(d):
     s=io.StringIO()
     dotscience.start()
-    assert dotscience.summary("test", d) == d
+    assert dotscience.metric("test", d) == d
     dotscience.publish(stream=s)
     m = _parse(s.getvalue())
     assert m["output"] == []
@@ -798,8 +819,8 @@ def test_summary_1b(d):
 def test_summary_n(a, b):
     s=io.StringIO()
     dotscience.start()
-    dotscience.add_summaries("a", a)
-    dotscience.add_summaries(b=b)
+    dotscience.add_metrics("a", a)
+    dotscience.add_metrics(b=b)
     dotscience.publish(stream=s)
     m = _parse(s.getvalue())
     assert m["output"] == []

pip install -e .
parse_log_pytest
requirements.txt
pytest hypothesis
apt-get update apt-get install -y gcc
3.7
examples/requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
absl-py==2.1.0
apply-defaults==0.1.6
astor==0.8.1
attrs==24.2.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
charset-normalizer==3.4.1
click==6.7
datadots-api==0.2.4
-e git+https://github.com/dotmesh-io/dotscience-python.git@2510ed4a159fcbe4e5f36974496e242d66d479dd#egg=dotscience
exceptiongroup==1.2.2
gast==0.6.0
google-pasta==0.2.0
grpcio==1.62.3
h5py==3.8.0
hypothesis==6.79.4
idna==3.10
importlib-metadata==6.7.0
iniconfig==2.0.0
joblib==0.14.0
jsonrpcclient==3.3.4
jsonschema==3.2.0
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
Markdown==3.4.4
MarkupSafe==2.1.5
numpy==1.21.6
packaging==24.0
pluggy==1.2.0
protobuf==4.24.4
pyrsistent==0.19.3
pytest==7.4.4
requests==2.31.0
scikit-learn==0.20.3
scipy==1.7.3
six==1.17.0
sortedcontainers==2.4.0
tensorboard==1.14.0
tensorflow==1.14.0
tensorflow-estimator==1.14.0
termcolor==2.3.0
tomli==2.0.1
typing_extensions==4.7.1
urllib3==2.0.7
Werkzeug==2.2.3
wrapt==1.16.0
zipp==3.15.0

name: dotscience-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - absl-py==2.1.0
      - apply-defaults==0.1.6
      - astor==0.8.1
      - attrs==24.2.0
      - charset-normalizer==3.4.1
      - click==6.7
      - datadots-api==0.2.4
      - exceptiongroup==1.2.2
      - gast==0.6.0
      - google-pasta==0.2.0
      - grpcio==1.62.3
      - h5py==3.8.0
      - hypothesis==6.79.4
      - idna==3.10
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - joblib==0.14.0
      - jsonrpcclient==3.3.4
      - jsonschema==3.2.0
      - keras-applications==1.0.8
      - keras-preprocessing==1.1.2
      - markdown==3.4.4
      - markupsafe==2.1.5
      - numpy==1.21.6
      - packaging==24.0
      - pluggy==1.2.0
      - protobuf==4.24.4
      - pyrsistent==0.19.3
      - pytest==7.4.4
      - requests==2.31.0
      - scikit-learn==0.20.3
      - scipy==1.7.3
      - six==1.17.0
      - sortedcontainers==2.4.0
      - tensorboard==1.14.0
      - tensorflow==1.14.0
      - tensorflow-estimator==1.14.0
      - termcolor==2.3.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - werkzeug==2.2.3
      - wrapt==1.16.0
      - zipp==3.15.0
prefix: /opt/conda/envs/dotscience-python

dotscience/test_dotscience.py::test_metric_to_summary_backwards_compatibility dotscience/test_dotscience.py::test_run_summary_1 dotscience/test_dotscience.py::test_run_summary_multi
dotscience/test_dotscience.py::test_run_null dotscience/test_dotscience.py::test_run_basics dotscience/test_dotscience.py::test_run_input_1 dotscience/test_dotscience.py::test_run_input_relative dotscience/test_dotscience.py::test_run_input_2 dotscience/test_dotscience.py::test_run_input_n dotscience/test_dotscience.py::test_run_input_recursive dotscience/test_dotscience.py::test_run_output_1 dotscience/test_dotscience.py::test_run_output_relative dotscience/test_dotscience.py::test_run_output_2 dotscience/test_dotscience.py::test_run_output_n dotscience/test_dotscience.py::test_run_output_recursive dotscience/test_dotscience.py::test_run_tensorflow_model dotscience/test_dotscience.py::test_run_tensorflow_model_with_classes dotscience/test_dotscience.py::test_run_sklearn_model dotscience/test_dotscience.py::test_run_labels_1 dotscience/test_dotscience.py::test_run_labels_multi dotscience/test_dotscience.py::test_run_parameter_1 dotscience/test_dotscience.py::test_run_parameter_multi dotscience/test_dotscience.py::test_run_start_1 dotscience/test_dotscience.py::test_run_start_2 dotscience/test_dotscience.py::test_run_end_1 dotscience/test_dotscience.py::test_run_end_2 dotscience/test_dotscience.py::test_no_mode dotscience/test_dotscience.py::test_notice_jupyter_mode dotscience/test_dotscience.py::test_notice_command_mode dotscience/test_dotscience.py::test_conflicting_mode_1 dotscience/test_dotscience.py::test_conflicting_mode_2 dotscience/test_dotscience.py::test_non_conflicting_mode_1 dotscience/test_dotscience.py::test_non_conflicting_mode_2 dotscience/test_dotscience.py::test_no_script_name_when_interactive dotscience/test_dotscience.py::test_default_script_name dotscience/test_dotscience.py::test_explicit_script_name dotscience/test_dotscience.py::test_null dotscience/test_dotscience.py::test_start_end dotscience/test_dotscience.py::test_description_a dotscience/test_dotscience.py::test_description_b dotscience/test_dotscience.py::test_description_c dotscience/test_dotscience.py::test_error_a dotscience/test_dotscience.py::test_error_b dotscience/test_dotscience.py::test_input_1a dotscience/test_dotscience.py::test_input_1b dotscience/test_dotscience.py::test_input_n dotscience/test_dotscience.py::test_output_1a dotscience/test_dotscience.py::test_output_1b dotscience/test_dotscience.py::test_output_n dotscience/test_dotscience.py::test_label_1a dotscience/test_dotscience.py::test_label_1b dotscience/test_dotscience.py::test_label_n dotscience/test_dotscience.py::test_summary_1a dotscience/test_dotscience.py::test_summary_1b dotscience/test_dotscience.py::test_summary_n dotscience/test_dotscience.py::test_parameter_1a dotscience/test_dotscience.py::test_parameter_1b dotscience/test_dotscience.py::test_parameter_n dotscience/test_dotscience.py::test_multi_publish_1 dotscience/test_dotscience.py::test_multi_publish_2 dotscience/test_dotscience.py::test_reconnect_resets_internal_state
dotscience/__init__.py README.md
dotscience/__init__.py README.md