You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@beam.apache.org by GitBox <gi...@apache.org> on 2021/06/07 23:52:13 UTC

[GitHub] [beam] davidcavazos opened a new pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

davidcavazos opened a new pull request #14962:
URL: https://github.com/apache/beam/pull/14962


   Adds the Windowing notebook for the Tour of Beam.
   
   ------------------------
   
   Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
   
    - [ ] [**Choose reviewer(s)**](https://beam.apache.org/contribute/#make-your-change) and mention them in a comment (`R: @username`).
    - [ ] Format the pull request title like `[BEAM-XXX] Fixes bug in ApproximateQuantiles`, where you replace `BEAM-XXX` with the appropriate JIRA issue, if applicable. This will automatically link the pull request to the issue.
    - [ ] Update `CHANGES.md` with noteworthy changes.
    - [ ] If this contribution is large, please file an Apache [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
   
   See the [Contributor Guide](https://beam.apache.org/contribute) for more tips on [how to make review process smoother](https://beam.apache.org/contribute/#make-reviewers-job-easier).
   
   `ValidatesRunner` compliance status (on master branch)
   --------------------------------------------------------
   
   <table>
     <thead>
       <tr>
         <th>Lang</th>
         <th>ULR</th>
         <th>Dataflow</th>
         <th>Flink</th>
         <th>Samza</th>
         <th>Spark</th>
         <th>Twister2</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>Go</td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Go/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Go/lastCompletedBuild/badge/icon">
           </a>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Go_VR_Flink/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Go_VR_Flink/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Go_VR_Spark/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Go_VR_Spark/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
       </tr>
       <tr>
         <td>Java</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_ULR/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_ULR/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow/lastCompletedBuild/badge/icon?subject=V1">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow_Streaming/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow_Streaming/lastCompletedBuild/badge/icon?subject=V1+Streaming">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow_Java11/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Dataflow_Java11/lastCompletedBuild/badge/icon?subject=V1+Java+11">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_VR_Dataflow_V2/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_VR_Dataflow_V2/lastCompletedBuild/badge/icon?subject=V2">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_VR_Dataflow_V2_Streaming/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_VR_Dataflow_V2_Streaming/lastCompletedBuild/badge/icon?subject=V2+Streaming">
           </a><br>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Flink/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Flink/lastCompletedBuild/badge/icon?subject=Java+8">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Flink_Java11/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Flink_Java11/lastCompletedBuild/badge/icon?subject=Java+11">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Flink_Batch/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Flink_Batch/lastCompletedBuild/badge/icon?subject=Portable">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Flink_Streaming/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Flink_Streaming/lastCompletedBuild/badge/icon?subject=Portable+Streaming">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Samza/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Samza/lastCompletedBuild/badge/icon">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Samza/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Samza/lastCompletedBuild/badge/icon?subject=Portable">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Spark/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Spark/lastCompletedBuild/badge/icon">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Spark_Batch/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_PVR_Spark_Batch/lastCompletedBuild/badge/icon?subject=Portable">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_SparkStructuredStreaming/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_SparkStructuredStreaming/lastCompletedBuild/badge/icon?subject=Structured+Streaming">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Twister2/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_ValidatesRunner_Twister2/lastCompletedBuild/badge/icon">
           </a>
         </td>
       </tr>
       <tr>
         <td>Python</td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Py_VR_Dataflow/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Py_VR_Dataflow/lastCompletedBuild/badge/icon?subject=V1">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Py_VR_Dataflow_V2/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Py_VR_Dataflow_V2/lastCompletedBuild/badge/icon?subject=V2">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Py_ValCont/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Py_ValCont/lastCompletedBuild/badge/icon?subject=ValCont">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Python_PVR_Flink_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Python_PVR_Flink_Cron/lastCompletedBuild/badge/icon?subject=Portable">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Python_VR_Flink/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Python_VR_Flink/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Python_VR_Spark/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Python_VR_Spark/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
       </tr>
       <tr>
         <td>XLang</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Direct/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Direct/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Dataflow/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Dataflow/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Flink/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Flink/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Spark/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_XVR_Spark/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
       </tr>
     </tbody>
   </table>
   
   Examples testing status on various runners
   --------------------------------------------------------
   
   <table>
     <thead>
       <tr>
         <th>Lang</th>
         <th>ULR</th>
         <th>Dataflow</th>
         <th>Flink</th>
         <th>Samza</th>
         <th>Spark</th>
         <th>Twister2</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>Go</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
       </tr>
       <tr>
         <td>Java</td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Java_Examples_Dataflow_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Java_Examples_Dataflow_Cron/lastCompletedBuild/badge/icon?subject=V1">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Java_Examples_Dataflow_Java11_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Java_Examples_Dataflow_Java11_Cron/lastCompletedBuild/badge/icon?subject=V1+Java11">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java_Examples_Dataflow_V2/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java_Examples_Dataflow_V2/lastCompletedBuild/badge/icon?subject=V2">
           </a><br>
         </td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
       </tr>
       <tr>
         <td>Python</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
       </tr>
       <tr>
         <td>XLang</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
       </tr>
     </tbody>
   </table>
   
   Post-Commit SDK/Transform Integration Tests Status (on master branch)
   ------------------------------------------------------------------------------------------------
   
   <table>
     <thead>
       <tr>
         <th>Go</th>
         <th>Java</th>
         <th>Python</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Go/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Go/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Java/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Java/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Python36/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Python36/lastCompletedBuild/badge/icon?subject=3.6">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Python37/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Python37/lastCompletedBuild/badge/icon?subject=3.7">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PostCommit_Python38/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PostCommit_Python38/lastCompletedBuild/badge/icon?subject=3.8">
           </a>
         </td>
       </tr>
     </tbody>
   </table>
   
   Pre-Commit Tests Status (on master branch)
   ------------------------------------------------------------------------------------------------
   
   <table>
     <thead>
       <tr>
         <th>---</th>
         <th>Java</th>
         <th>Python</th>
         <th>Go</th>
         <th>Website</th>
         <th>Whitespace</th>
         <th>Typescript</th>
       </tr>
     </thead>
     <tbody>
       <tr>
         <td>Non-portable</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Java_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Java_Cron/lastCompletedBuild/badge/icon">
           </a><br>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Python_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Python_Cron/lastCompletedBuild/badge/icon?subject=Tests">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_PythonLint_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_PythonLint_Cron/lastCompletedBuild/badge/icon?subject=Lint">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_PythonDocker_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_PythonDocker_Cron/badge/icon?subject=Docker">
           </a><br>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_PythonDocs_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_PythonDocs_Cron/badge/icon?subject=Docs">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Go_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Go_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Website_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Website_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Whitespace_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Whitespace_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Typescript_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Typescript_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
       </tr>
       <tr>
         <td>Portable</td>
         <td>---</td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_Portable_Python_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_Portable_Python_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>
           <a href="https://ci-beam.apache.org/job/beam_PreCommit_GoPortable_Cron/lastCompletedBuild/">
             <img alt="Build Status" src="https://ci-beam.apache.org/job/beam_PreCommit_GoPortable_Cron/lastCompletedBuild/badge/icon">
           </a>
         </td>
         <td>---</td>
         <td>---</td>
         <td>---</td>
       </tr>
     </tbody>
   </table>
   
   See [.test-infra/jenkins/README](https://github.com/apache/beam/blob/master/.test-infra/jenkins/README.md) for trigger phrase, status and link of all Jenkins jobs.
   
   
   GitHub Actions Tests Status (on master branch)
   ------------------------------------------------------------------------------------------------
   [![Build python source distribution and wheels](https://github.com/apache/beam/workflows/Build%20python%20source%20distribution%20and%20wheels/badge.svg?branch=master&event=schedule)](https://github.com/apache/beam/actions?query=workflow%3A%22Build+python+source+distribution+and+wheels%22+branch%3Amaster+event%3Aschedule)
   [![Python tests](https://github.com/apache/beam/workflows/Python%20tests/badge.svg?branch=master&event=schedule)](https://github.com/apache/beam/actions?query=workflow%3A%22Python+Tests%22+branch%3Amaster+event%3Aschedule)
   [![Java tests](https://github.com/apache/beam/workflows/Java%20Tests/badge.svg?branch=master&event=schedule)](https://github.com/apache/beam/actions?query=workflow%3A%22Java+Tests%22+branch%3Amaster+event%3Aschedule)
   
   See [CI.md](https://github.com/apache/beam/blob/master/CI.md) for more information about GitHub Actions CI.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] anguillanneuf commented on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
anguillanneuf commented on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-863579457


   Overall looks great. Gardening project, moon phases, the notebook has got personality and I like it a lot :) 
   
   Some comments as I was going through the [notebook](https://colab.research.google.com/github/davidcavazos/beam/blob/tour-of-beam/examples/notebooks/tour-of-beam/windowing.ipynb):
   
   1. `s/lets/let's`
   2. Suggested edit - redundancy: "In our example, the "processing" is done by PrintElementInfo which simply prints the element with its window information. ~For windows of three months every month~, each element is processed three times, one time per window." 
   3. Suggested edit - use a bulleted list: "Sliding windows allow us to do just that. We need to specify the window size in seconds just like with FixedWindows. We also need to specify a window period in seconds, which is how often we want to emit each window." 
   4. Suggested edit - redundancy - future tense: "If the next event happens within the next 30 days ~or less, like 20 days after the previous event,~ the session window [will extend and cover..] extends and covers that as well. If there are no new events for the next 30 days, the session window [will close..] closes and is emitted." 
   5. I had to scroll up to remember what input events look like in the later examples. It would be nice to include a screenshot of the input events to the right of the nice bar charts, then these screenshots can be easily used by other tutorials/talks. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos commented on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos commented on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870792499


   R: @pcoet -- for documentation
   
   FYI: @rosetn 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos commented on a change in pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos commented on a change in pull request #14962:
URL: https://github.com/apache/beam/pull/14962#discussion_r660824581



##########
File path: examples/notebooks/tour-of-beam/windowing.ipynb
##########
@@ -0,0 +1,703 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "name": "Windowing -- Tour of Beam",
+      "provenance": [],
+      "collapsed_sections": [],
+      "toc_visible": true
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "code",
+      "metadata": {
+        "cellView": "form",
+        "id": "upmJn_DjcThx"
+      },
+      "source": [
+        "#@title ###### Licensed to the Apache Software Foundation (ASF), Version 2.0 (the \"License\")\n",
+        "\n",
+        "# Licensed to the Apache Software Foundation (ASF) under one\n",
+        "# or more contributor license agreements. See the NOTICE file\n",
+        "# distributed with this work for additional information\n",
+        "# regarding copyright ownership. The ASF licenses this file\n",
+        "# to you under the Apache License, Version 2.0 (the\n",
+        "# \"License\"); you may not use this file except in compliance\n",
+        "# with the License. You may obtain a copy of the License at\n",
+        "#\n",
+        "#   http://www.apache.org/licenses/LICENSE-2.0\n",
+        "#\n",
+        "# Unless required by applicable law or agreed to in writing,\n",
+        "# software distributed under the License is distributed on an\n",
+        "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
+        "# KIND, either express or implied. See the License for the\n",
+        "# specific language governing permissions and limitations\n",
+        "# under the License."
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "5UC_aGanx6oE"
+      },
+      "source": [
+        "# Windowing -- _Tour of Beam_\n",
+        "\n",
+        "Sometimes, we want to [aggregate](https://beam.apache.org/documentation/transforms/python/overview/#aggregation) data, like `GroupByKey` or `Combine`, only at certain intervals, like hourly or daily, instead of processing the entire `PCollection` of data only once.\n",
+        "\n",
+        "We might want to emit a [moving average](https://en.wikipedia.org/wiki/Moving_average) as we're processing data.\n",
+        "\n",
+        "Maybe we want to analyze the user experience for a certain task in a web app, it would be nice to get the app events by sessions of activity.\n",
+        "\n",
+        "Or we could be running a streaming pipeline, and there is no end to the data, so how can we aggregate data?\n",
+        "\n",
+        "_Windows_ in Beam allow us to process only certain data intervals at a time.\n",
+        "In this notebook, we go through different ways of windowing our pipeline.\n",
+        "\n",
+        "Lets begin by installing `apache-beam`."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "R_Yhoc6N_Flg"
+      },
+      "source": [
+        "# Install apache-beam with pip.\n",
+        "!pip install --quiet apache-beam"
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "_OkWHiAvpWDZ"
+      },
+      "source": [
+        "First, lets define some helper functions to simplify the rest of the examples.\n",
+        "\n",
+        "We have a transform to help us analyze an element alongside its window information, and we have another transform to help us analyze how many elements landed into each window.\n",
+        "We use a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo)\n",
+        "to access that information.\n",
+        "\n",
+        "You don't need to understand these, you just need to know they exist 🙂."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "C9yAN1Hgk3dF"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "def human_readable_window(window) -> str:\n",
+        "  \"\"\"Formats a window object into a human readable string.\"\"\"\n",
+        "  if isinstance(window, beam.window.GlobalWindow):\n",
+        "    return str(window)\n",
+        "  return f'{window.start.to_utc_datetime()} - {window.end.to_utc_datetime()}'\n",
+        "\n",
+        "class PrintElementInfo(beam.DoFn):\n",
+        "  \"\"\"Prints an element with its Window information.\"\"\"\n",
+        "  def process(self, element, timestamp=beam.DoFn.TimestampParam, window=beam.DoFn.WindowParam):\n",
+        "    print(f'[{human_readable_window(window)}] {timestamp.to_utc_datetime()} -- {element}')\n",
+        "    yield element\n",
+        "\n",
+        "@beam.ptransform_fn\n",

Review comment:
       Thanks, I removed PTransforms and only use DoFn since we need to access the windowing information.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] aaltay commented on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
aaltay commented on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870217609


   What is the next step on this PR? Could you address the open comments?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos edited a comment on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos edited a comment on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870792499


   @aaltay sorry for the delay on this one, but comments have been addressed and should be ready for review.
   
   R: @pcoet
   
   FYI: @rosetn 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos edited a comment on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos edited a comment on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870789854


   > Overall looks great. Gardening project, moon phases, the notebook has got personality and I like it a lot :)
   > 
   > Some comments as I was going through the [notebook](https://colab.research.google.com/github/davidcavazos/beam/blob/tour-of-beam/examples/notebooks/tour-of-beam/windowing.ipynb):
   > 
   > 1. `s/lets/let's`
   
   Thanks, done.
   
   > 2. Suggested edit - redundancy: "In our example, the "processing" is done by PrintElementInfo which simply prints the element with its window information. ~For windows of three months every month~, each element is processed three times, one time per window."
   
   Changed
   
   > 3. Suggested edit - use a bulleted list: "Sliding windows allow us to do just that. We need to specify the window size in seconds just like with FixedWindows. We also need to specify a window period in seconds, which is how often we want to emit each window."
   
   Changed
   
   > 4. Suggested edit - redundancy - future tense: "If the next event happens within the next 30 days ~or less, like 20 days after the previous event,~ the session window [will extend and cover..] extends and covers that as well. If there are no new events for the next 30 days, the session window [will close..] closes and is emitted."
   
   Changed
   
   > 5. I had to scroll up to remember what input events look like in the later examples. It would be nice to include a screenshot of the input events to the right of the nice bar charts, then these screenshots can be easily included by other tutorials/talks.
   
   I actually ended up inlining the data on each snippet. It makes each sample a little more self contained, and simplified some indirection. It also makes it easier for people to modify the inputs and see how it affects things.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] anguillanneuf edited a comment on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
anguillanneuf edited a comment on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-863579457


   Overall looks great. Gardening project, moon phases, the notebook has got personality and I like it a lot :) 
   
   Some comments as I was going through the [notebook](https://colab.research.google.com/github/davidcavazos/beam/blob/tour-of-beam/examples/notebooks/tour-of-beam/windowing.ipynb):
   
   1. `s/lets/let's`
   2. Suggested edit - redundancy: "In our example, the "processing" is done by PrintElementInfo which simply prints the element with its window information. ~For windows of three months every month~, each element is processed three times, one time per window." 
   3. Suggested edit - use a bulleted list: "Sliding windows allow us to do just that. We need to specify the window size in seconds just like with FixedWindows. We also need to specify a window period in seconds, which is how often we want to emit each window." 
   4. Suggested edit - redundancy - future tense: "If the next event happens within the next 30 days ~or less, like 20 days after the previous event,~ the session window [will extend and cover..] extends and covers that as well. If there are no new events for the next 30 days, the session window [will close..] closes and is emitted." 
   5. I had to scroll up to remember what input events look like in the later examples. It would be nice to include a screenshot of the input events to the right of the nice bar charts, then these screenshots can be easily included by other tutorials/talks. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] aaltay commented on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
aaltay commented on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870217609


   What is the next step on this PR? Could you address the open comments?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] aaltay merged pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
aaltay merged pull request #14962:
URL: https://github.com/apache/beam/pull/14962


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos commented on a change in pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos commented on a change in pull request #14962:
URL: https://github.com/apache/beam/pull/14962#discussion_r660825491



##########
File path: examples/notebooks/tour-of-beam/windowing.ipynb
##########
@@ -0,0 +1,703 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "name": "Windowing -- Tour of Beam",
+      "provenance": [],
+      "collapsed_sections": [],
+      "toc_visible": true
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "code",
+      "metadata": {
+        "cellView": "form",
+        "id": "upmJn_DjcThx"
+      },
+      "source": [
+        "#@title ###### Licensed to the Apache Software Foundation (ASF), Version 2.0 (the \"License\")\n",
+        "\n",
+        "# Licensed to the Apache Software Foundation (ASF) under one\n",
+        "# or more contributor license agreements. See the NOTICE file\n",
+        "# distributed with this work for additional information\n",
+        "# regarding copyright ownership. The ASF licenses this file\n",
+        "# to you under the Apache License, Version 2.0 (the\n",
+        "# \"License\"); you may not use this file except in compliance\n",
+        "# with the License. You may obtain a copy of the License at\n",
+        "#\n",
+        "#   http://www.apache.org/licenses/LICENSE-2.0\n",
+        "#\n",
+        "# Unless required by applicable law or agreed to in writing,\n",
+        "# software distributed under the License is distributed on an\n",
+        "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
+        "# KIND, either express or implied. See the License for the\n",
+        "# specific language governing permissions and limitations\n",
+        "# under the License."
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "5UC_aGanx6oE"
+      },
+      "source": [
+        "# Windowing -- _Tour of Beam_\n",
+        "\n",
+        "Sometimes, we want to [aggregate](https://beam.apache.org/documentation/transforms/python/overview/#aggregation) data, like `GroupByKey` or `Combine`, only at certain intervals, like hourly or daily, instead of processing the entire `PCollection` of data only once.\n",
+        "\n",
+        "We might want to emit a [moving average](https://en.wikipedia.org/wiki/Moving_average) as we're processing data.\n",
+        "\n",
+        "Maybe we want to analyze the user experience for a certain task in a web app, it would be nice to get the app events by sessions of activity.\n",
+        "\n",
+        "Or we could be running a streaming pipeline, and there is no end to the data, so how can we aggregate data?\n",
+        "\n",
+        "_Windows_ in Beam allow us to process only certain data intervals at a time.\n",
+        "In this notebook, we go through different ways of windowing our pipeline.\n",
+        "\n",
+        "Lets begin by installing `apache-beam`."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "R_Yhoc6N_Flg"
+      },
+      "source": [
+        "# Install apache-beam with pip.\n",
+        "!pip install --quiet apache-beam"
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "_OkWHiAvpWDZ"
+      },
+      "source": [
+        "First, lets define some helper functions to simplify the rest of the examples.\n",
+        "\n",
+        "We have a transform to help us analyze an element alongside its window information, and we have another transform to help us analyze how many elements landed into each window.\n",
+        "We use a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo)\n",
+        "to access that information.\n",
+        "\n",
+        "You don't need to understand these, you just need to know they exist 🙂."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "C9yAN1Hgk3dF"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "def human_readable_window(window) -> str:\n",
+        "  \"\"\"Formats a window object into a human readable string.\"\"\"\n",
+        "  if isinstance(window, beam.window.GlobalWindow):\n",
+        "    return str(window)\n",
+        "  return f'{window.start.to_utc_datetime()} - {window.end.to_utc_datetime()}'\n",
+        "\n",
+        "class PrintElementInfo(beam.DoFn):\n",
+        "  \"\"\"Prints an element with its Window information.\"\"\"\n",
+        "  def process(self, element, timestamp=beam.DoFn.TimestampParam, window=beam.DoFn.WindowParam):\n",
+        "    print(f'[{human_readable_window(window)}] {timestamp.to_utc_datetime()} -- {element}')\n",
+        "    yield element\n",
+        "\n",
+        "@beam.ptransform_fn\n",
+        "def PrintWindowInfo(pcollection):\n",
+        "  \"\"\"Prints the Window information with how many elements landed in that window.\"\"\"\n",
+        "  class PrintCountsInfo(beam.DoFn):\n",
+        "    def process(self, num_elements, window=beam.DoFn.WindowParam):\n",
+        "      print(f'>> Window [{human_readable_window(window)}] has {num_elements} elements')\n",
+        "      yield num_elements\n",
+        "\n",
+        "  return (\n",
+        "      pcollection\n",
+        "      | 'Count elements per window' >> beam.combiners.Count.Globally().without_defaults()\n",
+        "      | 'Print counts info' >> beam.ParDo(PrintCountsInfo())\n",
+        "  )"
+      ],
+      "execution_count": 1,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "CQrojV2QnqIU"
+      },
+      "source": [
+        "Now lets create some data to use in the examples.\n",
+        "\n",
+        "Windows define data intervals based on time, so we need to tell Apache Beam a timestamp for each element.\n",
+        "\n",
+        "We define a `PTransform` for convenience, so we can attach the timestamps automatically.\n",
+        "\n",
+        "Apache Beam requires us to provide the timestamp as [Unix time](https://en.wikipedia.org/wiki/Unix_time), which is a way to represent a date and time as the number of seconds since January 1st, 1970.\n",
+        "\n",
+        "For our data, lets analyze some events about the seasons and moon phases for the year 2021, which might be [useful for a gardening project](https://www.almanac.com/content/planting-by-the-moon).\n",
+        "\n",
+        "To attach timestamps to each element, we can `Map` each element and return a [`TimestmpedValue`](https://beam.apache.org/documentation/transforms/python/elementwise/withtimestamps/)."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "Sgzscopvmh1f",
+        "outputId": "e0c6fc19-ab97-4754-8f1f-1601807be940"
+      },
+      "source": [
+        "import time\n",
+        "from apache_beam.options.pipeline_options import PipelineOptions\n",
+        "\n",
+        "def to_unix_time(time_str: str, time_format='%Y-%m-%d %H:%M:%S') -> int:\n",
+        "  \"\"\"Converts a time string into Unix time.\"\"\"\n",
+        "  time_tuple = time.strptime(time_str, time_format)\n",
+        "  return int(time.mktime(time_tuple))\n",
+        "\n",
+        "@beam.ptransform_fn\n",
+        "@beam.typehints.with_input_types(beam.pvalue.PBegin)\n",
+        "@beam.typehints.with_output_types(beam.window.TimestampedValue)\n",
+        "def AstronomicalEvents(pipeline):\n",
+        "  return (\n",
+        "      pipeline\n",
+        "      | 'Create data' >> beam.Create([\n",
+        "          ('2021-03-20 03:37:00', 'March Equinox 2021'),\n",
+        "          ('2021-04-26 22:31:00', 'Super full moon'),\n",
+        "          ('2021-05-11 13:59:00', 'Micro new moon'),\n",
+        "          ('2021-05-26 06:13:00', 'Super full moon, total lunar eclipse'),\n",
+        "          ('2021-06-20 22:32:00', 'June Solstice 2021'),\n",
+        "          ('2021-08-22 07:01:00', 'Blue moon'),\n",
+        "          ('2021-09-22 14:21:00', 'September Equinox 2021'),\n",
+        "          ('2021-11-04 15:14:00', 'Super new moon'),\n",
+        "          ('2021-11-19 02:57:00', 'Micro full moon, partial lunar eclipse'),\n",
+        "          ('2021-12-04 01:43:00', 'Super new moon'),\n",
+        "          ('2021-12-18 10:35:00', 'Micro full moon'),\n",
+        "          ('2021-12-21 09:59:00', 'December Solstice 2021'),\n",
+        "      ])\n",
+        "      | 'With timestamps' >> beam.MapTuple(\n",
+        "          lambda timestamp, element:\n",
+        "              beam.window.TimestampedValue(element, to_unix_time(timestamp))\n",
+        "      )\n",
+        "  )\n",
+        "\n",
+        "# Lets see how the data looks like.\n",
+        "beam_options = PipelineOptions(flags=[], type_check_additional='all')\n",
+        "with beam.Pipeline(options=beam_options) as pipeline:\n",
+        "  (\n",
+        "      pipeline\n",
+        "      | 'Astronomical events' >> AstronomicalEvents()\n",
+        "      | 'Print element' >> beam.Map(print)\n",
+        "  )"
+      ],
+      "execution_count": 3,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "text": [
+            "March Equinox 2021\n",
+            "Super full moon\n",
+            "Micro new moon\n",
+            "Super full moon, total lunar eclipse\n",
+            "June Solstice 2021\n",
+            "Blue moon\n",
+            "September Equinox 2021\n",
+            "December Solstice 2021\n",
+            "Super new moon\n",
+            "Micro full moon, partial lunar eclipse\n",
+            "Super new moon\n",
+            "Micro full moon\n"
+          ],
+          "name": "stdout"
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "qI0K3jSA2LbJ"
+      },
+      "source": [
+        "> ℹī¸ After running this, it looks like the timestamps disappeared!\n",
+        "> They're actually still _implicitly_ part of the element, just like the windowing information.\n",
+        "> If we need to access it, we can do so via a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo).\n",
+        "> Aggregation transforms use each element's timestamp along with the windowing we specified to create windows of elements."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "ymHF1WCqnG4V"
+      },
+      "source": [
+        "# Global window\n",
+        "\n",
+        "All pipelines use the [`GlobalWindow`](https://beam.apache.org/releases/pydoc/current/apache_beam.transforms.window.html#apache_beam.transforms.window.GlobalWindow) by default.\n",
+        "This is a single window that covers the entire `PCollection`.\n",
+        "\n",
+        "In many cases, especially for batch pipelines, this is what we want since we want to analyze all the data that we have.\n",
+        "\n",
+        "> ℹī¸ `GlobalWindow` is not very useful in a streaming pipeline unless you only need element-wise transforms.\n",
+        "> Aggregations, like `GroupByKey` and `Combine`, need to process the entire window, but a streaming pipeline has no end, so they would never finish."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "xDXdE9uysriw",
+        "outputId": "b39e7fe7-dc13-4d77-89af-f2d1312ab673"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "# All elements fall into the GlobalWindow by default.\n",
+        "with beam.Pipeline() as pipeline:\n",
+        "  (\n",
+        "      pipeline\n",
+        "      | 'Astrolonomical events' >> AstronomicalEvents()\n",
+        "      | 'Print element info' >> beam.ParDo(PrintElementInfo())\n",
+        "      | 'Print window info' >> PrintWindowInfo()\n",
+        "  )"
+      ],
+      "execution_count": 4,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "text": [
+            "[GlobalWindow] 2021-03-20 03:37:00 -- March Equinox 2021\n",
+            "[GlobalWindow] 2021-04-26 22:31:00 -- Super full moon\n",
+            "[GlobalWindow] 2021-05-11 13:59:00 -- Micro new moon\n",
+            "[GlobalWindow] 2021-05-26 06:13:00 -- Super full moon, total lunar eclipse\n",
+            "[GlobalWindow] 2021-06-20 22:32:00 -- June Solstice 2021\n",
+            "[GlobalWindow] 2021-08-22 07:01:00 -- Blue moon\n",
+            "[GlobalWindow] 2021-09-22 14:21:00 -- September Equinox 2021\n",
+            "[GlobalWindow] 2021-12-21 09:59:00 -- December Solstice 2021\n",
+            "[GlobalWindow] 2021-11-04 15:14:00 -- Super new moon\n",
+            "[GlobalWindow] 2021-11-19 02:57:00 -- Micro full moon, partial lunar eclipse\n",
+            "[GlobalWindow] 2021-12-04 01:43:00 -- Super new moon\n",
+            "[GlobalWindow] 2021-12-18 10:35:00 -- Micro full moon\n",
+            ">> Window [GlobalWindow] has 12 elements\n"
+          ],
+          "name": "stdout"
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "l3Kod_pR7a7S"
+      },
+      "source": [
+        "![Global window](data:image/png;base64,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
 UVORK5CYII=)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "7WkYLzFCo4Rl"
+      },
+      "source": [
+        "# Fixed time windows\n",
+        "\n",
+        "If we want to analyze our data hourly, daily, monthly, etc. We might want to create evenly spaced intervals.\n",
+        "\n",
+        "[`FixedWindows`](https://beam.apache.org/releases/pydoc/current/apache_beam.transforms.window.html#apache_beam.transforms.window.FixedWindows)\n",
+        "allow us to create fixed-sized windows.\n",
+        "We only need to specify the _window size_ in seconds.\n",
+        "\n",
+        "In Python, we can use [`timedelta`](https://docs.python.org/3/library/datetime.html#timedelta-objects)\n",
+        "to help us do the conversion of minutes, hours, or days for us.\n",
+        "\n",
+        "> ℹī¸ Some time deltas like a month cannot be so easily converted into seconds, since a month can have from 28 to 31 days.\n",

Review comment:
       Makes sense, I'm changing all the months mentions to days.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos commented on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos commented on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870789854


   > Overall looks great. Gardening project, moon phases, the notebook has got personality and I like it a lot :)
   > 
   > Some comments as I was going through the [notebook](https://colab.research.google.com/github/davidcavazos/beam/blob/tour-of-beam/examples/notebooks/tour-of-beam/windowing.ipynb):
   > 
   > 1. `s/lets/let's`
   
   Thanks, done.
   
   > 2. Suggested edit - redundancy: "In our example, the "processing" is done by PrintElementInfo which simply prints the element with its window information. ~For windows of three months every month~, each element is processed three times, one time per window."
   
   Changed
   
   > 3. Suggested edit - use a bulleted list: "Sliding windows allow us to do just that. We need to specify the window size in seconds just like with FixedWindows. We also need to specify a window period in seconds, which is how often we want to emit each window."
   
   Changed
   
   > 4. Suggested edit - redundancy - future tense: "If the next event happens within the next 30 days ~or less, like 20 days after the previous event,~ the session window [will extend and cover..] extends and covers that as well. If there are no new events for the next 30 days, the session window [will close..] closes and is emitted."
   
   Changed
   
   > 5. I had to scroll up to remember what input events look like in the later examples. It would be nice to include a screenshot of the input events to the right of the nice bar charts, then these screenshots can be easily included by other tutorials/talks.
   
   I actually ended up inlining the data on each snippet. It makes each sample a little more self contained, and simplified some indirection.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] davidcavazos edited a comment on pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
davidcavazos edited a comment on pull request #14962:
URL: https://github.com/apache/beam/pull/14962#issuecomment-870792499


   @aaltay sorry for the delay on this one, but comments have been addressed and should be ready for review.
   
   R: @pcoet -- for documentation
   
   FYI: @rosetn 
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [beam] aaltay commented on a change in pull request #14962: [BEAM-10937] Tour of Beam Windowing notebook

Posted by GitBox <gi...@apache.org>.
aaltay commented on a change in pull request #14962:
URL: https://github.com/apache/beam/pull/14962#discussion_r647026286



##########
File path: examples/notebooks/tour-of-beam/windowing.ipynb
##########
@@ -0,0 +1,703 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "name": "Windowing -- Tour of Beam",
+      "provenance": [],
+      "collapsed_sections": [],
+      "toc_visible": true
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "code",
+      "metadata": {
+        "cellView": "form",
+        "id": "upmJn_DjcThx"
+      },
+      "source": [
+        "#@title ###### Licensed to the Apache Software Foundation (ASF), Version 2.0 (the \"License\")\n",
+        "\n",
+        "# Licensed to the Apache Software Foundation (ASF) under one\n",
+        "# or more contributor license agreements. See the NOTICE file\n",
+        "# distributed with this work for additional information\n",
+        "# regarding copyright ownership. The ASF licenses this file\n",
+        "# to you under the Apache License, Version 2.0 (the\n",
+        "# \"License\"); you may not use this file except in compliance\n",
+        "# with the License. You may obtain a copy of the License at\n",
+        "#\n",
+        "#   http://www.apache.org/licenses/LICENSE-2.0\n",
+        "#\n",
+        "# Unless required by applicable law or agreed to in writing,\n",
+        "# software distributed under the License is distributed on an\n",
+        "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
+        "# KIND, either express or implied. See the License for the\n",
+        "# specific language governing permissions and limitations\n",
+        "# under the License."
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "5UC_aGanx6oE"
+      },
+      "source": [
+        "# Windowing -- _Tour of Beam_\n",
+        "\n",
+        "Sometimes, we want to [aggregate](https://beam.apache.org/documentation/transforms/python/overview/#aggregation) data, like `GroupByKey` or `Combine`, only at certain intervals, like hourly or daily, instead of processing the entire `PCollection` of data only once.\n",
+        "\n",
+        "We might want to emit a [moving average](https://en.wikipedia.org/wiki/Moving_average) as we're processing data.\n",
+        "\n",
+        "Maybe we want to analyze the user experience for a certain task in a web app, it would be nice to get the app events by sessions of activity.\n",
+        "\n",
+        "Or we could be running a streaming pipeline, and there is no end to the data, so how can we aggregate data?\n",
+        "\n",
+        "_Windows_ in Beam allow us to process only certain data intervals at a time.\n",
+        "In this notebook, we go through different ways of windowing our pipeline.\n",
+        "\n",
+        "Lets begin by installing `apache-beam`."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "R_Yhoc6N_Flg"
+      },
+      "source": [
+        "# Install apache-beam with pip.\n",
+        "!pip install --quiet apache-beam"
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "_OkWHiAvpWDZ"
+      },
+      "source": [
+        "First, lets define some helper functions to simplify the rest of the examples.\n",
+        "\n",
+        "We have a transform to help us analyze an element alongside its window information, and we have another transform to help us analyze how many elements landed into each window.\n",
+        "We use a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo)\n",
+        "to access that information.\n",
+        "\n",
+        "You don't need to understand these, you just need to know they exist 🙂."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "C9yAN1Hgk3dF"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "def human_readable_window(window) -> str:\n",
+        "  \"\"\"Formats a window object into a human readable string.\"\"\"\n",
+        "  if isinstance(window, beam.window.GlobalWindow):\n",
+        "    return str(window)\n",
+        "  return f'{window.start.to_utc_datetime()} - {window.end.to_utc_datetime()}'\n",
+        "\n",
+        "class PrintElementInfo(beam.DoFn):\n",
+        "  \"\"\"Prints an element with its Window information.\"\"\"\n",
+        "  def process(self, element, timestamp=beam.DoFn.TimestampParam, window=beam.DoFn.WindowParam):\n",
+        "    print(f'[{human_readable_window(window)}] {timestamp.to_utc_datetime()} -- {element}')\n",
+        "    yield element\n",
+        "\n",
+        "@beam.ptransform_fn\n",

Review comment:
       Maybe we can use either `beam.DoFn` or `@beam.ptransform_fn` consistently to reduce the number of concepts.

##########
File path: examples/notebooks/tour-of-beam/windowing.ipynb
##########
@@ -0,0 +1,703 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "name": "Windowing -- Tour of Beam",
+      "provenance": [],
+      "collapsed_sections": [],
+      "toc_visible": true
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "code",
+      "metadata": {
+        "cellView": "form",
+        "id": "upmJn_DjcThx"
+      },
+      "source": [
+        "#@title ###### Licensed to the Apache Software Foundation (ASF), Version 2.0 (the \"License\")\n",
+        "\n",
+        "# Licensed to the Apache Software Foundation (ASF) under one\n",
+        "# or more contributor license agreements. See the NOTICE file\n",
+        "# distributed with this work for additional information\n",
+        "# regarding copyright ownership. The ASF licenses this file\n",
+        "# to you under the Apache License, Version 2.0 (the\n",
+        "# \"License\"); you may not use this file except in compliance\n",
+        "# with the License. You may obtain a copy of the License at\n",
+        "#\n",
+        "#   http://www.apache.org/licenses/LICENSE-2.0\n",
+        "#\n",
+        "# Unless required by applicable law or agreed to in writing,\n",
+        "# software distributed under the License is distributed on an\n",
+        "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
+        "# KIND, either express or implied. See the License for the\n",
+        "# specific language governing permissions and limitations\n",
+        "# under the License."
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "5UC_aGanx6oE"
+      },
+      "source": [
+        "# Windowing -- _Tour of Beam_\n",
+        "\n",
+        "Sometimes, we want to [aggregate](https://beam.apache.org/documentation/transforms/python/overview/#aggregation) data, like `GroupByKey` or `Combine`, only at certain intervals, like hourly or daily, instead of processing the entire `PCollection` of data only once.\n",
+        "\n",
+        "We might want to emit a [moving average](https://en.wikipedia.org/wiki/Moving_average) as we're processing data.\n",
+        "\n",
+        "Maybe we want to analyze the user experience for a certain task in a web app, it would be nice to get the app events by sessions of activity.\n",
+        "\n",
+        "Or we could be running a streaming pipeline, and there is no end to the data, so how can we aggregate data?\n",
+        "\n",
+        "_Windows_ in Beam allow us to process only certain data intervals at a time.\n",
+        "In this notebook, we go through different ways of windowing our pipeline.\n",
+        "\n",
+        "Lets begin by installing `apache-beam`."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "R_Yhoc6N_Flg"
+      },
+      "source": [
+        "# Install apache-beam with pip.\n",
+        "!pip install --quiet apache-beam"
+      ],
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "_OkWHiAvpWDZ"
+      },
+      "source": [
+        "First, lets define some helper functions to simplify the rest of the examples.\n",
+        "\n",
+        "We have a transform to help us analyze an element alongside its window information, and we have another transform to help us analyze how many elements landed into each window.\n",
+        "We use a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo)\n",
+        "to access that information.\n",
+        "\n",
+        "You don't need to understand these, you just need to know they exist 🙂."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "id": "C9yAN1Hgk3dF"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "def human_readable_window(window) -> str:\n",
+        "  \"\"\"Formats a window object into a human readable string.\"\"\"\n",
+        "  if isinstance(window, beam.window.GlobalWindow):\n",
+        "    return str(window)\n",
+        "  return f'{window.start.to_utc_datetime()} - {window.end.to_utc_datetime()}'\n",
+        "\n",
+        "class PrintElementInfo(beam.DoFn):\n",
+        "  \"\"\"Prints an element with its Window information.\"\"\"\n",
+        "  def process(self, element, timestamp=beam.DoFn.TimestampParam, window=beam.DoFn.WindowParam):\n",
+        "    print(f'[{human_readable_window(window)}] {timestamp.to_utc_datetime()} -- {element}')\n",
+        "    yield element\n",
+        "\n",
+        "@beam.ptransform_fn\n",
+        "def PrintWindowInfo(pcollection):\n",
+        "  \"\"\"Prints the Window information with how many elements landed in that window.\"\"\"\n",
+        "  class PrintCountsInfo(beam.DoFn):\n",
+        "    def process(self, num_elements, window=beam.DoFn.WindowParam):\n",
+        "      print(f'>> Window [{human_readable_window(window)}] has {num_elements} elements')\n",
+        "      yield num_elements\n",
+        "\n",
+        "  return (\n",
+        "      pcollection\n",
+        "      | 'Count elements per window' >> beam.combiners.Count.Globally().without_defaults()\n",
+        "      | 'Print counts info' >> beam.ParDo(PrintCountsInfo())\n",
+        "  )"
+      ],
+      "execution_count": 1,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "CQrojV2QnqIU"
+      },
+      "source": [
+        "Now lets create some data to use in the examples.\n",
+        "\n",
+        "Windows define data intervals based on time, so we need to tell Apache Beam a timestamp for each element.\n",
+        "\n",
+        "We define a `PTransform` for convenience, so we can attach the timestamps automatically.\n",
+        "\n",
+        "Apache Beam requires us to provide the timestamp as [Unix time](https://en.wikipedia.org/wiki/Unix_time), which is a way to represent a date and time as the number of seconds since January 1st, 1970.\n",
+        "\n",
+        "For our data, lets analyze some events about the seasons and moon phases for the year 2021, which might be [useful for a gardening project](https://www.almanac.com/content/planting-by-the-moon).\n",
+        "\n",
+        "To attach timestamps to each element, we can `Map` each element and return a [`TimestmpedValue`](https://beam.apache.org/documentation/transforms/python/elementwise/withtimestamps/)."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "Sgzscopvmh1f",
+        "outputId": "e0c6fc19-ab97-4754-8f1f-1601807be940"
+      },
+      "source": [
+        "import time\n",
+        "from apache_beam.options.pipeline_options import PipelineOptions\n",
+        "\n",
+        "def to_unix_time(time_str: str, time_format='%Y-%m-%d %H:%M:%S') -> int:\n",
+        "  \"\"\"Converts a time string into Unix time.\"\"\"\n",
+        "  time_tuple = time.strptime(time_str, time_format)\n",
+        "  return int(time.mktime(time_tuple))\n",
+        "\n",
+        "@beam.ptransform_fn\n",
+        "@beam.typehints.with_input_types(beam.pvalue.PBegin)\n",
+        "@beam.typehints.with_output_types(beam.window.TimestampedValue)\n",
+        "def AstronomicalEvents(pipeline):\n",
+        "  return (\n",
+        "      pipeline\n",
+        "      | 'Create data' >> beam.Create([\n",
+        "          ('2021-03-20 03:37:00', 'March Equinox 2021'),\n",
+        "          ('2021-04-26 22:31:00', 'Super full moon'),\n",
+        "          ('2021-05-11 13:59:00', 'Micro new moon'),\n",
+        "          ('2021-05-26 06:13:00', 'Super full moon, total lunar eclipse'),\n",
+        "          ('2021-06-20 22:32:00', 'June Solstice 2021'),\n",
+        "          ('2021-08-22 07:01:00', 'Blue moon'),\n",
+        "          ('2021-09-22 14:21:00', 'September Equinox 2021'),\n",
+        "          ('2021-11-04 15:14:00', 'Super new moon'),\n",
+        "          ('2021-11-19 02:57:00', 'Micro full moon, partial lunar eclipse'),\n",
+        "          ('2021-12-04 01:43:00', 'Super new moon'),\n",
+        "          ('2021-12-18 10:35:00', 'Micro full moon'),\n",
+        "          ('2021-12-21 09:59:00', 'December Solstice 2021'),\n",
+        "      ])\n",
+        "      | 'With timestamps' >> beam.MapTuple(\n",
+        "          lambda timestamp, element:\n",
+        "              beam.window.TimestampedValue(element, to_unix_time(timestamp))\n",
+        "      )\n",
+        "  )\n",
+        "\n",
+        "# Lets see how the data looks like.\n",
+        "beam_options = PipelineOptions(flags=[], type_check_additional='all')\n",
+        "with beam.Pipeline(options=beam_options) as pipeline:\n",
+        "  (\n",
+        "      pipeline\n",
+        "      | 'Astronomical events' >> AstronomicalEvents()\n",
+        "      | 'Print element' >> beam.Map(print)\n",
+        "  )"
+      ],
+      "execution_count": 3,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "text": [
+            "March Equinox 2021\n",
+            "Super full moon\n",
+            "Micro new moon\n",
+            "Super full moon, total lunar eclipse\n",
+            "June Solstice 2021\n",
+            "Blue moon\n",
+            "September Equinox 2021\n",
+            "December Solstice 2021\n",
+            "Super new moon\n",
+            "Micro full moon, partial lunar eclipse\n",
+            "Super new moon\n",
+            "Micro full moon\n"
+          ],
+          "name": "stdout"
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "qI0K3jSA2LbJ"
+      },
+      "source": [
+        "> ℹī¸ After running this, it looks like the timestamps disappeared!\n",
+        "> They're actually still _implicitly_ part of the element, just like the windowing information.\n",
+        "> If we need to access it, we can do so via a custom [`DoFn`](https://beam.apache.org/documentation/transforms/python/elementwise/pardo).\n",
+        "> Aggregation transforms use each element's timestamp along with the windowing we specified to create windows of elements."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "ymHF1WCqnG4V"
+      },
+      "source": [
+        "# Global window\n",
+        "\n",
+        "All pipelines use the [`GlobalWindow`](https://beam.apache.org/releases/pydoc/current/apache_beam.transforms.window.html#apache_beam.transforms.window.GlobalWindow) by default.\n",
+        "This is a single window that covers the entire `PCollection`.\n",
+        "\n",
+        "In many cases, especially for batch pipelines, this is what we want since we want to analyze all the data that we have.\n",
+        "\n",
+        "> ℹī¸ `GlobalWindow` is not very useful in a streaming pipeline unless you only need element-wise transforms.\n",
+        "> Aggregations, like `GroupByKey` and `Combine`, need to process the entire window, but a streaming pipeline has no end, so they would never finish."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "xDXdE9uysriw",
+        "outputId": "b39e7fe7-dc13-4d77-89af-f2d1312ab673"
+      },
+      "source": [
+        "import apache_beam as beam\n",
+        "\n",
+        "# All elements fall into the GlobalWindow by default.\n",
+        "with beam.Pipeline() as pipeline:\n",
+        "  (\n",
+        "      pipeline\n",
+        "      | 'Astrolonomical events' >> AstronomicalEvents()\n",
+        "      | 'Print element info' >> beam.ParDo(PrintElementInfo())\n",
+        "      | 'Print window info' >> PrintWindowInfo()\n",
+        "  )"
+      ],
+      "execution_count": 4,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "text": [
+            "[GlobalWindow] 2021-03-20 03:37:00 -- March Equinox 2021\n",
+            "[GlobalWindow] 2021-04-26 22:31:00 -- Super full moon\n",
+            "[GlobalWindow] 2021-05-11 13:59:00 -- Micro new moon\n",
+            "[GlobalWindow] 2021-05-26 06:13:00 -- Super full moon, total lunar eclipse\n",
+            "[GlobalWindow] 2021-06-20 22:32:00 -- June Solstice 2021\n",
+            "[GlobalWindow] 2021-08-22 07:01:00 -- Blue moon\n",
+            "[GlobalWindow] 2021-09-22 14:21:00 -- September Equinox 2021\n",
+            "[GlobalWindow] 2021-12-21 09:59:00 -- December Solstice 2021\n",
+            "[GlobalWindow] 2021-11-04 15:14:00 -- Super new moon\n",
+            "[GlobalWindow] 2021-11-19 02:57:00 -- Micro full moon, partial lunar eclipse\n",
+            "[GlobalWindow] 2021-12-04 01:43:00 -- Super new moon\n",
+            "[GlobalWindow] 2021-12-18 10:35:00 -- Micro full moon\n",
+            ">> Window [GlobalWindow] has 12 elements\n"
+          ],
+          "name": "stdout"
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "l3Kod_pR7a7S"
+      },
+      "source": [
+        "![Global window](data:image/png;base64,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
 UVORK5CYII=)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "7WkYLzFCo4Rl"
+      },
+      "source": [
+        "# Fixed time windows\n",
+        "\n",
+        "If we want to analyze our data hourly, daily, monthly, etc. We might want to create evenly spaced intervals.\n",
+        "\n",
+        "[`FixedWindows`](https://beam.apache.org/releases/pydoc/current/apache_beam.transforms.window.html#apache_beam.transforms.window.FixedWindows)\n",
+        "allow us to create fixed-sized windows.\n",
+        "We only need to specify the _window size_ in seconds.\n",
+        "\n",
+        "In Python, we can use [`timedelta`](https://docs.python.org/3/library/datetime.html#timedelta-objects)\n",
+        "to help us do the conversion of minutes, hours, or days for us.\n",
+        "\n",
+        "> ℹī¸ Some time deltas like a month cannot be so easily converted into seconds, since a month can have from 28 to 31 days.\n",

Review comment:
       I think you can either:
   - Remove the month concept, drop this comment and and all the other approximately x months comments, and simply say 30 day, 90 day etc.
   - Or introduce custom windows later on which can do more sophisticated things.
   
   Probably the first one (simplifying) would be better.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org