cmem-cmemc 25.2.0__tar.gz → 25.4.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.
Files changed (59) hide show
  1. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/PKG-INFO +2 -2
  2. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/query.py +51 -16
  3. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/store.py +6 -2
  4. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/workflow.py +9 -0
  5. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/completion.py +30 -34
  6. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/context.py +2 -2
  7. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/manual_helper/multi_page.py +2 -0
  8. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/pyproject.toml +3 -3
  9. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/LICENSE +0 -0
  10. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/README-public.md +0 -0
  11. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/__init__.py +0 -0
  12. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/_cmemc.zsh +0 -0
  13. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/cli.py +0 -0
  14. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/command.py +0 -0
  15. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/command_group.py +0 -0
  16. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/__init__.py +0 -0
  17. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/acl.py +0 -0
  18. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/admin.py +0 -0
  19. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/client.py +0 -0
  20. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/config.py +0 -0
  21. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/dataset.py +0 -0
  22. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/graph.py +0 -0
  23. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/graph_imports.py +0 -0
  24. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/manual.py +0 -0
  25. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/metrics.py +0 -0
  26. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/migration.py +0 -0
  27. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/project.py +0 -0
  28. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/python.py +0 -0
  29. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/resource.py +0 -0
  30. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/scheduler.py +0 -0
  31. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/user.py +0 -0
  32. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/validation.py +0 -0
  33. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/variable.py +0 -0
  34. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/vocabulary.py +0 -0
  35. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/commands/workspace.py +0 -0
  36. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/config_parser.py +0 -0
  37. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/constants.py +0 -0
  38. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/exceptions.py +0 -0
  39. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/manual_helper/__init__.py +0 -0
  40. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/manual_helper/graph.py +0 -0
  41. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/manual_helper/single_page.py +0 -0
  42. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/__init__.py +0 -0
  43. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/abc.py +0 -0
  44. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/access_conditions_243.py +0 -0
  45. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/bootstrap_data.py +0 -0
  46. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/remove_noop_triple_251.py +0 -0
  47. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/shapes_widget_integrations_243.py +0 -0
  48. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/sparql_query_texts_242.py +0 -0
  49. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/migrations/workspace_configurations.py +0 -0
  50. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/object_list.py +0 -0
  51. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/parameter_types/__init__.py +0 -0
  52. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/parameter_types/path.py +0 -0
  53. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/placeholder.py +0 -0
  54. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/smart_path/__init__.py +0 -0
  55. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/smart_path/clients/__init__.py +0 -0
  56. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/smart_path/clients/http.py +0 -0
  57. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/string_processor.py +0 -0
  58. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/title_helper.py +0 -0
  59. {cmem_cmemc-25.2.0 → cmem_cmemc-25.4.0}/cmem_cmemc/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: cmem-cmemc
3
- Version: 25.2.0
3
+ Version: 25.4.0
4
4
  Summary: Command line client for eccenca Corporate Memory
5
5
  License: Apache-2.0
6
6
  Author: eccenca
@@ -30,7 +30,7 @@ Requires-Dist: certifi (>=2024.2.2)
30
30
  Requires-Dist: click (>=8.1.8,<8.2.0)
31
31
  Requires-Dist: click-didyoumean (>=0.3.1,<0.4.0)
32
32
  Requires-Dist: click-help-colors (>=0.9.4,<0.10.0)
33
- Requires-Dist: cmem-cmempy (==25.1.0)
33
+ Requires-Dist: cmem-cmempy (==25.3.0)
34
34
  Requires-Dist: configparser (>=7.2.0,<8.0.0)
35
35
  Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
36
36
  Requires-Dist: junit-xml (>=1.9,<2.0)
@@ -10,8 +10,8 @@ from time import sleep, time
10
10
  from uuid import uuid4
11
11
 
12
12
  import click
13
- from click import ClickException, UsageError
14
13
  from click.shell_completion import CompletionItem
14
+ from cmem.cmempy.config import get_cmem_base_uri
15
15
  from cmem.cmempy.queries import (
16
16
  QueryCatalog,
17
17
  SparqlQuery,
@@ -91,12 +91,12 @@ class ReplayStatistics:
91
91
  iri = query_["iri"]
92
92
  catalog_entry = self.catalog.get_query(iri)
93
93
  if catalog_entry is None:
94
- raise ClickException(f"measure_query - query {iri} is not in catalog.")
94
+ raise click.ClickException(f"measure_query - query {iri} is not in catalog.")
95
95
  return catalog_entry
96
96
  query_string = query_["queryString"]
97
97
  return SparqlQuery(text=query_string)
98
98
  except KeyError as error:
99
- raise ClickException(
99
+ raise click.ClickException(
100
100
  "measure_query - given input dict has no queryString key."
101
101
  ) from error
102
102
 
@@ -330,6 +330,13 @@ def _output_query_status_details(app: ApplicationContext, status_dict: dict) ->
330
330
 
331
331
 
332
332
  @click.command(cls=CmemcCommand, name="list")
333
+ @click.option(
334
+ "--catalog-graph",
335
+ default="https://ns.eccenca.com/data/queries/",
336
+ show_default=True,
337
+ shell_complete=completion.graph_uris,
338
+ help="The used query catalog graph.",
339
+ )
333
340
  @click.option(
334
341
  "--id-only",
335
342
  is_flag=True,
@@ -337,13 +344,13 @@ def _output_query_status_details(app: ApplicationContext, status_dict: dict) ->
337
344
  "This is useful for piping the ids into other cmemc commands.",
338
345
  )
339
346
  @click.pass_obj
340
- def list_command(app: ApplicationContext, id_only: bool) -> None:
347
+ def list_command(app: ApplicationContext, catalog_graph: str, id_only: bool) -> None:
341
348
  """List available queries from the catalog.
342
349
 
343
350
  Outputs a list of query URIs which can be used as reference for
344
351
  the query execute command.
345
352
  """
346
- queries = QueryCatalog().get_queries().items()
353
+ queries = QueryCatalog(graph=catalog_graph).get_queries().items()
347
354
  if id_only:
348
355
  # sort dict by short_url - https://docs.python.org/3/howto/sorting.html
349
356
  for _, sparql_query in sorted(queries, key=lambda k: k[1].short_url.lower()):
@@ -359,7 +366,12 @@ def list_command(app: ApplicationContext, id_only: bool) -> None:
359
366
  ]
360
367
  table.append(row)
361
368
  app.echo_info_table(
362
- table, headers=["Query URI", "Type", "Placeholder", "Label"], sort_column=3
369
+ table,
370
+ headers=["Query URI", "Type", "Placeholder", "Label"],
371
+ sort_column=3,
372
+ empty_table_message="There are no query available in the "
373
+ f"selected catalog ({catalog_graph}).",
374
+ caption=f"Queries from {catalog_graph} ({get_cmem_base_uri()})",
363
375
  )
364
376
 
365
377
 
@@ -367,6 +379,13 @@ def list_command(app: ApplicationContext, id_only: bool) -> None:
367
379
  @click.argument(
368
380
  "QUERIES", nargs=-1, required=True, shell_complete=completion.remote_queries_and_sparql_files
369
381
  )
382
+ @click.option(
383
+ "--catalog-graph",
384
+ default="https://ns.eccenca.com/data/queries/",
385
+ show_default=True,
386
+ shell_complete=completion.graph_uris,
387
+ help="The used query catalog graph.",
388
+ )
370
389
  @click.option(
371
390
  "--accept",
372
391
  default="default",
@@ -420,6 +439,7 @@ def list_command(app: ApplicationContext, id_only: bool) -> None:
420
439
  def execute_command( # noqa: PLR0913
421
440
  app: ApplicationContext,
422
441
  queries: tuple[str, ...],
442
+ catalog_graph: str,
423
443
  accept: str,
424
444
  no_imports: bool,
425
445
  base64: bool,
@@ -453,9 +473,14 @@ def execute_command( # noqa: PLR0913
453
473
  app.echo_debug("Parameter: " + str(placeholder))
454
474
  for file_or_uri in queries:
455
475
  app.echo_debug(f"Start of execution: {file_or_uri} with " f"placeholder {placeholder}")
456
- executed_query: SparqlQuery = QueryCatalog().get_query(file_or_uri, placeholder=placeholder)
476
+ executed_query: SparqlQuery = QueryCatalog(graph=catalog_graph).get_query(
477
+ file_or_uri, placeholder=placeholder
478
+ )
457
479
  if executed_query is None:
458
- raise ClickException(f"{file_or_uri} is neither a (readable) file nor a query URI.")
480
+ raise click.UsageError(
481
+ f"{file_or_uri} is neither a (readable) file nor "
482
+ f"a query URI in the catalog graph {catalog_graph}"
483
+ )
459
484
  app.echo_debug(
460
485
  f"Execute ({executed_query.query_type}): "
461
486
  f"{executed_query.label} < {executed_query.url}"
@@ -499,8 +524,15 @@ def execute_command( # noqa: PLR0913
499
524
  @click.argument(
500
525
  "QUERIES", nargs=-1, required=True, shell_complete=completion.remote_queries_and_sparql_files
501
526
  )
527
+ @click.option(
528
+ "--catalog-graph",
529
+ default="https://ns.eccenca.com/data/queries/",
530
+ show_default=True,
531
+ shell_complete=completion.graph_uris,
532
+ help="The used query catalog graph.",
533
+ )
502
534
  @click.pass_obj
503
- def open_command(app: ApplicationContext, queries: tuple[str, ...]) -> None:
535
+ def open_command(app: ApplicationContext, queries: tuple[str, ...], catalog_graph: str) -> None:
504
536
  """Open queries in the editor of the query catalog in your browser.
505
537
 
506
538
  With this command, you can open (remote) queries from the query catalog in
@@ -512,10 +544,13 @@ def open_command(app: ApplicationContext, queries: tuple[str, ...]) -> None:
512
544
  opening multiple browser tabs.
513
545
  """
514
546
  for file_or_uri in queries:
515
- opened_query = QueryCatalog().get_query(file_or_uri)
547
+ opened_query = QueryCatalog(graph=catalog_graph).get_query(file_or_uri)
516
548
  if opened_query is None:
517
- raise ClickException(f"{file_or_uri} is neither a (readable) file nor a query URI.")
518
- open_query_uri = opened_query.get_editor_url()
549
+ raise click.UsageError(
550
+ f"{file_or_uri} is neither a (readable) file nor "
551
+ f"a query URI in the catalog graph {catalog_graph}"
552
+ )
553
+ open_query_uri = opened_query.get_editor_url(graph=catalog_graph)
519
554
  app.echo_debug(f"Open {file_or_uri}: {open_query_uri}")
520
555
  click.launch(open_query_uri)
521
556
 
@@ -571,7 +606,7 @@ def status_command(
571
606
  queries = query_status_list.apply_filters(ctx=ctx, filter_=filter_)
572
607
 
573
608
  if query_id and len(queries) == 0:
574
- raise UsageError(f"Query with ID '{query_id}' does not exist (anymore).")
609
+ raise click.UsageError(f"Query with ID '{query_id}' does not exist (anymore).")
575
610
 
576
611
  if raw:
577
612
  app.echo_info_json(queries)
@@ -666,14 +701,14 @@ def replay_command( # noqa: PLR0913
666
701
  other data.
667
702
  """
668
703
  if loops <= 0:
669
- raise UsageError("Please set a positive loops integer value (>=1).")
704
+ raise click.UsageError("Please set a positive loops integer value (>=1).")
670
705
  try:
671
706
  with Path(replay_file).open(encoding="utf8") as _:
672
707
  input_queries = load(_)
673
708
  except JSONDecodeError as error:
674
- raise ClickException(f"File {replay_file} is not a valid JSON document.") from error
709
+ raise click.ClickException(f"File {replay_file} is not a valid JSON document.") from error
675
710
  if len(input_queries) == 0:
676
- raise ClickException(f"File {replay_file} contains no queries.")
711
+ raise click.ClickException(f"File {replay_file} contains no queries.")
677
712
  app.echo_debug(f"File {replay_file} contains {len(input_queries)} queries.")
678
713
 
679
714
  statistic = ReplayStatistics(app=app, label=run_label)
@@ -10,6 +10,7 @@ from cmem.cmempy.dp.admin import create_showcase_data, delete_bootstrap_data, im
10
10
  from cmem.cmempy.dp.admin.backup import get_zip, post_zip
11
11
  from cmem.cmempy.dp.workspace import migrate_workspaces
12
12
  from cmem.cmempy.health import get_dp_info
13
+ from cmem.cmempy.workspace import reload_workspace
13
14
  from jinja2 import Template
14
15
 
15
16
  from cmem_cmemc.command import CmemcCommand
@@ -53,7 +54,7 @@ def bootstrap_command(app: ApplicationContext, import_: bool, remove: bool) -> N
53
54
 
54
55
  Note: The import part of this command is equivalent to the 'bootstrap-data' migration recipe
55
56
  """
56
- if import_ and remove or not import_ and not remove:
57
+ if (import_ and remove) or (not import_ and not remove):
57
58
  raise UsageError("Either use the --import or the --remove option.")
58
59
  if import_:
59
60
  app.echo_info("Update or import bootstrap data ... ", nl=False)
@@ -99,12 +100,15 @@ def showcase_command(app: ApplicationContext, scale: int, create: bool, delete:
99
100
  raise UsageError("Either use the --create or the --delete flag.")
100
101
  if delete:
101
102
  raise NotImplementedError(
102
- "This feature is not implemented yet. " "Please delete the graphs manually."
103
+ "This feature is not implemented yet. Please delete the graphs manually."
103
104
  )
104
105
  if create:
105
106
  app.echo_info(f"Create showcase data with scale factor {scale} ... ", nl=False)
106
107
  create_showcase_data(scale_factor=scale)
107
108
  app.echo_success("done")
109
+ app.echo_info("Reload workspace ... ", nl=False)
110
+ reload_workspace()
111
+ app.echo_success("done")
108
112
 
109
113
 
110
114
  @click.command(cls=CmemcCommand, name="export")
@@ -51,8 +51,15 @@ FILE_EXTENSIONS_TO_PLUGIN_ID = {
51
51
  ".json": "json",
52
52
  ".xml": "xml",
53
53
  ".txt": "text",
54
+ ".md": "text",
54
55
  ".xlsx": "excel",
55
56
  ".zip": "multiCsv",
57
+ ".pdf": "binaryFile",
58
+ ".png": "binaryFile",
59
+ ".jpg": "binaryFile",
60
+ ".jpeg": "binaryFile",
61
+ ".gif": "binaryFile",
62
+ ".tiff": "binaryFile",
56
63
  }
57
64
 
58
65
  # Derive valid extensions from FILE_EXTENSIONS_TO_PLUGIN_ID keys
@@ -63,6 +70,7 @@ EXTRA_INPUT_MIME_TYPES = [
63
70
  "application/json",
64
71
  "application/xml",
65
72
  "text/csv",
73
+ "application/octet-stream",
66
74
  ]
67
75
 
68
76
  EXTRA_OUTPUT_MIME_TYPES = [
@@ -71,6 +79,7 @@ EXTRA_OUTPUT_MIME_TYPES = [
71
79
  "application/n-triples",
72
80
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
73
81
  "text/csv",
82
+ "application/octet-stream",
74
83
  ]
75
84
 
76
85
  STDOUT_UNSUPPORTED_MIME_TYPES = {
@@ -495,32 +495,6 @@ def installable_packages(ctx: Context, param: Argument, incomplete: str) -> list
495
495
  )
496
496
 
497
497
 
498
- def workflow_io_input_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
499
- """Prepare a list of acceptable workflow io input files."""
500
- return (
501
- file_list(incomplete=incomplete, suffix=".csv", description="CSV Dataset resource")
502
- + file_list(incomplete=incomplete, suffix=".xml", description="XML Dataset resource")
503
- + file_list(incomplete=incomplete, suffix=".json", description="JSON Dataset resource")
504
- + file_list(incomplete=incomplete, suffix=".xlsx", description="Excel Dataset resource")
505
- + file_list(incomplete=incomplete, suffix=".txt", description="Text Dataset resource")
506
- + file_list(incomplete=incomplete, suffix=".zip", description="Multi CSV Dataset resource")
507
- )
508
-
509
-
510
- def workflow_io_input_mimetypes(
511
- ctx: Context, param: Argument, incomplete: str
512
- ) -> list[CompletionItem]:
513
- """Prepare a list of acceptable workflow io input mimetypes."""
514
- return (
515
- file_list(incomplete=incomplete, suffix=".csv", description="CSV Dataset resource")
516
- + file_list(incomplete=incomplete, suffix=".xml", description="XML Dataset resource")
517
- + file_list(incomplete=incomplete, suffix=".json", description="JSON Dataset resource")
518
- + file_list(incomplete=incomplete, suffix=".xlsx", description="Excel Dataset resource")
519
- + file_list(incomplete=incomplete, suffix=".txt", description="Text Dataset resource")
520
- + file_list(incomplete=incomplete, suffix=".zip", description="Multi CSV Dataset resource")
521
- )
522
-
523
-
524
498
  def workflow_io_output_files(
525
499
  ctx: Context, param: Argument, incomplete: str
526
500
  ) -> list[CompletionItem]:
@@ -535,6 +509,18 @@ def workflow_io_output_files(
535
509
  )
536
510
 
537
511
 
512
+ def workflow_io_input_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
513
+ """Prepare a list of acceptable workflow io input files."""
514
+ files = []
515
+ for extension, info in get_dataset_file_mapping().items():
516
+ # handle zip extension separately.
517
+ if extension != ".zip":
518
+ files += file_list(
519
+ incomplete=incomplete, suffix=extension, description=info["description"]
520
+ )
521
+ return files
522
+
523
+
538
524
  def get_dataset_file_mapping() -> dict[str, dict[str, str]]:
539
525
  """Return file extension to type and description mapping"""
540
526
  return {
@@ -547,15 +533,22 @@ def get_dataset_file_mapping() -> dict[str, dict[str, str]]:
547
533
  ".json.zip": {"description": "JSON Dataset resource (zipped)", "type": "json"},
548
534
  ".jsonl": {"description": "JSON Lines Dataset resource", "type": "json"},
549
535
  ".jsonl.zip": {"description": "JSON Lines Dataset resource (zipped)", "type": "json"},
550
- ".yaml": {"description": "YAML Document", "type": "text"},
551
- ".yaml.zip": {"description": "YAML Document (zipped)", "type": "text"},
552
- ".yml": {"description": "YAML Document", "type": "text"},
553
- ".yml.zip": {"description": "YAML Document (zipped)", "type": "text"},
536
+ ".yaml": {"description": "YAML Text Document", "type": "text"},
537
+ ".yaml.zip": {"description": "YAML Text Document (zipped)", "type": "text"},
538
+ ".md": {"description": "Markdown Text Document", "type": "text"},
539
+ ".md.zip": {"description": "Markdown Text Document (zipped)", "type": "text"},
540
+ ".yml": {"description": "YAML Text Document", "type": "text"},
541
+ ".yml.zip": {"description": "YAML Text Document (zipped)", "type": "text"},
554
542
  ".ttl": {"description": "RDF file Dataset resource", "type": "file"},
555
543
  ".orc": {"description": "Apache ORC Dataset resource", "type": "orc"},
556
544
  ".txt": {"description": "Text dataset resource", "type": "text"},
557
545
  ".txt.zip": {"description": "Text dataset resource (zipped)", "type": "text"},
558
- ".zip": {"description": "multiCsv Dataset resource", "type": "multiCsv"},
546
+ ".zip": {"description": "Potential multiCsv Dataset resource", "type": "multiCsv"},
547
+ ".pdf": {"description": "Potential Binary Dataset resource", "type": "binaryFile"},
548
+ ".png": {"description": "Potential Binary Dataset resource", "type": "binaryFile"},
549
+ ".jpg": {"description": "Potential Binary Dataset resource", "type": "binaryFile"},
550
+ ".gif": {"description": "Potential Binary Dataset resource", "type": "binaryFile"},
551
+ ".tiff": {"description": "Potential Binary Dataset resource", "type": "binaryFile"},
559
552
  }
560
553
 
561
554
 
@@ -650,10 +643,11 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
650
643
  args = get_completion_args(incomplete)
651
644
  # setup configuration
652
645
  ApplicationContext.set_connection_from_params(ctx.find_root().params)
646
+ catalog_graph = ctx.params.get("catalog_graph")
653
647
  # extract placeholder from given queries in the command line
654
648
  options = []
655
649
  placeholders: dict[str, QueryPlaceholder] = {}
656
- catalog = QueryCatalog() # fetch all queries
650
+ catalog = QueryCatalog(graph=catalog_graph) if catalog_graph else QueryCatalog()
657
651
  for _, arg in enumerate(args):
658
652
  query = catalog.get_query(arg)
659
653
  if query is not None:
@@ -661,7 +655,7 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
661
655
  placeholders = placeholders | get_placeholders_for_query(iri=query.url)
662
656
  # collect all placeholder keys
663
657
  options.extend(list(query.get_placeholder_keys()))
664
- # look if cursor is in value position of the -p option and
658
+ # look if the cursor is in value position of the -p option and
665
659
  # use placeholder value completion, in case it is
666
660
  if args[len(args) - 2] in ("-p", "--parameter"):
667
661
  key = args[len(args) - 1]
@@ -683,8 +677,10 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
683
677
  def remote_queries(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
684
678
  """Prepare a list of query URIs."""
685
679
  ApplicationContext.set_connection_from_params(ctx.find_root().params)
680
+ catalog_graph = ctx.params.get("catalog_graph")
681
+ catalog = QueryCatalog(graph=catalog_graph) if catalog_graph else QueryCatalog()
686
682
  options = []
687
- for query in QueryCatalog().get_queries().values():
683
+ for query in catalog.get_queries().values():
688
684
  url = query.short_url
689
685
  label = query.label
690
686
  options.append((url, label))
@@ -29,9 +29,9 @@ from cmem_cmemc.exceptions import InvalidConfigurationError
29
29
  from cmem_cmemc.string_processor import StringProcessor, process_row
30
30
  from cmem_cmemc.utils import is_enabled, str_to_bool
31
31
 
32
- DI_TARGET_VERSION = "v25.1.0"
32
+ DI_TARGET_VERSION = "v25.2.0"
33
33
 
34
- EXPLORE_TARGET_VERSION = "v25.1.0"
34
+ EXPLORE_TARGET_VERSION = "v25.2.0"
35
35
 
36
36
  KNOWN_CONFIG_KEYS = {
37
37
  "CMEM_BASE_URI": cmempy_config.get_cmem_base_uri,
@@ -31,6 +31,7 @@ def get_icon_for_command_group(full_name: str) -> str:
31
31
  "project variable": "material/variable-box",
32
32
  "query": "eccenca/application-queries",
33
33
  "graph": "eccenca/artefact-dataset-eccencadataplatform",
34
+ "graph imports": "material/family-tree",
34
35
  "graph validation": "octicons/verified-16",
35
36
  "vocabulary": "eccenca/application-vocabularies",
36
37
  "vocabulary cache": "eccenca/application-vocabularies",
@@ -58,6 +59,7 @@ def get_tags_for_command_group(full_name: str) -> str:
58
59
  "project variable": ["Variables", "cmemc"],
59
60
  "query": ["SPARQL", "cmemc"],
60
61
  "graph": ["KnowledgeGraph", "cmemc"],
62
+ "graph imports": ["KnowledgeGraph", "cmemc"],
61
63
  "graph validation": ["KnowledgeGraph", "Validation", "cmemc"],
62
64
  "vocabulary": ["Vocabulary", "cmemc"],
63
65
  "vocabulary cache": ["Vocabulary", "cmemc"],
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "cmem-cmemc"
3
- version = "25.2.0"
3
+ version = "25.4.0"
4
4
  description = "Command line client for eccenca Corporate Memory"
5
5
  license = "Apache-2.0"
6
6
  classifiers = [
@@ -35,7 +35,7 @@ certifi = ">=2024.2.2"
35
35
  click = "^8.1.8, <8.2.0"
36
36
  click-didyoumean = "^0.3.1"
37
37
  click-help-colors = "^0.9.4"
38
- cmem-cmempy = "==25.1.0"
38
+ cmem-cmempy = "==25.3.0"
39
39
  # cmem-cmempy = { path = "cmempy", develop = true }
40
40
  configparser = "^7.2.0"
41
41
  jinja2 = "^3.1.6"
@@ -59,7 +59,7 @@ cmemc = 'cmem_cmemc.cli:main'
59
59
 
60
60
  [tool.poetry.group.dev.dependencies]
61
61
  genbadge = {extras = ["coverage"], version = "^1.1.1"}
62
- mypy = "^1.13.0"
62
+ mypy = "1.15.0"
63
63
  pip = "^25"
64
64
  pytest = "^8.3.3"
65
65
  pytest-cov = "^6.0.0"
File without changes