luciole-toolbox 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ # One-time repo/account setup for the workflows
2
+
3
+ This step happens outside this repo and can't be scripted from here — do
4
+ it once before the `release.yml` workflow can succeed.
5
+
6
+ ## PyPI Trusted Publishing (needed for `release.yml`)
7
+
8
+ Trusted Publishing lets GitHub Actions publish to PyPI via OIDC, with no
9
+ API token stored as a repo secret.
10
+
11
+ 1. Create the `luciole-toolbox` project on PyPI if it doesn't exist yet
12
+ (first publish can also be done manually once to reserve the name —
13
+ trusted publishing can be configured before or after that).
14
+ 2. Go to <https://pypi.org/manage/project/luciole-toolbox/settings/publishing/>
15
+ (or, for a not-yet-existing project, <https://pypi.org/manage/account/publishing/>
16
+ to pre-register a "pending" publisher).
17
+ 3. Add a new trusted publisher with:
18
+ - **Owner**: `info-fauna`
19
+ - **Repository name**: `luciole-toolbox`
20
+ - **Workflow name**: `release.yml`
21
+ - **Environment name**: `pypi`
22
+ 4. In the GitHub repo, go to **Settings → Environments → New environment**,
23
+ name it `pypi` (must match exactly). Optionally add required reviewers
24
+ here if you want a manual approval gate before every publish.
25
+
26
+ No secrets to add — `id-token: write` permission in `release.yml` handles
27
+ the OIDC handshake.
28
+
29
+ ## Triggering a release
30
+
31
+ Once the trusted publisher above is configured:
32
+
33
+ ```bash
34
+ git tag v0.1.0
35
+ git push origin v0.1.0
36
+ ```
37
+
38
+ This triggers `release.yml`, which builds the package (version comes from
39
+ the tag via `hatch-vcs`), publishes to PyPI, and creates a GitHub Release
40
+ with auto-generated notes and the built artifacts attached.
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.12"
22
+ - run: pip install ".[dev]"
23
+ - run: ruff check .
24
+
25
+ test:
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ with:
34
+ fetch-depth: 0
35
+ - uses: actions/setup-python@v5
36
+ with:
37
+ python-version: ${{ matrix.python-version }}
38
+ - run: pip install ".[dev]"
39
+ - run: pytest -m "not integration"
@@ -0,0 +1,44 @@
1
+ name: Docs
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: docs-${{ github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ build:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ fetch-depth: 0
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.12"
28
+ - run: pip install ".[docs]"
29
+ - run: mkdocs build --strict
30
+ - uses: actions/upload-pages-artifact@v3
31
+ if: github.event_name == 'push'
32
+ with:
33
+ path: site
34
+
35
+ deploy:
36
+ if: github.event_name == 'push'
37
+ needs: build
38
+ runs-on: ubuntu-latest
39
+ environment:
40
+ name: github-pages
41
+ url: ${{ steps.deployment.outputs.page_url }}
42
+ steps:
43
+ - id: deployment
44
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,24 @@
1
+ name: Integration tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ schedule:
7
+ - cron: "0 4 * * 1" # weekly (Monday) - catch upstream drift in swisstopo API / pyproj CDN even without new commits
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ integration:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+ - run: pip install ".[dev]"
24
+ - run: pytest -m integration
@@ -0,0 +1,55 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ - run: pip install build twine
22
+ - run: python -m build
23
+ - run: twine check dist/*
24
+ - uses: actions/upload-artifact@v4
25
+ with:
26
+ name: dist
27
+ path: dist/
28
+
29
+ publish:
30
+ needs: build
31
+ runs-on: ubuntu-latest
32
+ environment: pypi
33
+ permissions:
34
+ id-token: write # trusted publishing (OIDC) - no PyPI token stored as a secret
35
+ steps:
36
+ - uses: actions/download-artifact@v4
37
+ with:
38
+ name: dist
39
+ path: dist/
40
+ - uses: pypa/gh-action-pypi-publish@release/v1
41
+
42
+ github-release:
43
+ needs: build
44
+ runs-on: ubuntu-latest
45
+ permissions:
46
+ contents: write
47
+ steps:
48
+ - uses: actions/download-artifact@v4
49
+ with:
50
+ name: dist
51
+ path: dist/
52
+ - uses: softprops/action-gh-release@v2
53
+ with:
54
+ generate_release_notes: true
55
+ files: dist/*
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .pytest_cache/
5
+ .venv/
6
+ venv/
7
+ build/
8
+ dist/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ misc/
12
+ src/luciole_toolbox/_version.py
13
+ site/
@@ -0,0 +1,7 @@
1
+ {
2
+ "python.testing.pytestArgs": [
3
+ "tests"
4
+ ],
5
+ "python.testing.unittestEnabled": false,
6
+ "python.testing.pytestEnabled": true
7
+ }
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - `geo` module: CRS detection (WGS84/LV03/LV95), coordinate conversion,
13
+ CKM2/CNHA grid codes, and commune/canton lookup via the swisstopo API.
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.5
2
+ Name: luciole-toolbox
3
+ Version: 0.1.0
4
+ Author-email: Kim Biloni <kim.biloni@infofauna.ch>
5
+ License-Expression: MIT
6
+ Classifier: Operating System :: OS Independent
7
+ Classifier: Programming Language :: Python :: 3
8
+ Requires-Python: >=3.9
9
+ Requires-Dist: pyproj>=3.6
10
+ Requires-Dist: requests>=2.31
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=7.0; extra == 'dev'
13
+ Requires-Dist: ruff>=0.6; extra == 'dev'
14
+ Provides-Extra: docs
15
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
16
+ Requires-Dist: mkdocs>=1.6; extra == 'docs'
17
+ Requires-Dist: mkdocstrings[python]>=0.26; extra == 'docs'
18
+ Description-Content-Type: text/markdown
19
+
20
+ # luciole-toolbox
21
+
22
+ [![CI](https://github.com/info-fauna/luciole-toolbox/actions/workflows/ci.yml/badge.svg)](https://github.com/info-fauna/luciole-toolbox/actions/workflows/ci.yml)
23
+ [![PyPI](https://img.shields.io/pypi/v/luciole-toolbox.svg)](https://pypi.org/project/luciole-toolbox/)
24
+
25
+ Python utility library. Currently ships a `geo` module for Swiss coordinates:
26
+ CRS detection (WGS84/LV03/LV95), conversion between them, CKM2/CNHA grid
27
+ codes, and commune/canton lookup via the swisstopo API.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install luciole-toolbox
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ```python
38
+ from luciole_toolbox.geo import convert_coordinates, get_location_info, CRSType
39
+
40
+ convert_coordinates("46.9480", "7.4474", target=CRSType.LV95)
41
+ get_location_info("46.9480", "7.4474")
42
+ ```
43
+
44
+ Full API reference: <https://info-fauna.github.io/luciole-toolbox/>
45
+
46
+ ## Development
47
+
48
+ ```bash
49
+ pip install -e ".[dev]"
50
+ ```
51
+
52
+ ### Testing
53
+
54
+ ```bash
55
+ pytest # all tests, incl. calls to swisstopo/pyproj CDN
56
+ pytest -m "not integration" # skip tests hitting real network endpoints
57
+ ```
58
+
59
+ ### Docs
60
+
61
+ ```bash
62
+ pip install -e ".[docs]"
63
+ mkdocs serve # preview locally at http://127.0.0.1:8000
64
+ ```
65
+
66
+ ## Versioning & releases
67
+
68
+ The version is derived from git tags via `hatch-vcs` — there is no version
69
+ string to hand-edit. Notable changes are tracked in
70
+ [CHANGELOG.md](CHANGELOG.md). To cut a release, push a tag:
71
+
72
+ ```bash
73
+ git tag v0.1.0
74
+ git push origin v0.1.0
75
+ ```
76
+
77
+ This triggers the `release` workflow, which builds the package, publishes
78
+ it to PyPI, and creates a matching GitHub Release.
@@ -0,0 +1,59 @@
1
+ # luciole-toolbox
2
+
3
+ [![CI](https://github.com/info-fauna/luciole-toolbox/actions/workflows/ci.yml/badge.svg)](https://github.com/info-fauna/luciole-toolbox/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/luciole-toolbox.svg)](https://pypi.org/project/luciole-toolbox/)
5
+
6
+ Python utility library. Currently ships a `geo` module for Swiss coordinates:
7
+ CRS detection (WGS84/LV03/LV95), conversion between them, CKM2/CNHA grid
8
+ codes, and commune/canton lookup via the swisstopo API.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install luciole-toolbox
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```python
19
+ from luciole_toolbox.geo import convert_coordinates, get_location_info, CRSType
20
+
21
+ convert_coordinates("46.9480", "7.4474", target=CRSType.LV95)
22
+ get_location_info("46.9480", "7.4474")
23
+ ```
24
+
25
+ Full API reference: <https://info-fauna.github.io/luciole-toolbox/>
26
+
27
+ ## Development
28
+
29
+ ```bash
30
+ pip install -e ".[dev]"
31
+ ```
32
+
33
+ ### Testing
34
+
35
+ ```bash
36
+ pytest # all tests, incl. calls to swisstopo/pyproj CDN
37
+ pytest -m "not integration" # skip tests hitting real network endpoints
38
+ ```
39
+
40
+ ### Docs
41
+
42
+ ```bash
43
+ pip install -e ".[docs]"
44
+ mkdocs serve # preview locally at http://127.0.0.1:8000
45
+ ```
46
+
47
+ ## Versioning & releases
48
+
49
+ The version is derived from git tags via `hatch-vcs` — there is no version
50
+ string to hand-edit. Notable changes are tracked in
51
+ [CHANGELOG.md](CHANGELOG.md). To cut a release, push a tag:
52
+
53
+ ```bash
54
+ git tag v0.1.0
55
+ git push origin v0.1.0
56
+ ```
57
+
58
+ This triggers the `release` workflow, which builds the package, publishes
59
+ it to PyPI, and creates a matching GitHub Release.
@@ -0,0 +1,22 @@
1
+ # Luciole Toolbox
2
+
3
+ Python utility library. Currently ships a `geo` module for Swiss coordinates:
4
+ CRS detection (WGS84/LV03/LV95), conversion between them, CKM2/CNHA grid
5
+ codes, and commune/canton lookup via the swisstopo API.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install luciole-toolbox
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```python
16
+ from luciole_toolbox.geo import convert_coordinates, get_location_info, CRSType
17
+
18
+ convert_coordinates("46.9480", "7.4474", target=CRSType.LV95)
19
+ get_location_info("46.9480", "7.4474")
20
+ ```
21
+
22
+ See the [API Reference](reference.md) for full details.
@@ -0,0 +1,3 @@
1
+ # API Reference
2
+
3
+ ::: luciole_toolbox.geo
@@ -0,0 +1,29 @@
1
+ site_name: Luciole Toolbox
2
+ site_description: Python utility library for Swiss geodata handling.
3
+ repo_url: https://github.com/info-fauna/luciole-toolbox
4
+ repo_name: info-fauna/luciole-toolbox
5
+
6
+ theme:
7
+ name: material
8
+ palette:
9
+ - scheme: default
10
+ toggle:
11
+ icon: material/brightness-7
12
+ name: Switch to dark mode
13
+ - scheme: slate
14
+ toggle:
15
+ icon: material/brightness-4
16
+ name: Switch to light mode
17
+
18
+ nav:
19
+ - Home: index.md
20
+ - API Reference: reference.md
21
+
22
+ plugins:
23
+ - search
24
+ - mkdocstrings:
25
+ handlers:
26
+ python:
27
+ options:
28
+ show_source: false
29
+ show_root_heading: true
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["hatchling", "hatch-vcs"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "luciole-toolbox"
7
+ dynamic = ["version"]
8
+ description = ""
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Kim Biloni", email = "kim.biloni@infofauna.ch" },
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ "pyproj>=3.6",
21
+ "requests>=2.31",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "pytest>=7.0",
27
+ "ruff>=0.6",
28
+ ]
29
+ docs = [
30
+ "mkdocs>=1.6",
31
+ "mkdocs-material>=9.5",
32
+ "mkdocstrings[python]>=0.26",
33
+ ]
34
+
35
+ [tool.hatch.version]
36
+ source = "vcs"
37
+
38
+ [tool.hatch.build.hooks.vcs]
39
+ version-file = "src/luciole_toolbox/_version.py"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/luciole_toolbox"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
46
+ markers = [
47
+ "integration: hits a real network endpoint (swisstopo API, pyproj CDN grid shift files) - excluded via -m 'not integration'",
48
+ ]
49
+
50
+ [tool.ruff]
51
+ line-length = 100
52
+ target-version = "py39"
53
+
54
+ [tool.ruff.lint]
55
+ select = ["E", "F", "I", "UP"]
@@ -0,0 +1,3 @@
1
+ from luciole_toolbox._version import __version__
2
+
3
+ __all__ = ["__version__"]
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.0'
22
+ __version_tuple__ = version_tuple = (0, 1, 0)
23
+
24
+ __commit_id__ = commit_id = None