Skip to content
Snippets Groups Projects
Commit 2b32aaef authored by Mayr, Hannes's avatar Mayr, Hannes
Browse files

Merge branch 'dev' into 'improve-list-validation'

# Conflicts:
#   plotid/publish.py
parents e5a4d5bd df7f25c2
No related branches found
No related tags found
1 merge request!29Move list validation to own function
Pipeline #824261 waiting for manual action
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml
# Official language image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/python/tags/
image: python:latest image: python:latest
stages: stages:
- linting - linting
- testing - testing
- security
- docs - docs
# Change pip's cache directory to be inside the project directory since we can # Change pip's cache directory to be inside the project directory since we can
...@@ -18,49 +10,27 @@ stages: ...@@ -18,49 +10,27 @@ stages:
variables: variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
# Pip's cache doesn't store the python packages
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
#
# If you want to also cache the installed packages, you have to install
# them in a virtualenv and cache it as well.
cache:
paths:
# - .cache/pip #
# - venv/ #
before_script: before_script:
- python --version # For debugging - python --version # For debugging
- pip install -r requirements.txt # install dependencies from file - pip install --upgrade pip
# - pip install virtualenv - pip install --user -r requirements.txt # install dependencies from file
# - virtualenv venv
# - source venv/bin/activate
PEP8: PEP8:
stage: linting stage: linting
script: script:
- pip install flake8 - pip install flake8
- flake8 --count . # PEP8 linting - flake8 --count .
Pylint: Pylint:
stage: linting stage: linting
# allow_failure: true
script: script:
- pip install pylint - pip install pylint
- find . -type f -name '*.py' | xargs pylint -rn --rcfile='plotid/.pylintrc' # Find all python files and check the code with pylint. - find . -type f -name '*.py' | xargs pylint -rn --rcfile='plotid/.pylintrc' # Find all python files and check the code with pylint
test: test:
stage: testing stage: testing
tags: tags:
- docker - docker
script: script:
# - python -m unittest discover -s ./tests/ -p "test*" # deprecated unittest command
- python tests/runner_tests.py - python tests/runner_tests.py
coverage: '/TOTAL.*\s+(\d+\.\d+%)$/' coverage: "/TOTAL.*\\s+(\\d+\\.\\d+%)$/"
# - pip install tox flake8 # you can also use tox
# - tox -e py36,flake8
pages: pages:
stage: docs stage: docs
script: script:
...@@ -72,17 +42,27 @@ pages: ...@@ -72,17 +42,27 @@ pages:
paths: paths:
- public - public
rules: rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH - if: "$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH"
- when: manual - when: manual
sast:
variables:
SAST_EXCLUDED_PATHS: spec, test, tmp
stage: security
tags:
- docker
dependency_scanning:
stage: security
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
# Commenting out all other stages and jobs
#run:
# script:
# - python setup.py bdist_wheel
# # an alternative approach is to install and run:
# - pip install dist/*
# # run the command here
# artifacts:
# paths:
# - dist/*.whl
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
## Implement a new plot engine # Contributing
If you want to add another plot engine "$engine" to plotID, this document helps you to do it. Feel free to **report** all **issues** you encounter with plotID in our [issue tracker](https://git.rwth-aachen.de/plotid/plotid_python/-/issues). This will greatly help to improve plotID.
Contributing to plotID via **merge requests** is also highly appreciated. Please make sure that your code complies with the [PEP 8 - Style Guide](https://peps.python.org/pep-0008/) before creating a merge request. We try to have the whole code of plotID covered by unittests. So if you contribute new code to plotid please also provide unittests that cover the new functionality. Should you be interested in adding another plot engine to be supported by plotID, have a look at the section [Implement a new plot engine](#add-plot-engine). There are some hints how to proceed in this case.
## Setup development environment
Clone the repository and install the dependencies:
```bash
git clone https://git.rwth-aachen.de/plotid/plotid_python.git
cd plotid_python
pip install -r requirements.txt
```
Optionally, create a virtual environment as recommended in the [README.md](https://git.rwth-aachen.de/plotid/plotid_python/-/blob/main/README.md).
You can run all the unittests locally by calling the *tests/runner_tests.py* script. For linting we recommend using *flake8* and *pylint*.
The documentation is automatically built from docstrings in the code. So always document your code properly. The documentation can be built locally and can be found afterwards in *docs/build*:
```bash
cd docs
make html
```
## Implement a new plot engine {#add-plot-engine}
If you want to add another plot engine "$engine" to plotID, this section helps you to do it. For comparison have a look at already supported engines, e.g. in tagplot_matplotlib.py or tagplot_image.py.
### tagplot ### tagplot
Create a new module named "tagplot_$engine.py". Paste the following code and replace every "$engine" with the name of your engine: Create a new module named "tagplot_$engine.py". Paste the following code and replace every "$engine" with the name of your engine:
...@@ -8,11 +27,11 @@ Create a new module named "tagplot_$engine.py". Paste the following code and rep ...@@ -8,11 +27,11 @@ Create a new module named "tagplot_$engine.py". Paste the following code and rep
Tag your picture with an ID. Tag your picture with an ID.
Functions: Functions:
tagplot_$engine(PlotOptions instance) -> list tagplot_$engine(PlotOptions instance) -> PlotIDTransfer instance
""" """
import $engine import $engine
from plotid.create_id import create_id from plotid.create_id import create_id
from plotid.plotoptions import PlotOptions from plotid.plotoptions import PlotOptions, PlotIDTransfer
def tagplot_$engine(plotid_object): def tagplot_$engine(plotid_object):
...@@ -21,32 +40,44 @@ def tagplot_$engine(plotid_object): ...@@ -21,32 +40,44 @@ def tagplot_$engine(plotid_object):
The ID is placed visual on the figure window and returned as string in a The ID is placed visual on the figure window and returned as string in a
list together with the figures. list together with the figures.
TagPlot can tag multiple figures at once.
Parameters
----------
plotid_object : instance of PlotOptions
Returns
-------
PlotIDTransfer object
""" """
# Check if plotid_object is a valid instance of PlotOptions # Check if plotid_object is a valid instance of PlotOptions
if not isinstance(plotid_object, PlotOptions): if not isinstance(plotid_object, PlotOptions):
raise TypeError('The given options container is not an instance' raise TypeError('The given options container is not an instance'
'of PlotOptions.') 'of PlotOptions.')
ids_as_list = [] # Check if figs is a list of valid figures
for figure in plotid_object.figs:
if not isinstance(figure, $engine_figure_class):
raise TypeError('Figure is not a valid $engine-figure.')
# Loop to create and position the IDs
for fig in plotid_object.figs: for fig in plotid_object.figs:
figure_id = create_id(plotid_object.id_method) fig_id = create_id(plotid_object.id_method)
ids_as_list.append(figure_id) fig_id = plotid_object.prefix + fig_id
plotid_object.figure_ids.append(fig_id)
""" """
Insert here the tagging with $engine: Insert here the tagging with $engine:
Open the figure fig. Open the figure fig.
Place the string figure_id on it. Place the string figure_id on it.
Use plotid_object.position and plotid_object.rotation for position and rotation. Use plotid_object.position and plotid_object.rotation for position and rotation of the ID.
Save the tagged figure to plotid_object.figs. Save the tagged figure to plotid_object.figs.
""" """
figs_and_ids = PlotIDTransfer(plotid_object.figs, plotid_object.figure_ids)
return [plotid_object.figs, ids_as_list] return figs_and_ids
```
Last step: Last step:
Add the following code in tagplot.py: Add the following code in tagplot.py:
```python
match engine: match engine:
[...] [...]
case '$engine': case '$engine':
...@@ -60,7 +91,7 @@ To include a new plot engine in the publish function only save_plot.py has to be ...@@ -60,7 +91,7 @@ To include a new plot engine in the publish function only save_plot.py has to be
Import the plot engine at the top of the file. Import the plot engine at the top of the file.
In the beginning of the function save_plot() create the following line: In the beginning of the function save_plot() create the following line:
```python ```python
if isinstance(figures, $type_of_figure): if isinstance(figures, $engine_figure_class):
figures = [figures] figures = [figures]
[...] [...]
if not isinstance(figures, list): if not isinstance(figures, list):
...@@ -77,3 +108,5 @@ for i, fig in enumerate(figures): ...@@ -77,3 +108,5 @@ for i, fig in enumerate(figures):
plot_path.append(plot_names[i] + '.' + extension) plot_path.append(plot_names[i] + '.' + extension)
# Save the figure fig to plot_path[i] # Save the figure fig to plot_path[i]
``` ```
Additionally, please add some unittests for your code inside the *tests* directory.
In the end, you can also include a simple example in the *examples* directory how the newly plot engine can be used with plotID.
\ No newline at end of file
...@@ -8,7 +8,7 @@ plotID is a program connected to Research Data Management (RDM). It has two main ...@@ -8,7 +8,7 @@ plotID is a program connected to Research Data Management (RDM). It has two main
**Note:** To run plotID python version ≥ 3.10 is required. **Note:** To run plotID python version ≥ 3.10 is required.
## Installation ## Installation
Currently there are two options to run plotID. Either install it via pip from the Python Package Index (PyPi) or install plotID from the source code. Currently there are two options to run plotID. Either install it via pip from the Python Package Index (PyPi) or install plotID from the source code. Apart from setting up an optional virtual environment, installation is the same for Windows and Unix systems.
1. [Optional] Create a virtual environment and activate it: 1. [Optional] Create a virtual environment and activate it:
```bash ```bash
...@@ -99,6 +99,9 @@ If you want to build plotID yourself, follow these steps: ...@@ -99,6 +99,9 @@ If you want to build plotID yourself, follow these steps:
4. Build the package 4. Build the package
`python3 -m build` `python3 -m build`
## Contributing
Contributions to plotID are very welcome. If you encounter any issues with plotID please report them in our [issue tracker](https://git.rwth-aachen.de/plotid/plotid_python/-/issues). Code contributions via merge request are also highly appreciated. Please have a look at [CONTRIBUTING](https://git.rwth-aachen.de/plotid/plotid_python/-/blob/main/CONTRIBUTING.md) first.
## Documentation ## Documentation
If you have more questions about plotID, please have a look at the [documentation](https://plotid.pages.rwth-aachen.de/plotid_python). If you have more questions about plotID, please have a look at the [documentation](https://plotid.pages.rwth-aachen.de/plotid_python).
......
This diff is collapsed.
docs/source/_static/publish.png

98.3 KiB

This diff is collapsed.
docs/source/_static/tagplot.png

79.5 KiB

.. PlotID documentation master file, created by .. plotID documentation master file, created by
sphinx-quickstart on Tue Jun 21 14:09:27 2022. sphinx-quickstart on Tue Jun 21 14:09:27 2022.
You can adapt this file completely to your liking, but it should at least You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. contain the root `toctree` directive.
Welcome to PlotID's documentation! Welcome to plotID's documentation!
================================== ==================================
.. toctree:: .. toctree::
...@@ -11,6 +11,7 @@ Welcome to PlotID's documentation! ...@@ -11,6 +11,7 @@ Welcome to PlotID's documentation!
:caption: Contents: :caption: Contents:
README <readme_link.rst> README <readme_link.rst>
Structure and architecture <structure.rst>
Indices and tables Indices and tables
......
Structure and architecture of plotID
==================================
A visualization of the internal structure of plotID is provided here. The structure tries to follow Object Oriented Programming (OOP) principles. First tagplot() is depicted with matplotlib as example plot engine:
|structure tagplot|
In the following is shown how a call to publish is processed by plotID:
|structure publish|
.. |structure tagplot| image:: _static/tagplot.png
:width: 700
:alt: Graph to show the architecture of the function tagplot().
.. |structure publish| image:: _static/publish.png
:width: 700
:alt: Graph to show the architecture of the function publish().
...@@ -92,7 +92,6 @@ class PlotIDTransfer: ...@@ -92,7 +92,6 @@ class PlotIDTransfer:
Methods Methods
------- -------
__init__ __init__
validate_input : Check if input is correct type.
Attributes Attributes
---------- ----------
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Tag your picture with an ID. Tag your picture with an ID.
Functions: Functions:
tagplot_image(PlotOptions instance) -> list tagplot_image(PlotOptions instance) -> PlotIDTransfer instance
""" """
import os import os
from PIL import Image, ImageDraw, ImageFont, ImageOps from PIL import Image, ImageDraw, ImageFont, ImageOps
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Tag your matplotlib plot with an ID. Tag your matplotlib plot with an ID.
Functions: Functions:
tagplot_matplotlib(PlotOptions instance) -> list tagplot_matplotlib(PlotOptions instance) -> PlotIDTransfer instance
""" """
import matplotlib import matplotlib
......
...@@ -3,6 +3,7 @@ cycler==0.11.0 ...@@ -3,6 +3,7 @@ cycler==0.11.0
fonttools==4.32.0 fonttools==4.32.0
kiwisolver==1.4.2 kiwisolver==1.4.2
matplotlib==3.5.2 matplotlib==3.5.2
myst-parser==0.18.0
numpy==1.22.3 numpy==1.22.3
packaging==21.3 packaging==21.3
Pillow==9.1.0 Pillow==9.1.0
...@@ -10,3 +11,6 @@ pyparsing==3.0.8 ...@@ -10,3 +11,6 @@ pyparsing==3.0.8
python-dateutil==2.8.2 python-dateutil==2.8.2
qrcode==7.3.1 qrcode==7.3.1
six==1.16.0 six==1.16.0
Sphinx==5.0.2
sphinx-autoapi==1.8.4
sphinx-rtd-theme==1.0.0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment