cvec 1.5.2__tar.gz → 2.0.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.
- cvec-2.0.0/.agents/skills/pull-request/SKILL.md +12 -0
- cvec-2.0.0/.github/pull_request_template.md +19 -0
- {cvec-1.5.2 → cvec-2.0.0}/.github/workflows/ci.yml +8 -3
- cvec-2.0.0/.github/workflows/gha.yml +65 -0
- cvec-2.0.0/.github/workflows/pyproject-license-check.yml +56 -0
- cvec-1.5.2/README.md → cvec-2.0.0/PKG-INFO +22 -29
- cvec-1.5.2/PKG-INFO → cvec-2.0.0/README.md +0 -51
- {cvec-1.5.2 → cvec-2.0.0}/pyproject.toml +4 -4
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/cvec.py +12 -141
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/__init__.py +0 -10
- {cvec-1.5.2 → cvec-2.0.0}/tests/test_cvec.py +89 -0
- cvec-2.0.0/uv.lock +502 -0
- cvec-1.5.2/.claude/settings.local.json +0 -28
- cvec-1.5.2/.github/workflows/license-check-python.yml +0 -17
- cvec-1.5.2/.github/workflows/pyproject-license-check.yml +0 -17
- cvec-1.5.2/examples/add_agent_post_example.py +0 -52
- cvec-1.5.2/examples/get_modeling_metrics_data_arrow_example.py +0 -26
- cvec-1.5.2/examples/get_modeling_metrics_data_example.py +0 -33
- cvec-1.5.2/examples/get_modeling_metrics_example.py +0 -18
- cvec-1.5.2/src/cvec/models/agent_post.py +0 -44
- cvec-1.5.2/tests/test_modeling.py +0 -163
- cvec-1.5.2/uv.lock +0 -519
- {cvec-1.5.2 → cvec-2.0.0}/.claude/settings.json +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/.gitignore +0 -0
- /cvec-1.5.2/CLAUDE.md → /cvec-2.0.0/AGENTS.md +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/LICENSE +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/add_metric_data_arrow_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/add_metric_data_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/add_multiple_metrics_and_get_spans_for_them.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/eav_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/get_metric_arrow_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/get_metric_data_objects_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/get_metrics_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/get_spans_example.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/examples/show_eav_schema.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/scripts/csv_import.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/__init__.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/http_cache.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/eav_column.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/eav_filter.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/eav_table.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/metric.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/models/span.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/py.typed +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/utils/__init__.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/src/cvec/utils/arrow_converter.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/tests/__init__.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/tests/test_http_cache.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/tests/test_http_compression.py +0 -0
- {cvec-1.5.2 → cvec-2.0.0}/tests/test_token_refresh.py +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pull-request
|
|
3
|
+
description: Open a GitHub pull request using the project's template and including proof of work.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: Bash(cat .github/pull_request_template.md)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Use the following template for the PR description:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
!`cat .github/pull_request_template.md`
|
|
12
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!--- If this PR is closing or supporting a Linear ticket, please link it to the ticket. For example, include the ticket ID in the PR title in brackets, like "[PD1-999] Port to highcharts" -->
|
|
2
|
+
|
|
3
|
+
# Description
|
|
4
|
+
<!--- Describe your changes in detail -->
|
|
5
|
+
<!--- Why is this change required? What problem does it solve? -->
|
|
6
|
+
|
|
7
|
+
# Risks
|
|
8
|
+
|
|
9
|
+
<!--- The author should explain any risks posed by this change. -->
|
|
10
|
+
|
|
11
|
+
# Testing
|
|
12
|
+
|
|
13
|
+
## Author
|
|
14
|
+
|
|
15
|
+
<!--- The author should show proof of work, such as the output of a script calling the changed SDK against a CVector API. -->
|
|
16
|
+
|
|
17
|
+
## Reviewer
|
|
18
|
+
|
|
19
|
+
<!--- The author should add instructions for manual test steps that the reviewer should cover, and any special setup instructions. State 'No testing is required.' if no additional testing is required by the reviewer. -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: CI
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
@@ -9,6 +9,7 @@ on:
|
|
|
9
9
|
- src/**
|
|
10
10
|
- tests/**
|
|
11
11
|
push:
|
|
12
|
+
branches: [main]
|
|
12
13
|
paths:
|
|
13
14
|
- .github/workflows/ci.yml
|
|
14
15
|
- uv.lock
|
|
@@ -19,15 +20,19 @@ on:
|
|
|
19
20
|
jobs:
|
|
20
21
|
build:
|
|
21
22
|
runs-on: ubuntu-24.04
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
22
25
|
strategy:
|
|
23
26
|
matrix:
|
|
24
|
-
python-version: ["3.
|
|
27
|
+
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
|
|
25
28
|
|
|
26
29
|
steps:
|
|
27
30
|
- name: Checkout
|
|
28
31
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
32
|
+
with:
|
|
33
|
+
persist-credentials: false
|
|
29
34
|
|
|
30
|
-
- uses: CVector-Energy/python-test@
|
|
35
|
+
- uses: CVector-Energy/python-test@d223d8bc5764691c1c87f9609eddad67519d44bd # v2.0.1
|
|
31
36
|
with:
|
|
32
37
|
python-version: ${{ matrix.python-version }}
|
|
33
38
|
src-dirs: .
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: GitHub Actions Static Analysis
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- ".github/workflows/**"
|
|
8
|
+
- ".github/actions/**"
|
|
9
|
+
- "action.yml"
|
|
10
|
+
- "action.yaml"
|
|
11
|
+
- "**/action.yml"
|
|
12
|
+
- "**/action.yaml"
|
|
13
|
+
pull_request:
|
|
14
|
+
paths:
|
|
15
|
+
- ".github/workflows/**"
|
|
16
|
+
- ".github/actions/**"
|
|
17
|
+
- "action.yml"
|
|
18
|
+
- "action.yaml"
|
|
19
|
+
- "**/action.yml"
|
|
20
|
+
- "**/action.yaml"
|
|
21
|
+
|
|
22
|
+
permissions: {}
|
|
23
|
+
|
|
24
|
+
concurrency:
|
|
25
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
26
|
+
cancel-in-progress: true
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
zizmor:
|
|
30
|
+
name: zizmor
|
|
31
|
+
runs-on: ubuntu-24.04
|
|
32
|
+
permissions:
|
|
33
|
+
contents: read # check out the repository
|
|
34
|
+
actions: read # read workflow definitions for analysis
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout code
|
|
37
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
38
|
+
with:
|
|
39
|
+
persist-credentials: false
|
|
40
|
+
|
|
41
|
+
# zizmor's online audits (impostor-commit) resolve every `uses:` against the GitHub API. The default GITHUB_TOKEN only reaches this repository, so a reusable workflow or action pinned to a private CVector repository, such as CVector-Energy/.github, aborts the whole run with "missing or you have no access".
|
|
42
|
+
- name: Create GitHub App Token able to read the shared workflow repository
|
|
43
|
+
id: app
|
|
44
|
+
# A public repository cannot read the APP_PRIVATE_KEY organization secret, whose visibility is limited to private repositories, and a pull request from a fork receives no secrets at all. Neither case can reference a private workflow, so skip the token instead of failing the job.
|
|
45
|
+
if: ${{ github.event.repository.private && github.event.pull_request.head.repo.fork != true }}
|
|
46
|
+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
47
|
+
with:
|
|
48
|
+
client-id: ${{ vars.APP_ID }}
|
|
49
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
50
|
+
owner: ${{ github.repository_owner }}
|
|
51
|
+
repositories: |
|
|
52
|
+
.github
|
|
53
|
+
${{ github.event.repository.name }}
|
|
54
|
+
permission-contents: read
|
|
55
|
+
|
|
56
|
+
- name: Run zizmor
|
|
57
|
+
uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
|
|
58
|
+
with:
|
|
59
|
+
version: 1.25.2
|
|
60
|
+
advanced-security: false
|
|
61
|
+
annotations: true
|
|
62
|
+
token: ${{ steps.app.outputs.token || github.token }}
|
|
63
|
+
|
|
64
|
+
- name: Run actionlint
|
|
65
|
+
uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2.2.0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Python License Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
license-check:
|
|
12
|
+
runs-on: ubuntu-24.04
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
16
|
+
with:
|
|
17
|
+
persist-credentials: false
|
|
18
|
+
|
|
19
|
+
- name: Configure AWS credentials
|
|
20
|
+
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
|
|
21
|
+
with:
|
|
22
|
+
role-to-assume: arn:aws:iam::904233131484:role/CvecCodeArtifactInternalReadOnlyAccess
|
|
23
|
+
aws-region: us-east-1
|
|
24
|
+
|
|
25
|
+
- name: Configure CodeArtifact
|
|
26
|
+
run: |
|
|
27
|
+
CODEARTIFACT_AUTH_TOKEN=$(aws codeartifact get-authorization-token --domain cvector --domain-owner 904233131484 --region us-east-1 --query authorizationToken --output text)
|
|
28
|
+
echo "::add-mask::$CODEARTIFACT_AUTH_TOKEN"
|
|
29
|
+
echo "UV_INDEX_CVECTOR_INTERNAL_USERNAME=aws" >> "$GITHUB_ENV"
|
|
30
|
+
echo "UV_INDEX_CVECTOR_INTERNAL_PASSWORD=${CODEARTIFACT_AUTH_TOKEN}" >> "$GITHUB_ENV"
|
|
31
|
+
|
|
32
|
+
- name: Check Python licenses
|
|
33
|
+
uses: CVector-Energy/pyproject-license-check@fd767a3655df6df012e3f72bd6ad11d2bca99311 # v0.5.2
|
|
34
|
+
with:
|
|
35
|
+
app-id: ${{ vars.APP_ID }}
|
|
36
|
+
app-private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
37
|
+
# A project with no third-party runtime dependencies has no licenses to check, and LicenseCheck reports that as exit code 3, which the action fails on by default. Accepting it hides nothing: a dependency that cannot be resolved is still listed, with no license, and fails with exit code 1 — as does an incompatible license. Exit code 3 only ever means the project declares no dependencies at all.
|
|
38
|
+
allow-no-packages: true
|
|
39
|
+
# Source-aware license resolution (editable projects, private indexes, exact artifacts) is still unreleased, and the `allowed-license-references` and `license-overrides` inputs below depend on it. Move back to a tagged LicenseCheck release once the pull request lands.
|
|
40
|
+
licensecheck-version: git+https://github.com/FHPythonUtils/LicenseCheck.git@3d26581de610b08a44e697d7d5bb1ee6af6639a2 # LicenseCheck#151
|
|
41
|
+
allowed-license-references: LicenseRef-NVIDIA-Proprietary LicenseRef-NVIDIA-SOFTWARE-LICENSE
|
|
42
|
+
license-overrides: |
|
|
43
|
+
# Public Domain/BSD; the wheel excludes the GPL-covered Emacs mode.
|
|
44
|
+
"docutils==0.22.4" = "BSD-2-Clause"
|
|
45
|
+
# BSD-3-Clause; the wheel publishes the full license text without an SPDX identifier.
|
|
46
|
+
"us==3.2.0" = "BSD-3-Clause"
|
|
47
|
+
# NVIDIA CUDA Toolkit EULA; reviewed at 13.0.3.0.
|
|
48
|
+
"cuda-toolkit==13.0.3.0" = "LicenseRef-NVIDIA-Proprietary"
|
|
49
|
+
# NVIDIA CUDA Toolkit EULA; reviewed at 0.8.1.
|
|
50
|
+
"nvidia-cusparselt-cu13==0.8.1" = "LicenseRef-NVIDIA-Proprietary"
|
|
51
|
+
# PSF-2.0 (Python Software Foundation License); the wheel metadata has no SPDX identifier. Windows-only certbot dependency.
|
|
52
|
+
"pywin32==312" = "PSF-2.0"
|
|
53
|
+
# Apache-2.0; 1.7.5 publishes no CPython 3.14 wheel, so the audit resolves the private-index sdist and cannot read wheel metadata.
|
|
54
|
+
"cvxpy==1.7.5" = "Apache-2.0"
|
|
55
|
+
# Apache-2.0 OR BSD-3-Clause, matching dd-trace-py, which publishes this Datadog stub as a ddtrace 4.16 dependency; the wheel declares no license metadata.
|
|
56
|
+
"ddtrace-internal==0.1.0" = "Apache-2.0;; BSD-3-Clause"
|
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: cvec
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: SDK for CVector Energy
|
|
5
|
+
Author-email: CVector <support@cvector.energy>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Requires-Dist: brotli<2,>=1.2.0
|
|
19
|
+
Requires-Dist: pyarrow>=22.0.0
|
|
20
|
+
Requires-Dist: pydantic>=2.12.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
1
23
|
# CVec Client Library
|
|
2
24
|
|
|
3
25
|
The "cvec" package is the Python SDK for CVector Energy.
|
|
@@ -244,35 +266,6 @@ Add multiple metric data points to the database.
|
|
|
244
266
|
|
|
245
267
|
Return a list of metrics that had at least one transition in the given [`start_at`, `end_at`) interval. All metrics are returned if no `start_at` and `end_at` are given.
|
|
246
268
|
|
|
247
|
-
## `get_modeling_metrics(?start_at, ?end_at)`
|
|
248
|
-
|
|
249
|
-
Fetch modeling metrics from the modeling database. This method returns a list of available modeling metrics that had transitions in the specified time range.
|
|
250
|
-
|
|
251
|
-
- `start_at`: Optional start date for the query range (uses class default if not specified)
|
|
252
|
-
- `end_at`: Optional end date for the query range (uses class default if not specified)
|
|
253
|
-
|
|
254
|
-
Returns a list of `Metric` objects containing modeling metrics.
|
|
255
|
-
|
|
256
|
-
## `get_modeling_metrics_data(?names, ?start_at, ?end_at)`
|
|
257
|
-
|
|
258
|
-
Fetch actual data values from modeling metrics within a time range. This method returns the actual data points (values) for the specified modeling metrics, similar to `get_metric_data()` but for the modeling database.
|
|
259
|
-
|
|
260
|
-
- `names`: Optional list of modeling metric names to filter by
|
|
261
|
-
- `start_at`: Optional start time for the query (uses class default if not specified)
|
|
262
|
-
- `end_at`: Optional end time for the query (uses class default if not specified)
|
|
263
|
-
|
|
264
|
-
Returns a list of `MetricDataPoint` objects containing the actual data values.
|
|
265
|
-
|
|
266
|
-
## `get_modeling_metrics_data_arrow(?names, ?start_at, ?end_at)`
|
|
267
|
-
|
|
268
|
-
Fetch actual data values from modeling metrics within a time range in Apache Arrow format. This method returns the actual data points (values) for the specified modeling metrics in Arrow IPC format, which is more efficient for large datasets.
|
|
269
|
-
|
|
270
|
-
- `names`: Optional list of modeling metric names to filter by
|
|
271
|
-
- `start_at`: Optional start time for the query (uses class default if not specified)
|
|
272
|
-
- `end_at`: Optional end time for the query (uses class default if not specified)
|
|
273
|
-
|
|
274
|
-
Returns Arrow IPC format data that can be read using `pyarrow.ipc.open_file()`.
|
|
275
|
-
|
|
276
269
|
## `get_eav_tables()`
|
|
277
270
|
|
|
278
271
|
Get all EAV (Entity-Attribute-Value) tables for the tenant. EAV tables store semi-structured data where each row represents an entity with flexible attributes.
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: cvec
|
|
3
|
-
Version: 1.5.2
|
|
4
|
-
Summary: SDK for CVector Energy
|
|
5
|
-
Author-email: CVector <support@cvector.energy>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
License-File: LICENSE
|
|
8
|
-
Classifier: Intended Audience :: Developers
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
-
Requires-Python: >=3.10
|
|
18
|
-
Requires-Dist: brotli<2,>=1.2.0
|
|
19
|
-
Requires-Dist: pyarrow>=22.0.0
|
|
20
|
-
Requires-Dist: pydantic>=2.12.0
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
|
|
23
1
|
# CVec Client Library
|
|
24
2
|
|
|
25
3
|
The "cvec" package is the Python SDK for CVector Energy.
|
|
@@ -266,35 +244,6 @@ Add multiple metric data points to the database.
|
|
|
266
244
|
|
|
267
245
|
Return a list of metrics that had at least one transition in the given [`start_at`, `end_at`) interval. All metrics are returned if no `start_at` and `end_at` are given.
|
|
268
246
|
|
|
269
|
-
## `get_modeling_metrics(?start_at, ?end_at)`
|
|
270
|
-
|
|
271
|
-
Fetch modeling metrics from the modeling database. This method returns a list of available modeling metrics that had transitions in the specified time range.
|
|
272
|
-
|
|
273
|
-
- `start_at`: Optional start date for the query range (uses class default if not specified)
|
|
274
|
-
- `end_at`: Optional end date for the query range (uses class default if not specified)
|
|
275
|
-
|
|
276
|
-
Returns a list of `Metric` objects containing modeling metrics.
|
|
277
|
-
|
|
278
|
-
## `get_modeling_metrics_data(?names, ?start_at, ?end_at)`
|
|
279
|
-
|
|
280
|
-
Fetch actual data values from modeling metrics within a time range. This method returns the actual data points (values) for the specified modeling metrics, similar to `get_metric_data()` but for the modeling database.
|
|
281
|
-
|
|
282
|
-
- `names`: Optional list of modeling metric names to filter by
|
|
283
|
-
- `start_at`: Optional start time for the query (uses class default if not specified)
|
|
284
|
-
- `end_at`: Optional end time for the query (uses class default if not specified)
|
|
285
|
-
|
|
286
|
-
Returns a list of `MetricDataPoint` objects containing the actual data values.
|
|
287
|
-
|
|
288
|
-
## `get_modeling_metrics_data_arrow(?names, ?start_at, ?end_at)`
|
|
289
|
-
|
|
290
|
-
Fetch actual data values from modeling metrics within a time range in Apache Arrow format. This method returns the actual data points (values) for the specified modeling metrics in Arrow IPC format, which is more efficient for large datasets.
|
|
291
|
-
|
|
292
|
-
- `names`: Optional list of modeling metric names to filter by
|
|
293
|
-
- `start_at`: Optional start time for the query (uses class default if not specified)
|
|
294
|
-
- `end_at`: Optional end time for the query (uses class default if not specified)
|
|
295
|
-
|
|
296
|
-
Returns Arrow IPC format data that can be read using `pyarrow.ipc.open_file()`.
|
|
297
|
-
|
|
298
247
|
## `get_eav_tables()`
|
|
299
248
|
|
|
300
249
|
Get all EAV (Entity-Attribute-Value) tables for the tenant. EAV tables store semi-structured data where each row represents an entity with flexible attributes.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cvec"
|
|
3
|
-
version = "
|
|
3
|
+
version = "2.0.0"
|
|
4
4
|
description = "SDK for CVector Energy"
|
|
5
5
|
authors = [{ name = "CVector", email = "support@cvector.energy" }]
|
|
6
6
|
readme = "README.md"
|
|
7
|
-
requires-python = ">=3.
|
|
7
|
+
requires-python = ">=3.11"
|
|
8
8
|
dependencies = [
|
|
9
9
|
"pydantic>=2.12.0",
|
|
10
10
|
"pyarrow>=22.0.0",
|
|
@@ -17,16 +17,16 @@ classifiers = [
|
|
|
17
17
|
"Operating System :: OS Independent",
|
|
18
18
|
"Programming Language :: Python :: 3",
|
|
19
19
|
'Intended Audience :: Developers',
|
|
20
|
-
'Programming Language :: Python :: 3.10',
|
|
21
20
|
'Programming Language :: Python :: 3.11',
|
|
22
21
|
'Programming Language :: Python :: 3.12',
|
|
23
22
|
'Programming Language :: Python :: 3.13',
|
|
24
23
|
'Programming Language :: Python :: 3.14',
|
|
24
|
+
'Programming Language :: Python :: 3.15',
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
[dependency-groups]
|
|
28
28
|
dev = [
|
|
29
|
-
"pytest>=8.3.5,<
|
|
29
|
+
"pytest>=8.3.5,<10",
|
|
30
30
|
"mypy>=1.15.0,<2",
|
|
31
31
|
"ruff>=0.11.10,<1",
|
|
32
32
|
"python-claude>=0.3.0,<0.4",
|
|
@@ -14,7 +14,6 @@ from urllib.request import Request, urlopen
|
|
|
14
14
|
|
|
15
15
|
from cvec.http_cache import MAX_CACHE_ENTRIES, CacheEntry, parse_max_age
|
|
16
16
|
|
|
17
|
-
from cvec.models.agent_post import AgentPost, AgentPostRecommendation, AgentPostTag
|
|
18
17
|
from cvec.models.eav_column import EAVColumn
|
|
19
18
|
from cvec.models.eav_filter import EAVFilter
|
|
20
19
|
from cvec.models.eav_table import EAVTable
|
|
@@ -36,6 +35,7 @@ class CVec:
|
|
|
36
35
|
host: Optional[str]
|
|
37
36
|
default_start_at: Optional[datetime]
|
|
38
37
|
default_end_at: Optional[datetime]
|
|
38
|
+
timeout: Optional[float]
|
|
39
39
|
# Supabase authentication
|
|
40
40
|
_access_token: Optional[str]
|
|
41
41
|
_refresh_token: Optional[str]
|
|
@@ -49,10 +49,12 @@ class CVec:
|
|
|
49
49
|
default_start_at: Optional[datetime] = None,
|
|
50
50
|
default_end_at: Optional[datetime] = None,
|
|
51
51
|
api_key: Optional[str] = None,
|
|
52
|
+
timeout: Optional[float] = 30,
|
|
52
53
|
) -> None:
|
|
53
54
|
self.host = host or os.environ.get("CVEC_HOST")
|
|
54
55
|
self.default_start_at = default_start_at
|
|
55
56
|
self.default_end_at = default_end_at
|
|
57
|
+
self.timeout = timeout
|
|
56
58
|
|
|
57
59
|
# Supabase authentication
|
|
58
60
|
self._access_token = None
|
|
@@ -210,7 +212,7 @@ class CVec:
|
|
|
210
212
|
req = Request(
|
|
211
213
|
url, data=request_body, headers=request_headers, method=method
|
|
212
214
|
)
|
|
213
|
-
with urlopen(req) as response:
|
|
215
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
214
216
|
return self._process_response(response, url, method)
|
|
215
217
|
|
|
216
218
|
try:
|
|
@@ -234,7 +236,7 @@ class CVec:
|
|
|
234
236
|
req = Request(
|
|
235
237
|
url, data=request_body, headers=request_headers, method=method
|
|
236
238
|
)
|
|
237
|
-
with urlopen(req) as response:
|
|
239
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
238
240
|
return self._process_response(response, url, method)
|
|
239
241
|
except (HTTPError, URLError, ValueError, KeyError) as refresh_error:
|
|
240
242
|
logger.warning(
|
|
@@ -402,137 +404,6 @@ class CVec:
|
|
|
402
404
|
]
|
|
403
405
|
self._make_request("POST", endpoint, json_data=data_dicts) # type: ignore[arg-type]
|
|
404
406
|
|
|
405
|
-
def get_modeling_metrics(
|
|
406
|
-
self,
|
|
407
|
-
start_at: Optional[datetime] = None,
|
|
408
|
-
end_at: Optional[datetime] = None,
|
|
409
|
-
) -> List[Metric]:
|
|
410
|
-
"""
|
|
411
|
-
Return a list of modeling metrics that had at least one transition in the given [start_at, end_at) interval.
|
|
412
|
-
All metrics are returned if no start_at and end_at are given.
|
|
413
|
-
|
|
414
|
-
Args:
|
|
415
|
-
start_at: Optional start time for the query (uses class default if not specified)
|
|
416
|
-
end_at: Optional end time for the query (uses class default if not specified)
|
|
417
|
-
|
|
418
|
-
Returns:
|
|
419
|
-
List of Metric objects containing modeling metrics
|
|
420
|
-
"""
|
|
421
|
-
_start_at = start_at or self.default_start_at
|
|
422
|
-
_end_at = end_at or self.default_end_at
|
|
423
|
-
|
|
424
|
-
params: Dict[str, Any] = {
|
|
425
|
-
"start_at": _start_at.isoformat() if _start_at else None,
|
|
426
|
-
"end_at": _end_at.isoformat() if _end_at else None,
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
response_data = self._make_request(
|
|
430
|
-
"GET", "/api/modeling/metrics", params=params
|
|
431
|
-
)
|
|
432
|
-
return [Metric.model_validate(metric_data) for metric_data in response_data]
|
|
433
|
-
|
|
434
|
-
def get_modeling_metrics_data(
|
|
435
|
-
self,
|
|
436
|
-
names: Optional[List[str]] = None,
|
|
437
|
-
start_at: Optional[datetime] = None,
|
|
438
|
-
end_at: Optional[datetime] = None,
|
|
439
|
-
) -> List[MetricDataPoint]:
|
|
440
|
-
"""
|
|
441
|
-
Return all data-points within a given [start_at, end_at) interval,
|
|
442
|
-
optionally selecting a given list of modeling metric names.
|
|
443
|
-
Returns a list of MetricDataPoint objects, one for each metric value transition.
|
|
444
|
-
|
|
445
|
-
Args:
|
|
446
|
-
names: Optional list of modeling metric names to filter by
|
|
447
|
-
start_at: Optional start time for the query
|
|
448
|
-
end_at: Optional end time for the query
|
|
449
|
-
"""
|
|
450
|
-
_start_at = start_at or self.default_start_at
|
|
451
|
-
_end_at = end_at or self.default_end_at
|
|
452
|
-
|
|
453
|
-
params: Dict[str, Any] = {
|
|
454
|
-
"start_at": _start_at.isoformat() if _start_at else None,
|
|
455
|
-
"end_at": _end_at.isoformat() if _end_at else None,
|
|
456
|
-
"names": ",".join(names) if names else None,
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
response_data = self._make_request(
|
|
460
|
-
"GET", "/api/modeling/metrics/data", params=params
|
|
461
|
-
)
|
|
462
|
-
return [
|
|
463
|
-
MetricDataPoint.model_validate(point_data) for point_data in response_data
|
|
464
|
-
]
|
|
465
|
-
|
|
466
|
-
def get_modeling_metrics_data_arrow(
|
|
467
|
-
self,
|
|
468
|
-
names: Optional[List[str]] = None,
|
|
469
|
-
start_at: Optional[datetime] = None,
|
|
470
|
-
end_at: Optional[datetime] = None,
|
|
471
|
-
) -> bytes:
|
|
472
|
-
"""
|
|
473
|
-
Return all data-points within a given [start_at, end_at) interval,
|
|
474
|
-
optionally selecting a given list of modeling metric names.
|
|
475
|
-
Returns Arrow IPC format data that can be read using pyarrow.ipc.open_file.
|
|
476
|
-
|
|
477
|
-
Args:
|
|
478
|
-
names: Optional list of modeling metric names to filter by
|
|
479
|
-
start_at: Optional start time for the query
|
|
480
|
-
end_at: Optional end time for the query
|
|
481
|
-
"""
|
|
482
|
-
_start_at = start_at or self.default_start_at
|
|
483
|
-
_end_at = end_at or self.default_end_at
|
|
484
|
-
|
|
485
|
-
params: Dict[str, Any] = {
|
|
486
|
-
"start_at": _start_at.isoformat() if _start_at else None,
|
|
487
|
-
"end_at": _end_at.isoformat() if _end_at else None,
|
|
488
|
-
"names": ",".join(names) if names else None,
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
endpoint = "/api/modeling/metrics/data/arrow"
|
|
492
|
-
result = self._make_request("GET", endpoint, params=params)
|
|
493
|
-
assert isinstance(result, bytes)
|
|
494
|
-
return result
|
|
495
|
-
|
|
496
|
-
def add_agent_post(
|
|
497
|
-
self,
|
|
498
|
-
title: str,
|
|
499
|
-
author: str,
|
|
500
|
-
image_id: Optional[str] = None,
|
|
501
|
-
content: Optional[str] = None,
|
|
502
|
-
recommendations: Optional[List[AgentPostRecommendation]] = None,
|
|
503
|
-
tags: Optional[List[AgentPostTag]] = None,
|
|
504
|
-
is_private: bool = True,
|
|
505
|
-
) -> None:
|
|
506
|
-
"""
|
|
507
|
-
Add an agent post.
|
|
508
|
-
|
|
509
|
-
Note: If image_id is provided, the image must be uploaded to S3 beforehand.
|
|
510
|
-
The image_id should be the UUID used as the filename (without .png extension)
|
|
511
|
-
in the S3 bucket at the tenant's path.
|
|
512
|
-
|
|
513
|
-
Args:
|
|
514
|
-
title: Post title
|
|
515
|
-
author: Post author
|
|
516
|
-
image_id: Optional UUID of the uploaded image
|
|
517
|
-
content: Optional post content
|
|
518
|
-
recommendations: Optional list of recommendations
|
|
519
|
-
tags: Optional list of tags
|
|
520
|
-
is_private: Whether the post is private (only visible to superadmins). Defaults to True.
|
|
521
|
-
"""
|
|
522
|
-
|
|
523
|
-
post = AgentPost(
|
|
524
|
-
title=title,
|
|
525
|
-
author=author,
|
|
526
|
-
image_id=image_id,
|
|
527
|
-
content=content,
|
|
528
|
-
recommendations=recommendations,
|
|
529
|
-
tags=tags,
|
|
530
|
-
is_private=is_private,
|
|
531
|
-
)
|
|
532
|
-
payload = post.model_dump(mode="json", exclude_none=True)
|
|
533
|
-
|
|
534
|
-
self._make_request("POST", "/api/agent_posts/add", json_data=payload)
|
|
535
|
-
|
|
536
407
|
def _login_with_supabase(self, email: str, password: str) -> None:
|
|
537
408
|
"""
|
|
538
409
|
Login to Supabase and get access/refresh tokens.
|
|
@@ -557,7 +428,7 @@ class CVec:
|
|
|
557
428
|
request_body = json.dumps(payload).encode("utf-8")
|
|
558
429
|
req = Request(supabase_url, data=request_body, headers=headers, method="POST")
|
|
559
430
|
|
|
560
|
-
with urlopen(req) as response:
|
|
431
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
561
432
|
response_data = response.read()
|
|
562
433
|
data = json.loads(response_data.decode("utf-8"))
|
|
563
434
|
|
|
@@ -586,7 +457,7 @@ class CVec:
|
|
|
586
457
|
request_body = json.dumps(payload).encode("utf-8")
|
|
587
458
|
req = Request(supabase_url, data=request_body, headers=headers, method="POST")
|
|
588
459
|
|
|
589
|
-
with urlopen(req) as response:
|
|
460
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
590
461
|
response_data = response.read()
|
|
591
462
|
data = json.loads(response_data.decode("utf-8"))
|
|
592
463
|
|
|
@@ -609,7 +480,7 @@ class CVec:
|
|
|
609
480
|
config_url = f"{self.host}/config"
|
|
610
481
|
req = Request(config_url, method="GET")
|
|
611
482
|
|
|
612
|
-
with urlopen(req) as response:
|
|
483
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
613
484
|
response_data = response.read()
|
|
614
485
|
config_data = json.loads(response_data.decode("utf-8"))
|
|
615
486
|
|
|
@@ -664,7 +535,7 @@ class CVec:
|
|
|
664
535
|
def make_rpc_request() -> Any:
|
|
665
536
|
"""Inner function to make the actual RPC request."""
|
|
666
537
|
req = Request(url, data=request_body, headers=headers, method="POST")
|
|
667
|
-
with urlopen(req) as response:
|
|
538
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
668
539
|
response_data = response.read()
|
|
669
540
|
return json.loads(response_data.decode("utf-8"))
|
|
670
541
|
|
|
@@ -682,7 +553,7 @@ class CVec:
|
|
|
682
553
|
req = Request(
|
|
683
554
|
url, data=request_body, headers=headers, method="POST"
|
|
684
555
|
)
|
|
685
|
-
with urlopen(req) as response:
|
|
556
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
686
557
|
response_data = response.read()
|
|
687
558
|
return json.loads(response_data.decode("utf-8"))
|
|
688
559
|
except (HTTPError, URLError, ValueError, KeyError) as refresh_error:
|
|
@@ -731,7 +602,7 @@ class CVec:
|
|
|
731
602
|
def make_query_request() -> Any:
|
|
732
603
|
"""Inner function to make the actual query request."""
|
|
733
604
|
req = Request(url, headers=headers, method="GET")
|
|
734
|
-
with urlopen(req) as response:
|
|
605
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
735
606
|
response_data = response.read()
|
|
736
607
|
return json.loads(response_data.decode("utf-8"))
|
|
737
608
|
|
|
@@ -747,7 +618,7 @@ class CVec:
|
|
|
747
618
|
|
|
748
619
|
# Retry the request
|
|
749
620
|
req = Request(url, headers=headers, method="GET")
|
|
750
|
-
with urlopen(req) as response:
|
|
621
|
+
with urlopen(req, timeout=self.timeout) as response:
|
|
751
622
|
response_data = response.read()
|
|
752
623
|
return json.loads(response_data.decode("utf-8"))
|
|
753
624
|
except (HTTPError, URLError, ValueError, KeyError) as refresh_error:
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
from .agent_post import (
|
|
2
|
-
AgentPost,
|
|
3
|
-
AgentPostRecommendation,
|
|
4
|
-
AgentPostTag,
|
|
5
|
-
Severity,
|
|
6
|
-
)
|
|
7
1
|
from .eav_column import EAVColumn
|
|
8
2
|
from .eav_filter import EAVFilter
|
|
9
3
|
from .eav_table import EAVTable
|
|
@@ -11,14 +5,10 @@ from .metric import Metric, MetricDataPoint
|
|
|
11
5
|
from .span import Span
|
|
12
6
|
|
|
13
7
|
__all__ = [
|
|
14
|
-
"AgentPost",
|
|
15
|
-
"AgentPostRecommendation",
|
|
16
|
-
"AgentPostTag",
|
|
17
8
|
"EAVColumn",
|
|
18
9
|
"EAVFilter",
|
|
19
10
|
"EAVTable",
|
|
20
11
|
"Metric",
|
|
21
12
|
"MetricDataPoint",
|
|
22
|
-
"Severity",
|
|
23
13
|
"Span",
|
|
24
14
|
]
|