unitysvc-services 0.2.3__tar.gz → 0.2.5__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.
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/PKG-INFO +5 -2
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/README.md +4 -1
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/cli-reference.md +61 -14
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/data-structure.md +10 -2
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/file-schemas.md +11 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/getting-started.md +8 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/workflows.md +9 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/pyproject.toml +1 -1
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/listing_v1.py +5 -6
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/publisher.py +9 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/query.py +102 -258
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/PKG-INFO +5 -2
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/CONTRIBUTING.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/HISTORY.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/LICENSE +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/MANIFEST.in +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/api-reference.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/contributing.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/development.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/index.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/installation.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/docs/usage.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/setup.cfg +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/__init__.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/cli.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/format_data.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/list.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/__init__.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/base.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/provider_v1.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/seller_v1.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/service_v1.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/populate.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/py.typed +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/scaffold.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/update.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/utils.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/validator.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/SOURCES.txt +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/dependency_links.txt +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/entry_points.txt +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/requires.txt +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/top_level.txt +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/__init__.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/README.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/README.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/provider.toml +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/services/service1/code-example.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/services/service1/service.toml +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/services/service1/svcreseller.toml +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/terms-of-service.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/README.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/provider.json +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/services/service2/code-example.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/services/service2/service.json +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/services/service2/svcreseller.json +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/terms-of-service.md +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/seller.json +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/test_utils.py +0 -0
- {unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/test_validator.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: unitysvc-services
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.5
|
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
|
@@ -45,8 +45,11 @@ unitysvc_services publish
|
|
45
45
|
# Or publish specific types only
|
46
46
|
unitysvc_services publish providers
|
47
47
|
|
48
|
-
# Verify
|
48
|
+
# Verify with default fields
|
49
49
|
unitysvc_services query offerings
|
50
|
+
|
51
|
+
# Query with custom fields
|
52
|
+
unitysvc_services query providers --fields id,name,contact_email
|
50
53
|
```
|
51
54
|
|
52
55
|
## Key Features
|
@@ -157,6 +157,8 @@ unitysvc_services list listings [DATA_DIR]
|
|
157
157
|
|
158
158
|
Query data from UnitySVC backend API.
|
159
159
|
|
160
|
+
All query commands support field selection to customize output columns and pagination options.
|
161
|
+
|
160
162
|
### query providers
|
161
163
|
|
162
164
|
```bash
|
@@ -166,11 +168,13 @@ unitysvc_services query providers [OPTIONS]
|
|
166
168
|
**Options:**
|
167
169
|
|
168
170
|
- `--format, -f {table|json}` - Output format (default: table)
|
171
|
+
- `--fields FIELDS` - Comma-separated list of fields to display (default: id,name,display_name,status)
|
172
|
+
- `--skip SKIP` - Number of records to skip for pagination (default: 0)
|
173
|
+
- `--limit LIMIT` - Maximum number of records to return (default: 100)
|
169
174
|
|
170
|
-
**
|
175
|
+
**Available Fields:**
|
171
176
|
|
172
|
-
|
173
|
-
- `UNITYSVC_API_KEY` - API key for authentication
|
177
|
+
id, name, display_name, contact_email, secondary_contact_email, homepage, description, status, created_at, updated_at
|
174
178
|
|
175
179
|
### query sellers
|
176
180
|
|
@@ -178,42 +182,85 @@ unitysvc_services query providers [OPTIONS]
|
|
178
182
|
unitysvc_services query sellers [OPTIONS]
|
179
183
|
```
|
180
184
|
|
185
|
+
**Options:**
|
186
|
+
|
187
|
+
- `--format, -f {table|json}` - Output format (default: table)
|
188
|
+
- `--fields FIELDS` - Comma-separated list of fields to display (default: id,name,display_name,seller_type)
|
189
|
+
- `--skip SKIP` - Number of records to skip for pagination (default: 0)
|
190
|
+
- `--limit LIMIT` - Maximum number of records to return (default: 100)
|
191
|
+
|
192
|
+
**Available Fields:**
|
193
|
+
|
194
|
+
id, name, display_name, seller_type, contact_email, secondary_contact_email, homepage, description, business_registration, tax_id, account_manager_id, created_at, updated_at, status
|
195
|
+
|
181
196
|
### query offerings
|
182
197
|
|
183
198
|
```bash
|
184
199
|
unitysvc_services query offerings [OPTIONS]
|
185
200
|
```
|
186
201
|
|
202
|
+
**Options:**
|
203
|
+
|
204
|
+
- `--format, -f {table|json}` - Output format (default: table)
|
205
|
+
- `--fields FIELDS` - Comma-separated list of fields to display (default: id,service_name,service_type,provider_name,status)
|
206
|
+
- `--skip SKIP` - Number of records to skip for pagination (default: 0)
|
207
|
+
- `--limit LIMIT` - Maximum number of records to return (default: 100)
|
208
|
+
|
209
|
+
**Available Fields:**
|
210
|
+
|
211
|
+
id, definition_id, provider_id, status, price, service_name, service_type, provider_name
|
212
|
+
|
187
213
|
### query listings
|
188
214
|
|
189
215
|
```bash
|
190
216
|
unitysvc_services query listings [OPTIONS]
|
191
217
|
```
|
192
218
|
|
193
|
-
|
219
|
+
**Options:**
|
194
220
|
|
195
|
-
|
196
|
-
|
197
|
-
|
221
|
+
- `--format, -f {table|json}` - Output format (default: table)
|
222
|
+
- `--fields FIELDS` - Comma-separated list of fields to display (default: id,service_name,service_type,seller_name,listing_type,status)
|
223
|
+
- `--skip SKIP` - Number of records to skip for pagination (default: 0)
|
224
|
+
- `--limit LIMIT` - Maximum number of records to return (default: 100)
|
198
225
|
|
199
|
-
|
226
|
+
**Available Fields:**
|
200
227
|
|
201
|
-
|
228
|
+
id, offering_id, seller_id, status, created_at, updated_at, parameters_schema, parameters_ui_schema, tags, service_name, service_type, provider_name, seller_name, listing_type
|
202
229
|
|
203
|
-
|
204
|
-
unitysvc_services query documents [OPTIONS]
|
205
|
-
```
|
230
|
+
**Required Environment Variables:**
|
206
231
|
|
207
|
-
|
232
|
+
- `UNITYSVC_BASE_URL` - Backend API URL
|
233
|
+
- `UNITYSVC_API_KEY` - API key for authentication
|
208
234
|
|
209
235
|
**Examples:**
|
210
236
|
|
211
237
|
```bash
|
212
|
-
# Table output
|
238
|
+
# Table output with default fields
|
213
239
|
unitysvc_services query providers
|
214
240
|
|
215
241
|
# JSON output
|
216
242
|
unitysvc_services query offerings --format json
|
243
|
+
|
244
|
+
# Custom fields - show only specific columns
|
245
|
+
unitysvc_services query providers --fields id,name,contact_email
|
246
|
+
|
247
|
+
# Show all available fields for sellers
|
248
|
+
unitysvc_services query sellers --fields id,name,display_name,seller_type,contact_email,homepage,created_at,updated_at
|
249
|
+
|
250
|
+
# Custom fields for listings
|
251
|
+
unitysvc_services query listings --fields id,service_name,listing_type,status
|
252
|
+
|
253
|
+
# Retrieve more than 100 records
|
254
|
+
unitysvc_services query providers --limit 500
|
255
|
+
|
256
|
+
# Pagination: get second page of 100 records
|
257
|
+
unitysvc_services query offerings --skip 100 --limit 100
|
258
|
+
|
259
|
+
# Large dataset retrieval
|
260
|
+
unitysvc_services query listings --limit 1000
|
261
|
+
|
262
|
+
# Combine pagination with custom fields
|
263
|
+
unitysvc_services query sellers --skip 50 --limit 50 --fields id,name,contact_email
|
217
264
|
```
|
218
265
|
|
219
266
|
## publish - Publish to Backend
|
@@ -80,6 +80,13 @@ data/
|
|
80
80
|
- Location: `${provider_name}/services/${service_name}/listing-*.json`
|
81
81
|
- Both offerings and listings are defined in the same service directory under the provider
|
82
82
|
|
83
|
+
#### Multiple Listings Per Service
|
84
|
+
When a single service offering has multiple listings (e.g., different pricing tiers, different marketplaces), the filename becomes significant:
|
85
|
+
|
86
|
+
- **Filename as identifier**: If the `name` field is not provided in the listing file, the filename (without extension) is automatically used as the listing name
|
87
|
+
- **Example**: `listing-premium.json`, `listing-basic.json`, `listing-enterprise.json` for different tiers
|
88
|
+
- **Best practice**: Use descriptive filenames that indicate the listing variant, or explicitly set the `name` field in each file
|
89
|
+
|
83
90
|
### 7. External Files (Documentation, Code Examples, etc.)
|
84
91
|
- External files like code examples, documentation, images can be placed anywhere in the directory structure
|
85
92
|
- They are referenced by **relative paths** from the referencing file
|
@@ -181,10 +188,11 @@ data/
|
|
181
188
|
│ └── services/
|
182
189
|
│ ├── gpt-4/ # Service: "gpt-4"
|
183
190
|
│ │ ├── service.json # name = "gpt-4"
|
184
|
-
│ │
|
191
|
+
│ │ ├── listing-premium.json # name = "listing-premium" (or defaults to filename)
|
192
|
+
│ │ └── listing-basic.json # name = "listing-basic" (multiple listings for one service)
|
185
193
|
│ └── gpt-3.5-turbo/ # Service: "gpt-3.5-turbo"
|
186
194
|
│ ├── service.json # name = "gpt-3.5-turbo"
|
187
|
-
│ └── listing-svcreseller.json
|
195
|
+
│ └── listing-svcreseller.json # Single listing
|
188
196
|
└── anthropic/ # Provider: "anthropic"
|
189
197
|
├── provider.json # name = "anthropic"
|
190
198
|
└── services/
|
@@ -194,6 +194,7 @@ Listing files define how a seller presents/sells a service (downstream/marketpla
|
|
194
194
|
| Field | Type | Description |
|
195
195
|
|-------|------|-------------|
|
196
196
|
| `schema` | string | Must be `"listing_v1"` |
|
197
|
+
| `name` | string | Listing identifier (defaults to filename without extension if not provided) |
|
197
198
|
| `seller_name` | string | Seller identifier (references seller file) |
|
198
199
|
| `listing_status` | string | Listing status (see Status Values) |
|
199
200
|
|
@@ -209,6 +210,15 @@ Listing files define how a seller presents/sells a service (downstream/marketpla
|
|
209
210
|
| `documents` | array | Documentation files |
|
210
211
|
| `tags` | array | Search/filter tags |
|
211
212
|
|
213
|
+
### Listing Name Field
|
214
|
+
|
215
|
+
The `name` field identifies the listing and is especially important when multiple listings exist for a single service offering:
|
216
|
+
|
217
|
+
- **Automatic naming**: If the `name` field is not provided, the SDK automatically uses the filename (without extension) as the listing name
|
218
|
+
- **Multiple listings**: When you have multiple listings for one service (e.g., different tiers or marketplaces), use descriptive filenames
|
219
|
+
- **Example**: A file named `listing-premium.json` will automatically get `name = "listing-premium"` if the field is omitted
|
220
|
+
- **Best practice**: Use explicit `name` fields for clarity, or use descriptive filenames that will serve as meaningful listing identifiers
|
221
|
+
|
212
222
|
### listing_status Values
|
213
223
|
|
214
224
|
- `unknown` - Status not yet determined
|
@@ -223,6 +233,7 @@ Listing files define how a seller presents/sells a service (downstream/marketpla
|
|
223
233
|
|
224
234
|
```toml
|
225
235
|
schema = "listing_v1"
|
236
|
+
name = "listing-premium"
|
226
237
|
seller_name = "svcreseller"
|
227
238
|
service_name = "gpt-4"
|
228
239
|
listing_status = "in_service"
|
@@ -147,9 +147,17 @@ unitysvc_services publish sellers
|
|
147
147
|
### Step 9: Verify Your Published Data
|
148
148
|
|
149
149
|
```bash
|
150
|
+
# Query with default fields
|
150
151
|
unitysvc_services query providers
|
151
152
|
unitysvc_services query offerings
|
152
153
|
unitysvc_services query listings
|
154
|
+
|
155
|
+
# Query with custom fields - show only specific columns
|
156
|
+
unitysvc_services query providers --fields id,name,contact_email
|
157
|
+
unitysvc_services query listings --fields id,service_name,listing_type,status
|
158
|
+
|
159
|
+
# Query as JSON for programmatic use
|
160
|
+
unitysvc_services query offerings --format json
|
153
161
|
```
|
154
162
|
|
155
163
|
## Next Steps
|
@@ -102,9 +102,14 @@ unitysvc_services publish --data-path ./data
|
|
102
102
|
#### 7. Verify on Platform
|
103
103
|
|
104
104
|
```bash
|
105
|
+
# Query with default fields
|
105
106
|
unitysvc_services query providers
|
106
107
|
unitysvc_services query offerings
|
107
108
|
unitysvc_services query listings
|
109
|
+
|
110
|
+
# Or query with custom fields for focused output
|
111
|
+
unitysvc_services query providers --fields id,name,status
|
112
|
+
unitysvc_services query listings --fields id,service_name,listing_type,status
|
108
113
|
```
|
109
114
|
|
110
115
|
### Version Control Integration
|
@@ -269,7 +274,11 @@ unitysvc_services publish
|
|
269
274
|
#### 8. Verify
|
270
275
|
|
271
276
|
```bash
|
277
|
+
# Query with default fields
|
272
278
|
unitysvc_services query offerings
|
279
|
+
|
280
|
+
# Or query with custom fields
|
281
|
+
unitysvc_services query offerings --fields id,service_name,status
|
273
282
|
```
|
274
283
|
|
275
284
|
### Automation with CI/CD
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/listing_v1.py
RENAMED
@@ -3,12 +3,7 @@ from typing import Any
|
|
3
3
|
|
4
4
|
from pydantic import BaseModel, ConfigDict, Field
|
5
5
|
|
6
|
-
from unitysvc_services.models.base import
|
7
|
-
AccessInterface,
|
8
|
-
Document,
|
9
|
-
ListingStatusEnum,
|
10
|
-
Pricing,
|
11
|
-
)
|
6
|
+
from unitysvc_services.models.base import AccessInterface, Document, ListingStatusEnum, Pricing
|
12
7
|
|
13
8
|
|
14
9
|
class ListingV1(BaseModel):
|
@@ -32,6 +27,10 @@ class ListingV1(BaseModel):
|
|
32
27
|
|
33
28
|
seller_name: str | None = Field(default=None, description="Name of the seller offering this service listing")
|
34
29
|
|
30
|
+
name: str = Field(
|
31
|
+
max_length=255,
|
32
|
+
description="Name identifier for the service listing, default to filename",
|
33
|
+
)
|
35
34
|
# unique name for each provider, usually following upstream naming convention
|
36
35
|
# status of the service, public, deprecated etc
|
37
36
|
listing_status: ListingStatusEnum = Field(
|
@@ -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
|
@@ -154,6 +159,10 @@ class ServiceDataPublisher:
|
|
154
159
|
# Load the listing data file
|
155
160
|
data = self.load_data_file(data_file)
|
156
161
|
|
162
|
+
# If name is not provided, use filename (without extension)
|
163
|
+
if "name" not in data or not data.get("name"):
|
164
|
+
data["name"] = data_file.stem
|
165
|
+
|
157
166
|
# Resolve file references and include content
|
158
167
|
base_path = data_file.parent
|
159
168
|
data_with_content = self.resolve_file_references(data, base_path)
|
@@ -39,45 +39,53 @@ 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
|
-
|
50
|
-
|
51
|
-
|
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(f"{self.base_url}/publish/offerings", params={"skip": skip, "limit": limit})
|
52
50
|
response.raise_for_status()
|
53
51
|
result = response.json()
|
54
52
|
return result.get("data", result) if isinstance(result, dict) else result
|
55
53
|
|
56
|
-
def
|
57
|
-
"""List all
|
58
|
-
|
54
|
+
def list_service_listings(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
|
55
|
+
"""List all service listings from the backend.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
skip: Number of records to skip (for pagination)
|
59
|
+
limit: Maximum number of records to return
|
60
|
+
"""
|
61
|
+
response = self.client.get(f"{self.base_url}/publish/listings", params={"skip": skip, "limit": limit})
|
59
62
|
response.raise_for_status()
|
60
63
|
result = response.json()
|
61
64
|
return result.get("data", result) if isinstance(result, dict) else result
|
62
65
|
|
63
|
-
def
|
64
|
-
"""List all
|
65
|
-
|
66
|
+
def list_providers(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
|
67
|
+
"""List all providers from the backend.
|
68
|
+
|
69
|
+
Args:
|
70
|
+
skip: Number of records to skip (for pagination)
|
71
|
+
limit: Maximum number of records to return
|
72
|
+
"""
|
73
|
+
response = self.client.get(f"{self.base_url}/publish/providers", params={"skip": skip, "limit": limit})
|
66
74
|
response.raise_for_status()
|
67
75
|
result = response.json()
|
68
76
|
return result.get("data", result) if isinstance(result, dict) else result
|
69
77
|
|
70
|
-
def
|
71
|
-
"""List all
|
72
|
-
response = self.client.get(f"{self.base_url}/private/interfaces")
|
73
|
-
response.raise_for_status()
|
74
|
-
return response.json()
|
78
|
+
def list_sellers(self, skip: int = 0, limit: int = 100) -> list[dict[str, Any]]:
|
79
|
+
"""List all sellers from the backend.
|
75
80
|
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
Args:
|
82
|
+
skip: Number of records to skip (for pagination)
|
83
|
+
limit: Maximum number of records to return
|
84
|
+
"""
|
85
|
+
response = self.client.get(f"{self.base_url}/publish/sellers", params={"skip": skip, "limit": limit})
|
79
86
|
response.raise_for_status()
|
80
|
-
|
87
|
+
result = response.json()
|
88
|
+
return result.get("data", result) if isinstance(result, dict) else result
|
81
89
|
|
82
90
|
def close(self):
|
83
91
|
"""Close the HTTP client."""
|
@@ -111,6 +119,16 @@ def query_sellers(
|
|
111
119
|
"created_at, updated_at, status"
|
112
120
|
),
|
113
121
|
),
|
122
|
+
skip: int = typer.Option(
|
123
|
+
0,
|
124
|
+
"--skip",
|
125
|
+
help="Number of records to skip (for pagination)",
|
126
|
+
),
|
127
|
+
limit: int = typer.Option(
|
128
|
+
100,
|
129
|
+
"--limit",
|
130
|
+
help="Maximum number of records to return (default: 100)",
|
131
|
+
),
|
114
132
|
):
|
115
133
|
"""Query all sellers from the backend.
|
116
134
|
|
@@ -121,6 +139,12 @@ def query_sellers(
|
|
121
139
|
# Show only specific fields
|
122
140
|
unitysvc_services query sellers --fields id,name,contact_email
|
123
141
|
|
142
|
+
# Retrieve more than 100 records
|
143
|
+
unitysvc_services query sellers --limit 500
|
144
|
+
|
145
|
+
# Pagination: skip first 100, get next 100
|
146
|
+
unitysvc_services query sellers --skip 100 --limit 100
|
147
|
+
|
124
148
|
# Show all available fields
|
125
149
|
unitysvc_services query sellers --fields \\
|
126
150
|
id,name,display_name,seller_type,contact_email,homepage,created_at,updated_at
|
@@ -158,7 +182,7 @@ def query_sellers(
|
|
158
182
|
|
159
183
|
try:
|
160
184
|
with ServiceDataQuery() as query:
|
161
|
-
sellers = query.list_sellers()
|
185
|
+
sellers = query.list_sellers(skip=skip, limit=limit)
|
162
186
|
|
163
187
|
if format == "json":
|
164
188
|
# For JSON, filter fields if not all are requested
|
@@ -255,6 +279,16 @@ def query_providers(
|
|
255
279
|
"homepage, description, status, created_at, updated_at"
|
256
280
|
),
|
257
281
|
),
|
282
|
+
skip: int = typer.Option(
|
283
|
+
0,
|
284
|
+
"--skip",
|
285
|
+
help="Number of records to skip (for pagination)",
|
286
|
+
),
|
287
|
+
limit: int = typer.Option(
|
288
|
+
100,
|
289
|
+
"--limit",
|
290
|
+
help="Maximum number of records to return (default: 100)",
|
291
|
+
),
|
258
292
|
):
|
259
293
|
"""Query all providers from the backend.
|
260
294
|
|
@@ -262,6 +296,12 @@ def query_providers(
|
|
262
296
|
# Use default fields
|
263
297
|
unitysvc_services query providers
|
264
298
|
|
299
|
+
# Retrieve more than 100 records
|
300
|
+
unitysvc_services query providers --limit 500
|
301
|
+
|
302
|
+
# Pagination: skip first 100, get next 100
|
303
|
+
unitysvc_services query providers --skip 100 --limit 100
|
304
|
+
|
265
305
|
# Show only specific fields
|
266
306
|
unitysvc_services query providers --fields id,name,contact_email
|
267
307
|
|
@@ -298,7 +338,7 @@ def query_providers(
|
|
298
338
|
|
299
339
|
try:
|
300
340
|
with ServiceDataQuery() as query:
|
301
|
-
providers = query.list_providers()
|
341
|
+
providers = query.list_providers(skip=skip, limit=limit)
|
302
342
|
|
303
343
|
if format == "json":
|
304
344
|
# For JSON, filter fields if not all are requested
|
@@ -389,6 +429,16 @@ def query_offerings(
|
|
389
429
|
"service_type, provider_name"
|
390
430
|
),
|
391
431
|
),
|
432
|
+
skip: int = typer.Option(
|
433
|
+
0,
|
434
|
+
"--skip",
|
435
|
+
help="Number of records to skip (for pagination)",
|
436
|
+
),
|
437
|
+
limit: int = typer.Option(
|
438
|
+
100,
|
439
|
+
"--limit",
|
440
|
+
help="Maximum number of records to return (default: 100)",
|
441
|
+
),
|
392
442
|
):
|
393
443
|
"""Query all service offerings from UnitySVC backend.
|
394
444
|
|
@@ -399,6 +449,12 @@ def query_offerings(
|
|
399
449
|
# Show only specific fields
|
400
450
|
unitysvc_services query offerings --fields id,service_name,status
|
401
451
|
|
452
|
+
# Retrieve more than 100 records
|
453
|
+
unitysvc_services query offerings --limit 500
|
454
|
+
|
455
|
+
# Pagination: skip first 100, get next 100
|
456
|
+
unitysvc_services query offerings --skip 100 --limit 100
|
457
|
+
|
402
458
|
# Show all available fields
|
403
459
|
unitysvc_services query offerings --fields \\
|
404
460
|
id,service_name,service_type,provider_name,status,price,definition_id,provider_id
|
@@ -430,7 +486,7 @@ def query_offerings(
|
|
430
486
|
|
431
487
|
try:
|
432
488
|
with ServiceDataQuery() as query:
|
433
|
-
offerings = query.list_service_offerings()
|
489
|
+
offerings = query.list_service_offerings(skip=skip, limit=limit)
|
434
490
|
|
435
491
|
if format == "json":
|
436
492
|
# For JSON, filter fields if not all are requested
|
@@ -489,11 +545,21 @@ def query_listings(
|
|
489
545
|
"--fields",
|
490
546
|
help=(
|
491
547
|
"Comma-separated list of fields to display. Available fields: "
|
492
|
-
"id, offering_id, seller_id, status, created_at, updated_at, "
|
548
|
+
"id, offering_id, offering_status, seller_id, status, created_at, updated_at, "
|
493
549
|
"parameters_schema, parameters_ui_schema, tags, service_name, "
|
494
550
|
"service_type, provider_name, seller_name, listing_type"
|
495
551
|
),
|
496
552
|
),
|
553
|
+
skip: int = typer.Option(
|
554
|
+
0,
|
555
|
+
"--skip",
|
556
|
+
help="Number of records to skip (for pagination)",
|
557
|
+
),
|
558
|
+
limit: int = typer.Option(
|
559
|
+
100,
|
560
|
+
"--limit",
|
561
|
+
help="Maximum number of records to return (default: 100)",
|
562
|
+
),
|
497
563
|
):
|
498
564
|
"""Query all service listings from UnitySVC backend.
|
499
565
|
|
@@ -504,6 +570,12 @@ def query_listings(
|
|
504
570
|
# Show only specific fields
|
505
571
|
unitysvc_services query listings --fields id,service_name,status
|
506
572
|
|
573
|
+
# Retrieve more than 100 records
|
574
|
+
unitysvc_services query listings --limit 500
|
575
|
+
|
576
|
+
# Pagination: skip first 100, get next 100
|
577
|
+
unitysvc_services query listings --skip 100 --limit 100
|
578
|
+
|
507
579
|
# Show all available fields
|
508
580
|
unitysvc_services query listings --fields \\
|
509
581
|
id,service_name,service_type,seller_name,listing_type,status,provider_name
|
@@ -515,6 +587,7 @@ def query_listings(
|
|
515
587
|
allowed_fields = {
|
516
588
|
"id",
|
517
589
|
"offering_id",
|
590
|
+
"offering_status",
|
518
591
|
"seller_id",
|
519
592
|
"status",
|
520
593
|
"created_at",
|
@@ -541,7 +614,7 @@ def query_listings(
|
|
541
614
|
|
542
615
|
try:
|
543
616
|
with ServiceDataQuery() as query:
|
544
|
-
listings = query.list_service_listings()
|
617
|
+
listings = query.list_service_listings(skip=skip, limit=limit)
|
545
618
|
|
546
619
|
if format == "json":
|
547
620
|
# For JSON, filter fields if not all are requested
|
@@ -583,232 +656,3 @@ def query_listings(
|
|
583
656
|
except Exception as e:
|
584
657
|
console.print(f"[red]✗[/red] Failed to query service listings: {e}", style="bold red")
|
585
658
|
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
|
+
Version: 0.2.5
|
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
|
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
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/__init__.py
RENAMED
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/provider_v1.py
RENAMED
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/seller_v1.py
RENAMED
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services/models/service_v1.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/entry_points.txt
RENAMED
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/requires.txt
RENAMED
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/src/unitysvc_services.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/provider.toml
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider1/terms-of-service.md
RENAMED
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/provider.json
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unitysvc_services-0.2.3 → unitysvc_services-0.2.5}/tests/example_data/provider2/terms-of-service.md
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|