unitysvc-services 0.2.3__py3-none-any.whl → 0.2.4__py3-none-any.whl

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.
@@ -106,6 +106,11 @@ class ServiceDataPublisher:
106
106
 
107
107
  # Resolve file references and include content
108
108
  base_path = data_file.parent
109
+ data = convert_convenience_fields_to_documents(
110
+ data, base_path, logo_field="logo", terms_field="terms_of_service"
111
+ )
112
+
113
+ # Resolve file references and include content
109
114
  data_with_content = self.resolve_file_references(data, base_path)
110
115
 
111
116
  # Extract provider_name from directory structure
@@ -39,45 +39,65 @@ class ServiceDataQuery:
39
39
  timeout=30.0,
40
40
  )
41
41
 
42
- def list_service_offerings(self) -> list[dict[str, Any]]:
43
- """List all service offerings from the backend."""
44
- response = self.client.get(f"{self.base_url}/publish/offerings")
45
- response.raise_for_status()
46
- result = response.json()
47
- return result.get("data", result) if isinstance(result, dict) else result
42
+ def list_service_offerings(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
43
+ """List all service offerings from the backend.
48
44
 
49
- def list_service_listings(self) -> list[dict[str, Any]]:
50
- """List all service listings from the backend."""
51
- response = self.client.get(f"{self.base_url}/publish/listings")
45
+ Args:
46
+ skip: Number of records to skip (for pagination)
47
+ limit: Maximum number of records to return
48
+ """
49
+ response = self.client.get(
50
+ f"{self.base_url}/publish/offerings",
51
+ params={"skip": skip, "limit": limit}
52
+ )
52
53
  response.raise_for_status()
53
54
  result = response.json()
54
55
  return result.get("data", result) if isinstance(result, dict) else result
55
56
 
56
- def list_providers(self) -> list[dict[str, Any]]:
57
- """List all providers from the backend."""
58
- response = self.client.get(f"{self.base_url}/publish/providers")
57
+ def list_service_listings(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
58
+ """List all service listings from the backend.
59
+
60
+ Args:
61
+ skip: Number of records to skip (for pagination)
62
+ limit: Maximum number of records to return
63
+ """
64
+ response = self.client.get(
65
+ f"{self.base_url}/publish/listings",
66
+ params={"skip": skip, "limit": limit}
67
+ )
59
68
  response.raise_for_status()
60
69
  result = response.json()
61
70
  return result.get("data", result) if isinstance(result, dict) else result
62
71
 
63
- def list_sellers(self) -> list[dict[str, Any]]:
64
- """List all sellers from the backend."""
65
- response = self.client.get(f"{self.base_url}/publish/sellers")
72
+ def list_providers(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
73
+ """List all providers from the backend.
74
+
75
+ Args:
76
+ skip: Number of records to skip (for pagination)
77
+ limit: Maximum number of records to return
78
+ """
79
+ response = self.client.get(
80
+ f"{self.base_url}/publish/providers",
81
+ params={"skip": skip, "limit": limit}
82
+ )
66
83
  response.raise_for_status()
67
84
  result = response.json()
68
85
  return result.get("data", result) if isinstance(result, dict) else result
69
86
 
70
- def list_access_interfaces(self) -> dict[str, Any]:
71
- """List all access interfaces from the backend (private endpoint)."""
72
- response = self.client.get(f"{self.base_url}/private/interfaces")
73
- response.raise_for_status()
74
- return response.json()
87
+ def list_sellers(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
88
+ """List all sellers from the backend.
75
89
 
76
- def list_documents(self) -> dict[str, Any]:
77
- """List all documents from the backend (private endpoint)."""
78
- response = self.client.get(f"{self.base_url}/private/documents")
90
+ Args:
91
+ skip: Number of records to skip (for pagination)
92
+ limit: Maximum number of records to return
93
+ """
94
+ response = self.client.get(
95
+ f"{self.base_url}/publish/sellers",
96
+ params={"skip": skip, "limit": limit}
97
+ )
79
98
  response.raise_for_status()
80
- return response.json()
99
+ result = response.json()
100
+ return result.get("data", result) if isinstance(result, dict) else result
81
101
 
82
102
  def close(self):
83
103
  """Close the HTTP client."""
@@ -111,6 +131,16 @@ def query_sellers(
111
131
  "created_at, updated_at, status"
112
132
  ),
113
133
  ),
134
+ skip: int = typer.Option(
135
+ 0,
136
+ "--skip",
137
+ help="Number of records to skip (for pagination)",
138
+ ),
139
+ limit: int = typer.Option(
140
+ 100,
141
+ "--limit",
142
+ help="Maximum number of records to return (default: 100)",
143
+ ),
114
144
  ):
115
145
  """Query all sellers from the backend.
116
146
 
@@ -121,6 +151,12 @@ def query_sellers(
121
151
  # Show only specific fields
122
152
  unitysvc_services query sellers --fields id,name,contact_email
123
153
 
154
+ # Retrieve more than 100 records
155
+ unitysvc_services query sellers --limit 500
156
+
157
+ # Pagination: skip first 100, get next 100
158
+ unitysvc_services query sellers --skip 100 --limit 100
159
+
124
160
  # Show all available fields
125
161
  unitysvc_services query sellers --fields \\
126
162
  id,name,display_name,seller_type,contact_email,homepage,created_at,updated_at
@@ -158,7 +194,7 @@ def query_sellers(
158
194
 
159
195
  try:
160
196
  with ServiceDataQuery() as query:
161
- sellers = query.list_sellers()
197
+ sellers = query.list_sellers(skip=skip, limit=limit)
162
198
 
163
199
  if format == "json":
164
200
  # For JSON, filter fields if not all are requested
@@ -255,6 +291,16 @@ def query_providers(
255
291
  "homepage, description, status, created_at, updated_at"
256
292
  ),
257
293
  ),
294
+ skip: int = typer.Option(
295
+ 0,
296
+ "--skip",
297
+ help="Number of records to skip (for pagination)",
298
+ ),
299
+ limit: int = typer.Option(
300
+ 100,
301
+ "--limit",
302
+ help="Maximum number of records to return (default: 100)",
303
+ ),
258
304
  ):
259
305
  """Query all providers from the backend.
260
306
 
@@ -262,6 +308,12 @@ def query_providers(
262
308
  # Use default fields
263
309
  unitysvc_services query providers
264
310
 
311
+ # Retrieve more than 100 records
312
+ unitysvc_services query providers --limit 500
313
+
314
+ # Pagination: skip first 100, get next 100
315
+ unitysvc_services query providers --skip 100 --limit 100
316
+
265
317
  # Show only specific fields
266
318
  unitysvc_services query providers --fields id,name,contact_email
267
319
 
@@ -298,7 +350,7 @@ def query_providers(
298
350
 
299
351
  try:
300
352
  with ServiceDataQuery() as query:
301
- providers = query.list_providers()
353
+ providers = query.list_providers(skip=skip, limit=limit)
302
354
 
303
355
  if format == "json":
304
356
  # For JSON, filter fields if not all are requested
@@ -389,6 +441,16 @@ def query_offerings(
389
441
  "service_type, provider_name"
390
442
  ),
391
443
  ),
444
+ skip: int = typer.Option(
445
+ 0,
446
+ "--skip",
447
+ help="Number of records to skip (for pagination)",
448
+ ),
449
+ limit: int = typer.Option(
450
+ 100,
451
+ "--limit",
452
+ help="Maximum number of records to return (default: 100)",
453
+ ),
392
454
  ):
393
455
  """Query all service offerings from UnitySVC backend.
394
456
 
@@ -399,6 +461,12 @@ def query_offerings(
399
461
  # Show only specific fields
400
462
  unitysvc_services query offerings --fields id,service_name,status
401
463
 
464
+ # Retrieve more than 100 records
465
+ unitysvc_services query offerings --limit 500
466
+
467
+ # Pagination: skip first 100, get next 100
468
+ unitysvc_services query offerings --skip 100 --limit 100
469
+
402
470
  # Show all available fields
403
471
  unitysvc_services query offerings --fields \\
404
472
  id,service_name,service_type,provider_name,status,price,definition_id,provider_id
@@ -430,7 +498,7 @@ def query_offerings(
430
498
 
431
499
  try:
432
500
  with ServiceDataQuery() as query:
433
- offerings = query.list_service_offerings()
501
+ offerings = query.list_service_offerings(skip=skip, limit=limit)
434
502
 
435
503
  if format == "json":
436
504
  # For JSON, filter fields if not all are requested
@@ -489,11 +557,21 @@ def query_listings(
489
557
  "--fields",
490
558
  help=(
491
559
  "Comma-separated list of fields to display. Available fields: "
492
- "id, offering_id, seller_id, status, created_at, updated_at, "
560
+ "id, offering_id, offering_status, seller_id, status, created_at, updated_at, "
493
561
  "parameters_schema, parameters_ui_schema, tags, service_name, "
494
562
  "service_type, provider_name, seller_name, listing_type"
495
563
  ),
496
564
  ),
565
+ skip: int = typer.Option(
566
+ 0,
567
+ "--skip",
568
+ help="Number of records to skip (for pagination)",
569
+ ),
570
+ limit: int = typer.Option(
571
+ 100,
572
+ "--limit",
573
+ help="Maximum number of records to return (default: 100)",
574
+ ),
497
575
  ):
498
576
  """Query all service listings from UnitySVC backend.
499
577
 
@@ -504,6 +582,12 @@ def query_listings(
504
582
  # Show only specific fields
505
583
  unitysvc_services query listings --fields id,service_name,status
506
584
 
585
+ # Retrieve more than 100 records
586
+ unitysvc_services query listings --limit 500
587
+
588
+ # Pagination: skip first 100, get next 100
589
+ unitysvc_services query listings --skip 100 --limit 100
590
+
507
591
  # Show all available fields
508
592
  unitysvc_services query listings --fields \\
509
593
  id,service_name,service_type,seller_name,listing_type,status,provider_name
@@ -515,6 +599,7 @@ def query_listings(
515
599
  allowed_fields = {
516
600
  "id",
517
601
  "offering_id",
602
+ "offering_status",
518
603
  "seller_id",
519
604
  "status",
520
605
  "created_at",
@@ -541,7 +626,7 @@ def query_listings(
541
626
 
542
627
  try:
543
628
  with ServiceDataQuery() as query:
544
- listings = query.list_service_listings()
629
+ listings = query.list_service_listings(skip=skip, limit=limit)
545
630
 
546
631
  if format == "json":
547
632
  # For JSON, filter fields if not all are requested
@@ -583,232 +668,3 @@ def query_listings(
583
668
  except Exception as e:
584
669
  console.print(f"[red]✗[/red] Failed to query service listings: {e}", style="bold red")
585
670
  raise typer.Exit(code=1)
586
-
587
-
588
- @app.command("interfaces")
589
- def query_interfaces(
590
- format: str = typer.Option(
591
- "table",
592
- "--format",
593
- "-f",
594
- help="Output format: table, json",
595
- ),
596
- fields: str = typer.Option(
597
- "id,name,context_type,access_method,is_active",
598
- "--fields",
599
- help=(
600
- "Comma-separated list of fields to display. Available fields: "
601
- "id, entity_id, context_type, access_method, api_endpoint, name, "
602
- "description, request_transformer, rate_limits, constraint, "
603
- "is_active, is_primary, sort_order, created_at, updated_at"
604
- ),
605
- ),
606
- ):
607
- """Query all access interfaces from UnitySVC backend (private endpoint).
608
-
609
- Examples:
610
- # Use default fields
611
- unitysvc_services query interfaces
612
-
613
- # Show only specific fields
614
- unitysvc_services query interfaces --fields id,name,access_method
615
-
616
- # Show all available fields
617
- unitysvc_services query interfaces --fields \\
618
- id,name,context_type,access_method,entity_id,is_active,is_primary
619
- """
620
- # Parse fields list
621
- field_list = [f.strip() for f in fields.split(",")]
622
-
623
- # Define allowed fields from AccessInterfacePublic model
624
- allowed_fields = {
625
- "id",
626
- "entity_id",
627
- "context_type",
628
- "access_method",
629
- "api_endpoint",
630
- "name",
631
- "description",
632
- "request_transformer",
633
- "rate_limits",
634
- "constraint",
635
- "is_active",
636
- "is_primary",
637
- "sort_order",
638
- "created_at",
639
- "updated_at",
640
- }
641
-
642
- # Validate fields
643
- invalid_fields = [f for f in field_list if f not in allowed_fields]
644
- if invalid_fields:
645
- console.print(
646
- f"[red]Error:[/red] Invalid field(s): {', '.join(invalid_fields)}",
647
- style="bold red",
648
- )
649
- console.print(f"[yellow]Available fields:[/yellow] {', '.join(sorted(allowed_fields))}")
650
- raise typer.Exit(code=1)
651
-
652
- try:
653
- with ServiceDataQuery() as query:
654
- data = query.list_access_interfaces()
655
-
656
- if format == "json":
657
- # For JSON, filter fields if not all are requested
658
- interfaces = data.get("data", [])
659
- if set(field_list) != allowed_fields:
660
- filtered_interfaces = [
661
- {k: v for k, v in interface.items() if k in field_list} for interface in interfaces
662
- ]
663
- console.print(json.dumps({"data": filtered_interfaces, "count": data.get("count", 0)}, indent=2))
664
- else:
665
- console.print(json.dumps(data, indent=2))
666
- else:
667
- interfaces = data.get("data", [])
668
- if not interfaces:
669
- console.print("[yellow]No access interfaces found.[/yellow]")
670
- else:
671
- table = Table(title="Access Interfaces")
672
-
673
- # Add columns dynamically based on selected fields
674
- for field in field_list:
675
- # Capitalize and format field names for display
676
- column_name = field.replace("_", " ").title()
677
- table.add_column(column_name)
678
-
679
- # Add rows
680
- for interface in interfaces:
681
- row = []
682
- for field in field_list:
683
- value = interface.get(field)
684
- if value is None:
685
- row.append("N/A")
686
- elif isinstance(value, dict | list):
687
- row.append(str(value)[:50]) # Truncate complex types
688
- else:
689
- row.append(str(value))
690
- table.add_row(*row)
691
-
692
- console.print(table)
693
- console.print(f"\n[green]Total:[/green] {data.get('count', 0)} access interface(s)")
694
- except ValueError as e:
695
- console.print(f"[red]✗[/red] {e}", style="bold red")
696
- raise typer.Exit(code=1)
697
- except Exception as e:
698
- console.print(f"[red]✗[/red] Failed to query access interfaces: {e}", style="bold red")
699
- raise typer.Exit(code=1)
700
-
701
-
702
- @app.command("documents")
703
- def query_documents(
704
- format: str = typer.Option(
705
- "table",
706
- "--format",
707
- "-f",
708
- help="Output format: table, json",
709
- ),
710
- fields: str = typer.Option(
711
- "id,title,category,mime_type,context_type,is_public",
712
- "--fields",
713
- help=(
714
- "Comma-separated list of fields to display. Available fields: "
715
- "id, entity_id, context_type, title, description, mime_type, "
716
- "version, category, meta, sort_order, is_active, is_public, "
717
- "external_url, object_key, filename, filesize, created_at, updated_at"
718
- ),
719
- ),
720
- ):
721
- """Query all documents from UnitySVC backend (private endpoint).
722
-
723
- Examples:
724
- # Use default fields
725
- unitysvc_services query documents
726
-
727
- # Show only specific fields
728
- unitysvc_services query documents --fields id,title,category
729
-
730
- # Show all available fields
731
- unitysvc_services query documents --fields \\
732
- id,title,category,mime_type,context_type,is_public,filename,filesize
733
- """
734
- # Parse fields list
735
- field_list = [f.strip() for f in fields.split(",")]
736
-
737
- # Define allowed fields from DocumentPublic model
738
- allowed_fields = {
739
- "id",
740
- "entity_id",
741
- "context_type",
742
- "title",
743
- "description",
744
- "mime_type",
745
- "version",
746
- "category",
747
- "meta",
748
- "sort_order",
749
- "is_active",
750
- "is_public",
751
- "external_url",
752
- "object_key",
753
- "filename",
754
- "filesize",
755
- "created_at",
756
- "updated_at",
757
- }
758
-
759
- # Validate fields
760
- invalid_fields = [f for f in field_list if f not in allowed_fields]
761
- if invalid_fields:
762
- console.print(
763
- f"[red]Error:[/red] Invalid field(s): {', '.join(invalid_fields)}",
764
- style="bold red",
765
- )
766
- console.print(f"[yellow]Available fields:[/yellow] {', '.join(sorted(allowed_fields))}")
767
- raise typer.Exit(code=1)
768
-
769
- try:
770
- with ServiceDataQuery() as query:
771
- data = query.list_documents()
772
-
773
- if format == "json":
774
- # For JSON, filter fields if not all are requested
775
- documents = data.get("data", [])
776
- if set(field_list) != allowed_fields:
777
- filtered_documents = [{k: v for k, v in doc.items() if k in field_list} for doc in documents]
778
- console.print(json.dumps({"data": filtered_documents, "count": data.get("count", 0)}, indent=2))
779
- else:
780
- console.print(json.dumps(data, indent=2))
781
- else:
782
- documents = data.get("data", [])
783
- if not documents:
784
- console.print("[yellow]No documents found.[/yellow]")
785
- else:
786
- table = Table(title="Documents")
787
-
788
- # Add columns dynamically based on selected fields
789
- for field in field_list:
790
- # Capitalize and format field names for display
791
- column_name = field.replace("_", " ").title()
792
- table.add_column(column_name)
793
-
794
- # Add rows
795
- for doc in documents:
796
- row = []
797
- for field in field_list:
798
- value = doc.get(field)
799
- if value is None:
800
- row.append("N/A")
801
- elif isinstance(value, dict | list):
802
- row.append(str(value)[:50]) # Truncate complex types
803
- else:
804
- row.append(str(value))
805
- table.add_row(*row)
806
-
807
- console.print(table)
808
- console.print(f"\n[green]Total:[/green] {data.get('count', 0)} document(s)")
809
- except ValueError as e:
810
- console.print(f"[red]✗[/red] {e}", style="bold red")
811
- raise typer.Exit(code=1)
812
- except Exception as e:
813
- console.print(f"[red]✗[/red] Failed to query documents: {e}", style="bold red")
814
- raise typer.Exit(code=1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitysvc-services
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: SDK for digital service providers on UnitySVC
5
5
  Author-email: Bo Peng <bo.peng@unitysvc.com>
6
6
  Maintainer-email: Bo Peng <bo.peng@unitysvc.com>
@@ -87,8 +87,11 @@ unitysvc_services publish
87
87
  # Or publish specific types only
88
88
  unitysvc_services publish providers
89
89
 
90
- # Verify
90
+ # Verify with default fields
91
91
  unitysvc_services query offerings
92
+
93
+ # Query with custom fields
94
+ unitysvc_services query providers --fields id,name,contact_email
92
95
  ```
93
96
 
94
97
  ## Key Features
@@ -3,9 +3,9 @@ unitysvc_services/cli.py,sha256=OK0IZyAckxP15jRWU_W49hl3t7XcNRtd8BoDMyRKqNM,682
3
3
  unitysvc_services/format_data.py,sha256=Jl9Vj3fRX852fHSUa5DzO-oiFQwuQHC3WMCDNIlo1Lc,5460
4
4
  unitysvc_services/list.py,sha256=QDp9BByaoeFeJxXJN9RQ-jU99mH9Guq9ampfXCbpZmI,7033
5
5
  unitysvc_services/populate.py,sha256=zkcjIy8BWuQSO7JwiRNHKgGoxQvc3ujluUQdYixdBvY,6626
6
- unitysvc_services/publisher.py,sha256=qEkui7T7DQr_CfXzDvWMuTJrPpKbcldfwPi6Ocv-ILA,35367
6
+ unitysvc_services/publisher.py,sha256=hRqbN9rXeFLgfsjK9ViFQjPNbYR3trcqanPUecjcSjM,35567
7
7
  unitysvc_services/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- unitysvc_services/query.py,sha256=p-fG1iosAuzdHYnaYmEe2zdHQVZzWk2LhWmu5B4sAdA,30203
8
+ unitysvc_services/query.py,sha256=yfCIMTjQwantf9LxktpRcE05qrBIKQMkanpb9JYYsi0,24228
9
9
  unitysvc_services/scaffold.py,sha256=Y73IX8vskImxSvxDgR0mvEFuAMYnBKfttn3bjcz3jmQ,40331
10
10
  unitysvc_services/update.py,sha256=K9swocTUnqqiSgARo6GmuzTzUySSpyqqPPW4xF7ZU-g,9659
11
11
  unitysvc_services/utils.py,sha256=GN0gkVTU8fOx2G0EbqnWmx8w9eFsoPfRprPjwCyPYkE,11371
@@ -16,9 +16,9 @@ unitysvc_services/models/listing_v1.py,sha256=CC_GXoN3NHJFzEQ3cBHDQpdUaBNpvLdHAR
16
16
  unitysvc_services/models/provider_v1.py,sha256=cYK5kDDmzQEnLvUC2C8dKz-ZXci7hVn3fjNrJkaSr10,2050
17
17
  unitysvc_services/models/seller_v1.py,sha256=SU4rqYAh9hE4EeUrEkqaVrLwusenV7MotPF77VcsRKo,3263
18
18
  unitysvc_services/models/service_v1.py,sha256=u16zqM3khrJoTw_v0d45tMcKXjko5k_v3w8xwUtZ6nM,2720
19
- unitysvc_services-0.2.3.dist-info/licenses/LICENSE,sha256=_p8V6A8OMPu2HIztn3O01v0-urZFwk0Dd3Yk_PTIlL8,1065
20
- unitysvc_services-0.2.3.dist-info/METADATA,sha256=MqWBQxgCpX6dpqmS1K95RXr-2yhvS8YyHDqfE0mZiYU,6515
21
- unitysvc_services-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- unitysvc_services-0.2.3.dist-info/entry_points.txt,sha256=-vodnbPmo7QQmFu8jdG6sCyGRVM727w9Nhwp4Vwau_k,64
23
- unitysvc_services-0.2.3.dist-info/top_level.txt,sha256=GIotQj-Ro2ruR7eupM1r58PWqIHTAq647ORL7E2kneo,18
24
- unitysvc_services-0.2.3.dist-info/RECORD,,
19
+ unitysvc_services-0.2.4.dist-info/licenses/LICENSE,sha256=_p8V6A8OMPu2HIztn3O01v0-urZFwk0Dd3Yk_PTIlL8,1065
20
+ unitysvc_services-0.2.4.dist-info/METADATA,sha256=FmrqIeMrb31pjtn7u0RyBz-tn-acfTo0omSIqLLwdNg,6628
21
+ unitysvc_services-0.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ unitysvc_services-0.2.4.dist-info/entry_points.txt,sha256=-vodnbPmo7QQmFu8jdG6sCyGRVM727w9Nhwp4Vwau_k,64
23
+ unitysvc_services-0.2.4.dist-info/top_level.txt,sha256=GIotQj-Ro2ruR7eupM1r58PWqIHTAq647ORL7E2kneo,18
24
+ unitysvc_services-0.2.4.dist-info/RECORD,,