From 706a1b795e6af9da25756ad0cf67cfb9bcd3bb39 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 29 Dec 2024 19:26:51 -0600 Subject: [PATCH 1/2] add one-function log config and filter Sparse CSR warnings --- lenskit/lenskit/logging/config.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lenskit/lenskit/logging/config.py b/lenskit/lenskit/logging/config.py index 8cf5ecf34..43c6c113a 100644 --- a/lenskit/lenskit/logging/config.py +++ b/lenskit/lenskit/logging/config.py @@ -35,6 +35,15 @@ def active_logging_config() -> LoggingConfig | None: return _active_config +def basic_logging(level: int = logging.INFO): + """ + Simple one-function logging configuration for notebooks and similar. + """ + cfg = LoggingConfig() + cfg.level = level + cfg.apply() + + class LoggingConfig: # pragma: nocover """ Configuration for LensKit logging. @@ -145,6 +154,7 @@ def apply(self): set_progress_impl("rich") warnings.showwarning = log_warning + warnings.filterwarnings("ignore", message=r"Sparse CSR tensor support is in beta state") _active_config = self From 609f89f5617e69666c66ca210f5030c4460324e0 Mon Sep 17 00:00:00 2001 From: Michael Ekstrand Date: Sun, 29 Dec 2024 19:36:33 -0600 Subject: [PATCH 2/2] add basic_logging setup --- docs/guide/GettingStarted.ipynb | 5945 +-------------------------- docs/guide/logging.rst | 3 + lenskit/lenskit/logging/__init__.py | 3 +- 3 files changed, 102 insertions(+), 5849 deletions(-) diff --git a/docs/guide/GettingStarted.ipynb b/docs/guide/GettingStarted.ipynb index 961cd87ed..c8f8957bc 100644 --- a/docs/guide/GettingStarted.ipynb +++ b/docs/guide/GettingStarted.ipynb @@ -68,6 +68,26 @@ "from pyprojroot.here import here" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We also need to set up logging, both to unify it and to silence noisy debug-level messages. When running LensKit from a script, you usually want to use `INFO`-level logging, and to use the `LoggingConfig` class for more flexibility." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "\n", + "from lenskit.logging import basic_logging\n", + "\n", + "basic_logging(logging.WARNING)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -79,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -158,7 +178,7 @@ "4 1 5 3.0 889751712" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -179,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -196,7 +216,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -222,5838 +242,67 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/michael/Documents/LensKit/lkpy/lenskit/lenskit/als/_explicit.py:91: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at /Users/runner/miniforge3/conda-bld/libtorch_1732815742335/work/aten/src/ATen/SparseCsrTensorImpl.cpp:55.)\n", - " rmat = rmat.to_sparse_csr()\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\r\n", - "epoch 1 users: 0%| | 0/943 [00:00\n", " \n", " ALS\n", - " 0.080082\n", - " 0.021305\n", - " 0.082607\n", + " 0.128447\n", + " 0.091585\n", + " 0.196082\n", " \n", " \n", " II\n", - " 0.059951\n", - " 0.005444\n", - " 0.039962\n", + " 0.093132\n", + " 0.035806\n", + " 0.104097\n", " \n", " \n", "\n", @@ -6108,11 +357,11 @@ "text/plain": [ " NDCG RBP RecipRank\n", "model \n", - "ALS 0.080082 0.021305 0.082607\n", - "II 0.059951 0.005444 0.039962" + "ALS 0.128447 0.091585 0.196082\n", + "II 0.093132 0.035806 0.104097" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -6123,12 +372,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfsAAAHpCAYAAACFlZVCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAu+klEQVR4nO3df3RU9Z3/8deQX0P5ETFgAmyIiRYIB1GZAE10xK02CFblbOrGtsDKgj2jrkgiFELwF1azFbQchCSLJFpWD8RTdEF3XJOykqVmupSY0GJHrIdIKGaKiTgR/JqQcL9/cJjtdAYkkDDDh+fjnDmH+7nve+f9OcfrK/fOvTM2y7IsAQAAY/WLdAMAAKBvEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2IdhWZba29vFVxAAAExA2Ifx5ZdfKjExUV9++WWkWwEA4LwR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYLjbSDQA9ZVmWjh07FlgeMGCAbDZbBDsCgOhG2OOic+zYMd11112B5a1bt2rgwIER7AgAohuX8QEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAw0U87EtLS5Weni673S6Hw6GdO3eesb62tlYOh0N2u10ZGRkqLy8PqVm9erXGjBmj/v37KzU1VQUFBfr666/7agoAAES1iIZ9VVWVFi5cqOLiYjU0NMjpdGr69Olqbm4OW9/U1KQZM2bI6XSqoaFBy5Yt04IFC7Rly5ZAzauvvqqlS5fq8ccfl9frVUVFhaqqqlRUVHShpgUAQFSxWZZlRerNp0yZookTJ6qsrCwwlpmZqZkzZ6qkpCSkfsmSJdq2bZu8Xm9gzOVyac+ePfJ4PJKkf/mXf5HX69X27dsDNY888oh27dr1jVcNTmlvb1diYqL8fr8GDx58rtNDHzl69KjuuuuuwPLWrVs1cODACHYEANEtNlJv3NnZqfr6ei1dujRoPDc3V3V1dWG38Xg8ys3NDRqbNm2aKioqdPz4ccXFxenGG2/UK6+8ol27dmny5Mnav3+/3G63/umf/um0vXR0dKijoyOw3N7efh4zOz3H4o19st9Lja2rU4l/tXzzo5tlxcZHrB8T1K+cE+kWAPShiIV9a2ururu7lZycHDSenJwsn88Xdhufzxe2vqurS62trRo+fLjuueceffbZZ7rxxhtlWZa6urp0//33h/xR8ddKSkr05JNPnv+kAACIQhG/Qc9mswUtW5YVMvZN9X89vmPHDj399NMqLS3V+++/r9dff11vvfWWnnrqqdPus6ioSH6/P/A6ePDguU4HAICoE7Ez+6FDhyomJibkLP7w4cMhZ++npKSkhK2PjY1VUlKSJOnRRx/V7NmzNX/+fEnSNddco2PHjuknP/mJiouL1a9f6N83CQkJSkhI6I1pAQAQdSJ2Zh8fHy+Hw6Gampqg8ZqaGuXk5ITdJjs7O6S+urpaWVlZiouLkyR99dVXIYEeExMjy7IUwXsRAQCImIhexi8sLNSGDRtUWVkpr9ergoICNTc3y+VySTp5eX3OnP+7ccjlcunAgQMqLCyU1+tVZWWlKioqtGjRokDNHXfcobKyMm3evFlNTU2qqanRo48+qjvvvFMxMTEXfI4AAERaxC7jS1J+fr7a2tq0YsUKtbS0aPz48XK73UpLS5MktbS0BD1zn56eLrfbrYKCAq1bt04jRozQmjVrlJeXF6hZvny5bDabli9frkOHDmnYsGG644479PTTT1/w+QEAEA0i+px9tOqr5+x59K532Lo6lfj7TYFl/4Qf8ujdeeLRO8BsEb8bHwAA9C3CHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADBcb6QaAnrJi4uSf8MOgZQDA6RH2uPjYbLJi4yPdBQBcNLiMDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYLiIh31paanS09Nlt9vlcDi0c+fOM9bX1tbK4XDIbrcrIyND5eXlQetvvvlm2Wy2kNftt9/el9MAACBqRTTsq6qqtHDhQhUXF6uhoUFOp1PTp09Xc3Nz2PqmpibNmDFDTqdTDQ0NWrZsmRYsWKAtW7YEal5//XW1tLQEXnv37lVMTIzuvvvuCzUtAACiis2yLCtSbz5lyhRNnDhRZWVlgbHMzEzNnDlTJSUlIfVLlizRtm3b5PV6A2Mul0t79uyRx+MJ+x6rV6/WY489ppaWFg0YMCBsTUdHhzo6OgLL7e3tSk1Nld/v1+DBg891eiEcizf22r6A3lS/ck6kWwDQhyJ2Zt/Z2an6+nrl5uYGjefm5qquri7sNh6PJ6R+2rRp2r17t44fPx52m4qKCt1zzz2nDXpJKikpUWJiYuCVmpraw9kAABC9Ihb2ra2t6u7uVnJyctB4cnKyfD5f2G18Pl/Y+q6uLrW2tobU79q1S3v37tX8+fPP2EtRUZH8fn/gdfDgwR7OBgCA6BUb6QZsNlvQsmVZIWPfVB9uXDp5Vj9+/HhNnjz5jD0kJCQoISHhbFsGAOCiErEz+6FDhyomJibkLP7w4cMhZ++npKSkhK2PjY1VUlJS0PhXX32lzZs3f+NZPQAApotY2MfHx8vhcKimpiZovKamRjk5OWG3yc7ODqmvrq5WVlaW4uLigsZfe+01dXR0aNasWb3bOAAAF5mIPnpXWFioDRs2qLKyUl6vVwUFBWpubpbL5ZJ08rP0OXP+7y5hl8ulAwcOqLCwUF6vV5WVlaqoqNCiRYtC9l1RUaGZM2eGnPEDAHCpiehn9vn5+Wpra9OKFSvU0tKi8ePHy+12Ky0tTZLU0tIS9Mx9enq63G63CgoKtG7dOo0YMUJr1qxRXl5e0H4/+ugj/eY3v1F1dfUFnQ8AANEoos/ZR6v29nYlJibynD0uGTxnD5gt4l+XCwAA+hZhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYLjYSDcAALiwLMvSsWPHAssDBgyQzWaLYEfoa4Q9AFxijh07prvuuiuwvHXrVg0cODCCHaGvcRkfAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMF/GwLy0tVXp6uux2uxwOh3bu3HnG+traWjkcDtntdmVkZKi8vDyk5osvvtCDDz6o4cOHy263KzMzU263u6+mAABAVIto2FdVVWnhwoUqLi5WQ0ODnE6npk+frubm5rD1TU1NmjFjhpxOpxoaGrRs2TItWLBAW7ZsCdR0dnbqe9/7nj755BP96le/0r59+/Tiiy9q5MiRF2paAABEldhIvvnzzz+vefPmaf78+ZKk1atX65133lFZWZlKSkpC6svLyzVq1CitXr1akpSZmandu3dr1apVysvLkyRVVlbq888/V11dneLi4iRJaWlpZ+yjo6NDHR0dgeX29vbemB4AAFEhYmHf2dmp+vp6LV26NGg8NzdXdXV1YbfxeDzKzc0NGps2bZoqKip0/PhxxcXFadu2bcrOztaDDz6orVu3atiwYfrRj36kJUuWKCYmJux+S0pK9OSTT/bOxAD0GcfijZFuwQi2rk4l/tXyzY9ulhUbH7F+TFC/ck6kWzijiF3Gb21tVXd3t5KTk4PGk5OT5fP5wm7j8/nC1nd1dam1tVWStH//fv3qV79Sd3e33G63li9frueee05PP/30aXspKiqS3+8PvA4ePHieswMAIHpE9DK+JNlstqBly7JCxr6p/q/HT5w4oSuuuELr169XTEyMHA6HPv30U61cuVKPPfZY2H0mJCQoISHhfKYBAEDUiljYDx06VDExMSFn8YcPHw45ez8lJSUlbH1sbKySkpIkScOHD1dcXFzQJfvMzEz5fD51dnYqPp5LVQCAS0vELuPHx8fL4XCopqYmaLympkY5OTlht8nOzg6pr66uVlZWVuBmvBtuuEEff/yxTpw4Eaj56KOPNHz4cIIeAHBJiuijd4WFhdqwYYMqKyvl9XpVUFCg5uZmuVwuSSc/S58z5/9uenC5XDpw4IAKCwvl9XpVWVmpiooKLVq0KFBz//33q62tTQ8//LA++ugj/ed//qeeeeYZPfjggxd8fgAARIOIfmafn5+vtrY2rVixQi0tLRo/frzcbnfgUbmWlpagZ+7T09PldrtVUFCgdevWacSIEVqzZk3gsTtJSk1NVXV1tQoKCjRhwgSNHDlSDz/8sJYsWXLB5wcAQDSwWafucENAe3u7EhMT5ff7NXjw4F7bL48NIVpF+2NDp3AM9Q5bV6cSf78psOyf8EMevTtP0X4MRfzrcgEAQN8i7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADBfRX70DAFx4Vkyc/BN+GLQMsxH2AHCpsdn4lbtLDJfxAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABgu4mFfWlqq9PR02e12ORwO7dy584z1tbW1cjgcstvtysjIUHl5edD6l19+WTabLeT19ddf9+U0AACIWhEN+6qqKi1cuFDFxcVqaGiQ0+nU9OnT1dzcHLa+qalJM2bMkNPpVENDg5YtW6YFCxZoy5YtQXWDBw9WS0tL0Mtut1+IKQEAEHViI/nmzz//vObNm6f58+dLklavXq133nlHZWVlKikpCakvLy/XqFGjtHr1aklSZmamdu/erVWrVikvLy9QZ7PZlJKSckHmAABAtIvYmX1nZ6fq6+uVm5sbNJ6bm6u6urqw23g8npD6adOmaffu3Tp+/Hhg7OjRo0pLS9Pf/d3f6fvf/74aGhrO2EtHR4fa29uDXgAAmCJiYd/a2qru7m4lJycHjScnJ8vn84Xdxufzha3v6upSa2urJGns2LF6+eWXtW3bNm3atEl2u1033HCD/vSnP522l5KSEiUmJgZeqamp5zk7AACiR8Rv0LPZbEHLlmWFjH1T/V+Pf+c739GsWbN07bXXyul06rXXXtPo0aP1wgsvnHafRUVF8vv9gdfBgwfPdToAAESdiH1mP3ToUMXExIScxR8+fDjk7P2UlJSUsPWxsbFKSkoKu02/fv00adKkM57ZJyQkKCEhoYczAADg4hCxM/v4+Hg5HA7V1NQEjdfU1CgnJyfsNtnZ2SH11dXVysrKUlxcXNhtLMtSY2Ojhg8f3juNAwBwkYnoZfzCwkJt2LBBlZWV8nq9KigoUHNzs1wul6STl9fnzJkTqHe5XDpw4IAKCwvl9XpVWVmpiooKLVq0KFDz5JNP6p133tH+/fvV2NioefPmqbGxMbBPAAAuNRF99C4/P19tbW1asWKFWlpaNH78eLndbqWlpUmSWlpagp65T09Pl9vtVkFBgdatW6cRI0ZozZo1QY/dffHFF/rJT34in8+nxMREXX/99fqf//kfTZ48+YLPDwCAaGCzTt3hhoD29nYlJibK7/dr8ODBvbZfx+KNvbYvoDfVr5zzzUVRgGMI0Sraj6GI340PAAD6FmEPAIDhevSZ/YkTJ/TBBx/ommuukXTy62s7OzsD62NiYnT//ferXz/+hgAAIFr0KOw3b96sf/u3f1Ntba0kafHixbrssssUG3tyN62trbLb7Zo3b17vdwoAAM5Jj07BX3rppZBH2Gpra9XU1KSmpiatXLlSr7zySq82CAAAzk+Pwt7r9WrcuHGnXT916lTt2bPnvJsCAAC9p0eX8VtbWzVw4MDA8v79+4O+pjYuLk7Hjh3rve4AAMB569GZfXJysvbt2xdYHjZsWNDNeF6vl9+RBwAgyvQo7G+55RY9/fTTYddZlqWSkhLdcsstvdIYAADoHT26jF9cXKyJEydqypQpWrRokUaPHi2bzaYPP/xQq1at0r59+7RxI99wBQBANOlR2F911VWqqanRvffeq/z8/MBvyFuWpbFjx6q6ulpXX311nzQKAADOTY9/CGfy5Mn64x//qMbGRn300UeSpG9/+9u6/vrre705AABw/noc9u3t7Ro4cKCuu+46XXfddYHxEydO6OjRo736wzEAAOD89egGvTfeeENZWVn6+uuvQ9Z9/fXXmjRpkt58881eaw4AAJy/HoV9WVmZfvrTn+pb3/pWyLpvfetbWrJkidauXdtrzQEAgPPXo7Dfu3evbr755tOuv+mmm/SHP/zhfHsCAAC9qEdhf+TIEXV1dZ12/fHjx3XkyJHzbgoAAPSeHoX9lVdeqd27d592/e7du5WWlnbeTQEAgN7To7D/h3/4BxUXF+svf/lLyDqfz6fly5crLy+v15oDAADnr0eP3i1dulRbt27Vt7/9bc2aNUtjxoyRzWaT1+vVq6++qtTUVC1durSvegUAAOegR2E/aNAgvffeeyoqKlJVVVXg8/khQ4Zo1qxZeuaZZzRo0KA+aRQAAJybHn+pTmJiokpLS7Vu3Tq1trbKsiwNGzYs8NW5AAAguvQ47E9pa2vTgQMHZLPZFBMTE/S79gAAIHr06AY9Sfrggw900003KTk5WVOmTNHkyZN1xRVX6Lvf/W7Qb90DAIDo0KMze5/Pp6lTp2rYsGF6/vnnNXbsWFmWpT/+8Y968cUX5XQ6tXfvXl1xxRV91S8AAOihHoX9L37xC6Wlpem9996T3W4PjN922226//77deONN+oXv/iFSkpKer1RAABwbnp0Gb+mpkZLliwJCvpT+vfvr8WLF+udd97pteYAAMD561HY79+/XxMnTjzt+qysLO3fv/+8mwIAAL2nR2H/5ZdfnvH36gcNGqSjR4+ed1MAAKD39PjRuy+//DLsZXxJam9vl2VZ590UAADoPT0Ke8uyNHr06DOu58t1AACILj0K+3fffbev+gAAAH2kR2E/derUvuoDAAD0kR6Ffb9+/b7xMr3NZlNXV9d5NQUAAHpPj8L+jTfeOO26uro6vfDCC9ygBwBAlOlR2N91110hYx9++KGKior05ptv6sc//rGeeuqpXmsOAACcvx7/EM4pn376qe677z5NmDBBXV1damxs1C9/+UuNGjWqN/sDAADnqcdh7/f7tWTJEl199dX64IMPtH37dr355psaP378OTVQWlqq9PR02e12ORwO7dy584z1tbW1cjgcstvtysjIUHl5+WlrN2/eLJvNppkzZ55TbwAAmKBHYf/ss88qIyNDb731ljZt2qS6ujo5nc5zfvOqqiotXLhQxcXFamhokNPp1PTp09Xc3By2vqmpSTNmzJDT6VRDQ4OWLVumBQsWaMuWLSG1Bw4c0KJFi86rPwAATGCzenBHXb9+/dS/f3/deuutiomJOW3d66+/flb7mzJliiZOnKiysrLAWGZmpmbOnBn2l/OWLFmibdu2yev1BsZcLpf27Nkjj8cTGOvu7tbUqVM1d+5c7dy5U1988YX+4z/+46x6kk5+E2BiYqL8fv8Zvx64pxyLN/bavoDeVL9yTqRbOCscQ4hW0X4M9egGvTlz5vTaN+R1dnaqvr5eS5cuDRrPzc1VXV1d2G08Ho9yc3ODxqZNm6aKigodP35ccXFxkqQVK1Zo2LBhmjdv3jd+LCBJHR0d6ujoCCy3t7f3dDoAAEStHoX9yy+/3Gtv3Nraqu7ubiUnJweNJycny+fzhd3G5/OFre/q6lJra6uGDx+u9957TxUVFWpsbDzrXkpKSvTkk0/2eA4AAFwMzvlu/N7yt1cKvun79cPVnxr/8ssvNWvWLL344osaOnToWfdQVFQkv98feB08eLAHMwAAILr1+FfvesvQoUMVExMTchZ/+PDhkLP3U1JSUsLWx8bGKikpSR988IE++eQT3XHHHYH1J06ckCTFxsZq3759uuqqq0L2m5CQoISEhPOdEgAAUSliZ/bx8fFyOByqqakJGq+pqVFOTk7YbbKzs0Pqq6urlZWVpbi4OI0dO1Z/+MMf1NjYGHjdeeed+vu//3s1NjYqNTW1z+YDAEC0itiZvSQVFhZq9uzZysrKUnZ2ttavX6/m5ma5XC5JJy+vHzp0SBs3nrwD1+Vyae3atSosLNR9990nj8ejiooKbdq0SZJkt9tDnve/7LLLJOmcvwcAAICLXUTDPj8/X21tbVqxYoVaWlo0fvx4ud1upaWlSZJaWlqCnrlPT0+X2+1WQUGB1q1bpxEjRmjNmjXKy8uL1BQAAIh6PXrO/lLBc/a41ET7M8KncAwhWkX7MRTxu/EBAEDfIuwBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYLiIh31paanS09Nlt9vlcDi0c+fOM9bX1tbK4XDIbrcrIyND5eXlQetff/11ZWVl6bLLLtOAAQN03XXX6d///d/7cgoAAES1iIZ9VVWVFi5cqOLiYjU0NMjpdGr69Olqbm4OW9/U1KQZM2bI6XSqoaFBy5Yt04IFC7Rly5ZAzeWXX67i4mJ5PB79/ve/19y5czV37ly98847F2paAABEFZtlWVak3nzKlCmaOHGiysrKAmOZmZmaOXOmSkpKQuqXLFmibdu2yev1BsZcLpf27Nkjj8dz2veZOHGibr/9dj311FNh13d0dKijoyOw3N7ertTUVPn9fg0ePPhcphaWY/HGXtsX0JvqV86JdAtnhWMI0Sraj6GIndl3dnaqvr5eubm5QeO5ubmqq6sLu43H4wmpnzZtmnbv3q3jx4+H1FuWpe3bt2vfvn266aabTttLSUmJEhMTA6/U1NRzmBEAANEpYmHf2tqq7u5uJScnB40nJyfL5/OF3cbn84Wt7+rqUmtra2DM7/dr4MCBio+P1+23364XXnhB3/ve907bS1FRkfx+f+B18ODB85gZAADRJTbSDdhstqBly7JCxr6p/m/HBw0apMbGRh09elTbt29XYWGhMjIydPPNN4fdZ0JCghISEs5xBgAARLeIhf3QoUMVExMTchZ/+PDhkLP3U1JSUsLWx8bGKikpKTDWr18/XX311ZKk6667Tl6vVyUlJacNewAATBaxy/jx8fFyOByqqakJGq+pqVFOTk7YbbKzs0Pqq6urlZWVpbi4uNO+l2VZQTfgAQBwKYnoZfzCwkLNnj1bWVlZys7O1vr169Xc3CyXyyXp5Gfphw4d0saNJ+/AdblcWrt2rQoLC3XffffJ4/GooqJCmzZtCuyzpKREWVlZuuqqq9TZ2Sm3262NGzcG3fEPAMClJKJhn5+fr7a2Nq1YsUItLS0aP3683G630tLSJEktLS1Bz9ynp6fL7XaroKBA69at04gRI7RmzRrl5eUFao4dO6YHHnhAf/7zn9W/f3+NHTtWr7zyivLz8y/4/AAAiAYRfc4+WrW3tysxMZHn7HHJiPZnhE/hGEK0ivZjKOJflwsAAPoWYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAw0U87EtLS5Weni673S6Hw6GdO3eesb62tlYOh0N2u10ZGRkqLy8PWv/iiy/K6XRqyJAhGjJkiG699Vbt2rWrL6cAAEBUi2jYV1VVaeHChSouLlZDQ4OcTqemT5+u5ubmsPVNTU2aMWOGnE6nGhoatGzZMi1YsEBbtmwJ1OzYsUM//OEP9e6778rj8WjUqFHKzc3VoUOHLtS0AACIKjbLsqxIvfmUKVM0ceJElZWVBcYyMzM1c+ZMlZSUhNQvWbJE27Ztk9frDYy5XC7t2bNHHo8n7Ht0d3dryJAhWrt2rebMmRO2pqOjQx0dHYHl9vZ2paamyu/3a/Dgwec6vRCOxRt7bV9Ab6pfGf7YiDYcQ4hW0X4MRezMvrOzU/X19crNzQ0az83NVV1dXdhtPB5PSP20adO0e/duHT9+POw2X331lY4fP67LL7/8tL2UlJQoMTEx8EpNTe3hbAAAiF4RC/vW1lZ1d3crOTk5aDw5OVk+ny/sNj6fL2x9V1eXWltbw26zdOlSjRw5UrfeeutpeykqKpLf7w+8Dh482MPZAAAQvWIj3YDNZgtatiwrZOyb6sONS9Kzzz6rTZs2aceOHbLb7afdZ0JCghISEnrSNgAAF42Ihf3QoUMVExMTchZ/+PDhkLP3U1JSUsLWx8bGKikpKWh81apVeuaZZ/TrX/9aEyZM6N3mAQC4iETsMn58fLwcDodqamqCxmtqapSTkxN2m+zs7JD66upqZWVlKS4uLjC2cuVKPfXUU/qv//ovZWVl9X7zAABcRCL66F1hYaE2bNigyspKeb1eFRQUqLm5WS6XS9LJz9L/+g56l8ulAwcOqLCwUF6vV5WVlaqoqNCiRYsCNc8++6yWL1+uyspKXXnllfL5fPL5fDp69OgFnx8AANEgop/Z5+fnq62tTStWrFBLS4vGjx8vt9uttLQ0SVJLS0vQM/fp6elyu90qKCjQunXrNGLECK1Zs0Z5eXmBmtLSUnV2duoHP/hB0Hs9/vjjeuKJJy7IvAAAiCYRfc4+WrW3tysxMZHn7HHJiPZnhE/hGEK0ivZjKOJflwsAAPoWYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYLiIh31paanS09Nlt9vlcDi0c+fOM9bX1tbK4XDIbrcrIyND5eXlQes/+OAD5eXl6corr5TNZtPq1av7sHsAAKJfRMO+qqpKCxcuVHFxsRoaGuR0OjV9+nQ1NzeHrW9qatKMGTPkdDrV0NCgZcuWacGCBdqyZUug5quvvlJGRob+9V//VSkpKRdqKgAARK2Ihv3zzz+vefPmaf78+crMzNTq1auVmpqqsrKysPXl5eUaNWqUVq9erczMTM2fP1///M//rFWrVgVqJk2apJUrV+qee+5RQkLChZoKAABRK2Jh39nZqfr6euXm5gaN5+bmqq6uLuw2Ho8npH7atGnavXu3jh8/fs69dHR0qL29PegFAIApIhb2ra2t6u7uVnJyctB4cnKyfD5f2G18Pl/Y+q6uLrW2tp5zLyUlJUpMTAy8UlNTz3lfAABEm4jfoGez2YKWLcsKGfum+nDjPVFUVCS/3x94HTx48Jz3BQBAtImN1BsPHTpUMTExIWfxhw8fDjl7PyUlJSVsfWxsrJKSks65l4SEBD7fBwAYK2Jn9vHx8XI4HKqpqQkar6mpUU5OTthtsrOzQ+qrq6uVlZWluLi4PusVAICLWUQv4xcWFmrDhg2qrKyU1+tVQUGBmpub5XK5JJ28vD5nzpxAvcvl0oEDB1RYWCiv16vKykpVVFRo0aJFgZrOzk41NjaqsbFRnZ2dOnTokBobG/Xxxx9f8PkBABANInYZX5Ly8/PV1tamFStWqKWlRePHj5fb7VZaWpokqaWlJeiZ+/T0dLndbhUUFGjdunUaMWKE1qxZo7y8vEDNp59+quuvvz6wvGrVKq1atUpTp07Vjh07LtjcAACIFjbr1B1uCGhvb1diYqL8fr8GDx7ca/t1LN7Ya/sCelP9yjnfXBQFOIYQraL9GIr43fgAAKBvEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMBxhDwCA4Qh7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAADEfYAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAYjrAHAMBwhD0AAIYj7AEAMFzEw760tFTp6emy2+1yOBzauXPnGetra2vlcDhkt9uVkZGh8vLykJotW7Zo3LhxSkhI0Lhx4/TGG2/0VfsAAES9iIZ9VVWVFi5cqOLiYjU0NMjpdGr69Olqbm4OW9/U1KQZM2bI6XSqoaFBy5Yt04IFC7Rly5ZAjcfjUX5+vmbPnq09e/Zo9uzZ+sd//Ef97//+74WaFgAAUcVmWZYVqTefMmWKJk6cqLKyssBYZmamZs6cqZKSkpD6JUuWaNu2bfJ6vYExl8ulPXv2yOPxSJLy8/PV3t6ut99+O1Bz2223aciQIdq0adNZ9dXe3q7ExET5/X4NHjz4XKcXwrF4Y6/tC+hN9SvnRLqFs8IxhGgV7cdQbKTeuLOzU/X19Vq6dGnQeG5ururq6sJu4/F4lJubGzQ2bdo0VVRU6Pjx44qLi5PH41FBQUFIzerVq0/bS0dHhzo6OgLLfr9f0snQ703dHf+vV/cH9Jbe/m+9r3AMIVr11TE0aNAg2Wy2895PxMK+tbVV3d3dSk5ODhpPTk6Wz+cLu43P5wtb39XVpdbWVg0fPvy0NafbpySVlJToySefDBlPTU092+kAF7XEF1yRbgG4qPXVMdRbV5gjFvan/O1fLJZlnfGvmHD1fzve030WFRWpsLAwsHzixAl9/vnnSkpK6pW/qND72tvblZqaqoMHD/bqRy3ApYJj6OIwaNCgXtlPxMJ+6NChiomJCTnjPnz4cMiZ+SkpKSlh62NjY5WUlHTGmtPtU5ISEhKUkJAQNHbZZZed7VQQQYMHD+Z/VMB54Bi6NETsbvz4+Hg5HA7V1NQEjdfU1CgnJyfsNtnZ2SH11dXVysrKUlxc3BlrTrdPAABMF9HL+IWFhZo9e7aysrKUnZ2t9evXq7m5WS7Xyc8+ioqKdOjQIW3cePIOXJfLpbVr16qwsFD33XefPB6PKioqgu6yf/jhh3XTTTfp5z//ue666y5t3bpVv/71r/Wb3/wmInMEACDSIhr2+fn5amtr04oVK9TS0qLx48fL7XYrLS1NktTS0hL0zH16errcbrcKCgq0bt06jRgxQmvWrFFeXl6gJicnR5s3b9by5cv16KOP6qqrrlJVVZWmTJlyweeHvpOQkKDHH3885OMXAGeHY+jSEtHn7AEAQN+L+NflAgCAvkXYAwBgOMIeAADDEfYAABiOsEfUqaurU0xMjG677bag8U8++UQ2m02NjY1ht+vu7lZJSYnGjh2r/v376/LLL9d3vvMdvfTSSxega+DicO+992rmzJkh/4bZIv51ucDfqqys1EMPPaQNGzaoublZo0aNOqvtnnjiCa1fv15r165VVlaW2tvbtXv3bh05cqSPOwaA6EbYI6ocO3ZMr732mn73u9/J5/Pp5Zdf1mOPPXZW27755pt64IEHdPfddwfGrr322r5qFQAuGlzGR1SpqqrSmDFjNGbMGM2aNUsvvfSSzvarIFJSUvTf//3f+uyzz/q4SwC4uBD2iCoVFRWaNWuWJOm2227T0aNHtX379rPa9vnnn9dnn32mlJQUTZgwQS6XS2+//XZftgsAFwXCHlFj37592rVrl+655x5JUmxsrPLz81VZWXlW248bN0579+7Vb3/7W82dO1d/+ctfdMcdd2j+/Pl92TYARD0+s0fUqKioUFdXl0aOHBkYsyxLcXFxZ32TXb9+/TRp0iRNmjRJBQUFeuWVVzR79mwVFxcrPT29r1oHgKjGmT2iQldXlzZu3KjnnntOjY2NgdeePXuUlpamV1999Zz2O27cOEknb/wDgEsVZ/aICm+99ZaOHDmiefPmKTExMWjdD37wA1VUVOj73/++pJOX+//WuHHj9KMf/Ug33HCDcnJylJKSoqamJhUVFWn06NEaO3bsBZkHAEQjwh5RoaKiQrfeemtI0EtSXl6ennnmGX3++eeSFPhM/681NTVp2rRp2rRpk0pKSuT3+5WSkqLvfve7euKJJxQby3/qAC5d/MQtAACG4zN7AAAMR9gDAGA4wh4AAMMR9gAAGI6wBwDAcIQ9AACGI+wBADAcYQ8AgOEIewAX1M0336yFCxeedf3LL7+syy67rM/6AS4FhD0AAIYj7AEAMBxhD0DSycvrDz30kBYuXKghQ4YoOTlZ69ev17FjxzR37lwNGjRIV111ld5+++3ANrW1tZo8ebISEhI0fPhwLV26VF1dXYH1x44d05w5czRw4EANHz5czz33XMj7dnZ26qc//alGjhypAQMGaMqUKdqxY8eFmDJwySDsAQT88pe/1NChQ7Vr1y499NBDuv/++3X33XcrJydH77//vqZNm6bZs2frq6++0qFDhzRjxgxNmjRJe/bsUVlZmSoqKvSzn/0ssL/Fixfr3Xff1RtvvKHq6mrt2LFD9fX1Qe85d+5cvffee9q8ebN+//vf6+6779Ztt92mP/3pTxd6+oC5LACwLGvq1KnWjTfeGFju6uqyBgwYYM2ePTsw1tLSYkmyPB6PtWzZMmvMmDHWiRMnAuvXrVtnDRw40Oru7ra+/PJLKz4+3tq8eXNgfVtbm9W/f3/r4YcftizLsj7++GPLZrNZhw4dCurllltusYqKiizLsqyXXnrJSkxM7IMZA5cOfuQbQMCECRMC/46JiVFSUpKuueaawFhycrIk6fDhw/J6vcrOzpbNZgusv+GGG3T06FH9+c9/1pEjR9TZ2ans7OzA+ssvv1xjxowJLL///vuyLEujR48O6qOjo0NJSUm9Pj/gUkXYAwiIi4sLWrbZbEFjp4L9xIkTsiwrKOglybKsQN2pf5/JiRMnFBMTo/r6esXExAStGzhw4DnNAUAowh7AORk3bpy2bNkSFPp1dXUaNGiQRo4cqSFDhiguLk6//e1vNWrUKEnSkSNH9NFHH2nq1KmSpOuvv17d3d06fPiwnE5nxOYCmI4b9ACckwceeEAHDx7UQw89pA8//FBbt27V448/rsLCQvXr108DBw7UvHnztHjxYm3fvl179+7Vvffeq379/u9/O6NHj9aPf/xjzZkzR6+//rqampr0u9/9Tj//+c/ldrsjODvALJzZAzgnI0eOlNvt1uLFi3Xttdfq8ssv17x587R8+fJAzcqVK3X06FHdeeedGjRokB555BH5/f6g/bz00kv62c9+pkceeUSHDh1SUlKSsrOzNWPGjAs9JcBYNutsPlgDAAAXLS7jAwBgOMIeAADDEfYAABiOsAcAwHCEPQAAhiPsAQAwHGEPAIDhCHsAAAxH2AMAYDjCHgAAwxH2AAAY7v8DRYpxRu/55mAAAAAASUVORK5CYII=", + "image/png": "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r9tvv71fFgoAAK5Or/8Qzt13360//vGPqqmp0eeffy5J+u53v6tJkyb5fXEAAKDveh17t9utgQMH6s4779Sdd97pGT9//rza29v9+odjAABA3/XqA3pvvvmmkpKS9PXXX/s89vXXX+uuu+7S22+/7bfFAQCAvutV7IuLi/WTn/xE3/nOd3we+853vqPly5dr8+bNflscAADou17F/pNPPtHUqVMv+fh9992njz/+uK9rAgAAftSr2J8+fVpdXV2XfPzcuXM6ffp0nxcFAAD8p1exv+2223TkyJFLPn7kyBHFxsb2eVEAAMB/ehX7f/qnf1J+fr7+8pe/+DzW1NSkVatWad68eX5bHAAA6LteffVuxYoV2rdvn7773e9q/vz5GjdunBwOh2pra/Xaa68pJiZGK1as6K+1AgCAq9Cr2A8aNEiHDx9WXl6eSktLPe/PR0ZGav78+Vq7dq0GDRrULwsFAABXp9c/qhMREaGioiJt2bJFLS0tsixLw4YN8/x0LgAACCy9jv1Fra2tOnHihBwOh4KCgrz+rj0AAAgcvfqAniR9+umnuu++++R0OpWcnKy7775bt956q77//e97/a17AAAQGHp1Zt/U1KQpU6Zo2LBh2rBhg8aPHy/LsvTHP/5R27dvV1pamj755BPdeuut/bVeAADQS72K/c9//nPFxsbq8OHDCg8P94zPmDFDixcv1r333quf//znKiws9PtCAQDA1enVZfzy8nItX77cK/QX3XTTTVq2bJneffddvy0OAAD0Xa9i/8UXX2jy5MmXfDwpKUlffPFFnxcFAAD8p1exP3PmzGX/Xv2gQYPU3t7e50UBAAD/6fVX786cOdPjZXxJcrvdsiyrz4sCAAD+06vYW5alsWPHXvZxflwHAIDA0qvYf/DBB/21DgAA0E96FfspU6b01zoAAEA/6VXsBwwY8K2X6R0Oh7q6uvq0KAAA4D+9iv2bb755yccqKir0i1/8gg/oAQAQYHoV+zlz5viMffbZZ8rLy9Pbb7+tRx99VM8995zfFgcAAPqu138I56I///nPeuKJJzRhwgR1dXWppqZGr776qkaNGuXP9QEAgD7qdezb2tq0fPly3X777fr000/1/vvv6+2331ZiYmJ/rA8AAPRRry7jv/jii3rhhRcUHR2t3bt393hZHwAABJZexX7FihW66aabdPvtt+vVV1/Vq6++2uO8N954wy+LAwAAfder2C9YsIBfyAMA4DrTq9i/8sor/bQMAADQX6760/gAAOD6QOwBADAcsQcAwHDEHgAAwxF7AAAMR+wBADAcsQcAwHC2x76oqEhxcXEKDw+Xy+XSoUOHLjv/4MGDcrlcCg8P1+jRo7V161afOX/961/15JNPavjw4QoPD1d8fLzKysr66xAAAAhotsa+tLRU2dnZys/PV3V1tdLS0jRz5kzV19f3OL+urk6zZs1SWlqaqqurtXLlSi1ZskR79+71zOns7NTf//3f6/jx4/rVr36lY8eOafv27Ro5cuS1OiwAAAJKr35Bz982bNighQsXatGiRZKkjRs36t1331VxcbEKCwt95m/dulWjRo3Sxo0bJUnx8fE6cuSI1q9fr3nz5kmSduzYoS+//FIVFRUKCQmRJMXGxl52HR0dHero6PDcd7vd/jg8AAACgm1n9p2dnaqqqlJ6errXeHp6uioqKnrcprKy0mf+9OnTdeTIEZ07d06S9NZbbyklJUVPPvmknE6nEhMTtXbtWnV3d19yLYWFhYqIiPDcYmJi+nh0AAAEDtti39LSou7ubjmdTq9xp9OppqamHrdpamrqcX5XV5daWlokSV988YV+9atfqbu7W2VlZVq1apVeeuklPf/885dcS15entra2jy3kydP9vHoAAAIHLZexpfk81f0LMu67F/W62n+346fP39et956q7Zt26agoCC5XC79+c9/1rp16/TTn/60x32GhYUpLCysL4cBAEDAsi32UVFRCgoK8jmLb25u9jl7vyg6OrrH+cHBwRo6dKgkafjw4QoJCVFQUJBnTnx8vJqamtTZ2anQ0FA/HwkAAIHNtsv4oaGhcrlcKi8v9xovLy9Xampqj9ukpKT4zN+/f7+SkpI8H8a755579Kc//Unnz5/3zPn88881fPhwQg8AuCHZ+tW73Nxcvfzyy9qxY4dqa2uVk5Oj+vp6ZWVlSbrwXvqCBQs887OysnTixAnl5uaqtrZWO3bsUElJiZYuXeqZs3jxYrW2turpp5/W559/rv/4j//Q2rVr9eSTT17z4wMAIBDY+p59RkaGWltbVVBQoMbGRiUmJqqsrMzzVbnGxkav79zHxcWprKxMOTk52rJli0aMGKFNmzZ5vnYnSTExMdq/f79ycnI0YcIEjRw5Uk8//bSWL19+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", "text/plain": [ "
" ] @@ -6145,7 +394,7 @@ ], "metadata": { "kernelspec": { - "display_name": "dev-full", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/docs/guide/logging.rst b/docs/guide/logging.rst index 125c938c0..cb179424e 100644 --- a/docs/guide/logging.rst +++ b/docs/guide/logging.rst @@ -43,6 +43,9 @@ Calling :meth:`LoggingConfig.apply` configures both Python standard library warnings to the log system, and generally makes sure that LensKit and other code emitting logs (including your code) will send them to useful places. +For setup with even less code, but less flexibility, you can use the +:func:`basic_logging` function. + Environment Variables and Defaults ---------------------------------- diff --git a/lenskit/lenskit/logging/__init__.py b/lenskit/lenskit/logging/__init__.py index d551b25c7..9ef65622b 100644 --- a/lenskit/lenskit/logging/__init__.py +++ b/lenskit/lenskit/logging/__init__.py @@ -7,12 +7,13 @@ import structlog -from .config import LoggingConfig +from .config import LoggingConfig, basic_logging from .progress import Progress, item_progress, set_progress_impl from .tasks import Task __all__ = [ "LoggingConfig", + "basic_logging", "Progress", "item_progress", "set_progress_impl",