You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by th...@apache.org on 2021/12/21 09:58:00 UTC

[arrow] branch master updated: ARROW-14602: [Doc] Tutorial - Python feature PR

This is an automated email from the ASF dual-hosted git repository.

thisisnic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new f165370  ARROW-14602: [Doc] Tutorial - Python feature PR
f165370 is described below

commit f165370c919da5d84faed1cf36ad1a137ddcfaf0
Author: Alenka Frim <fr...@gmail.com>
AuthorDate: Tue Dec 21 09:55:48 2021 +0000

    ARROW-14602: [Doc] Tutorial - Python feature PR
    
    This is a draft of the **Python Tutorial** that will be included in the (New) Contributors Guide.
    
    It is a tutorial explaining the steps in making [ARROW-14977: [Python] Add a "made-up" feature for the guide tutorial](https://github.com/apache/arrow/pull/11900).
    
    Closes #11913 from AlenkaF/ARROW-14602
    
    Lead-authored-by: Alenka Frim <fr...@gmail.com>
    Co-authored-by: Alenka Frim <Al...@users.noreply.github.com>
    Signed-off-by: Nic Crane <th...@gmail.com>
---
 docs/source/developers/guide/index.rst             |   4 +-
 .../developers/guide/step_by_step/building.rst     |   2 +-
 docs/source/developers/guide/tutorials/index.rst   |   2 +-
 .../developers/guide/tutorials/python_tutorial.rst | 532 +++++++++++++++++++++
 .../python_tutorial_github_find_in_file.jpeg       | Bin 0 -> 98025 bytes
 .../python_tutorial_github_pr_notice.jpeg          | Bin 0 -> 124653 bytes
 .../tutorials/python_tutorial_github_search.jpeg   | Bin 0 -> 104437 bytes
 .../tutorials/python_tutorial_jira_comment.jpeg    | Bin 0 -> 82115 bytes
 .../python_tutorial_jira_description.jpeg          | Bin 0 -> 94669 bytes
 .../tutorials/python_tutorial_jira_issue.jpeg      | Bin 0 -> 162426 bytes
 .../tutorials/python_tutorial_jira_title.jpeg      | Bin 0 -> 80541 bytes
 .../guide/tutorials/python_tutorial_pr.jpeg        | Bin 0 -> 144207 bytes
 12 files changed, 537 insertions(+), 3 deletions(-)

diff --git a/docs/source/developers/guide/index.rst b/docs/source/developers/guide/index.rst
index 324971c..54ec292 100644
--- a/docs/source/developers/guide/index.rst
+++ b/docs/source/developers/guide/index.rst
@@ -54,6 +54,8 @@ to Arrow:
 
 Read more about the project in the :ref:`architectural_overview` section.
 
+.. _quick-ref-guide:
+
 Quick Reference
 ===============
 
@@ -81,7 +83,7 @@ of adding a basic feature.
    appropriate :ref:`communication` channel.
 
    See a short description about the building process of 
-   :ref:`PyArrow or the R package<build-arrow>` or go straight to detailed
+   :ref:`PyArrow or the R package<build-arrow-guide>` or go straight to detailed
    instructions on how to build one of Arrow libraries in the
    `documentation <https://arrow.apache.org/docs/>`_ .
  
diff --git a/docs/source/developers/guide/step_by_step/building.rst b/docs/source/developers/guide/step_by_step/building.rst
index 5b1f874..628b926 100644
--- a/docs/source/developers/guide/step_by_step/building.rst
+++ b/docs/source/developers/guide/step_by_step/building.rst
@@ -29,7 +29,7 @@
 .. documentation.
 
 
-.. _build-arrow:
+.. _build-arrow-guide:
 
 ************************************
 Building the Arrow libraries 🏋🏿‍♀️
diff --git a/docs/source/developers/guide/tutorials/index.rst b/docs/source/developers/guide/tutorials/index.rst
index f9f7ed1..dcefab2 100644
--- a/docs/source/developers/guide/tutorials/index.rst
+++ b/docs/source/developers/guide/tutorials/index.rst
@@ -22,7 +22,7 @@ Tutorials
 *********
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 1
 
    python_tutorial
    r_tutorial
\ No newline at end of file
diff --git a/docs/source/developers/guide/tutorials/python_tutorial.rst b/docs/source/developers/guide/tutorials/python_tutorial.rst
index b9852b3..049c871 100644
--- a/docs/source/developers/guide/tutorials/python_tutorial.rst
+++ b/docs/source/developers/guide/tutorials/python_tutorial.rst
@@ -25,3 +25,535 @@
 ***************
 Python tutorial
 ***************
+
+In this tutorial we will make an actual feature contribution to
+Arrow following the steps specified by :ref:`quick-ref-guide`
+section of the guide and a more detailed :ref:`step_by_step`
+section. Navigate there whenever there is some information
+you may find is missing here.
+
+The feature contribution will be added to the compute module
+in PyArrow. But you can also follow the steps in case you are
+correcting a bug or adding a binding.
+
+This tutorial is different from the :ref:`step_by_step` as we
+will be working on a specific case. This tutorial is not meant
+as a step-by-step guide.
+
+**Lets start!**
+
+Set up
+------
+
+Let's setup the Arrow repository. We presume here that Git is
+already installed. Otherwise please see the :ref:`set-up` section.
+
+Once the `Apache Arrow repository <https://github.com/apache/arrow>`_
+is forked we will clone it and add the link of the main repository
+to our upstream.
+
+.. code:: console
+
+   $ git clone https://github.com/<your username>/arrow.git
+   $ cd arrow
+   $ git remote add upstream https://github.com/apache/arrow
+
+Building PyArrow
+----------------
+
+Script for building PyArrow differs depending on the Operating
+System you are using. For this reason we will only refer to
+the instructions for the building process in this tutorial.
+
+.. seealso::
+
+   For the **introduction** to the building process refer to the
+   :ref:`build-arrow-guide` section.
+
+   For the **instructions** on how to build PyArrow refer to the
+   :ref:`build_pyarrow` section.
+
+Create a JIRA issue for the new feature
+---------------------------------------
+
+We will add a new feature that imitates an existing function
+``min_max`` from the ``arrow.compute`` module but makes the
+interval bigger by 1 in both directions. Note that this is a
+made-up function for the purpose of this guide.
+
+See the example of the ``pc.min_max`` in
+`this link <https://arrow.apache.org/cookbook/py/data.html#computing-mean-min-max-values-of-an-array>`_.
+
+First we need to create a JIRA issue as it doesn't exist yet.
+With a JIRA account created we will navigate to the
+`Apache Arrow JIRA dashboard <https://issues.apache.org/jira/projects/ARROW>`_
+and click on the **Create** button.
+
+.. figure:: python_tutorial_jira_title.jpeg
+   :scale: 70 %
+   :alt: JIRA dashboard with a window for creating a new issue.
+
+   Creating a JIRA issue, adding title (summary) and components.
+
+.. figure:: python_tutorial_jira_description.jpeg
+   :scale: 70 %
+   :alt: JIRA dashboard with a window for creating a
+         description for the new issue.
+
+   Creating a JIRA issue, adding a description.
+
+We should make sure to assign ourselves to the issue to let others
+know we are working on it. If that option is not working, we would
+need to ask for a project maintainer’s help on the
+:ref:`mailing_list`.
+
+Lets also add some comments to start a conversation.
+
+.. figure:: python_tutorial_jira_comment.jpeg
+   :scale: 50 %
+   :alt: JIRA issue page where comment is being added.
+
+   Adding a comment to the JIRA ticket we created.
+
+We have successfully created a new JIRA issue with index
+`ARROW-14977 <https://issues.apache.org/jira/browse/ARROW-14977>`_.
+
+.. figure:: python_tutorial_jira_issue.jpeg
+   :scale: 50 %
+   :alt: JIRA page of the issue just created.
+
+   Our JIRA issue. Yay!
+
+.. seealso::
+
+   To get more information on JIRA issues go to
+   :ref:`finding-issues` part of the guide.
+
+Start the work on a new branch
+------------------------------
+
+Before we start working on adding the feature we should
+create a new branch from updated master.
+
+.. code:: console
+
+   $ git checkout master
+   $ git fetch upstream
+   $ git pull --ff-only upstream master
+   $ git checkout -b ARROW-14977
+
+Lets research the Arrow library to see where the ``pc.min_max``
+function is defined/connected with the C++ and get an idea
+where we could implement the new feature.
+
+.. figure:: python_tutorial_github_search.jpeg
+   :scale: 50 %
+   :alt: Apache Arrow GitHub repository dashboard where we are
+         searching for a pc.min_max function reference.
+
+   We could try to search for the function reference in a
+   GitHub Apache Arrow repository.
+
+.. figure:: python_tutorial_github_find_in_file.jpeg
+   :scale: 50 %
+   :alt: In the GitHub repository we are searching through the
+         test_compute.py file for the pc.min_max function.
+
+   And search through the ``test_compute.py`` file in ``pyarrow``
+   folder.
+
+From the search we can see that the function is tested in the
+``python/pyarrow/tests/test_compute.py`` file that would mean the
+function is defined in the ``compute.py`` file.
+
+After examining the ``compute.py`` file we can see that together
+with ``_compute.pyx`` the functions from C++ get wrapped into Python.
+We will define the new feature at the end of the ``compute.py`` file. 
+
+Lets run some code in the Python console from ``arrow/python``
+directory in order to learn more about ``pc.min_max``.
+
+.. code:: console
+
+   $ cd python
+   $ python
+
+   Python 3.9.7 (default, Oct 22 2021, 13:24:00) 
+   [Clang 13.0.0 (clang-1300.0.29.3)] on darwin
+   Type "help", "copyright", "credits" or "license" for more information.
+   
+We have entered into the Python console from the shell and we can
+do some research:
+
+.. code-block:: python
+
+   >>> import pyarrow.compute as pc
+   >>> data = [4, 5, 6, None, 1]
+   >>> data
+   [4, 5, 6, None, 1]
+   >>> pc.min_max(data)
+   <pyarrow.StructScalar: [('min', 1), ('max', 6)]>
+   >>> pc.min_max(data, skip_nulls=False)
+   <pyarrow.StructScalar: [('min', None), ('max', None)]>
+
+We will call our new feature ``pc.tutorial_min_max``. We want the
+result from our function, that takes the same input data, to be
+``[('min-', 0), ('max+', 7)]``. If we specify that the null value should be
+included, the result should be equal to ``pc.min_max`` that is
+``[('min', None), ('max', None)]``.
+
+Lets add the first trial code into ``arrow/python/pyarrow/compute.py``
+where we first test the call to the "min_max" function from C++:
+
+.. code-block:: python
+
+   def tutorial_min_max(values, skip_nulls=True):
+       """
+       Add docstrings
+
+       Parameters
+       ----------
+       values : Array
+
+       Returns
+       -------
+       result : TODO
+
+       Examples
+       --------
+       >>> import pyarrow.compute as pc
+       >>> data = [4, 5, 6, None, 1]
+       >>> pc.tutorial_min_max(data)
+       <pyarrow.StructScalar: [('min-', 0), ('max+', 7)]>
+       """
+
+       options = ScalarAggregateOptions(skip_nulls=skip_nulls)
+       return call_function("min_max", [values], options)
+
+To see if this works we will need to import ``pyarrow.compute``
+again and try:
+
+.. code-block:: python
+
+   >>> import pyarrow.compute as pc
+   >>> data = [4, 5, 6, None, 1]
+   >>> pc.tutorial_min_max(data)
+   <pyarrow.StructScalar: [('min', 1), ('max', 6)]>
+
+It’s working. Now we must correct the limits to get the corrected
+interval. To do that we have to do some research on ``pyarrow.StructScalar``.
+In `test_scalars.py <https://github.com/apache/arrow/blob/994074d2e7ff073301e0959dbc5bb595a1e2a41b/python/pyarrow/tests/test_scalars.py#L547-L553>`_
+under the ``test_struct_duplicate_fields`` we can see an example
+of how the ``StructScalar`` is created. We could again run the
+Python console and try creating one ourselves.
+
+.. code-block:: python
+
+   >>> import pyarrow as pa
+   >>> ty = pa.struct([
+   ...      pa.field('min-', pa.int64()),
+   ...      pa.field('max+', pa.int64()),
+   ...    ])
+   >>> pa.scalar([('min-', 3), ('max+', 9)], type=ty)
+   <pyarrow.StructScalar: [('min-', 3), ('max+', 9)]>
+
+.. note::
+
+   In cases where we don't yet have good documentation, unit tests
+   can be a good place to look for code examples.
+
+With the new gained knowledge about ``StructScalar`` and additional
+options for the ``pc.min_max`` function we can finish the work.
+
+.. code-block:: python
+
+   def tutorial_min_max(values, skip_nulls=True):
+
+      """
+      Compute the minimum-1 and maximum+1 values of a numeric array.
+
+      This is a made-up feature for the tutorial purposes.
+
+      Parameters
+      ----------
+      values : Array
+      skip_nulls : bool, default True
+          If True, ignore nulls in the input.
+
+      Returns
+      -------
+      result : StructScalar of min-1 and max+1
+
+      Examples
+      --------
+      >>> import pyarrow.compute as pc
+      >>> data = [4, 5, 6, None, 1]
+      >>> pc.tutorial_min_max(data)
+      <pyarrow.StructScalar: [('min-', 0), ('max+', 7)]>
+      """
+
+      options = ScalarAggregateOptions(skip_nulls=skip_nulls)
+      min_max = call_function("min_max", [values], options)
+
+      if min_max[0].as_py() is not None:
+        min_t = min_max[0].as_py()-1
+        max_t = min_max[1].as_py()+1
+      else:
+        min_t = min_max[0].as_py()
+        max_t = min_max[1].as_py()
+
+      ty = pa.struct([
+        pa.field('min-', pa.int64()),
+        pa.field('max+', pa.int64()),
+      ])
+      return pa.scalar([('min-', min_t), ('max+', max_t)], type=ty)
+
+.. TODO seealso
+   .. For more information about the Arrow codebase visit 
+   .. :ref:``. (link to working on the Arrow codebase section)
+
+Adding a test
+-------------
+
+Now we should add a unit test to ``python/pyarrow/tests/test_compute.py``
+and run the pytest.
+
+.. code-block:: python
+
+   def test_tutorial_min_max():
+       arr = [4, 5, 6, None, 1]
+       l1 = {'min-': 0, 'max+': 7}
+       l2 = {'min-': None, 'max+': None}
+       assert pc.tutorial_min_max(arr).as_py() == l1
+       assert pc.tutorial_min_max(arr,
+                                  skip_nulls=False).as_py() == l2
+
+With the unit test added we can run the pytest from the shell. To run
+a specific unit test, pass in the test name to the ``-k`` parameter.
+
+.. code:: console
+
+   $ cd python
+   $ python -m pytest pyarrow/tests/test_compute.py -k test_tutorial_min_max                    
+   ======================== test session starts ==========================
+   platform darwin -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
+   rootdir: /Users/alenkafrim/repos/arrow/python, configfile: setup.cfg
+   plugins: hypothesis-6.24.1, lazy-fixture-0.6.3
+   collected 204 items / 203 deselected / 1 selected                                                                                   
+
+   pyarrow/tests/test_compute.py .                                  [100%]
+
+   ======================== 1 passed, 203 deselected in 0.16s ============
+   
+
+   $ python -m pytest pyarrow/tests/test_compute.py                       
+   ======================== test session starts ===========================
+   platform darwin -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
+   rootdir: /Users/alenkafrim/repos/arrow/python, configfile: setup.cfg
+   plugins: hypothesis-6.24.1, lazy-fixture-0.6.3
+   collected 204 items                                                                                                                 
+
+   pyarrow/tests/test_compute.py ................................... [ 46%]
+   .................................................                 [100%]
+
+   ========================= 204 passed in 0.49s ==========================
+
+.. seealso::
+
+   For more information about testing see :ref:`testing` section.
+
+Check styling
+-------------
+
+At the end we also need to check the styling. In Arrow we use a
+utility called `Archery <https://arrow.apache.org/docs/developers/archery.html>`_
+to check if code is in line with PEP 8 style guide.
+
+.. code:: console
+   
+   $ archery lint --python --fix
+   INFO:archery:Running Python formatter (autopep8)
+   INFO:archery:Running Python linter (flake8)
+   /Users/alenkafrim/repos/arrow/python/pyarrow/tests/test_compute.py:2288:80: E501 line too long (88 > 79 characters)
+
+With the ``--fix`` command Archery will attempt to fix style issues,
+but some issues like line length can't be fixed automatically.
+We should make the necessary corrections ourselves and run
+Archery again.
+
+.. code:: console
+
+   $ archery lint --python --fix
+   INFO:archery:Running Python formatter (autopep8)
+   INFO:archery:Running Python linter (flake8)
+
+Done. Now lets make the Pull Request!
+
+Creating a Pull Request
+-----------------------
+
+First let's review our changes in the shell using
+``git status`` to see which files have been changed and to
+commit only the ones we are working on.
+
+.. code:: console
+
+   $ git status
+   On branch ARROW-14977
+   Changes not staged for commit:
+     (use "git add <file>..." to update what will be committed)
+     (use "git restore <file>..." to discard changes in working directory)
+      modified:   python/pyarrow/compute.py
+      modified:   python/pyarrow/tests/test_compute.py
+
+   no changes added to commit (use "git add" and/or "git commit -a")
+
+And ``git diff`` to see the changes in the files
+in order to spot any error we might have made.
+
+.. code:: console
+
+   $ git diff
+   diff --git a/python/pyarrow/compute.py b/python/pyarrow/compute.py
+   index 9dac606c3..e8fc775d8 100644
+   --- a/python/pyarrow/compute.py
+   +++ b/python/pyarrow/compute.py
+   @@ -774,3 +774,45 @@ def bottom_k_unstable(values, k, sort_keys=None, *, memory_pool=None):
+            sort_keys = map(lambda key_name: (key_name, "ascending"), sort_keys)
+        options = SelectKOptions(k, sort_keys)
+        return call_function("select_k_unstable", [values], options, memory_pool)
+   +
+   +
+   +def tutorial_min_max(values, skip_nulls=True):
+   +    """
+   +    Compute the minimum-1 and maximum-1 values of a numeric array.
+   +
+   +    This is a made-up feature for the tutorial purposes.
+   +
+   +    Parameters
+   +    ----------
+   +    values : Array
+   +    skip_nulls : bool, default True
+   +        If True, ignore nulls in the input.
+   +
+   +    Returns
+   +    -------
+   +    result : StructScalar of min-1 and max+1
+   +
+   +    Examples
+   +    --------
+   +    >>> import pyarrow.compute as pc
+   +    >>> data = [4, 5, 6, None, 1]
+   +    >>> pc.tutorial_min_max(data)
+   +    <pyarrow.StructScalar: [('min-', 0), ('max+', 7)]>
+   +    """
+   +
+   +    options = ScalarAggregateOptions(skip_nulls=skip_nulls)
+   +    min_max = call_function("min_max", [values], options)
+   +
+   ...
+
+Everything looks OK. Now we can make the commit (save our changes
+to the branch history):
+
+.. code:: console
+
+   $ git commit -am "Adding a new compute feature for tutorial purposes"
+   [ARROW-14977 170ef85be] Adding a new compute feature for tutorial purposes
+    2 files changed, 51 insertions(+)
+   
+
+We can use ``git log`` to check the history of commits:
+
+.. code:: console
+
+   $ git log
+   commit 170ef85beb8ee629be651e3f93bcc4a69e29cfb8 (HEAD -> ARROW-14977)
+   Author: Alenka Frim <fr...@gmail.com>
+   Date:   Tue Dec 7 13:45:06 2021 +0100
+
+       Adding a new compute feature for tutorial purposes
+
+   commit 8cebc4948ab5c5792c20a3f463e2043e01c49828 (master)
+   Author: Sutou Kouhei <ko...@clear-code.com>
+   Date:   Sun Dec 5 15:19:46 2021 +0900
+
+       ARROW-14981: [CI][Docs] Upload built documents
+       
+       We can use this in release process instead of building on release
+       manager's local environment.
+       
+       Closes #11856 from kou/ci-docs-upload
+       
+       Authored-by: Sutou Kouhei <ko...@clear-code.com>
+       Signed-off-by: Sutou Kouhei <ko...@clear-code.com>
+   ...
+
+If we would started the branch some time ago, we may need to rebase to
+upstream master to make sure there are no merge conflicts:
+
+.. code:: console
+
+   $ git pull upstream master --rebase
+
+And now we can push our work to the forked Arrow repository on GitHub
+called ``origin``.
+
+.. code:: console
+
+   $ git push origin ARROW-14977
+   Enumerating objects: 13, done.
+   Counting objects: 100% (13/13), done.
+   Delta compression using up to 8 threads
+   Compressing objects: 100% (7/7), done.
+   Writing objects: 100% (7/7), 1.19 KiB | 1.19 MiB/s, done.
+   Total 7 (delta 6), reused 0 (delta 0), pack-reused 0
+   remote: Resolving deltas: 100% (6/6), completed with 6 local objects.
+   remote: 
+   remote: Create a pull request for 'ARROW-14977' on GitHub by visiting:
+   remote:      https://github.com/AlenkaF/arrow/pull/new/ARROW-14977
+   remote: 
+   To https://github.com/AlenkaF/arrow.git
+    * [new branch]          ARROW-14977 -> ARROW-14977
+
+Now we have to go to the `Arrow repository on GitHub <https://github.com/apache/arrow>`_
+to create a Pull Request. On the GitHub Arrow
+page (main or forked) we will see a yellow notice
+bar with a note that we made recent pushes to the branch
+ARROW-14977. That’s great, now we can make the Pull Request
+by clicking on **Compare & pull request**. 
+
+.. figure:: python_tutorial_github_pr_notice.jpeg
+   :scale: 50 %
+   :alt: GitHub page of the Apache Arrow repository showing a notice bar
+         indicating change has been made in our branch and a Pull Request
+         can be created.
+
+   Notice bar on the Apache Arrow repository.
+
+First we need to change the Title to *ARROW-14977: [Python] Add a "made-up"*
+*feature for the guide tutorial* in order to match it
+with the JIRA issue. Note a punctuation mark was added!
+
+We will also add a description to make it clear to others what we are
+trying to do.
+
+Once I click **Create pull request** my code can be reviewed as a
+Pull Request in the Apache Arrow repository.
+
+.. figure:: python_tutorial_pr.jpeg
+   :scale: 50 %
+   :alt: GitHub page of the Pull Request showing the title and a
+         description.
+
+   Here it is, our Pull Request!
+
+The Pull Request gets connected to the JIRA issue and the CI is
+running. After some time passes and we get a review we can correct
+the code, comment, resolve conversations and so on. The Pull Request
+we made can be viewed `here <https://github.com/apache/arrow/pull/11900>`_.
+
+.. seealso::
+   
+   For more information about Pull Request workflow see :ref:`pr_and_github`.
+
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_github_find_in_file.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_github_find_in_file.jpeg
new file mode 100644
index 0000000..8253beb
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_github_find_in_file.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_github_pr_notice.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_github_pr_notice.jpeg
new file mode 100644
index 0000000..46de38f
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_github_pr_notice.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_github_search.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_github_search.jpeg
new file mode 100644
index 0000000..de0e3e8
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_github_search.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_jira_comment.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_jira_comment.jpeg
new file mode 100644
index 0000000..5460a2b
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_jira_comment.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_jira_description.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_jira_description.jpeg
new file mode 100644
index 0000000..46a3a73
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_jira_description.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_jira_issue.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_jira_issue.jpeg
new file mode 100644
index 0000000..918fcbd
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_jira_issue.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_jira_title.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_jira_title.jpeg
new file mode 100644
index 0000000..9da8950
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_jira_title.jpeg differ
diff --git a/docs/source/developers/guide/tutorials/python_tutorial_pr.jpeg b/docs/source/developers/guide/tutorials/python_tutorial_pr.jpeg
new file mode 100644
index 0000000..6be18d7
Binary files /dev/null and b/docs/source/developers/guide/tutorials/python_tutorial_pr.jpeg differ