weave-python 0.27.0__tar.gz → 0.28.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.
- {weave_python-0.27.0 → weave_python-0.28.0}/.github/workflows/generate.yaml +8 -6
- {weave_python-0.27.0 → weave_python-0.28.0}/.gitignore +4 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/PKG-INFO +1 -1
- weave_python-0.28.0/tools/sqlcgen/README.md +106 -0
- weave_python-0.28.0/tools/sqlcgen/sqlcgen.py +147 -0
- weave_python-0.28.0/tools/sqlcgen/test_sqlcgen.py +280 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/uv.lock +8 -8
- weave_python-0.28.0/weave/weaveapi/llmx/v1/architecture_pb2.py +74 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/architecture_pb2.pyi +1323 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/capabilities_pb2.py +88 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/capabilities_pb2.pyi +1613 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/model_pb2.py +54 -0
- {weave_python-0.27.0/weave/weaveapi/modex → weave_python-0.28.0/weave/weaveapi/llmx}/v1/model_pb2.pyi +294 -189
- weave_python-0.28.0/weave/weaveapi/llmx/v1/pricing_pb2.py +54 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/pricing_pb2.pyi +597 -0
- weave_python-0.28.0/weave/weaveapi/llmx/v1/provider_pb2.py +38 -0
- {weave_python-0.27.0/weave/weaveapi/modex → weave_python-0.28.0/weave/weaveapi/llmx}/v1/provider_pb2.pyi +31 -19
- weave_python-0.28.0/weave/weaveapi/llmx/v1/service_pb2.py +180 -0
- {weave_python-0.27.0/weave/weaveapi/modex → weave_python-0.28.0/weave/weaveapi/llmx}/v1/service_pb2.pyi +174 -44
- {weave_python-0.27.0/weave/weaveapi/modex → weave_python-0.28.0/weave/weaveapi/llmx}/v1/service_pb2_grpc.py +103 -105
- weave_python-0.28.0/weave/weaveapi/llmx/v1/service_pb2_grpc.pyi +266 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/inline_data_pb2_grpc.py +2 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/inline_data_pb2_grpc.pyi +20 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/relationship_pb2_grpc.py +2 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/relationship_pb2_grpc.pyi +20 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/training_pb2_grpc.py +2 -0
- weave_python-0.28.0/weave/weaveapi/synthesize/v1/training_pb2_grpc.pyi +20 -0
- weave_python-0.27.0/sqlc.yaml +0 -19
- weave_python-0.27.0/weave/weaveapi/modex/v1/model_pb2.py +0 -58
- weave_python-0.27.0/weave/weaveapi/modex/v1/provider_pb2.py +0 -38
- weave_python-0.27.0/weave/weaveapi/modex/v1/service_pb2.py +0 -180
- weave_python-0.27.0/weave/weaveapi/modex/v1/service_pb2_grpc.pyi +0 -268
- weave_python-0.27.0/weave/weavesql/weavedb/models.py +0 -124
- weave_python-0.27.0/weave/weavesql/weavedb/queries.py +0 -306
- {weave_python-0.27.0 → weave_python-0.28.0}/.github/workflows/format-lint.yaml +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/.github/workflows/release.yaml +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/.python-version +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/buf.gen.yaml +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/pyproject.toml +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/renovate.json +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/service_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/session_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/session_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/session_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/session_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/usage_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/usage_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/usage_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/usage_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/user_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/user_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/user_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/auth/v1/user_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/configuration_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/configuration_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/configuration_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/configuration_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/generate_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/generate_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/generate_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/generate_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/generate/v1/service_pb2_grpc.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/mcpregistry/v1/server_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/llmx/v1/architecture_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/mcpregistry/v1/server_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/llmx/v1/architecture_pb2_grpc.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/modex/v1/model_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/llmx/v1/capabilities_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/modex/v1/model_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/llmx/v1/capabilities_pb2_grpc.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/modex/v1/provider_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/llmx/v1/model_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/modex/v1/provider_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/llmx/v1/model_pb2_grpc.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/payment/v1/invoice_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/llmx/v1/pricing_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/payment/v1/invoice_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/llmx/v1/pricing_pb2_grpc.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/payment/v1/subscription_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/llmx/v1/provider_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/payment/v1/subscription_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/llmx/v1/provider_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/server_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/server_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/auth_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/mcpregistry/v1/server_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/auth_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/mcpregistry/v1/server_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/mcpregistry/v1/service_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/invoice_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/invoice_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/nosql_database_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/payment/v1/invoice_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/nosql_database_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/payment/v1/invoice_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/service_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/subscription_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/payment/v1/subscription_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/object_store_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/payment/v1/subscription_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/object_store_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/payment/v1/subscription_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/auth_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/auth_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/sql_database_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/storage/v1/auth_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/sql_database_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/storage/v1/auth_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/nosql_database_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/nosql_database_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/storage_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/storage/v1/nosql_database_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/storage/v1/storage_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/storage/v1/nosql_database_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/object_store_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/object_store_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/dataset_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/storage/v1/object_store_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/dataset_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/storage/v1/object_store_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/service_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/sql_database_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/sql_database_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/inline_data_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/storage/v1/sql_database_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/inline_data_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/storage/v1/sql_database_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/storage_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/storage/v1/storage_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/relationship_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/storage/v1/storage_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/relationship_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/storage/v1/storage_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/dataset_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/dataset_pb2.pyi +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/training_pb2_grpc.py → /weave_python-0.28.0/weave/weaveapi/synthesize/v1/dataset_pb2_grpc.py +0 -0
- /weave_python-0.27.0/weave/weaveapi/synthesize/v1/training_pb2_grpc.pyi → /weave_python-0.28.0/weave/weaveapi/synthesize/v1/dataset_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/inline_data_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/inline_data_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/relationship_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/relationship_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/service_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/service_pb2.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/service_pb2_grpc.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/service_pb2_grpc.pyi +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/training_pb2.py +0 -0
- {weave_python-0.27.0 → weave_python-0.28.0}/weave/weaveapi/synthesize/v1/training_pb2.pyi +0 -0
|
@@ -53,7 +53,6 @@ jobs:
|
|
|
53
53
|
with:
|
|
54
54
|
cache-dependency-glob: "uv.lock"
|
|
55
55
|
enable-cache: true
|
|
56
|
-
pyproject-file: pyproject.toml
|
|
57
56
|
|
|
58
57
|
- name: Clear out gen previous api gen files
|
|
59
58
|
uses: weave-labs/ci/.github/actions/clean-generated-output-dir@main
|
|
@@ -65,15 +64,18 @@ jobs:
|
|
|
65
64
|
with:
|
|
66
65
|
working-directory: "weave/weavesql"
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
# disabled until sqlc supports copyfrom command for python
|
|
68
|
+
# https://github.com/sqlc-dev/sqlc-gen-python/pull/92
|
|
69
|
+
#
|
|
70
|
+
# - name: Generate sqlc configuration
|
|
71
|
+
# run: python3 tools/sqlcgen/sqlcgen.py --schema schema/weavesql
|
|
72
|
+
#
|
|
73
|
+
# - name: Generate sql schema
|
|
74
|
+
# run: sqlc generate
|
|
70
75
|
|
|
71
76
|
- name: Generate proto schema
|
|
72
77
|
run: buf generate
|
|
73
78
|
|
|
74
|
-
- name: Remove schema directory
|
|
75
|
-
run: rm -rf schema
|
|
76
|
-
|
|
77
79
|
- name: Run uv sync
|
|
78
80
|
run: uv sync
|
|
79
81
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# sqlcgen - SQLC Configuration Generator for Python
|
|
2
|
+
|
|
3
|
+
This tool automatically generates `sqlc.yaml` configuration for Python projects based on directories found in the
|
|
4
|
+
schema/weavesql directory.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
From the `weave-python` directory:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
python tools/sqlcgen/sqlcgen.py [options]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Options
|
|
15
|
+
|
|
16
|
+
- `--schema`: Path to schema directory containing database folders (default: "schema/weavesql")
|
|
17
|
+
- `--output`: Output file path for generated sqlc.yaml (default: "sqlc.yaml")
|
|
18
|
+
|
|
19
|
+
### Examples
|
|
20
|
+
|
|
21
|
+
Generate configuration:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python tools/sqlcgen/sqlcgen.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Use custom schema directory:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python tools/sqlcgen/sqlcgen.py --schema ../custom/schema --output custom-sqlc.yaml
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## How it Works
|
|
34
|
+
|
|
35
|
+
1. Scans the schema directory for subdirectories
|
|
36
|
+
2. For each subdirectory that contains both `migrations/` and `queries/` folders:
|
|
37
|
+
- Creates an SQLC configuration entry
|
|
38
|
+
- Sets the package name as `{dirname}db` (e.g., `weave` → `weavedb`)
|
|
39
|
+
- Sets the output directory as `weave/weavesql/{package}`
|
|
40
|
+
3. Generates a complete `sqlc.yaml` with all discovered databases
|
|
41
|
+
|
|
42
|
+
## Example Structure
|
|
43
|
+
|
|
44
|
+
Given this structure:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
schema/weavesql/
|
|
48
|
+
├── weave/
|
|
49
|
+
│ ├── migrations/
|
|
50
|
+
│ └── queries/
|
|
51
|
+
└── llmx/
|
|
52
|
+
├── migrations/
|
|
53
|
+
└── queries/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The tool will generate configurations for:
|
|
57
|
+
|
|
58
|
+
- `weave` → package `weavedb`, output to `weave/weavesql/weavedb`
|
|
59
|
+
- `llmx` → package `llmxdb`, output to `weave/weavesql/llmxdb`
|
|
60
|
+
|
|
61
|
+
## Generated Configuration
|
|
62
|
+
|
|
63
|
+
The tool generates sqlc.yaml with:
|
|
64
|
+
|
|
65
|
+
- The sqlc Python plugin (sqlc-gen-python_1.3.0)
|
|
66
|
+
- Both sync and async querier generation
|
|
67
|
+
- String enum support
|
|
68
|
+
- Query parameter limit of 2
|
|
69
|
+
|
|
70
|
+
## Integration with CI/CD
|
|
71
|
+
|
|
72
|
+
This tool is used in the GitHub Actions workflow to dynamically generate sqlc.yaml before running `sqlc generate`:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
- name: Generate sqlc configuration
|
|
76
|
+
run: python tools/sqlcgen/sqlcgen.py
|
|
77
|
+
|
|
78
|
+
- name: Generate sql schema
|
|
79
|
+
run: sqlc generate
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Using with Task
|
|
83
|
+
|
|
84
|
+
The project includes a Taskfile for common operations:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Generate sqlc configuration
|
|
88
|
+
task generate-sqlc-config
|
|
89
|
+
|
|
90
|
+
# Generate all code (sqlc config + sqlc generate)
|
|
91
|
+
task generate
|
|
92
|
+
|
|
93
|
+
# Run tests for sqlcgen
|
|
94
|
+
task test-sqlcgen
|
|
95
|
+
|
|
96
|
+
# Clean generated files
|
|
97
|
+
task clean
|
|
98
|
+
|
|
99
|
+
# Show all available tasks
|
|
100
|
+
task --list
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Requirements
|
|
104
|
+
|
|
105
|
+
- Python 3.7+
|
|
106
|
+
- No external dependencies (uses only Python standard library)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
sqlcgen - SQLC Configuration Generator for Python projects
|
|
4
|
+
|
|
5
|
+
This tool automatically generates sqlc.yaml configuration based on directories
|
|
6
|
+
found in the schema/weavesql directory.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import List, NamedTuple
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Database(NamedTuple):
|
|
16
|
+
"""Represents a database configuration."""
|
|
17
|
+
|
|
18
|
+
name: str # e.g., "weave", "llmx"
|
|
19
|
+
package: str # e.g., "weavedb", "llmxdb"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def find_databases(schema_dir: Path) -> List[Database]:
|
|
23
|
+
"""
|
|
24
|
+
Find all valid database directories in the schema directory.
|
|
25
|
+
|
|
26
|
+
A valid database directory must contain both 'migrations' and 'queries' subdirectories.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
schema_dir: Path to the schema directory containing database folders
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
List of Database objects sorted by name
|
|
33
|
+
"""
|
|
34
|
+
databases = []
|
|
35
|
+
|
|
36
|
+
if not schema_dir.exists():
|
|
37
|
+
print(f"Schema directory {schema_dir} does not exist", file=sys.stderr)
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
|
|
40
|
+
for entry in sorted(schema_dir.iterdir()):
|
|
41
|
+
if not entry.is_dir():
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
# Skip hidden directories
|
|
45
|
+
if entry.name.startswith("."):
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
# Check if migrations and queries directories exist
|
|
49
|
+
migrations_path = entry / "migrations"
|
|
50
|
+
queries_path = entry / "queries"
|
|
51
|
+
|
|
52
|
+
if not migrations_path.exists():
|
|
53
|
+
print(f"Skipping {entry.name}: migrations directory not found")
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
if not queries_path.exists():
|
|
57
|
+
print(f"Skipping {entry.name}: queries directory not found")
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
databases.append(Database(name=entry.name, package=f"{entry.name}db"))
|
|
61
|
+
|
|
62
|
+
return databases
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def generate_sqlc_config(
|
|
66
|
+
databases: List[Database], output_file: Path, schema_prefix: str = "schema/weavesql"
|
|
67
|
+
):
|
|
68
|
+
"""
|
|
69
|
+
Generate sqlc.yaml configuration for Python using the sqlc Python plugin.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
databases: List of Database objects
|
|
73
|
+
output_file: Path where the generated config should be written
|
|
74
|
+
schema_prefix: Prefix path to schema directory
|
|
75
|
+
"""
|
|
76
|
+
# Start with version and plugin configuration
|
|
77
|
+
config_lines = [
|
|
78
|
+
'version: "2"',
|
|
79
|
+
"plugins:",
|
|
80
|
+
" - name: py",
|
|
81
|
+
" wasm:",
|
|
82
|
+
" url: https://downloads.sqlc.dev/plugin/sqlc-gen-python_1.3.0.wasm",
|
|
83
|
+
" sha256: fbedae96b5ecae2380a70fb5b925fd4bff58a6cfb1f3140375d098fbab7b3a3c",
|
|
84
|
+
"sql:",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
for db in databases:
|
|
88
|
+
db_config = f''' - schema: "{schema_prefix}/{db.name}/migrations"
|
|
89
|
+
queries: "{schema_prefix}/{db.name}/queries"
|
|
90
|
+
engine: "postgresql"
|
|
91
|
+
codegen:
|
|
92
|
+
- out: "weave/weavesql/{db.package}"
|
|
93
|
+
plugin: "py"
|
|
94
|
+
options:
|
|
95
|
+
package: "weave.weavesql.{db.package}"
|
|
96
|
+
emit_async_querier: true
|
|
97
|
+
emit_str_enum: true
|
|
98
|
+
emit_sync_querier: true
|
|
99
|
+
query_parameter_limit: 2'''
|
|
100
|
+
config_lines.append(db_config)
|
|
101
|
+
|
|
102
|
+
# Write output file
|
|
103
|
+
with open(output_file, "w") as f:
|
|
104
|
+
f.write("\n".join(config_lines) + "\n")
|
|
105
|
+
|
|
106
|
+
print(f"Generated {output_file} with {len(databases)} database configurations")
|
|
107
|
+
for db in databases:
|
|
108
|
+
print(f" - {db.name} -> {db.package}")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def main():
|
|
112
|
+
"""Main entry point for the script."""
|
|
113
|
+
parser = argparse.ArgumentParser(
|
|
114
|
+
description="Generate sqlc.yaml configuration for Python projects from schema directories"
|
|
115
|
+
)
|
|
116
|
+
parser.add_argument(
|
|
117
|
+
"--schema",
|
|
118
|
+
type=str,
|
|
119
|
+
default="schema/weavesql",
|
|
120
|
+
help="Path to schema directory containing database folders (default: schema/weavesql)",
|
|
121
|
+
)
|
|
122
|
+
parser.add_argument(
|
|
123
|
+
"--output",
|
|
124
|
+
type=str,
|
|
125
|
+
default="sqlc.yaml",
|
|
126
|
+
help="Output file path for generated sqlc.yaml (default: sqlc.yaml)",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
args = parser.parse_args()
|
|
130
|
+
|
|
131
|
+
# Convert paths
|
|
132
|
+
schema_dir = Path(args.schema)
|
|
133
|
+
output_file = Path(args.output)
|
|
134
|
+
|
|
135
|
+
# Find databases
|
|
136
|
+
databases = find_databases(schema_dir)
|
|
137
|
+
|
|
138
|
+
if not databases:
|
|
139
|
+
print("No valid database directories found")
|
|
140
|
+
sys.exit(0)
|
|
141
|
+
|
|
142
|
+
# Generate configuration
|
|
143
|
+
generate_sqlc_config(databases, output_file, schema_prefix=args.schema)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
main()
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Tests for the sqlcgen tool.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import tempfile
|
|
7
|
+
import unittest
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from unittest.mock import patch
|
|
10
|
+
import sys
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
# Add the parent directory to the path so we can import sqlcgen
|
|
14
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
15
|
+
import sqlcgen
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestSQLCGen(unittest.TestCase):
|
|
19
|
+
"""Test cases for the sqlcgen tool."""
|
|
20
|
+
|
|
21
|
+
def setUp(self):
|
|
22
|
+
"""Set up test fixtures."""
|
|
23
|
+
# Create a temporary directory for testing
|
|
24
|
+
self.test_dir = tempfile.TemporaryDirectory()
|
|
25
|
+
self.test_path = Path(self.test_dir.name)
|
|
26
|
+
|
|
27
|
+
def tearDown(self):
|
|
28
|
+
"""Clean up test fixtures."""
|
|
29
|
+
self.test_dir.cleanup()
|
|
30
|
+
|
|
31
|
+
def create_test_schema(self, databases):
|
|
32
|
+
"""
|
|
33
|
+
Create a test schema directory structure.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
databases: List of database names to create
|
|
37
|
+
"""
|
|
38
|
+
schema_dir = self.test_path / "schema" / "weavesql"
|
|
39
|
+
for db_name in databases:
|
|
40
|
+
db_dir = schema_dir / db_name
|
|
41
|
+
(db_dir / "migrations").mkdir(parents=True)
|
|
42
|
+
(db_dir / "queries").mkdir(parents=True)
|
|
43
|
+
# Create dummy files
|
|
44
|
+
(db_dir / "migrations" / "001_init.sql").touch()
|
|
45
|
+
(db_dir / "queries" / "queries.sql").touch()
|
|
46
|
+
return schema_dir
|
|
47
|
+
|
|
48
|
+
def test_find_databases_with_valid_structure(self):
|
|
49
|
+
"""Test finding databases with valid directory structure."""
|
|
50
|
+
schema_dir = self.create_test_schema(["weave", "llmx", "modex"])
|
|
51
|
+
|
|
52
|
+
databases = sqlcgen.find_databases(schema_dir)
|
|
53
|
+
|
|
54
|
+
self.assertEqual(len(databases), 3)
|
|
55
|
+
self.assertEqual(databases[0].name, "llmx")
|
|
56
|
+
self.assertEqual(databases[0].package, "llmxdb")
|
|
57
|
+
self.assertEqual(databases[1].name, "modex")
|
|
58
|
+
self.assertEqual(databases[1].package, "modexdb")
|
|
59
|
+
self.assertEqual(databases[2].name, "weave")
|
|
60
|
+
self.assertEqual(databases[2].package, "weavedb")
|
|
61
|
+
|
|
62
|
+
def test_find_databases_skips_invalid_directories(self):
|
|
63
|
+
"""Test that directories without migrations or queries are skipped."""
|
|
64
|
+
schema_dir = self.create_test_schema(["valid"])
|
|
65
|
+
|
|
66
|
+
# Create invalid directories
|
|
67
|
+
(schema_dir / "no_migrations").mkdir()
|
|
68
|
+
(schema_dir / "no_migrations" / "queries").mkdir()
|
|
69
|
+
|
|
70
|
+
(schema_dir / "no_queries").mkdir()
|
|
71
|
+
(schema_dir / "no_queries" / "migrations").mkdir()
|
|
72
|
+
|
|
73
|
+
(schema_dir / ".hidden").mkdir()
|
|
74
|
+
(schema_dir / ".hidden" / "migrations").mkdir()
|
|
75
|
+
(schema_dir / ".hidden" / "queries").mkdir()
|
|
76
|
+
|
|
77
|
+
# Create a file (not a directory)
|
|
78
|
+
(schema_dir / "not_a_dir.txt").touch()
|
|
79
|
+
|
|
80
|
+
databases = sqlcgen.find_databases(schema_dir)
|
|
81
|
+
|
|
82
|
+
# Should only find the valid database
|
|
83
|
+
self.assertEqual(len(databases), 1)
|
|
84
|
+
self.assertEqual(databases[0].name, "valid")
|
|
85
|
+
|
|
86
|
+
def test_find_databases_with_nonexistent_directory(self):
|
|
87
|
+
"""Test that nonexistent directory causes exit."""
|
|
88
|
+
nonexistent = self.test_path / "nonexistent"
|
|
89
|
+
|
|
90
|
+
with self.assertRaises(SystemExit) as cm:
|
|
91
|
+
sqlcgen.find_databases(nonexistent)
|
|
92
|
+
|
|
93
|
+
self.assertEqual(cm.exception.code, 1)
|
|
94
|
+
|
|
95
|
+
def test_generate_sqlc_config(self):
|
|
96
|
+
"""Test generation of sqlc.yaml configuration."""
|
|
97
|
+
databases = [
|
|
98
|
+
sqlcgen.Database("weave", "weavedb"),
|
|
99
|
+
sqlcgen.Database("llmx", "llmxdb"),
|
|
100
|
+
]
|
|
101
|
+
output_file = self.test_path / "sqlc.yaml"
|
|
102
|
+
|
|
103
|
+
sqlcgen.generate_sqlc_config(databases, output_file)
|
|
104
|
+
|
|
105
|
+
# Check that file was created
|
|
106
|
+
self.assertTrue(output_file.exists())
|
|
107
|
+
|
|
108
|
+
# Read and verify content
|
|
109
|
+
content = output_file.read_text()
|
|
110
|
+
|
|
111
|
+
# Check for required elements
|
|
112
|
+
self.assertIn('version: "2"', content)
|
|
113
|
+
self.assertIn("plugins:", content)
|
|
114
|
+
self.assertIn("name: py", content)
|
|
115
|
+
self.assertIn("sqlc-gen-python_1.3.0.wasm", content)
|
|
116
|
+
|
|
117
|
+
# Check for database configurations
|
|
118
|
+
self.assertIn('schema: "schema/weavesql/weave/migrations"', content)
|
|
119
|
+
self.assertIn('queries: "schema/weavesql/weave/queries"', content)
|
|
120
|
+
self.assertIn('package: "weave.weavesql.weavedb"', content)
|
|
121
|
+
self.assertIn('out: "weave/weavesql/weavedb"', content)
|
|
122
|
+
|
|
123
|
+
self.assertIn('schema: "schema/weavesql/llmx/migrations"', content)
|
|
124
|
+
self.assertIn('queries: "schema/weavesql/llmx/queries"', content)
|
|
125
|
+
self.assertIn('package: "weave.weavesql.llmxdb"', content)
|
|
126
|
+
self.assertIn('out: "weave/weavesql/llmxdb"', content)
|
|
127
|
+
|
|
128
|
+
# Check for options
|
|
129
|
+
self.assertIn("emit_async_querier: true", content)
|
|
130
|
+
self.assertIn("emit_str_enum: true", content)
|
|
131
|
+
self.assertIn("emit_sync_querier: true", content)
|
|
132
|
+
self.assertIn("query_parameter_limit: 2", content)
|
|
133
|
+
|
|
134
|
+
def test_generate_sqlc_config_with_custom_schema_prefix(self):
|
|
135
|
+
"""Test generation with custom schema prefix."""
|
|
136
|
+
databases = [
|
|
137
|
+
sqlcgen.Database("test", "testdb"),
|
|
138
|
+
]
|
|
139
|
+
output_file = self.test_path / "sqlc.yaml"
|
|
140
|
+
|
|
141
|
+
sqlcgen.generate_sqlc_config(
|
|
142
|
+
databases, output_file, schema_prefix="custom/path"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
content = output_file.read_text()
|
|
146
|
+
self.assertIn('schema: "custom/path/test/migrations"', content)
|
|
147
|
+
self.assertIn('queries: "custom/path/test/queries"', content)
|
|
148
|
+
|
|
149
|
+
def test_main_integration(self):
|
|
150
|
+
"""Test the main function with real directory structure."""
|
|
151
|
+
schema_dir = self.create_test_schema(["db1", "db2"])
|
|
152
|
+
output_file = self.test_path / "output.yaml"
|
|
153
|
+
|
|
154
|
+
# Mock sys.argv
|
|
155
|
+
test_args = [
|
|
156
|
+
"sqlcgen.py",
|
|
157
|
+
"--schema",
|
|
158
|
+
str(schema_dir),
|
|
159
|
+
"--output",
|
|
160
|
+
str(output_file),
|
|
161
|
+
]
|
|
162
|
+
|
|
163
|
+
with patch.object(sys, "argv", test_args):
|
|
164
|
+
sqlcgen.main()
|
|
165
|
+
|
|
166
|
+
# Verify output file was created
|
|
167
|
+
self.assertTrue(output_file.exists())
|
|
168
|
+
|
|
169
|
+
# Verify content
|
|
170
|
+
content = output_file.read_text()
|
|
171
|
+
self.assertIn("db1", content)
|
|
172
|
+
self.assertIn("db2", content)
|
|
173
|
+
self.assertIn("db1db", content)
|
|
174
|
+
self.assertIn("db2db", content)
|
|
175
|
+
|
|
176
|
+
def test_main_with_no_databases(self):
|
|
177
|
+
"""Test main function when no valid databases are found."""
|
|
178
|
+
empty_dir = self.test_path / "empty"
|
|
179
|
+
empty_dir.mkdir()
|
|
180
|
+
output_file = self.test_path / "output.yaml"
|
|
181
|
+
|
|
182
|
+
test_args = [
|
|
183
|
+
"sqlcgen.py",
|
|
184
|
+
"--schema",
|
|
185
|
+
str(empty_dir),
|
|
186
|
+
"--output",
|
|
187
|
+
str(output_file),
|
|
188
|
+
]
|
|
189
|
+
|
|
190
|
+
with patch.object(sys, "argv", test_args):
|
|
191
|
+
with self.assertRaises(SystemExit) as cm:
|
|
192
|
+
sqlcgen.main()
|
|
193
|
+
|
|
194
|
+
# Should exit with code 0 (not an error, just no databases)
|
|
195
|
+
self.assertEqual(cm.exception.code, 0)
|
|
196
|
+
|
|
197
|
+
# Output file should not be created
|
|
198
|
+
self.assertFalse(output_file.exists())
|
|
199
|
+
|
|
200
|
+
def test_database_namedtuple(self):
|
|
201
|
+
"""Test the Database namedtuple."""
|
|
202
|
+
db = sqlcgen.Database("mydb", "mydbpkg")
|
|
203
|
+
self.assertEqual(db.name, "mydb")
|
|
204
|
+
self.assertEqual(db.package, "mydbpkg")
|
|
205
|
+
|
|
206
|
+
def test_sorting_of_databases(self):
|
|
207
|
+
"""Test that databases are sorted alphabetically."""
|
|
208
|
+
schema_dir = self.create_test_schema(["zebra", "alpha", "beta"])
|
|
209
|
+
|
|
210
|
+
databases = sqlcgen.find_databases(schema_dir)
|
|
211
|
+
|
|
212
|
+
# Should be sorted alphabetically
|
|
213
|
+
self.assertEqual(databases[0].name, "alpha")
|
|
214
|
+
self.assertEqual(databases[1].name, "beta")
|
|
215
|
+
self.assertEqual(databases[2].name, "zebra")
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TestSQLCGenOutput(unittest.TestCase):
|
|
219
|
+
"""Test the actual output format of generated configurations."""
|
|
220
|
+
|
|
221
|
+
def test_yaml_structure(self):
|
|
222
|
+
"""Test that the generated YAML has the correct structure."""
|
|
223
|
+
with tempfile.NamedTemporaryFile(mode="w+", suffix=".yaml", delete=False) as f:
|
|
224
|
+
databases = [
|
|
225
|
+
sqlcgen.Database("test", "testdb"),
|
|
226
|
+
]
|
|
227
|
+
output_file = Path(f.name)
|
|
228
|
+
|
|
229
|
+
sqlcgen.generate_sqlc_config(databases, output_file)
|
|
230
|
+
|
|
231
|
+
# Read and parse line by line to check structure
|
|
232
|
+
lines = output_file.read_text().splitlines()
|
|
233
|
+
|
|
234
|
+
# Check indentation and structure
|
|
235
|
+
self.assertEqual(lines[0], 'version: "2"')
|
|
236
|
+
self.assertEqual(lines[1], "plugins:")
|
|
237
|
+
self.assertTrue(lines[2].startswith(" - name:"))
|
|
238
|
+
|
|
239
|
+
# Find sql section
|
|
240
|
+
sql_line = next(i for i, line in enumerate(lines) if line == "sql:")
|
|
241
|
+
self.assertTrue(sql_line > 0)
|
|
242
|
+
|
|
243
|
+
# Check database configuration starts with proper indentation
|
|
244
|
+
db_start = sql_line + 1
|
|
245
|
+
self.assertTrue(lines[db_start].startswith(" - schema:"))
|
|
246
|
+
|
|
247
|
+
# Clean up
|
|
248
|
+
output_file.unlink()
|
|
249
|
+
|
|
250
|
+
def test_multiple_databases_formatting(self):
|
|
251
|
+
"""Test formatting with multiple databases."""
|
|
252
|
+
with tempfile.NamedTemporaryFile(mode="w+", suffix=".yaml", delete=False) as f:
|
|
253
|
+
databases = [
|
|
254
|
+
sqlcgen.Database("first", "firstdb"),
|
|
255
|
+
sqlcgen.Database("second", "seconddb"),
|
|
256
|
+
]
|
|
257
|
+
output_file = Path(f.name)
|
|
258
|
+
|
|
259
|
+
sqlcgen.generate_sqlc_config(databases, output_file)
|
|
260
|
+
|
|
261
|
+
content = output_file.read_text()
|
|
262
|
+
|
|
263
|
+
# Count database entries
|
|
264
|
+
schema_count = content.count(" - schema:")
|
|
265
|
+
self.assertEqual(schema_count, 2)
|
|
266
|
+
|
|
267
|
+
# Verify each database has all required fields
|
|
268
|
+
for db in databases:
|
|
269
|
+
self.assertIn(
|
|
270
|
+
f'schema: "schema/weavesql/{db.name}/migrations"', content
|
|
271
|
+
)
|
|
272
|
+
self.assertIn(f'queries: "schema/weavesql/{db.name}/queries"', content)
|
|
273
|
+
self.assertIn(f'package: "weave.weavesql.{db.package}"', content)
|
|
274
|
+
|
|
275
|
+
# Clean up
|
|
276
|
+
output_file.unlink()
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
if __name__ == "__main__":
|
|
280
|
+
unittest.main()
|
|
@@ -55,16 +55,16 @@ wheels = [
|
|
|
55
55
|
|
|
56
56
|
[[package]]
|
|
57
57
|
name = "protobuf"
|
|
58
|
-
version = "6.
|
|
58
|
+
version = "6.32.0"
|
|
59
59
|
source = { registry = "https://pypi.org/simple" }
|
|
60
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
60
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/df/fb4a8eeea482eca989b51cffd274aac2ee24e825f0bf3cbce5281fa1567b/protobuf-6.32.0.tar.gz", hash = "sha256:a81439049127067fc49ec1d36e25c6ee1d1a2b7be930675f919258d03c04e7d2", size = 440614, upload-time = "2025-08-14T21:21:25.015Z" }
|
|
61
61
|
wheels = [
|
|
62
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
63
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
64
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
65
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
66
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
67
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/33/18/df8c87da2e47f4f1dcc5153a81cd6bca4e429803f4069a299e236e4dd510/protobuf-6.32.0-cp310-abi3-win32.whl", hash = "sha256:84f9e3c1ff6fb0308dbacb0950d8aa90694b0d0ee68e75719cb044b7078fe741", size = 424409, upload-time = "2025-08-14T21:21:12.366Z" },
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/e1/59/0a820b7310f8139bd8d5a9388e6a38e1786d179d6f33998448609296c229/protobuf-6.32.0-cp310-abi3-win_amd64.whl", hash = "sha256:a8bdbb2f009cfc22a36d031f22a625a38b615b5e19e558a7b756b3279723e68e", size = 435735, upload-time = "2025-08-14T21:21:15.046Z" },
|
|
64
|
+
{ url = "https://files.pythonhosted.org/packages/cc/5b/0d421533c59c789e9c9894683efac582c06246bf24bb26b753b149bd88e4/protobuf-6.32.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d52691e5bee6c860fff9a1c86ad26a13afbeb4b168cd4445c922b7e2cf85aaf0", size = 426449, upload-time = "2025-08-14T21:21:16.687Z" },
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/ec/7b/607764ebe6c7a23dcee06e054fd1de3d5841b7648a90fd6def9a3bb58c5e/protobuf-6.32.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:501fe6372fd1c8ea2a30b4d9be8f87955a64d6be9c88a973996cef5ef6f0abf1", size = 322869, upload-time = "2025-08-14T21:21:18.282Z" },
|
|
66
|
+
{ url = "https://files.pythonhosted.org/packages/40/01/2e730bd1c25392fc32e3268e02446f0d77cb51a2c3a8486b1798e34d5805/protobuf-6.32.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:75a2aab2bd1aeb1f5dc7c5f33bcb11d82ea8c055c9becbb41c26a8c43fd7092c", size = 322009, upload-time = "2025-08-14T21:21:19.893Z" },
|
|
67
|
+
{ url = "https://files.pythonhosted.org/packages/9c/f2/80ffc4677aac1bc3519b26bc7f7f5de7fce0ee2f7e36e59e27d8beb32dd1/protobuf-6.32.0-py3-none-any.whl", hash = "sha256:ba377e5b67b908c8f3072a57b63e2c6a4cbd18aea4ed98d2584350dbf46f2783", size = 169287, upload-time = "2025-08-14T21:21:23.515Z" },
|
|
68
68
|
]
|
|
69
69
|
|
|
70
70
|
[[package]]
|