Skip to content

Conversation

mfkaptan-motius
Copy link
Collaborator

  • Add dynamic unit synchronization from QUDT repository with GraphQL enum generation.
  • Includes custom @reference directive for semantic linking.
  • BREAKING CHANGE: Replace static YAML-based units with dynamic QUDT synchronization.
  • Updates CLI commands and removes legacy unit definitions.

Resolves #43 #62

@mfkaptan-motius mfkaptan-motius force-pushed the feat/qudt-units-43 branch 3 times, most recently from e4cfb23 to d242912 Compare September 4, 2025 11:35
@mfkaptan-motius mfkaptan-motius changed the base branch from main to develop September 12, 2025 08:39
- Add dynamic unit synchronization from QUDT repository
 with GraphQL enum generation
- Includes custom @reference directive for semantic linking.
- Cleans up stale data during new sync

Signed-off-by: Mustafa Kaptan <[email protected]>
Updates CLI commands and removes legacy unit definitions.

BREAKING CHANGE: Replace static YAML-based units
with dynamic QUDT synchronization.

Signed-off-by: Mustafa Kaptan <[email protected]>
- Add unit tests
- Add E2E CLI tests
- Add fixtures for units sync functionality.
- Includes mocking for external QUDT API calls.

Signed-off-by: Mustafa Kaptan <[email protected]>
Remove reading from unit_enums.graphql while composing schema

BREAKING CHANGE: unit_enums.graphql is no longer read while composing schema,
tests and schema loading is broken with this commit

Signed-off-by: Mustafa Kaptan <[email protected]>
- Add README covering QUDT integration, CLI usage,
technical implementation, and workflow examples.
- Check in some of the generated units under examples
- Rename existing enums to QUDT ones in examples and test data
- Add documentation to the docs-gen

Signed-off-by: Mustafa Kaptan <[email protected]>
from s2dm.tools.validators import validate_language_tag
from s2dm.units.sync import UNITS_META_FILENAME, UNITS_META_VERSION_KEY, check_latest_qudt_version, sync_qudt_units

S2DM_HOME = Path.home() / ".s2dm"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the idea behind that default location?

The export commands would then also be aware of that location, right?

)
@click.option(
"--output-dir",
"output_dir",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

@units.command(name="sync")
@click.option(
"--version",
"version_",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why with _ suffix?


import json
import re
import urllib.request
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vote for requests. Much easer to use imo

)

QUDT_UNITS_TTL_URL_MAIN: str = (
"https://raw.githubusercontent.com/qudt/qudt-public-repo/main/src/main/rdf/vocab/unit/VOCAB_QUDT-UNITS-ALL.ttl"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicated string with URL template. I would try to store the github URL only once

"""
with urllib.request.urlopen(QUDT_GITHUB_API_URL) as resp: # nosec - public metadata
data = json.loads(resp.read().decode("utf-8"))
# Tags are objects with 'name', e.g., 'v3.1.4'. Pick the first entry.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that assumption is correct that the first entry will always hold the latest tag, I might be wrong though

grouped[row.quantity_kind_label].append(row)

written: list[Path] = []
effective_version = version or "main"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the "main" literal is used too often (3 times). Maybe use it as a default value for the cli --version?


try:
version_to_use = version_ or check_latest_qudt_version()
except Exception as e: # pragma: no cover - generic guard for CLI UX
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too broad, it should be quite clear what the urllib.request() can throw

else:
console.print(f"[green]✓[/green] Generated {len(written)} enum files under {output_dir}")
console.print(f"Version: {version_to_use}")
except Exception as e: # pragma: no cover - generic guard for CLI UX
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you noticed, but I am not a fan of generic Exception try catches just to render a message but hiding the stacktrace in return

try:
written = sync_qudt_units(output_dir, version_to_use, dry_run=dry_run)
if dry_run:
console.print(f"[blue]ℹ[/blue] Would generate {len(written)} enum files under {output_dir}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we do that format regularily also with warnings and errors: We should write a function to print a nice info, warning and error instead of copy pasting it everywhere

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

♻️ Reuse standard units from an established vocabulary
2 participants