pltr-cli 0.10.0__tar.gz → 0.11.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.
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/PKG-INFO +1 -1
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/pyproject.toml +1 -1
- pltr_cli-0.11.0/src/pltr/__init__.py +1 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/ontology.py +93 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/dataset.py +5 -8
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/ontology.py +71 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_ontology.py +105 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_ontology.py +79 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/uv.lock +1 -1
- pltr_cli-0.10.0/src/pltr/__init__.py +0 -1
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/.github/workflows/ci.yml +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/.github/workflows/publish.yml +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/.github/workflows/test-publish.yml +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/.gitignore +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/.pre-commit-config.yaml +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/CHANGELOG.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/CLAUDE.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/LICENSE +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/README.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/RELEASE.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/children.csv +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/README.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/api/wrapper.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/examples/csv-upload.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/examples/gallery.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/features/dataset-transactions.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/aliases.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/authentication.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/commands.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/quick-start.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/troubleshooting.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/docs/user-guide/workflows.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/folder_info.json +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/folders.json +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/mypy.ini +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/scripts/release.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/__main__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/base.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/manager.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/oauth.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/storage.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/auth/token.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/cli.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/admin.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/alias.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/completion.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/configure.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/connectivity.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/dataset.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/folder.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/mediasets.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/orchestration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/project.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/resource.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/resource_role.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/shell.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/space.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/sql.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/commands/verify.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/config/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/config/aliases.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/config/profiles.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/config/settings.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/admin.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/base.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/connectivity.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/folder.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/mediasets.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/orchestration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/project.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/resource.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/resource_role.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/space.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/services/sql.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/utils/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/utils/alias_resolver.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/utils/completion.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/utils/formatting.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/src/pltr/utils/progress.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/conftest.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/README.md +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/conftest.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/test_auth_flow.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/test_cli_integration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/test_data_workflows.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/test_data_workflows_simple.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/integration/test_simple_integration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/test_base.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/test_manager.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/test_oauth.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/test_storage.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_auth/test_token.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_admin.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_alias.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_completion.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_connectivity.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_dataset.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_folder.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_orchestration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_shell.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_sql.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_commands/test_verify_simple.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_config/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_config/test_aliases.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_config/test_profiles.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_config/test_settings.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_admin.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_base.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_connectivity.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_dataset.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_dataset_transactions.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_folder.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_orchestration.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_project.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_resource.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_resource_role.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_space.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_services/test_sql.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_utils/__init__.py +0 -0
- {pltr_cli-0.10.0 → pltr_cli-0.11.0}/tests/test_utils/test_alias_resolver.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.11.0"
|
|
@@ -366,6 +366,99 @@ def list_linked_objects(
|
|
|
366
366
|
raise typer.Exit(1)
|
|
367
367
|
|
|
368
368
|
|
|
369
|
+
@app.command("object-count")
|
|
370
|
+
def count_objects(
|
|
371
|
+
ontology_rid: str = typer.Argument(..., help="Ontology Resource Identifier"),
|
|
372
|
+
object_type: str = typer.Argument(..., help="Object type API name"),
|
|
373
|
+
profile: Optional[str] = typer.Option(None, "--profile", "-p", help="Profile name"),
|
|
374
|
+
format: str = typer.Option(
|
|
375
|
+
"table", "--format", "-f", help="Output format (table, json, csv)"
|
|
376
|
+
),
|
|
377
|
+
output: Optional[str] = typer.Option(
|
|
378
|
+
None, "--output", "-o", help="Output file path"
|
|
379
|
+
),
|
|
380
|
+
branch: Optional[str] = typer.Option(None, "--branch", "-b", help="Branch name"),
|
|
381
|
+
):
|
|
382
|
+
"""Count objects of a specific type."""
|
|
383
|
+
try:
|
|
384
|
+
service = OntologyObjectService(profile=profile)
|
|
385
|
+
|
|
386
|
+
with SpinnerProgressTracker().track_spinner(
|
|
387
|
+
f"Counting {object_type} objects..."
|
|
388
|
+
):
|
|
389
|
+
result = service.count_objects(ontology_rid, object_type, branch=branch)
|
|
390
|
+
|
|
391
|
+
formatter.format_dict(result, format=format, output=output)
|
|
392
|
+
|
|
393
|
+
if output:
|
|
394
|
+
formatter.print_success(f"Count result saved to {output}")
|
|
395
|
+
|
|
396
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
397
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
398
|
+
raise typer.Exit(1)
|
|
399
|
+
except Exception as e:
|
|
400
|
+
formatter.print_error(f"Failed to count objects: {e}")
|
|
401
|
+
raise typer.Exit(1)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@app.command("object-search")
|
|
405
|
+
def search_objects(
|
|
406
|
+
ontology_rid: str = typer.Argument(..., help="Ontology Resource Identifier"),
|
|
407
|
+
object_type: str = typer.Argument(..., help="Object type API name"),
|
|
408
|
+
query: str = typer.Option(..., "--query", "-q", help="Search query string"),
|
|
409
|
+
profile: Optional[str] = typer.Option(None, "--profile", "-p", help="Profile name"),
|
|
410
|
+
format: str = typer.Option(
|
|
411
|
+
"table", "--format", "-f", help="Output format (table, json, csv)"
|
|
412
|
+
),
|
|
413
|
+
output: Optional[str] = typer.Option(
|
|
414
|
+
None, "--output", "-o", help="Output file path"
|
|
415
|
+
),
|
|
416
|
+
page_size: Optional[int] = typer.Option(
|
|
417
|
+
None, "--page-size", help="Number of results per page"
|
|
418
|
+
),
|
|
419
|
+
properties: Optional[str] = typer.Option(
|
|
420
|
+
None, "--properties", help="Comma-separated list of properties to include"
|
|
421
|
+
),
|
|
422
|
+
branch: Optional[str] = typer.Option(None, "--branch", "-b", help="Branch name"),
|
|
423
|
+
):
|
|
424
|
+
"""Search objects by query."""
|
|
425
|
+
try:
|
|
426
|
+
service = OntologyObjectService(profile=profile)
|
|
427
|
+
|
|
428
|
+
prop_list = properties.split(",") if properties else None
|
|
429
|
+
|
|
430
|
+
with SpinnerProgressTracker().track_spinner(
|
|
431
|
+
f"Searching {object_type} objects..."
|
|
432
|
+
):
|
|
433
|
+
objects = service.search_objects(
|
|
434
|
+
ontology_rid,
|
|
435
|
+
object_type,
|
|
436
|
+
query,
|
|
437
|
+
page_size=page_size,
|
|
438
|
+
properties=prop_list,
|
|
439
|
+
branch=branch,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
if format == "table" and objects:
|
|
443
|
+
# Use first object's keys as columns
|
|
444
|
+
columns = list(objects[0].keys()) if objects else []
|
|
445
|
+
formatter.format_table(
|
|
446
|
+
objects, columns=columns, format=format, output=output
|
|
447
|
+
)
|
|
448
|
+
else:
|
|
449
|
+
formatter.format_list(objects, format=format, output=output)
|
|
450
|
+
|
|
451
|
+
if output:
|
|
452
|
+
formatter.print_success(f"Search results saved to {output}")
|
|
453
|
+
|
|
454
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
455
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
456
|
+
raise typer.Exit(1)
|
|
457
|
+
except Exception as e:
|
|
458
|
+
formatter.print_error(f"Failed to search objects: {e}")
|
|
459
|
+
raise typer.Exit(1)
|
|
460
|
+
|
|
461
|
+
|
|
369
462
|
# Action commands
|
|
370
463
|
@app.command("action-apply")
|
|
371
464
|
def apply_action(
|
|
@@ -487,18 +487,15 @@ class DatasetService(BaseService):
|
|
|
487
487
|
# Ensure output directory exists
|
|
488
488
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
489
489
|
|
|
490
|
-
|
|
490
|
+
# Use Dataset.File.content() which returns bytes directly
|
|
491
|
+
# Note: In SDK v1.27.0, the method is 'content' not 'read'
|
|
492
|
+
file_content = self.service.Dataset.File.content(
|
|
491
493
|
dataset_rid=dataset_rid, file_path=file_path, branch_name=branch
|
|
492
494
|
)
|
|
493
495
|
|
|
494
|
-
# Write file content to disk
|
|
496
|
+
# Write file content to disk (file_content is bytes)
|
|
495
497
|
with open(output_path, "wb") as f:
|
|
496
|
-
|
|
497
|
-
# If it's a stream
|
|
498
|
-
f.write(file_content.read())
|
|
499
|
-
else:
|
|
500
|
-
# If it's bytes
|
|
501
|
-
f.write(file_content)
|
|
498
|
+
f.write(file_content)
|
|
502
499
|
|
|
503
500
|
return {
|
|
504
501
|
"dataset_rid": dataset_rid,
|
|
@@ -287,6 +287,77 @@ class OntologyObjectService(BaseService):
|
|
|
287
287
|
except Exception as e:
|
|
288
288
|
raise RuntimeError(f"Failed to list linked objects: {e}")
|
|
289
289
|
|
|
290
|
+
def count_objects(
|
|
291
|
+
self,
|
|
292
|
+
ontology_rid: str,
|
|
293
|
+
object_type: str,
|
|
294
|
+
branch: Optional[str] = None,
|
|
295
|
+
) -> Dict[str, Any]:
|
|
296
|
+
"""
|
|
297
|
+
Count objects of a specific type.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
ontology_rid: Ontology Resource Identifier
|
|
301
|
+
object_type: Object type API name
|
|
302
|
+
branch: Branch name (optional)
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Dictionary containing count information
|
|
306
|
+
"""
|
|
307
|
+
try:
|
|
308
|
+
count = self.service.OntologyObject.count(
|
|
309
|
+
ontology_rid,
|
|
310
|
+
object_type,
|
|
311
|
+
branch_name=branch,
|
|
312
|
+
)
|
|
313
|
+
return {
|
|
314
|
+
"ontology_rid": ontology_rid,
|
|
315
|
+
"object_type": object_type,
|
|
316
|
+
"count": count,
|
|
317
|
+
"branch": branch,
|
|
318
|
+
}
|
|
319
|
+
except Exception as e:
|
|
320
|
+
raise RuntimeError(f"Failed to count objects: {e}")
|
|
321
|
+
|
|
322
|
+
def search_objects(
|
|
323
|
+
self,
|
|
324
|
+
ontology_rid: str,
|
|
325
|
+
object_type: str,
|
|
326
|
+
query: str,
|
|
327
|
+
page_size: Optional[int] = None,
|
|
328
|
+
properties: Optional[List[str]] = None,
|
|
329
|
+
branch: Optional[str] = None,
|
|
330
|
+
) -> List[Dict[str, Any]]:
|
|
331
|
+
"""
|
|
332
|
+
Search objects by query.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
ontology_rid: Ontology Resource Identifier
|
|
336
|
+
object_type: Object type API name
|
|
337
|
+
query: Search query string
|
|
338
|
+
page_size: Number of results per page
|
|
339
|
+
properties: List of properties to include
|
|
340
|
+
branch: Branch name (optional)
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
List of matching object dictionaries
|
|
344
|
+
"""
|
|
345
|
+
try:
|
|
346
|
+
result = self.service.OntologyObject.search(
|
|
347
|
+
ontology_rid,
|
|
348
|
+
object_type,
|
|
349
|
+
query=query,
|
|
350
|
+
page_size=page_size,
|
|
351
|
+
properties=properties,
|
|
352
|
+
branch_name=branch,
|
|
353
|
+
)
|
|
354
|
+
objects = []
|
|
355
|
+
for obj in result:
|
|
356
|
+
objects.append(self._format_object(obj))
|
|
357
|
+
return objects
|
|
358
|
+
except Exception as e:
|
|
359
|
+
raise RuntimeError(f"Failed to search objects: {e}")
|
|
360
|
+
|
|
290
361
|
def _format_object(self, obj: Any) -> Dict[str, Any]:
|
|
291
362
|
"""Format object for consistent output."""
|
|
292
363
|
# Objects may have various properties - extract them dynamically
|
|
@@ -220,6 +220,111 @@ def test_list_linked_objects_command(mock_services):
|
|
|
220
220
|
mock_instance.list_linked_objects.assert_called_once()
|
|
221
221
|
|
|
222
222
|
|
|
223
|
+
def test_count_objects_command(mock_services):
|
|
224
|
+
"""Test count objects command."""
|
|
225
|
+
mock_instance = Mock()
|
|
226
|
+
mock_instance.count_objects.return_value = {
|
|
227
|
+
"ontology_rid": "ri.ontology.main.ontology.test",
|
|
228
|
+
"object_type": "Employee",
|
|
229
|
+
"count": 42,
|
|
230
|
+
"branch": None,
|
|
231
|
+
}
|
|
232
|
+
mock_services["object"].return_value = mock_instance
|
|
233
|
+
|
|
234
|
+
result = runner.invoke(
|
|
235
|
+
app, ["object-count", "ri.ontology.main.ontology.test", "Employee"]
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
assert result.exit_code == 0
|
|
239
|
+
mock_instance.count_objects.assert_called_once_with(
|
|
240
|
+
"ri.ontology.main.ontology.test", "Employee", branch=None
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_count_objects_with_branch(mock_services):
|
|
245
|
+
"""Test count objects with branch specified."""
|
|
246
|
+
mock_instance = Mock()
|
|
247
|
+
mock_instance.count_objects.return_value = {
|
|
248
|
+
"ontology_rid": "ri.ontology.main.ontology.test",
|
|
249
|
+
"object_type": "Employee",
|
|
250
|
+
"count": 24,
|
|
251
|
+
"branch": "master",
|
|
252
|
+
}
|
|
253
|
+
mock_services["object"].return_value = mock_instance
|
|
254
|
+
|
|
255
|
+
result = runner.invoke(
|
|
256
|
+
app,
|
|
257
|
+
[
|
|
258
|
+
"object-count",
|
|
259
|
+
"ri.ontology.main.ontology.test",
|
|
260
|
+
"Employee",
|
|
261
|
+
"--branch",
|
|
262
|
+
"master",
|
|
263
|
+
],
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
assert result.exit_code == 0
|
|
267
|
+
mock_instance.count_objects.assert_called_once_with(
|
|
268
|
+
"ri.ontology.main.ontology.test", "Employee", branch="master"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_search_objects_command(mock_services):
|
|
273
|
+
"""Test search objects command."""
|
|
274
|
+
mock_instance = Mock()
|
|
275
|
+
mock_instance.search_objects.return_value = [
|
|
276
|
+
{"employee_id": "EMP001", "name": "John Doe"}
|
|
277
|
+
]
|
|
278
|
+
mock_services["object"].return_value = mock_instance
|
|
279
|
+
|
|
280
|
+
result = runner.invoke(
|
|
281
|
+
app,
|
|
282
|
+
[
|
|
283
|
+
"object-search",
|
|
284
|
+
"ri.ontology.main.ontology.test",
|
|
285
|
+
"Employee",
|
|
286
|
+
"--query",
|
|
287
|
+
"John",
|
|
288
|
+
],
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
assert result.exit_code == 0
|
|
292
|
+
mock_instance.search_objects.assert_called_once()
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def test_search_objects_with_options(mock_services):
|
|
296
|
+
"""Test search objects with all options."""
|
|
297
|
+
mock_instance = Mock()
|
|
298
|
+
mock_instance.search_objects.return_value = [
|
|
299
|
+
{"employee_id": "EMP001", "name": "John Doe"}
|
|
300
|
+
]
|
|
301
|
+
mock_services["object"].return_value = mock_instance
|
|
302
|
+
|
|
303
|
+
result = runner.invoke(
|
|
304
|
+
app,
|
|
305
|
+
[
|
|
306
|
+
"object-search",
|
|
307
|
+
"ri.ontology.main.ontology.test",
|
|
308
|
+
"Employee",
|
|
309
|
+
"--query",
|
|
310
|
+
"Jane",
|
|
311
|
+
"--page-size",
|
|
312
|
+
"10",
|
|
313
|
+
"--properties",
|
|
314
|
+
"name,department",
|
|
315
|
+
"--branch",
|
|
316
|
+
"master",
|
|
317
|
+
],
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
assert result.exit_code == 0
|
|
321
|
+
call_args = mock_instance.search_objects.call_args
|
|
322
|
+
assert call_args[0] == ("ri.ontology.main.ontology.test", "Employee", "Jane")
|
|
323
|
+
assert call_args[1]["page_size"] == 10
|
|
324
|
+
assert call_args[1]["properties"] == ["name", "department"]
|
|
325
|
+
assert call_args[1]["branch"] == "master"
|
|
326
|
+
|
|
327
|
+
|
|
223
328
|
# Action command tests
|
|
224
329
|
def test_apply_action_command(mock_services):
|
|
225
330
|
"""Test apply action command."""
|
|
@@ -335,6 +335,85 @@ def test_list_linked_objects(mock_ontology_object_service, sample_object):
|
|
|
335
335
|
mock_ontology_object_class.list_linked_objects.assert_called_once()
|
|
336
336
|
|
|
337
337
|
|
|
338
|
+
def test_count_objects(mock_ontology_object_service):
|
|
339
|
+
"""Test counting objects."""
|
|
340
|
+
service, mock_ontology_object_class = mock_ontology_object_service
|
|
341
|
+
mock_ontology_object_class.count.return_value = 42
|
|
342
|
+
|
|
343
|
+
result = service.count_objects("ri.ontology.main.ontology.test", "Employee")
|
|
344
|
+
|
|
345
|
+
assert result["count"] == 42
|
|
346
|
+
assert result["ontology_rid"] == "ri.ontology.main.ontology.test"
|
|
347
|
+
assert result["object_type"] == "Employee"
|
|
348
|
+
assert result["branch"] is None
|
|
349
|
+
mock_ontology_object_class.count.assert_called_once_with(
|
|
350
|
+
"ri.ontology.main.ontology.test", "Employee", branch_name=None
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def test_count_objects_with_branch(mock_ontology_object_service):
|
|
355
|
+
"""Test counting objects with branch specified."""
|
|
356
|
+
service, mock_ontology_object_class = mock_ontology_object_service
|
|
357
|
+
mock_ontology_object_class.count.return_value = 24
|
|
358
|
+
|
|
359
|
+
result = service.count_objects(
|
|
360
|
+
"ri.ontology.main.ontology.test", "Employee", branch="master"
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
assert result["count"] == 24
|
|
364
|
+
assert result["branch"] == "master"
|
|
365
|
+
mock_ontology_object_class.count.assert_called_once_with(
|
|
366
|
+
"ri.ontology.main.ontology.test", "Employee", branch_name="master"
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def test_search_objects(mock_ontology_object_service, sample_object):
|
|
371
|
+
"""Test searching objects."""
|
|
372
|
+
service, mock_ontology_object_class = mock_ontology_object_service
|
|
373
|
+
mock_ontology_object_class.search.return_value = [sample_object]
|
|
374
|
+
|
|
375
|
+
result = service.search_objects(
|
|
376
|
+
"ri.ontology.main.ontology.test", "Employee", "John"
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
assert len(result) == 1
|
|
380
|
+
assert result[0]["employee_id"] == "EMP001"
|
|
381
|
+
assert result[0]["name"] == "John Doe"
|
|
382
|
+
mock_ontology_object_class.search.assert_called_once_with(
|
|
383
|
+
"ri.ontology.main.ontology.test",
|
|
384
|
+
"Employee",
|
|
385
|
+
query="John",
|
|
386
|
+
page_size=None,
|
|
387
|
+
properties=None,
|
|
388
|
+
branch_name=None,
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def test_search_objects_with_options(mock_ontology_object_service, sample_object):
|
|
393
|
+
"""Test searching objects with all options."""
|
|
394
|
+
service, mock_ontology_object_class = mock_ontology_object_service
|
|
395
|
+
mock_ontology_object_class.search.return_value = [sample_object]
|
|
396
|
+
|
|
397
|
+
result = service.search_objects(
|
|
398
|
+
"ri.ontology.main.ontology.test",
|
|
399
|
+
"Employee",
|
|
400
|
+
"Jane",
|
|
401
|
+
page_size=10,
|
|
402
|
+
properties=["name", "department"],
|
|
403
|
+
branch="master",
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
assert len(result) == 1
|
|
407
|
+
mock_ontology_object_class.search.assert_called_once_with(
|
|
408
|
+
"ri.ontology.main.ontology.test",
|
|
409
|
+
"Employee",
|
|
410
|
+
query="Jane",
|
|
411
|
+
page_size=10,
|
|
412
|
+
properties=["name", "department"],
|
|
413
|
+
branch_name="master",
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
|
|
338
417
|
# ActionService Tests
|
|
339
418
|
def test_apply_action(mock_action_service, sample_action_result):
|
|
340
419
|
"""Test applying an action."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.10.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|