Skip to content

Commit

Permalink
Merge pull request #57 from AVATEAM-IT-SYSTEMHAUS/55-improve-dev-cycle
Browse files Browse the repository at this point in the history
Improve dev cycle
  • Loading branch information
oniboni authored May 16, 2024
2 parents ea93ba8 + 43a43f4 commit 1406e66
Show file tree
Hide file tree
Showing 27 changed files with 653 additions and 196 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:
branches:
- "*"

env:
FORCE_COLOR: "1"

jobs:
lint:

Expand All @@ -23,6 +26,8 @@ jobs:
with:
python-version: '3.x'
- name: Install dependencies
run: make dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade hatch
- name: Lint
run: make lint
run: hatch fmt --check
26 changes: 16 additions & 10 deletions .github/workflows/python-publish-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This workflow will upload a Python Package using Twine when a release is created
# This workflow will upload a Python Package using Hatch when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package to Test-Pypi
Expand All @@ -7,6 +7,9 @@ on:
workflow_dispatch:
push:

env:
FORCE_COLOR: "1"

jobs:
deploy-test:

Expand All @@ -21,13 +24,16 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build
pip install --upgrade hatch
- name: Bump temp dev release
run: |
sed -i "/^ version=/ s/[0-9]\.[0-9]\.[0-9]/&-$(date +%s)/" setup.py
python setup.py sdist bdist_wheel
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
CURRENT_VERSION=$(NO_COLOR="1" hatch version)
TIMESTAMP=$(date +%s)
hatch version "$CURRENT_VERSION-$TIMESTAMP"
- name: Build package
run: hatch build
- name: Publish package
env:
HATCH_INDEX_USER: __token__
HATCH_INDEX_AUTH: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: hatch publish --repo test
21 changes: 12 additions & 9 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This workflow will upload a Python Package using Twine when a release is created
# This workflow will upload a Python Package using Hatch when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package
Expand All @@ -9,6 +9,9 @@ on:
tags:
- v[0-9].[0-9].[0-9]

env:
FORCE_COLOR: "1"

jobs:
deploy-test:

Expand All @@ -23,11 +26,11 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build
run: |
python setup.py sdist bdist_wheel
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
pip install --upgrade hatch
- name: Build package
run: hatch build
- name: Publish package
env:
HATCH_INDEX_USER: __token__
HATCH_INDEX_AUTH: ${{ secrets.PYPI_API_TOKEN }}
run: hatch publish
37 changes: 37 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Project test

on:
workflow_dispatch:
push:
branches:
- main
tags:
- "*"

pull_request:
branches:
- "*"

env:
FORCE_COLOR: "1"

jobs:
test:

runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade hatch
- name: Test coverage
run: hatch test --cover
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,10 @@ MANIFEST
.venv
.vscode
test-docs


# pytest
junit/
.coverage
coverage.xml
htmlcov
31 changes: 31 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: detect-private-key
- repo: local
hooks:
- id: lint
name: run the linter
entry: hatch fmt -l
language: system
pass_filenames: false
types: [ python ]
- id: format
name: run the formatter
entry: hatch fmt -f
language: system
pass_filenames: false
types: [ python ]
- id: test
name: run tests
entry: hatch test -a
language: system
pass_filenames: false
types: [ python ]
3 changes: 2 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Copyright (c) 2018 Benjamin Bittner
Copyright (c) 2024 Antonia Siegert

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -16,4 +17,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
10 changes: 0 additions & 10 deletions Makefile

This file was deleted.

25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,28 @@ More Plugins for MkDocs can be found [here](http://www.mkdocs.org/user-guide/plu
Install the newest pre-release version using pip:

`pip install -i https://test.pypi.org/simple/ mkdocs-kroki-plugin`


## Development

Setup:

```sh
git clone git@github.com:AVATEAM-IT-SYSTEMHAUS/mkdocs-kroki-plugin.git
cd mkdocs-kroki-plugin
pipx install hatch
pipx install pre-commit
pre-commit install
```

Run tests (for all supported python versions):

```sh
hatch test -a
```

Run static code analysis:

```sh
hatch fmt
```
1 change: 1 addition & 0 deletions kroki/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = "0.7.1"
100 changes: 47 additions & 53 deletions kroki/client.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import base64
import requests
import zlib

from dataclasses import dataclass
from logging import DEBUG
from typing import Final

import requests
from mkdocs.exceptions import PluginError
from mkdocs.plugins import get_plugin_logger
from mkdocs.structure.files import Files as MkDocsFiles
from mkdocs.structure.pages import Page as MkDocsPage
from typing import Optional

from kroki.config import KrokiDiagramTypes
from kroki.util import DownloadedImage

log = get_plugin_logger(__name__)


MAX_URI_SIZE: Final[int] = 4096


@dataclass
class KrokiResponse:
err_msg: Optional[str] = None
image_url: Optional[str] = None
err_msg: None | str = None
image_url: None | str = None

def is_ok(self) -> bool:
return self.image_url is not None and self.err_msg is None
Expand All @@ -41,7 +44,7 @@ def __init__(
self.diagram_types = diagram_types
self.fail_fast = fail_fast

log.debug(f"Client initialized: {self.http_method}, {self.server_url}")
log.debug("Client initialized", extra={"http_method": self.http_method, "server_url": self.server_url})

def _kroki_url_base(self, kroki_type: str) -> str:
file_type = self.diagram_types.get_file_ext(kroki_type)
Expand All @@ -53,26 +56,19 @@ def _kroki_url_get(
kroki_diagram_data: str,
kroki_diagram_options: dict[str, str],
) -> KrokiResponse:
kroki_data_param = base64.urlsafe_b64encode(
zlib.compress(str.encode(kroki_diagram_data), 9)
).decode()
kroki_data_param = base64.urlsafe_b64encode(zlib.compress(str.encode(kroki_diagram_data), 9)).decode()

kroki_query_param = (
"&".join([f"{k}={v}" for k, v in kroki_diagram_options.items()])
if len(kroki_diagram_options) > 0
else ""
"&".join([f"{k}={v}" for k, v in kroki_diagram_options.items()]) if len(kroki_diagram_options) > 0 else ""
)
if len(kroki_data_param) >= 4096:
log.warning(
f"Length of encoded diagram is {len(kroki_data_param)}. "
"Kroki may not be able to read the data completely!"
)

kroki_url = self._kroki_url_base(kroki_type)
log.debug(f"{kroki_url}/{kroki_data_param}?{kroki_query_param}")
return KrokiResponse(
image_url=f"{kroki_url}/{kroki_data_param}?{kroki_query_param}"
)
image_url = f"{kroki_url}/{kroki_data_param}?{kroki_query_param}"
if len(image_url) >= MAX_URI_SIZE:
log.warning("Kroki may not be able to read the data completely!", extra={"data_len": len(image_url)})

log.debug("Image url: %s", image_url)
return KrokiResponse(image_url=image_url)

def _kroki_post(
self,
Expand All @@ -82,44 +78,46 @@ def _kroki_post(
files: MkDocsFiles,
page: MkDocsPage,
) -> KrokiResponse:
try:
url = self._kroki_url_base(kroki_type)
url = self._kroki_url_base(kroki_type)

log.debug(f"_kroki_post [POST {url}]")
log.debug("POST %s", url)
try:
response = requests.post(
url,
headers=self.headers,
json={
"diagram_source": kroki_diagram_data,
"diagram_options": kroki_diagram_options,
},
timeout=10,
)

if response.status_code == requests.codes.ok:
downloaded_image = DownloadedImage(
response.content,
self.diagram_types.get_file_ext(kroki_type),
kroki_diagram_options,
)
downloaded_image.save(files, page)
return KrokiResponse(image_url=downloaded_image.file_name)

elif response.status_code == 400:
return KrokiResponse(err_msg="Diagram error!")
else:
error_message = f"Could not retrieve image data, got: {response}"
if self.fail_fast:
raise PluginError(error_message)
else:
log.error(error_message)

except requests.RequestException as error:
error_message = f"Request error [url:{url}]: {error}"
log.exception(error_message, stack_info=log.isEnabledFor(DEBUG))
if self.fail_fast:
raise PluginError(f"Request error [url:{url}]: {error}") from error
else:
log.error(error, stack_info=log.isEnabledFor(DEBUG))
raise PluginError(error_message) from error

return KrokiResponse(err_msg=error_message)

if response.status_code == requests.codes.ok:
downloaded_image = DownloadedImage(
response.content,
self.diagram_types.get_file_ext(kroki_type),
kroki_diagram_options,
)
downloaded_image.save(files, page)
return KrokiResponse(image_url=downloaded_image.file_name)

error_message = (
"Diagram error!"
if response.status_code == requests.codes.bad_request
else f"Could not retrieve image data, got: {response}"
)
log.error(error_message)
if self.fail_fast:
raise PluginError(error_message)

return KrokiResponse(err_msg="Could not render!")
return KrokiResponse(err_msg=error_message)

def get_image_url(
self,
Expand All @@ -130,10 +128,6 @@ def get_image_url(
page: MkDocsPage,
) -> KrokiResponse:
if self.http_method == "GET":
return self._kroki_url_get(
kroki_type, kroki_diagram_data, kroki_diagram_options
)
return self._kroki_url_get(kroki_type, kroki_diagram_data, kroki_diagram_options)

return self._kroki_post(
kroki_type, kroki_diagram_data, kroki_diagram_options, files, page
)
return self._kroki_post(kroki_type, kroki_diagram_data, kroki_diagram_options, files, page)
Loading

0 comments on commit 1406e66

Please sign in to comment.