From 9c23d78dd88721ffea0fdce0fe08a5d8e9de9e5c Mon Sep 17 00:00:00 2001 From: Matt Fisher Date: Tue, 2 Jul 2024 20:08:31 -0600 Subject: [PATCH 1/2] Add climatology endpoint and viz --- .pre-commit-config.yaml | 4 + demo.ipynb | 92 ++++++++++++++++++--- src/aross_stations_db/api/v1/climatology.py | 33 ++++++++ src/aross_stations_db/api/v1/output.py | 16 ++++ src/aross_stations_db/api/v1/routes.py | 3 +- src/aross_stations_db/query.py | 30 +++++++ 6 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 src/aross_stations_db/api/v1/climatology.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cb48e24..9f705fa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,6 +43,10 @@ repos: rev: "v2.2.6" hooks: - id: codespell + exclude: > + (?x)^( + .*\.ipynb + )$ - repo: https://github.com/shellcheck-py/shellcheck-py rev: "v0.10.0.1" diff --git a/demo.ipynb b/demo.ipynb index 5495da5..393241e 100644 --- a/demo.ipynb +++ b/demo.ipynb @@ -10,10 +10,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "62946305-1d70-4570-8d67-5f9c5560c695", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Welcome; aross-statations-db v0.1.dev45+g3d35165.d20240702 is installed and imported.\n" + ] + } + ], "source": [ "import aross_stations_db\n", "\n", @@ -22,14 +30,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "16660440-9532-48df-932e-939926b641b5", "metadata": {}, "outputs": [], "source": [ "API_BASE_URL = \"http://api:8000/v1\"\n", "\n", - "QUERY_START_DATE = \"2023-01-01\"\n", + "QUERY_START_DATE = \"2020-01-01\"\n", "QUERY_END_DATE = \"2023-06-01\"\n", "QUERY_POLYGON = \"POLYGON ((-159.32130625160698 69.56469019745796, -159.32130625160698 68.08208920517862, -150.17196253090276 68.08208920517862, -150.17196253090276 69.56469019745796, -159.32130625160698 69.56469019745796))\"\n", "\n", @@ -39,12 +47,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "4dbe785f-7ed1-4aa2-a7de-6f4df1973442", "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6f23be1a82e24172913a97c230d92de0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[90, 0], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_in_title', 'zoom_out_text…" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import leafmap\n", "from ipyleaflet import (\n", @@ -70,10 +94,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "ceec4ec5-e179-4e2d-9412-fb7aa519c8e0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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iMUVERERkYpYXBERERGpiMUVERERkYp4QTtRPsELtomI8gceuSIiIiJSEY9cFRA8qkFERJQ38MgVERERkYpYXBERERGpiMUVERERkYpYXBERERGpiMUVERERkYpYXBERERGpiMUVERERkYpYXBERERGpiMUVERERkYpYXBERERGpiMUVERERkYpYXBERERGpiMUVERERkYpYXBERERGpyCy3B0BElBtKjtmWYfuNz4Nf80iIqKDhkSsiIiIiFbG4IiIiIlIRiysiIiIiFfGaKyIiyhCvSyN6NSyuiIiIKF/Kq38A8LQgERERkYpYXBERERGpiKcFKU/Iq4d2iYiIjMUjV0REREQqYnFFREREpKJcL67u3LmD7t27o2jRorCyskKVKlVw4sQJZbqIYMKECXB3d4eVlRWaN2+Of/75x6CP6OhohISEwN7eHo6OjujXrx+ePn1qkDl37hwaNGgAS0tLeHl5YdasWa/l9REREVHhkqvF1aNHj1CvXj2Ym5vjt99+w6VLlzBnzhwUKVJEycyaNQtfffUVQkNDcezYMdjY2CAoKAgJCQlKJiQkBBcvXsTu3buxdetWHDhwAAMGDFCmx8bGomXLlvD29sbJkycxe/ZsTJo0Cd98881rfb1ERERU8OXqBe0zZ86El5cXli9frrT5+Pgo/xcRzJs3D+PHj8ebb74JAPj+++/h6uqKzZs3o0uXLrh8+TJ27NiBsLAw+Pv7AwAWLFiANm3a4IsvvoCHhwfWrFmDpKQkLFu2DBYWFqhUqRLOnDmDL7/80qAI00tMTERiYqLyODY2NqcWARERERUwuXrkasuWLfD390fHjh3h4uICPz8/LF26VJkeHh6OiIgING/eXGlzcHBAnTp1cPToUQDA0aNH4ejoqBRWANC8eXOYmJjg2LFjSqZhw4awsLBQMkFBQbhy5QoePXqUblwzZsyAg4OD8uPl5aX6ayciIqKCKVePXF2/fh1LlizBiBEj8MknnyAsLAxDhw6FhYUFevXqhYiICACAq6urwfNcXV2VaREREXBxcTGYbmZmBicnJ4NM2iNiafuMiIgwOA0JAGPHjsWIESOUx7GxsSywiIhUxluwUEGVq8WVTqeDv78/pk+fDgDw8/PDhQsXEBoail69euXauLRaLbRaba7Nn4iIiPKvXD0t6O7uDl9fX4O2ihUr4tatWwAANzc3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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import datetime as dt\n", "\n", @@ -83,27 +118,60 @@ "\n", "TIMESERIES_QUERY_URL = f\"{API_BASE_URL}/events/timeseries/monthly?{SPATIOTEMPORAL_QUERY_STRING}\"\n", "\n", - "def barchart(*, query_url: str, title: str):\n", + "def barchart(*, query_url: str, index_col: str, rot: int = 0, title: str):\n", " \n", " timeseries_data = pandas.read_json(query_url)\n", - " timeseries_data.set_index(\"date\", inplace=True)\n", - " timeseries_data.index = timeseries_data.index.strftime(\"%Y-%m\")\n", + " timeseries_data.set_index(index_col, inplace=True)\n", + " if index_col == \"date\":\n", + " timeseries_data.index = timeseries_data.index.strftime(\"%Y-%m\")\n", + "\n", " return timeseries_data.plot(\n", " kind=\"bar\",\n", " title=title,\n", " ylabel=\"Event count\",\n", " xlabel=\"Month\",\n", - " rot=0,\n", + " rot=rot,\n", " legend=False,\n", " )\n", "\n", "plt.show(\n", " barchart(\n", " query_url=TIMESERIES_QUERY_URL,\n", + " index_col=\"date\",\n", + " rot=45,\n", " title=f\"Monthly rain on snow events\\n[{QUERY_START_DATE}, {QUERY_END_DATE})\",\n", " )\n", ")" ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ee8669e8-d5a7-4841-b1b3-a184f0caf9d4", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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ku967927h7S0tByv4apUqRKysrJw69atHD+b/V3m9NmKFStKy7P/W758ea1+ObX16NEDBw8elD63du1avHjxIt/v5caNG9DT09Ma097eHlZWVlo/ewVRunTpHC8aP3fuHD7//HNYWlrCwsICNjY2UnhQsv9f/96zA1R+P7s3btzI9TvLXl4Y65k1axbOnj0LZ2dn1K5dGxMnTszxL3wnJyetQPv6/4M3btzARx99BD09+V9dr9dsZ2eHjz76SApI+/fvR4MGDdCwYUPcuXMHV69excGDB5GVlZVvaLp06RLOnTsHGxsb2evjjz8G8O81Vtk6duyIgwcPStfj7dmzB0lJSejYsaNsvJSUFNja2mqN+eTJE9l4wH/7/daoUSO0bdsWkyZNQqlSpfDZZ58hLCxMdi0WFQxDE701Xbp0wdatWxEaGoqWLVtqHWF5U/r6+jm2i9cudi6KMdzd3eHl5YXff/8dAPD7779DrVajQ4cOitddWHLbhpzaX92u/fv349NPP4WRkRGWLFmCLVu2ICoqCl26dCnQPixOOnXqBENDQ+lo0++//46aNWsqujgfePOjfXl59YhStuTkZDRq1AinTp3C5MmT8ffffyMqKgozZ84E8O8Fw/kpjJ9/Jd50PR06dMDVq1excOFCODo6Yvbs2ahcubLWEePC3o769etj//79ePbsGWJjY9GgQQN4eHjAysoK+/fvx/79+2FmZobq1avnOU5WVhaqVKmCqKioHF9ff/211Ldjx44QQmDt2rUAgDVr1sDS0hItWrSQjWdra5vreJMnTy60/aJSqbBu3TrExMQgODgYt2/fRu/eveHl5YUnT57k+3nSZqDrAujD8fnnn+Orr77C4cOHZYewX+fi4oKdO3fi8ePHsqNN2acqXFxcCrzuovhLMFuPHj0QEhKCu3fvIiIiAv7+/rLTJTnJPhV49uxZ+Pr6FlltSvz5558wMjLC9u3bZbe0h4WFafXNaT/a2NjAxMQkxzmELl68CD09Pa2jXdmyv8v4+HjpdEe2+Ph4aXn2f3O6WyunNmtra/j7+2PlypXo2rUrDh48iPnz5+dYw+v1ZGVl4dKlS9LRCwBITExEcnLyG/3s5WXPnj148OAB1q9fj4YNG0rt165dK9T15MTFxSXX7yx7eWFxcHDA119/ja+//hpJSUmoUaMGpk6dipYtWxZoHBcX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RERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQK6DQ0TZ8+HbVq1YK5uTlsbW0REBCA+Ph4WZ/GjRtDpVLJXv3795f1uXnzJvz9/WFiYgJbW1sMHz4cL1++lPXZs2cPatSoAY1Gg/LlyyM8PFyrnsWLF8PV1RVGRkbw9vbG0aNHC32biYiI6N1koMuV7927F0FBQahVqxZevnyJb7/9Fs2bN8f58+dhamoq9fvyyy8xefJk6b2JiYn058zMTPj7+8Pe3h6HDh3C3bt30aNHDxgaGmLatGkAgGvXrsHf3x/9+/fHypUrER0djb59+8LBwQF+fn4AgNWrVyMkJAShoaHw9vbG/Pnz4efnh/j4eNja2r6lPUJERO8S11GbC33M6zP8C33Md8G7sC91Gpq2bdsmex8eHg5bW1vExsaiYcOGUruJiQns7e1zHGPHjh04f/48du7cCTs7O1SrVg1TpkzByJEjMXHiRKjVaoSGhsLNzQ1z5swBAFSqVAkHDhzAvHnzpNA0d+5cfPnll+jVqxcAIDQ0FJs3b8Yvv/yCUaNGFcXmExER0TukWF3TlJKSAgCwtraWta9cuRKlSpWCh4cHRo8ejbS0NGlZTEwMqlSpAjs7O6nNz88PqampOHfunNTH19dXNqafnx9iYmIAABkZGYiNjZX10dPTg6+vr9SHiIiIPmw6PdL0qqysLAwZMgT16tWDh4eH1N6lSxe4uLjA0dERp0+fxsiRIxEfH4/169cDABISEmSBCYD0PiEhIc8+qampePbsGR49eoTMzMwc+1y8eDHHetPT05Geni69T01NfcMtJyIiondBsQlNQUFBOHv2LA4cOCBr79evn/TnKlWqwMHBAc2aNcOVK1dQrly5t12mZPr06Zg0aZLO1k9ERERvV7E4PRccHIzIyEjs3r0bTk5Oefb19vYGAFy+fBkAYG9vj8TERFmf7PfZ10Hl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VOjQoQMcHBwQFBSEQ4cOFXjlx48fR/Xq1VG9enUAQEhICKpXr47x48dDX18fp0+fxqeffoqPP/4Yffr0gZeXF/bv3y87LbZy5UpUrFgRzZo1Q6tWrVC/fn3ZHEyWlpbYsWMHrl27Bi8vL3zzzTcYP368bC6nunXrIiIiAsuWLUPVqlWxbt06bNy4ER4eHgXeJiIiIno/FfiaJgMDA7Ru3RqtW7dGWloaNmzYgIiICDRp0gROTk64cuWK4rEaN24MIUSuy7dv357vGNbW1oiIiMizj6enJ/bv359nn/bt26N9+/b5ro+IiIg+TAUOTa8yMTGBn58fHj16hBs3buDChQuFVRcRERFRsfJGD+xNS0vDypUr0apVK5QuXRrz58/H559/jnPnzhV2fURERETFQoGPNHXq1AmRkZEwMTFBhw4dMG7cON5lRkRERO+9AocmfX19rFmzBn5+ftDX1y+KmoiIiIiKnQKHppUrVxZFHURERETFmuJrmlq1aoWUlBTp/YwZM5CcnCy9f/DgAdzd3Qu1OCIiIqLiQnFo2r59O9LT06X306ZNw8OHD6X3L1++RHx8fOFWR0RERFRMKA5Nr8+nlNf8SkRERETvmzeacoCIiIjoQ6M4NKlUKqhUKq02IiIiog+B4rvnhBDo2bOn9Ny358+fo3///jA1NQUA2fVORERERO8bxaEpMDBQ9r5bt25afXr06PHfKyIiIiIqhhSHprCwsKKsg4iIiKhY44XgRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESmg09C0b98+tGnTBo6OjlCpVNi4caNsuRAC48ePh4ODA4yNjeHr64tLly7J+jx8+BBdu3aFhYUFrKys0KdPHzx58kTW5/Tp02jQoAGMjIzg7OyMWbNmadWydu1aVKxYEUZGRqhSpQq2bNlS6NtLRERE7y6dhqanT5+iatWq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0uvWrVv/dfOIiIioGHunQtOTJ09w5coVODg4wMvLC4aGhoiOjpaWx8fH4+bNm/Dx8QEA+Pj44MyZM0hKSpL6REVFwcLCAu7u7lKfV8fI7pM9Rm40Gg0sLCxkLyIiInp/FevQNGzYMOzduxfXr1/HoUOH8Pnnn0NfXx+dO3eGpaUl+vTpg5CQEOzevRuxsbHo1asXfHx8UKdOHQBA8+bN4e7uju7du+PUqVPYvn07xo4di6CgIGg0GgBA//79cfXqVYwYMQIXL17EkiVLsGbNGgwdOlSXm05ERETFTLG+pumff/5B586d8eDBA9jY2KB+/fo4fPgwbGxsAADz5s2Dnp4e2rZti/T0dPj5+WHJkiXS5/X19REZGYkBAwbAx8cHpqamCAwMxOTJk6U+bm5u2Lx5M4YOHYoFCxbAyckJP/30E6cbICIiIpliHZpWrVqV53IjIyMsXrwYixcvzrWPi4sLtmzZkuc4jRs3xsmTJ9+oRiIiIvowFOvTc0RERETFBUMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQIMTUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNL1m8eLFcHV1hZGREby9vXH06FFdl0RERETFAEPTK1avXo2QkBBMmDABJ06cQNWqVeHn54ekpCRdl0ZEREQ6xtD0irlz5+LLL79Er1694O7ujtDQUJiYmOCXX37RdWlERESkYwxN/19GRgZiY2Ph6+srtenp6cHX1xcxMTE6rIyIiIiKAwNdF1Bc3L9/H5mZmbCzs5O129nZ4eLFi1r909PTkZ6eLr1PSUkBAKSmpua7rqz0tP9YrTYl6y2owq7zXagRKPw634UaAX7fheVdqBHg911Y3oUaAX7fSvoIIfIfUJAQQojbt28LAOLQoUOy9uHDh4vatWtr9Z8wYYIAwBdffPHFF198vQevW7du5ZsVeKTp/ytVqhT09fWRmJgoa09MTIS9vb1W/9GjRyMkJER6n5WVhYcPH6JkyZJQqVSFUlNqaiqcnZ1x69YtWFhYFMqYhY01Fp53oU7WWHjehTpZY+F5F+r8UGsUQuDx48dwdHTMty9D0/+nVqvh5eWF6OhoBAQEAPg3CEVHRyM4OFirv0ajgUajkbVZWVkVSW0WFhbF9gc4G2ssPO9Cnayx8LwLdbLGwvMu1Pkh1mhpaamoH0PTK0JCQhAYGIiaNWuidu3amD9/Pp4+fYpevXrpujQiIiLSMYamV3Ts2BH37t3D+PHjkZCQgGrVqmHbtm1aF4cTERHRh4eh6TXBwcE5no7TBY1GgwkTJmidBixOWGPheRfqZI2F512okzUWnnehTtaYP5UQSu6xIyIiIvqwcXJLIiIiIgUYmoiIiIgUYGgiIiIiUoChqRjat28f2rRpA0dHR6hUKmzcuFHXJWmZPn06atWqBXNzc9ja2iIgIADx8fG6Lktm6dKl8PT0lObz8PHxwdatW3VdVp5mzJgBlUqFIUOG6LoUmYkTJ0KlUsleFStW1HVZWm7fvo1u3bqhZMmSMDY2RpUqVXD8+HFdlyXj6uqqtS9VKhWCgoJ0XZokMzMT48aNg5ubG4yNjVGuXDlMmTJF2WMm3qLHjx9jyJAhcHFxgbGxMerWrYtjx47ptKb8fn8LITB+/Hg4ODjA2NgYvr6+uHTpUrGqcf369WjevLk0WXNcXNxbrS+/Gl+8eIGRI0eiSpUqMDU1haOjI3r06IE7d+4UeV0MTcXQ06dPUbVqVSxevFjXpeRq7969CAoKwuHDhxEVFYUXL16gefPmePr0qa5Lkzg5OWHGjBmIjY3F8ePH0bRpU3z22Wc4d+6crkvL0bFjx/Djjz/C09NT16XkqHLlyrh79670OnDggK5Lknn06BHq1asHQ0NDbN26FefPn8ecOXNQokQJXZcmc+zYMdl+jIqKAgC0b99ex5X9z8yZM7F06VIsWrQIFy5cwMyZMzFr1iwsXLhQ16XJ9O3bF1FRUfjtt99w5swZNG/eHL6+vrh9+7bOasrv9/esWbPwww8/IDQ0FEeOHIGpqSn8/Pzw/PnzYlPj06dPUb9+fcycOfOt1ZRTDbnVmJaWhhMnTmDcuHE4ceIE1q9fj/j4eHz66adFX1hhPLeNig4AsWHDBl2Xka+kpCQBQOzdu1fXpeSpRIkS4qefftJ1GVoeP34sPvroIxEVFSUaNWokBg8erOuSZCZMmCCqVq2q6zLyNHLkSFG/fn1dl1FggwcPFuXKlRNZWVm6LkXi7+8vevfuLWv74osvRNeuXXVUkba0tDShr68vIiMjZe01atQQY8aM0VFVcq///s7KyhL29vZi9uzZUltycrLQaDTijz/+0EGFef8dc+3aNQFAnDx58q3W9Dolfw8ePXpUABA3btwo0lp4pIkKRUpKCgDA2tpax5XkLDMzE6tWrcLTp0/h4+Oj63K0BAUFwd/fH76+vrouJVeXLl2Co6MjypYti65du+LmzZu6Lknmr7/+Qs2aNdG+fXvY2tqievXqWL58ua7LylNGRgZ+//139O7du9CeWVkY6tati+joaPzf//0fAODUqVM4cOAAWrZsqePK/ufly5fIzMyEkZGRrN3Y2LjYHQXNdu3aNSQkJMj+P7e0tIS3tzdiYmJ0WNm7LyUlBSqVqsgeZ5aNk1vSf5aVlYUhQ4agXr168PDw0HU5MmfOnIGPjw+eP38OMzMzbNiwAe7u7rouS2bVqlU4ceKEzq/FyIu3tzfCw8NRoUIF3L17F5MmTUKDBg1w9uxZmJub67o8AMDVq1exdOlShISE4Ntvv8WxY8cwaNAgqNVqBAYG6rq8HG3cuBHJycno2bOnrkuRGTVqFFJTU1GxYkXo6+sjMzMTU6dORdeuXXVdmsTc3Bw+Pj6YMmUKKlWqBDs7O/zxxx+IiYlB+fLldV1ejhISEgBA6ykTdnZ20jIquOfPn2PkyJHo3LlzkT8zj6GJ/rOgoCCcPXu2WP7rrkKFCoiLi0NKSgrWrVuHwMBA7N27t9gEp1u3bmHw4MGIiorS+hdzcfLqEQZPT094e3vDxcUFa9asQZ8+fXRY2f9kZWWhZs2amDZtGgCgevXqOHv2LEJDQ4ttaPr555/RsmVLRU9Xf5vWrFmDlStXIiIiApUrV0ZcXByGDBkCR0fHYrUvf/vtN/Tu3RulS5eGvr4+atSogc6dOyM2NlbXpdFb8uLFC3To0AFCCCxdurTI18fTc/SfBAcHIzIyErt374aTk5Ouy9GiVqtRvnx5eHl5Yfr06ahatSoWLFig67IksbGxSEpKQo0aNWBgYAADAwPs3bsXP/zwAwwMDJCZmanrEnNkZWWFjz/+GJcvX9Z1KRIHBwetMFypUqVidxox240bN7Bz50707dtX16VoGT58OEaNGoVOnTqhSpUq6N69O4YOHYrp06frujSZcuXKYe/evXjy5Alu3bqFo0eP4sWLFyhbtqyuS8uRvb09ACAxMVHWnpiYKC0j5bID040bNxAVFVXkR5kAhiZ6Q0IIBAcHY8OGDdi1axfc3Nx0XZIiWVlZSE9P13UZkmbNmuHMmTOIi4uTXjVr1kTXrl0RFxcHfX19XZeYoydPnuDKlStwcHDQdSmSevXqaU178X//939wcXHRUUV5CwsLg62tLfz9/XVdipa0tDTo6cn/etDX10dWVpaOKsqbqakpHBwc8OjRI2zfvh2fffaZrkvKkZubG+zt7REdHS21paam4siRI8XyWsviLDswXbp0CTt37kTJkiXfynp5eq4YevLkiexf8NeuXUNcXBysra1RpkwZHVb2P0FBQYiIiMCmTZtgbm4unY+3tLSEsbGxjqv71+jRo9GyZUuUKVMGjx8/RkREBPbs2YPt27frujSJubm51nVgpqamKFmyZLG6PmzYsGFo06YNXFxccOfOHUyYMAH6+vro3LmzrkuTDB06FHXr1sW0adPQoUMHHD16FMuWLcOyZct0XZqWrKwshIWFITAwEAYGxe/XcJs2bTB16lSUKVMGlStXxsmTJzF37lz07t1b16XJbN++HUIIVKhQAZcvX8bw4cNRsWJF9OrVS2c15ff7e8iQIfjuu+/w0Ucfwc3NDePGjYOjoyMCAgKKTY0PHz7EzZs3pXmPsv8xYm9v/9aOiOVVo4ODA9q1a4cTJ04gMjISmZmZ0t9B1tbWUKvVRVdYkd6bR29k9+7dAoDWKzAwUNelSXKqD4AICwvTdWmS3r17CxcXF6FWq4WNjY1o1qyZ2LFjh67LyldxnHKgY8eOwsHBQajValG6dGnRsWNHcfnyZV2XpeXvv/8WHh4eQqPRiIoVK4ply5bpuqQcbd++XQAQ8fHxui4lR6mpqWLw4MGiTJkywsjISJQtW1aMGTNGpKen67o0mdWrV4uyZcsKtVot7O3tRVBQkEhOTtZpTfn9/s7KyhLjxo0TdnZ2QqPRiGbNmr31n4P8agwLC8tx+YQJE4pFjdlTIeT02r17d5HWpRKimE3xSkRERFQM8ZomIiIiIgUYmoiIiIgUYGgiIiIiUoChiYiIiEgBhiYiIiIiBRiaiIiIiBRgaCIiIiJSgKGJiIiISAGGJiKiIqRSqbBx40Zdl0FEhYChiYjeSz179oRKpUL//v21lgUFBUGlUqFnz56Ftr6JEyeiWrVqhTYeERU/DE1E9N5ydnbGqlWr8OzZM6nt+fPniIiIKDYPvyaidwdDExG9t2rUqAFnZ2esX79ealu/fj3KlCmD6tWrS23p6ekYNGgQbG1tYWRkhPr16+PYsWPS8j179kClUiE6Oho1a9aEiYkJ6tatKz39PTw8HJMmTcKpU6egUqmgUqkQHh4uff7+/fv4/PPPYWJigo8++gh//fVX0W88ERU6hiYieq/17t0bYWFh0vtffvkFvXr1kvUZMWIE/vzzT6xYsQInTpxA+fLl4efnh4cPH8r6jRkzBnPmzMHx48dhYGCA3r17AwA6duyIb775BpUrV8bdu3dx9+5ddOzYUfrcpEmT0KFDB5w+fRqtWrVC165dtcYmouKPoYmI3mvdunXDgQMHcOPGDdy4cQMHDx5Et27dpOVPnz7F0qVLMXv2bLRs2RLu7u5Yvnw5jI2N8fPPP8vGmjp1Kho1agR3d3eMGjUKhw4dwvPnz2FsbAwzMzMYGBjA3t4e9vb2MDY2lj7Xs2dPdO7cGeXLl8e0adPw5MkTHD169K3tAyIqHAa6LoCIqCjZ2NjA398f4eHhEELA398fpUqVkpZfuXIFL168QL169aQ2Q0ND1K5dGxcuXJCN5enpKf3ZwcEBAJCUlJTv9VGvfs7U1BQWFhZISkr6T9tFRG8fQxMRvfd69+6N4OBgAMDixYvfeBxDQ0PpzyqVCgCQlZVVoM9lf1bJ54ioeOHpOSJ677Vo0QIZGRl48eIF/Pz8ZMvKlSsHtVqNgwcPSm0vXrzAsWPH4O7urngdarUamZmZhVYzERU/PNJERO89fX196VSbvr6+bJmpqSkGDBiA4cOHw9raGmXKlMGsWbOQlpaGPn36KF6Hq6srrl27hri4ODg5OcHc3BwajaZQt4OIdIuhiYg+CBYWFrkumzFjBrKystC9e3c8fvwYNWvWxPbt21GiRAnF47dt2xbr169HkyZNkJycjLCwsEKdPJOIdE8lhBC6LoKIiIiouOM1TUREREQKMDQRERERKcDQRERERKQAQxMRERGRAgxNRERERAowNBEREREpwNBEREREpABDExEREZECDE1ERERECjA0ERERESnA0ERERESkAEMTERERkQL/D8bhPpsQYGQxAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "CLIMATOLOGY_QUERY_URL = f\"{API_BASE_URL}/events/climatology/monthly?{SPATIOTEMPORAL_QUERY_STRING}\"\n", + "\n", + "plt.show(\n", + " barchart(\n", + " query_url=CLIMATOLOGY_QUERY_URL,\n", + " index_col=\"month\",\n", + " title=f\"Monthly climatology of rain on snow events\\n[{QUERY_START_DATE}, {QUERY_END_DATE})\",\n", + " )\n", + ")" + ] } ], "metadata": { diff --git a/src/aross_stations_db/api/v1/climatology.py b/src/aross_stations_db/api/v1/climatology.py new file mode 100644 index 0000000..b5f70b2 --- /dev/null +++ b/src/aross_stations_db/api/v1/climatology.py @@ -0,0 +1,33 @@ +import datetime as dt +from typing import Annotated + +from fastapi import APIRouter, Depends, Query +from geoalchemy2 import WKTElement +from sqlalchemy.orm import Session + +from aross_stations_db.api.v1.output import ( + ClimatologyJsonElement, + climatology_query_results_to_json, +) +from aross_stations_db.middleware import get_db_session +from aross_stations_db.query import climatology_query + +router = APIRouter() + + +@router.get("/monthly") +def get_monthly_climatology( + db: Annotated[Session, Depends(get_db_session)], + *, + start: Annotated[dt.datetime, Query(description="ISO-format timestamp")], + end: Annotated[dt.datetime, Query(description="ISO-format timestamp")], + polygon: Annotated[str | None, WKTElement, Query(description="WKT shape")] = None, +) -> list[ClimatologyJsonElement]: + """Get a monthly climatology of events matching query parameters.""" + # TODO: Validate query spans >1 year? Or >= 2 years? Should the query parameters be + # changed to enforce best practices for visualizing a climatology (e.g. there + # should always be the same number of Januaries as Februaries as ...etc., so we + # could accept a start year, end year, and start month.) + query = climatology_query(db=db, start=start, end=end, polygon=polygon) + + return climatology_query_results_to_json(query.all()) diff --git a/src/aross_stations_db/api/v1/output.py b/src/aross_stations_db/api/v1/output.py index ac7549b..afe8495 100644 --- a/src/aross_stations_db/api/v1/output.py +++ b/src/aross_stations_db/api/v1/output.py @@ -1,5 +1,7 @@ import datetime as dt +from typing import Annotated +from annotated_types import Ge, Le from geojson_pydantic import ( Feature, FeatureCollection, @@ -48,3 +50,17 @@ def timeseries_query_results_to_json( TimeseriesJsonElement(date=date, event_count=event_count) for date, event_count in results ] + + +class ClimatologyJsonElement(BaseModel): + month: Annotated[int, Ge(1), Le(12)] + event_count: int + + +def climatology_query_results_to_json( + results: list[Row[tuple[int, int]]], +) -> list[ClimatologyJsonElement]: + return [ + ClimatologyJsonElement(month=month, event_count=event_count) + for month, event_count in results + ] diff --git a/src/aross_stations_db/api/v1/routes.py b/src/aross_stations_db/api/v1/routes.py index f103c15..661c540 100644 --- a/src/aross_stations_db/api/v1/routes.py +++ b/src/aross_stations_db/api/v1/routes.py @@ -1,9 +1,10 @@ from fastapi import APIRouter +from aross_stations_db.api.v1.climatology import router as climatology_router from aross_stations_db.api.v1.stations import router as stations_router from aross_stations_db.api.v1.timeseries import router as timeseries_router router = APIRouter() router.include_router(stations_router, prefix="/stations") router.include_router(timeseries_router, prefix="/events/timeseries") -# router.include_router(climatology_router, prefix="/events/climatology") +router.include_router(climatology_router, prefix="/events/climatology") diff --git a/src/aross_stations_db/query.py b/src/aross_stations_db/query.py index a24e221..d967590 100644 --- a/src/aross_stations_db/query.py +++ b/src/aross_stations_db/query.py @@ -72,3 +72,33 @@ def timeseries_query( ) return query.group_by("month").order_by("month") + + +def climatology_query( + db: Session, + *, + start: dt.datetime, + end: dt.datetime, + polygon: str | None = None, +) -> RowReturningQuery[tuple[int, int]]: + query = cast( + # TODO: A better way! Avoid duplicating information; the type of func.count() + # can be inferred automatically, but not func.date_trunc(). + # https://github.com/sqlalchemy/sqlalchemy/discussions/11564 + RowReturningQuery[tuple[int, int]], + db.query( + func.extract("month", Event.time_start).label("month"), + func.count(Event.time_start).label("count"), + ), + ).filter(Event.time_start >= start, Event.time_end < end) + + if polygon: + query = query.join( + Station, # TODO: Event.station relationship + ).filter( + Station.location.ST_Within( + func.ST_SetSRID(func.ST_GeomFromText(polygon), 4326), + ) + ) + + return query.group_by("month").order_by("month") From e732ea022a958765f6000070a8c82b0c055916ad Mon Sep 17 00:00:00 2001 From: Matt Fisher Date: Tue, 2 Jul 2024 20:13:22 -0600 Subject: [PATCH 2/2] Don't build images on PRs --- .github/workflows/build-and-publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 11982a1..407dde6 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -1,8 +1,6 @@ name: Build & publish artifacts on: - workflow_dispatch: - pull_request: push: branches: - "main"