unitysvc-services 0.1.4__py3-none-any.whl → 0.1.5__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.
@@ -7,6 +7,7 @@ from pathlib import Path
7
7
  from typing import Any
8
8
 
9
9
  import tomli_w
10
+ from jinja2 import Template
10
11
 
11
12
 
12
13
  def load_data_file(file_path: Path) -> tuple[dict[str, Any], str]:
@@ -336,3 +337,55 @@ def convert_convenience_fields_to_documents(
336
337
  del data[terms_field]
337
338
 
338
339
  return data
340
+
341
+
342
+ def render_template_file(
343
+ file_path: Path,
344
+ listing: dict[str, Any] | None = None,
345
+ offering: dict[str, Any] | None = None,
346
+ provider: dict[str, Any] | None = None,
347
+ seller: dict[str, Any] | None = None,
348
+ ) -> tuple[str, str]:
349
+ """Render a Jinja2 template file and return content and new filename.
350
+
351
+ If the file is not a template (.j2 extension), returns the file content as-is
352
+ and the original filename.
353
+
354
+ Args:
355
+ file_path: Path to the file (may or may not be a .j2 template)
356
+ listing: Listing data for template rendering (optional)
357
+ offering: Offering data for template rendering (optional)
358
+ provider: Provider data for template rendering (optional)
359
+ seller: Seller data for template rendering (optional)
360
+
361
+ Returns:
362
+ Tuple of (rendered_content, new_filename_without_j2)
363
+
364
+ Raises:
365
+ Exception: If template rendering fails
366
+ """
367
+ # Read file content
368
+ with open(file_path, encoding="utf-8") as f:
369
+ file_content = f.read()
370
+
371
+ # Check if this is a Jinja2 template
372
+ is_template = file_path.name.endswith(".j2")
373
+
374
+ if is_template:
375
+ # Render the template
376
+ template = Template(file_content)
377
+ rendered_content = template.render(
378
+ listing=listing or {},
379
+ offering=offering or {},
380
+ provider=provider or {},
381
+ seller=seller or {},
382
+ )
383
+
384
+ # Strip .j2 from filename
385
+ # Example: test.py.j2 -> test.py
386
+ new_filename = file_path.name[:-3] # Remove last 3 characters (.j2)
387
+
388
+ return rendered_content, new_filename
389
+ else:
390
+ # Not a template - return as-is
391
+ return file_content, file_path.name
@@ -322,8 +322,15 @@ class DataValidator:
322
322
 
323
323
  return len(errors) == 0, errors
324
324
 
325
- def validate_md_file(self, file_path: Path) -> tuple[bool, list[str]]:
326
- """Validate a markdown file (basic existence check and Jinja2 syntax)."""
325
+ def validate_jinja2_file(self, file_path: Path) -> tuple[bool, list[str]]:
326
+ """Validate a file with Jinja2 template syntax.
327
+
328
+ This validates any file ending with .j2 extension, including:
329
+ - .md.j2 (Jinja2 markdown templates)
330
+ - .py.j2 (Jinja2 Python code example templates)
331
+ - .js.j2 (Jinja2 JavaScript code example templates)
332
+ - .sh.j2 (Jinja2 shell script templates)
333
+ """
327
334
  errors: list[str] = []
328
335
 
329
336
  try:
@@ -344,7 +351,7 @@ class DataValidator:
344
351
 
345
352
  return len(errors) == 0, errors
346
353
  except Exception as e:
347
- return False, [f"Failed to read markdown file: {e}"]
354
+ return False, [f"Failed to read template file: {e}"]
348
355
 
349
356
  def validate_seller_uniqueness(self) -> tuple[bool, list[str]]:
350
357
  """
@@ -502,13 +509,18 @@ class DataValidator:
502
509
  if any(part.startswith(".") for part in file_path.parts):
503
510
  continue
504
511
 
505
- if file_path.is_file() and file_path.suffix in [".json", ".toml", ".md"]:
512
+ # Check if file should be validated
513
+ # Only .j2 files (Jinja2 templates) are validated for Jinja2 syntax
514
+ is_template = file_path.name.endswith(".j2")
515
+ is_data_file = file_path.suffix in [".json", ".toml"]
516
+
517
+ if file_path.is_file() and (is_data_file or is_template):
506
518
  relative_path = file_path.relative_to(self.data_dir)
507
519
 
508
- if file_path.suffix in [".json", ".toml"]:
520
+ if is_data_file:
509
521
  is_valid, errors = self.validate_data_file(file_path)
510
- elif file_path.suffix == ".md":
511
- is_valid, errors = self.validate_md_file(file_path)
522
+ elif is_template:
523
+ is_valid, errors = self.validate_jinja2_file(file_path)
512
524
  else:
513
525
  continue
514
526
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitysvc-services
3
- Version: 0.1.4
3
+ Version: 0.1.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>
@@ -40,22 +40,23 @@ Requires-Dist: mkdocs-material; extra == "docs"
40
40
  Requires-Dist: mkdocs-autorefs; extra == "docs"
41
41
  Dynamic: license-file
42
42
 
43
- # UnitySVC Provider SDK
43
+ # UnitySVC Services SDK
44
44
 
45
45
  ![PyPI version](https://img.shields.io/pypi/v/unitysvc-services.svg)
46
46
  [![Documentation Status](https://readthedocs.org/projects/unitysvc-services/badge/?version=latest)](https://unitysvc-services.readthedocs.io/en/latest/?version=latest)
47
47
 
48
- Client library and CLI tools for digital service providers to interact with the UnitySVC platform.
48
+ Client library and CLI tools for sellers and providers of digital service to interact with the UnitySVC platform.
49
49
 
50
50
  **📚 [Full Documentation](https://unitysvc-services.readthedocs.io)** | **🚀 [Getting Started](https://unitysvc-services.readthedocs.io/en/latest/getting-started/)** | **📖 [CLI Reference](https://unitysvc-services.readthedocs.io/en/latest/cli-reference/)**
51
51
 
52
52
  ## Overview
53
53
 
54
- UnitySVC Provider SDK enables digital service providers to manage their service offerings through a **local-first, version-controlled workflow**:
54
+ UnitySVC Services SDK enables digital service sellers and providers to manage their service offerings through a **local-first, version-controlled workflow**:
55
55
 
56
56
  - **Define** service data using schema-validated files (JSON/TOML)
57
57
  - **Manage** everything locally in git-controlled directories
58
- - **Validate** data against schemas before publishing
58
+ - **Validate** data against schemas
59
+ - **Test** code examples using provider credentials
59
60
  - **Publish** to UnitySVC platform when ready
60
61
  - **Automate** with populate scripts for dynamic catalogs
61
62
 
@@ -67,31 +68,34 @@ pip install unitysvc-services
67
68
 
68
69
  Requires Python 3.11+
69
70
 
71
+ **CLI Alias:** The command `unitysvc_services` can also be invoked using the shorter alias `usvc`.
72
+
70
73
  ## Quick Example
71
74
 
72
75
  ```bash
73
- # Initialize provider and service
74
- unitysvc_services init provider my-provider
75
- unitysvc_services init offering my-service
76
- unitysvc_services init seller my-marketplace
76
+ # Initialize provider and service (using short alias 'usvc')
77
+ usvc init provider my-provider
78
+ usvc init offering my-service
79
+ usvc init seller my-marketplace
77
80
 
78
81
  # Validate and format
79
- unitysvc_services validate
80
- unitysvc_services format
82
+ usvc validate
83
+ usvc format
84
+
85
+ # Test code examples with upstream credentials
86
+ usvc test list --provider fireworks
87
+ usvc test run --provider fireworks --services "llama*"
88
+
89
+ # if you write a script to manage services
90
+ usvc populate
81
91
 
82
92
  # Publish to platform (publishes all: sellers, providers, offerings, listings)
83
93
  export UNITYSVC_BASE_URL="https://api.unitysvc.com/api/v1"
84
94
  export UNITYSVC_API_KEY="your-api-key"
85
- unitysvc_services publish
86
-
87
- # Or publish specific types only
88
- unitysvc_services publish providers
89
-
90
- # Verify with default fields
91
- unitysvc_services query offerings
95
+ usvc publish
92
96
 
93
- # Query with custom fields
94
- unitysvc_services query providers --fields id,name,contact_email
97
+ # Query unitysvc backend to verify data
98
+ usvc query providers --fields id,name,contact_email
95
99
  ```
96
100
 
97
101
  ## Key Features
@@ -108,13 +112,13 @@ unitysvc_services query providers --fields id,name,contact_email
108
112
  ### Manual Workflow (small catalogs)
109
113
 
110
114
  ```bash
111
- init → edit files → validate → format → publish → verify
115
+ init → edit files → validate → test → format → publish → verify
112
116
  ```
113
117
 
114
118
  ### Automated Workflow (large/dynamic catalogs)
115
119
 
116
120
  ```bash
117
- init provider → configure populate script → populate → validate → publish
121
+ init → configure populate script → populate → validate → publish
118
122
  ```
119
123
 
120
124
  See [Workflows Documentation](https://unitysvc-services.readthedocs.io/en/latest/workflows/) for details.
@@ -137,24 +141,27 @@ See [Data Structure Documentation](https://unitysvc-services.readthedocs.io/en/l
137
141
 
138
142
  ## CLI Commands
139
143
 
140
- | Command | Description |
141
- | ---------- | -------------------------------------- |
142
- | `init` | Initialize new data files from schemas |
143
- | `list` | List local data files |
144
- | `query` | Query backend API for published data |
145
- | `publish` | Publish data to backend |
146
- | `update` | Update local file fields |
147
- | `validate` | Validate data consistency |
148
- | `format` | Format data files |
149
- | `populate` | Execute provider populate scripts |
144
+ | Command | Description |
145
+ | ---------- | ------------------------------------------------ |
146
+ | `init` | Initialize new data files from schemas |
147
+ | `list` | List local data files |
148
+ | `query` | Query backend API for published data |
149
+ | `publish` | Publish data to backend |
150
+ | `update` | Update local file fields |
151
+ | `validate` | Validate data consistency |
152
+ | `format` | Format data files |
153
+ | `populate` | Execute provider populate scripts |
154
+ | `test` | Test code examples with upstream API credentials |
150
155
 
151
- Run `unitysvc_services --help` or see [CLI Reference](https://unitysvc-services.readthedocs.io/en/latest/cli-reference/) for complete documentation.
156
+ Run `usvc --help` or see [CLI Reference](https://unitysvc-services.readthedocs.io/en/latest/cli-reference/) for complete documentation.
152
157
 
153
158
  ## Documentation
154
159
 
155
160
  - **[Getting Started](https://unitysvc-services.readthedocs.io/en/latest/getting-started/)** - Installation and first steps
156
161
  - **[Data Structure](https://unitysvc-services.readthedocs.io/en/latest/data-structure/)** - File organization rules
157
162
  - **[Workflows](https://unitysvc-services.readthedocs.io/en/latest/workflows/)** - Manual and automated patterns
163
+ - **[Documenting Service Listings](https://unitysvc-services.readthedocs.io/en/latest/documenting-services/)** - Add documentation to services
164
+ - **[Creating Code Examples](https://unitysvc-services.readthedocs.io/en/latest/code-examples/)** - Develop and test code examples
158
165
  - **[CLI Reference](https://unitysvc-services.readthedocs.io/en/latest/cli-reference/)** - All commands and options
159
166
  - **[File Schemas](https://unitysvc-services.readthedocs.io/en/latest/file-schemas/)** - Schema specifications
160
167
  - **[Python API](https://unitysvc-services.readthedocs.io/en/latest/api-reference/)** - Programmatic usage
@@ -0,0 +1,26 @@
1
+ unitysvc_services/__init__.py,sha256=J6F3RlZCJUVjhZoprfbrYCxe3l9ynQQbGO7pf7FyqlM,110
2
+ unitysvc_services/api.py,sha256=d3xY4ElA4aCAl62xrwjZ6qIWUoYT-4Q8wJ8BJbyZzXI,11990
3
+ unitysvc_services/cli.py,sha256=omHzrWk8iZJUjZTE5KCmEK1wnRGGnQk_BNV-hKqucnA,725
4
+ unitysvc_services/format_data.py,sha256=Jl9Vj3fRX852fHSUa5DzO-oiFQwuQHC3WMCDNIlo1Lc,5460
5
+ unitysvc_services/list.py,sha256=QDp9BByaoeFeJxXJN9RQ-jU99mH9Guq9ampfXCbpZmI,7033
6
+ unitysvc_services/populate.py,sha256=jiqS2D3_widV6siPe3OBvw7ZdG9MuddEIOuTUCtMM5c,7605
7
+ unitysvc_services/publisher.py,sha256=mKlY7-zEP8dtldcO8DJtbXVrdOACZCYsu49yP2iSD4w,53855
8
+ unitysvc_services/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ unitysvc_services/query.py,sha256=q0_g5YAl9cPlHpW7k7Y6A-t4fQSdI-_4Jl6g2KgkEm0,24049
10
+ unitysvc_services/scaffold.py,sha256=Y73IX8vskImxSvxDgR0mvEFuAMYnBKfttn3bjcz3jmQ,40331
11
+ unitysvc_services/test.py,sha256=ZwWr2WCfzRBY39tuijK5P2v0VZ7PXwg3tFtJkTOsGrU,28341
12
+ unitysvc_services/update.py,sha256=K9swocTUnqqiSgARo6GmuzTzUySSpyqqPPW4xF7ZU-g,9659
13
+ unitysvc_services/utils.py,sha256=9htuxyzEjjbbAi704td9mOrtPzSOJzY46ALuup6bJW0,13093
14
+ unitysvc_services/validator.py,sha256=sasMpdDhoWZJZ-unrnDhaJfyxHSm3IgQjEdmPvXrFEE,29525
15
+ unitysvc_services/models/__init__.py,sha256=hJCc2KSZmIHlKWKE6GpLGdeVB6LIpyVUKiOKnwmKvCs,200
16
+ unitysvc_services/models/base.py,sha256=cSxOYs_YSrqkQLBKIGVZmK627MyMft7cDn0WnrQlzPM,18736
17
+ unitysvc_services/models/listing_v1.py,sha256=PPb9hIdWQp80AWKLxFXYBDcWXzNcDrO4v6rqt5_i2qo,3083
18
+ unitysvc_services/models/provider_v1.py,sha256=76EK1i0hVtdx_awb00-ZMtSj4Oc9Zp4xZ-DeXmG3iTY,2701
19
+ unitysvc_services/models/seller_v1.py,sha256=oll2ZZBPBDX8wslHrbsCKf_jIqHNte2VEj5RJ9bawR4,3520
20
+ unitysvc_services/models/service_v1.py,sha256=Xpk-K-95M1LRqYM8nNJcll8t-lsW9Xdi2_bVbYNs8-M,3019
21
+ unitysvc_services-0.1.5.dist-info/licenses/LICENSE,sha256=_p8V6A8OMPu2HIztn3O01v0-urZFwk0Dd3Yk_PTIlL8,1065
22
+ unitysvc_services-0.1.5.dist-info/METADATA,sha256=LZrIRYvKsl0t2mptoidJVkjOeNJFbx_a-QgUxEJLsgY,7234
23
+ unitysvc_services-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
+ unitysvc_services-0.1.5.dist-info/entry_points.txt,sha256=RBhVHKky3rsOly4jVa29c7UAw5ZwNNWnttmtzozr5O0,97
25
+ unitysvc_services-0.1.5.dist-info/top_level.txt,sha256=GIotQj-Ro2ruR7eupM1r58PWqIHTAq647ORL7E2kneo,18
26
+ unitysvc_services-0.1.5.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  unitysvc_services = unitysvc_services.cli:app
3
+ usvc = unitysvc_services.cli:app
@@ -1,25 +0,0 @@
1
- unitysvc_services/__init__.py,sha256=J6F3RlZCJUVjhZoprfbrYCxe3l9ynQQbGO7pf7FyqlM,110
2
- unitysvc_services/api.py,sha256=FKIid1gUJcEcN_4P9d5-SgmJfW73WHBg5wXsVHeqNHQ,9888
3
- unitysvc_services/cli.py,sha256=OK0IZyAckxP15jRWU_W49hl3t7XcNRtd8BoDMyRKqNM,682
4
- unitysvc_services/format_data.py,sha256=Jl9Vj3fRX852fHSUa5DzO-oiFQwuQHC3WMCDNIlo1Lc,5460
5
- unitysvc_services/list.py,sha256=QDp9BByaoeFeJxXJN9RQ-jU99mH9Guq9ampfXCbpZmI,7033
6
- unitysvc_services/populate.py,sha256=zkcjIy8BWuQSO7JwiRNHKgGoxQvc3ujluUQdYixdBvY,6626
7
- unitysvc_services/publisher.py,sha256=dkufYcuBJ0dDoTQJm7BMOug_Pr2RyXMVI8nvZjy-zdM,50420
8
- unitysvc_services/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- unitysvc_services/query.py,sha256=2Rn6gioAN3W6KIumVzCpSJXzhJLJUDLkDla_GVwNx9I,24793
10
- unitysvc_services/scaffold.py,sha256=Y73IX8vskImxSvxDgR0mvEFuAMYnBKfttn3bjcz3jmQ,40331
11
- unitysvc_services/update.py,sha256=K9swocTUnqqiSgARo6GmuzTzUySSpyqqPPW4xF7ZU-g,9659
12
- unitysvc_services/utils.py,sha256=GN0gkVTU8fOx2G0EbqnWmx8w9eFsoPfRprPjwCyPYkE,11371
13
- unitysvc_services/validator.py,sha256=VAII5mu_Jdyr96v4nwXzihsoAj7DJiXN6LjhL8lGGUo,29054
14
- unitysvc_services/models/__init__.py,sha256=hJCc2KSZmIHlKWKE6GpLGdeVB6LIpyVUKiOKnwmKvCs,200
15
- unitysvc_services/models/base.py,sha256=3FdlR-_tBOFC2JbVNFNQA4-D1Lhlo5UZQh1QDgKnS_I,18293
16
- unitysvc_services/models/listing_v1.py,sha256=PPb9hIdWQp80AWKLxFXYBDcWXzNcDrO4v6rqt5_i2qo,3083
17
- unitysvc_services/models/provider_v1.py,sha256=76EK1i0hVtdx_awb00-ZMtSj4Oc9Zp4xZ-DeXmG3iTY,2701
18
- unitysvc_services/models/seller_v1.py,sha256=oll2ZZBPBDX8wslHrbsCKf_jIqHNte2VEj5RJ9bawR4,3520
19
- unitysvc_services/models/service_v1.py,sha256=Xpk-K-95M1LRqYM8nNJcll8t-lsW9Xdi2_bVbYNs8-M,3019
20
- unitysvc_services-0.1.4.dist-info/licenses/LICENSE,sha256=_p8V6A8OMPu2HIztn3O01v0-urZFwk0Dd3Yk_PTIlL8,1065
21
- unitysvc_services-0.1.4.dist-info/METADATA,sha256=7LiJhVwEw0fL72bOWwX7kU5KjQ-PDmt23CD4FgEI8YU,6628
22
- unitysvc_services-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- unitysvc_services-0.1.4.dist-info/entry_points.txt,sha256=-vodnbPmo7QQmFu8jdG6sCyGRVM727w9Nhwp4Vwau_k,64
24
- unitysvc_services-0.1.4.dist-info/top_level.txt,sha256=GIotQj-Ro2ruR7eupM1r58PWqIHTAq647ORL7E2kneo,18
25
- unitysvc_services-0.1.4.dist-info/RECORD,,