continuo-python-runtime 0.6.0__py3-none-any.whl → 0.8.0__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.
- continuo_python_runtime/contract/kinds.py +18 -3
- continuo_python_runtime/contract/loader.py +9 -0
- continuo_python_runtime/contract/merge.py +7 -1
- continuo_python_runtime/contract/model.py +2 -1
- continuo_python_runtime/contract/secret_ref.py +31 -0
- continuo_python_runtime/harness.py +2 -1
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/METADATA +30 -19
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/RECORD +12 -11
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/WHEEL +0 -0
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/entry_points.txt +0 -0
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/licenses/LICENSE +0 -0
- {continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Per-kind contract rules: which fields a node of each kind must carry.
|
|
2
2
|
|
|
3
|
-
Each kind is one ``KindRules`` entry composed of a script policy
|
|
4
|
-
|
|
5
|
-
contract branches on the kind's name.
|
|
3
|
+
Each kind is one ``KindRules`` entry composed of a script policy, a reads rule,
|
|
4
|
+
and whether it may name a Secret. Adding a kind means adding one entry to
|
|
5
|
+
``RULES``; nothing that parses a contract branches on the kind's name.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
@@ -88,17 +88,32 @@ class CsvRead(ReadsRule):
|
|
|
88
88
|
return dict(reads)
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
class NoReads(ReadsRule):
|
|
92
|
+
"""No declared reads: the node's script fetches its own data."""
|
|
93
|
+
|
|
94
|
+
def validate(
|
|
95
|
+
self, reads: Any, label: str, *, dialect: str | None, check_reads: bool
|
|
96
|
+
) -> dict[str, str]:
|
|
97
|
+
if reads is None or (isinstance(reads, dict) and not reads):
|
|
98
|
+
return {}
|
|
99
|
+
raise ContractError(
|
|
100
|
+
f"{label}: a python-api node declares no 'reads' (its script fetches its own data)"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
91
104
|
@dataclass(frozen=True)
|
|
92
105
|
class KindRules:
|
|
93
106
|
"""What a node of one kind must declare."""
|
|
94
107
|
|
|
95
108
|
script_required: bool
|
|
96
109
|
reads: ReadsRule
|
|
110
|
+
secret_allowed: bool = False
|
|
97
111
|
|
|
98
112
|
|
|
99
113
|
RULES: dict[str, KindRules] = {
|
|
100
114
|
"python-node": KindRules(script_required=True, reads=SqlReads()),
|
|
101
115
|
"python-csv": KindRules(script_required=False, reads=CsvRead()),
|
|
116
|
+
"python-api": KindRules(script_required=True, reads=NoReads(), secret_allowed=True),
|
|
102
117
|
}
|
|
103
118
|
|
|
104
119
|
|
|
@@ -21,6 +21,7 @@ from continuo_python_runtime.contract.model import (
|
|
|
21
21
|
Column,
|
|
22
22
|
Node,
|
|
23
23
|
)
|
|
24
|
+
from continuo_python_runtime.contract.secret_ref import validate_secret_ref
|
|
24
25
|
from continuo_python_runtime.errors import ContractError
|
|
25
26
|
from continuo_python_runtime.types import parse_sql_type
|
|
26
27
|
|
|
@@ -38,6 +39,7 @@ _ALLOWED_KEYS = {
|
|
|
38
39
|
"output_columns",
|
|
39
40
|
"config",
|
|
40
41
|
"content_hash",
|
|
42
|
+
"secret_ref",
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
_REQUIRED_STRING_FIELDS = ("schema", "table", "owner", "schedule")
|
|
@@ -221,6 +223,12 @@ def parse_node(
|
|
|
221
223
|
raw.get("reads"), label, dialect=dialect, check_reads=check_reads
|
|
222
224
|
)
|
|
223
225
|
|
|
226
|
+
secret_ref = ""
|
|
227
|
+
if "secret_ref" in raw:
|
|
228
|
+
if not rules.secret_allowed:
|
|
229
|
+
raise ContractError(f"{label}: 'secret_ref' is not allowed for kind {kind}")
|
|
230
|
+
secret_ref = validate_secret_ref(raw["secret_ref"], label)
|
|
231
|
+
|
|
224
232
|
raw_columns = raw.get("output_columns")
|
|
225
233
|
if not isinstance(raw_columns, list) or not raw_columns:
|
|
226
234
|
raise ContractError(f"{label}: 'output_columns' must be a non-empty list")
|
|
@@ -285,6 +293,7 @@ def parse_node(
|
|
|
285
293
|
config=config,
|
|
286
294
|
content_hash=content_hash,
|
|
287
295
|
kind=kind,
|
|
296
|
+
secret_ref=secret_ref,
|
|
288
297
|
)
|
|
289
298
|
|
|
290
299
|
|
|
@@ -22,7 +22,7 @@ def node_entry(node: Node) -> dict:
|
|
|
22
22
|
four (source_hash, shared_code_hash, config_hash, content_hash). The
|
|
23
23
|
nullable field is always present in output_columns.
|
|
24
24
|
"""
|
|
25
|
-
|
|
25
|
+
entry = {
|
|
26
26
|
"schema": node.schema,
|
|
27
27
|
"table": node.table,
|
|
28
28
|
"owner": node.owner,
|
|
@@ -43,6 +43,11 @@ def node_entry(node: Node) -> dict:
|
|
|
43
43
|
"extra_columns": node.extra_columns,
|
|
44
44
|
"config": dict(node.config),
|
|
45
45
|
}
|
|
46
|
+
# Only a kind that may name a Secret ever carries one; emitting the key
|
|
47
|
+
# only when set keeps every other node's config_hash unchanged.
|
|
48
|
+
if node.secret_ref:
|
|
49
|
+
entry["secret_ref"] = node.secret_ref
|
|
50
|
+
return entry
|
|
46
51
|
|
|
47
52
|
|
|
48
53
|
def _lint_node_closure(
|
|
@@ -131,6 +136,7 @@ def _csv_hash_inputs(node: Node, repo_root: Path) -> tuple[bytes, list[bytes]]:
|
|
|
131
136
|
_HASH_INPUTS: dict[str, Callable[[Node, Path], tuple[bytes, list[bytes]]]] = {
|
|
132
137
|
"python-node": _script_hash_inputs,
|
|
133
138
|
"python-csv": _csv_hash_inputs,
|
|
139
|
+
"python-api": _script_hash_inputs,
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
|
|
@@ -6,7 +6,7 @@ from typing import Any
|
|
|
6
6
|
# Module-level constants
|
|
7
7
|
CRITICALITIES = frozenset({"REGULATORY", "CORE", "SECONDARY"})
|
|
8
8
|
EXTRA_COLUMNS_POLICIES = frozenset({"raise", "warn"})
|
|
9
|
-
KINDS = frozenset({"python-node", "python-csv"})
|
|
9
|
+
KINDS = frozenset({"python-node", "python-csv", "python-api"})
|
|
10
10
|
DEFAULT_KIND = "python-node"
|
|
11
11
|
CONTRACT_VERSION = 1
|
|
12
12
|
|
|
@@ -37,6 +37,7 @@ class Node:
|
|
|
37
37
|
config: dict[str, Any] = field(default_factory=dict)
|
|
38
38
|
content_hash: str | None = None
|
|
39
39
|
kind: str = DEFAULT_KIND
|
|
40
|
+
secret_ref: str = ""
|
|
40
41
|
|
|
41
42
|
@property
|
|
42
43
|
def relation(self) -> str:
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""The name of the Kubernetes Secret a node's pod receives as env vars.
|
|
2
|
+
|
|
3
|
+
The ``continuo-api-`` prefix keeps a contract from naming any other Secret in
|
|
4
|
+
the namespace (the warehouse credentials, the platform's own credentials).
|
|
5
|
+
continuo's topology-controller and execution-controller enforce the same
|
|
6
|
+
pattern; this check gives the author the error in CI instead.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
|
|
13
|
+
from continuo_python_runtime.errors import ContractError
|
|
14
|
+
|
|
15
|
+
SECRET_REF_PATTERN = re.compile(r"^continuo-api-[a-z0-9]([-a-z0-9]*[a-z0-9])?$")
|
|
16
|
+
SECRET_REF_MAX_LEN = 253
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def validate_secret_ref(value: object, label: str) -> str:
|
|
20
|
+
"""Return ``value`` if it is a valid ``continuo-api-*`` Secret name."""
|
|
21
|
+
if (
|
|
22
|
+
not isinstance(value, str)
|
|
23
|
+
or len(value) > SECRET_REF_MAX_LEN
|
|
24
|
+
or not SECRET_REF_PATTERN.fullmatch(value)
|
|
25
|
+
):
|
|
26
|
+
raise ContractError(
|
|
27
|
+
f"{label}: 'secret_ref' must be a Kubernetes Secret name starting with "
|
|
28
|
+
f"'continuo-api-' (lowercase letters, digits, '-'; at most "
|
|
29
|
+
f"{SECRET_REF_MAX_LEN} chars), got {value!r}"
|
|
30
|
+
)
|
|
31
|
+
return value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Container entrypoint: dispatches a single node's script and writes its output.
|
|
2
2
|
|
|
3
|
-
``run_node`` is the sole write sink for a python
|
|
3
|
+
``run_node`` is the sole write sink for a python node. It resolves the
|
|
4
4
|
node from the contract, loads and executes its script inside a
|
|
5
5
|
:class:`~continuo_python_runtime.context.RunContext`, conforms the result to
|
|
6
6
|
the declared schema, and writes it through the runtime adapter. Exactly one
|
|
@@ -227,6 +227,7 @@ def _produce_from_csv(
|
|
|
227
227
|
|
|
228
228
|
_PRODUCERS: dict[str, Callable[[Node, Any, Path, CsvSourceReader | None], Any]] = {
|
|
229
229
|
"python-node": _produce_from_script,
|
|
230
|
+
"python-api": _produce_from_script,
|
|
230
231
|
"python-csv": _produce_from_csv,
|
|
231
232
|
}
|
|
232
233
|
|
{continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: continuo-python-runtime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Runtime harness, contract tooling, and CI lint for Continuo python nodes.
|
|
5
5
|
Author: Simone Carolini
|
|
6
6
|
Maintainer: Simone Carolini
|
|
@@ -41,15 +41,16 @@ Five artifacts come out of this repository:
|
|
|
41
41
|
- **The `continuo-engine-contract` PyPI package** — the `WarehouseAdapter`
|
|
42
42
|
port, the contract schema, the shared SQL/type/config guards, and the
|
|
43
43
|
sentinel result-block format. Adapter authors outside this repo pin it.
|
|
44
|
-
- **The
|
|
45
|
-
`continuo-trino-adapter`) — one `WarehouseAdapter` implementation per
|
|
44
|
+
- **The three engine-adapter PyPI packages** (`continuo-postgres-adapter`,
|
|
45
|
+
`continuo-trino-adapter`, `continuo-duckdb-adapter`) — one `WarehouseAdapter` implementation per
|
|
46
46
|
warehouse engine, each published independently under the same tag. A
|
|
47
47
|
domain repo normally never installs these directly (the engine image
|
|
48
48
|
already has the matching one baked in); they exist as standalone PyPI
|
|
49
49
|
packages for the "build your own container" shape (see below) and for
|
|
50
50
|
third-party adapter authors to reference.
|
|
51
51
|
- **Per-engine base images**, one per warehouse engine
|
|
52
|
-
(`continuo-python-runtime-postgres`, `continuo-python-runtime-trino
|
|
52
|
+
(`continuo-python-runtime-postgres`, `continuo-python-runtime-trino`,
|
|
53
|
+
`continuo-python-runtime-duckdb`), that
|
|
53
54
|
domain repos build `FROM`. Each image bakes in the runtime and a single
|
|
54
55
|
`WarehouseAdapter` for that engine, and serves both roles that adapter has:
|
|
55
56
|
the node harness (`ENTRYPOINT ["continuo-runtime"]`, `CMD ["run"]`) and the
|
|
@@ -57,15 +58,17 @@ Five artifacts come out of this repository:
|
|
|
57
58
|
- **`template/`** — a copy-ready domain repo: `Dockerfile`, `contracts/`,
|
|
58
59
|
`scripts/`, and the `release.yml` CI/CD workflow.
|
|
59
60
|
|
|
60
|
-
One `vX.Y.Z` git tag releases all of it: `publish-pypi.yml` builds all
|
|
61
|
-
PyPI distributions into a single `dist
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
One `vX.Y.Z` git tag releases all of it: `publish-pypi.yml` builds all five
|
|
62
|
+
PyPI distributions into a single `dist/`, verifies them (and full engine
|
|
63
|
+
images built from them) on amd64 and arm64, and only then publishes them
|
|
64
|
+
together. It then builds all three engine images natively per architecture —
|
|
65
|
+
each installing its matching pinned adapter version from that same release —
|
|
66
|
+
pulls and smoke-tests the exact pushed digests, and finally gives the verified
|
|
67
|
+
amd64 + arm64 digests one multi-arch tag. See `CONTRIBUTING.md` (Releasing).
|
|
65
68
|
|
|
66
69
|
### What this repo owns
|
|
67
70
|
|
|
68
|
-
This repository owns the entire python-node surface: the engine contract,
|
|
71
|
+
This repository owns the entire python-node surface: the engine contract, the three
|
|
69
72
|
engine adapters, the validation runner, and the node harness. The former
|
|
70
73
|
`continuo-validation` repository was merged in — there is no longer a separate
|
|
71
74
|
validation-side port, adapter class, entry-point group, or image. One
|
|
@@ -80,16 +83,18 @@ validation-side port, adapter class, entry-point group, or image. One
|
|
|
80
83
|
| `continuo-engine-contract` | `continuo_engine_contract` | this repo, `contract/` | The `WarehouseAdapter` port, contract schema, the SQL/type/config guards adapters must run, and the result-block format. Published to PyPI. |
|
|
81
84
|
| `continuo-postgres-adapter` | `continuo_postgres_adapter` | this repo, `adapters/postgres/` | `PostgresAdapter` — one class, both roles. Published to PyPI. |
|
|
82
85
|
| `continuo-trino-adapter` | `continuo_trino_adapter` | this repo, `adapters/trino/` | `TrinoAdapter` — one class, both roles, for Trino/Iceberg. Published to PyPI. |
|
|
86
|
+
| `continuo-duckdb-adapter` | `continuo_duckdb_adapter` | this repo, `adapters/duckdb/` | `DuckDBAdapter` — one class, both roles, for DuckDB on a DuckLake (Postgres catalog, Parquet on S3). Published to PyPI. |
|
|
83
87
|
|
|
84
|
-
All
|
|
88
|
+
All five are uv workspace members (`[tool.uv.workspace]` in the root
|
|
85
89
|
`pyproject.toml`), so `uv sync --all-packages --all-groups` at the repo root
|
|
86
90
|
installs everything for local development.
|
|
87
91
|
|
|
88
|
-
**All
|
|
89
|
-
same `vX.Y.Z` tag. The
|
|
92
|
+
**All five packages in the table above are published to PyPI**, under the
|
|
93
|
+
same `vX.Y.Z` tag. The three engine images then **install the matching pinned
|
|
90
94
|
adapter version from PyPI** — `Dockerfile.postgres` installs
|
|
91
95
|
`continuo-postgres-adapter==X.Y.Z`, `Dockerfile.trino` installs
|
|
92
|
-
`continuo-trino-adapter==X.Y.Z`
|
|
96
|
+
`continuo-trino-adapter==X.Y.Z` and `Dockerfile.duckdb` installs
|
|
97
|
+
`continuo-duckdb-adapter==X.Y.Z` — rather than building it from this repo's
|
|
93
98
|
source tree, so each image still ships exactly one adapter and the runtime
|
|
94
99
|
still discovers it through the `continuo_engine.adapters` entry-point group
|
|
95
100
|
at run time. The image **name** (`continuo-python-runtime-<engine>`) and the
|
|
@@ -97,7 +102,7 @@ adapter's pip **distribution** name (`continuo-<engine>-adapter`) are two
|
|
|
97
102
|
different artifacts of the same adapter — same engine, same version, same
|
|
98
103
|
runtime behavior, different packaging; see "Build your own container" below
|
|
99
104
|
for a build shape that installs the pip package directly instead of `FROM`
|
|
100
|
-
the image. All
|
|
105
|
+
the image. All five packages are still built, type-checked, and tested by CI
|
|
101
106
|
on every change.
|
|
102
107
|
|
|
103
108
|
### The result block is a frozen wire contract
|
|
@@ -149,7 +154,7 @@ the pre-flight check once before your next release; it reports every affected
|
|
|
149
154
|
read at once:
|
|
150
155
|
|
|
151
156
|
```bash
|
|
152
|
-
continuo-runtime validate contracts/ --dialect postgres # or trino
|
|
157
|
+
continuo-runtime validate contracts/ --dialect postgres # or trino, duckdb
|
|
153
158
|
```
|
|
154
159
|
|
|
155
160
|
The runtime image does not re-run this gate, so a read that passes here is
|
|
@@ -179,6 +184,12 @@ produced, never how it is checked or written.
|
|
|
179
184
|
header but not declared are governed by the same `extra_columns` policy as
|
|
180
185
|
a script node's output — `raise` (default) fails the run, `warn` drops
|
|
181
186
|
them and logs a warning. See `template/contracts/example_csv.yml`.
|
|
187
|
+
- **`python-api`** — a script node that fetches its own data (typically over
|
|
188
|
+
HTTP) and declares no `reads:`. `ctx.read` has nothing to return. It may name
|
|
189
|
+
one Kubernetes Secret with `secret_ref: continuo-api-<name>`; continuo
|
|
190
|
+
attaches that Secret to the node's pod, so each of its keys is an env var the
|
|
191
|
+
script reads with `os.environ[...]`. The contract never holds a secret value
|
|
192
|
+
or env var name; the Secret itself is created in the cluster by the operator.
|
|
182
193
|
|
|
183
194
|
## The script API
|
|
184
195
|
|
|
@@ -275,9 +286,9 @@ A domain repo picks its warehouse engine by which base image it builds
|
|
|
275
286
|
`FROM`:
|
|
276
287
|
|
|
277
288
|
```dockerfile
|
|
278
|
-
FROM ghcr.io/carolsimone/continuo-python-runtime-postgres:v0.
|
|
289
|
+
FROM ghcr.io/carolsimone/continuo-python-runtime-postgres:v0.8.0
|
|
279
290
|
# or
|
|
280
|
-
FROM ghcr.io/carolsimone/continuo-python-runtime-trino:v0.
|
|
291
|
+
FROM ghcr.io/carolsimone/continuo-python-runtime-trino:v0.8.0
|
|
281
292
|
```
|
|
282
293
|
|
|
283
294
|
The engine is part of the image **name**; the tag is the bare version, so
|
|
@@ -288,7 +299,7 @@ pinned PyPI version of the `continuo-postgres-adapter` or
|
|
|
288
299
|
`continuo-trino-adapter` package built from this repo's `adapters/postgres/`
|
|
289
300
|
or `adapters/trino/` source (see the table above) — registered under the
|
|
290
301
|
`continuo_engine.adapters` entry-point group (entry names `postgres` /
|
|
291
|
-
`trino`). The runtime discovers it via `discover_adapter()` at run time, so a
|
|
302
|
+
`trino` / `duckdb`). The runtime discovers it via `discover_adapter()` at run time, so a
|
|
292
303
|
single image serves every node in the service and the release-time
|
|
293
304
|
validation Job for it. The executor injects the warehouse connection as
|
|
294
305
|
environment variables (engine-native, e.g.
|
|
@@ -6,25 +6,26 @@ continuo_python_runtime/context.py,sha256=K-9XXYlQ4OZ250rCOq6EJNq7fg_D5sK6tOcu7D
|
|
|
6
6
|
continuo_python_runtime/csv_loader.py,sha256=a5Hwu-YIzIiko8X1_vqShsnzjs2-OsKEUSCHLXg_dio,3346
|
|
7
7
|
continuo_python_runtime/csv_source.py,sha256=7g8Tu6ieiJLvWH4Ep4nwYlOdGkjeePr12K5UHuO8TNc,4136
|
|
8
8
|
continuo_python_runtime/errors.py,sha256=nfZzfBhQ2ajm7USAWKKaGY2uUlh8eNjNPNYYuaOJgZE,1032
|
|
9
|
-
continuo_python_runtime/harness.py,sha256=
|
|
9
|
+
continuo_python_runtime/harness.py,sha256=vsoahI38OCaCEpg9Il7xcHYcsXp6A5cxY_fjCC8xGJk,13046
|
|
10
10
|
continuo_python_runtime/hashing.py,sha256=70iXQb0CmjGqniTPofXY6WapydQ7aK2XOk5dzpEf-zk,3354
|
|
11
11
|
continuo_python_runtime/lint.py,sha256=M59UtCHHVQnJKNolIkvkRk_AgGAFvxD9zkKAMMK-7GI,12984
|
|
12
12
|
continuo_python_runtime/types.py,sha256=_ssxNE2Lq5782n9_Ihs-u_6ybCCy8XaL6iYbE35tBug,5057
|
|
13
13
|
continuo_python_runtime/contract/__init__.py,sha256=S79x6j_P0CmaSuCGzeWoK1U0507KvD2MZXwQl9DFWMM,37
|
|
14
|
-
continuo_python_runtime/contract/kinds.py,sha256=
|
|
15
|
-
continuo_python_runtime/contract/loader.py,sha256=
|
|
16
|
-
continuo_python_runtime/contract/merge.py,sha256=
|
|
17
|
-
continuo_python_runtime/contract/model.py,sha256
|
|
14
|
+
continuo_python_runtime/contract/kinds.py,sha256=Ht-hCT7R5A1tEnPlbGL-b9FyJQBvpDWrXK9PBt7yA28,4938
|
|
15
|
+
continuo_python_runtime/contract/loader.py,sha256=9HsV7dJhCwudjOPXBapYFKiZtslyXIkiZ_WfeuLh5-E,14858
|
|
16
|
+
continuo_python_runtime/contract/merge.py,sha256=Zw--_-v3ERE02Nu7qqLtbHa3Hr__0a1SF-2PRqUfXAY,7594
|
|
17
|
+
continuo_python_runtime/contract/model.py,sha256=WB_Qw4koP8BEwuiAZwIEsKFQRa_6QHHBK4xi4eGvPQo,1082
|
|
18
18
|
continuo_python_runtime/contract/paths.py,sha256=SRn70pJkDAIpXw0IcMU2iNKPKvct8w_SZP2ec-lV91M,1458
|
|
19
|
+
continuo_python_runtime/contract/secret_ref.py,sha256=96jh2G81clpabiEWGIsxbd9r5GKEGLb4Sa1-WJ9G59Q,1131
|
|
19
20
|
continuo_python_runtime/csv_readers/__init__.py,sha256=9TKvjC37C77uRaJQZuO0--zVj2OvuNwpJE6nWx7j2S8,806
|
|
20
21
|
continuo_python_runtime/csv_readers/https.py,sha256=tMJ9k5F0b9SAydpon0ZlOznfjvjhF2BBLltyVmvRneE,4998
|
|
21
22
|
continuo_python_runtime/csv_readers/s3.py,sha256=zmvHs3TxlN2alPKrdaHzPyREmkve2nBiAsHRXXe1mE0,2246
|
|
22
23
|
continuo_python_runtime/validation/__init__.py,sha256=hz5oGXsoaUoygR0_pBby9PS6cEfrre518EE0HGB58eE,79
|
|
23
24
|
continuo_python_runtime/validation/runner.py,sha256=7pbksf7MXfTNcdklCOkOXg9qfRiJtyI_dbgbL3a9LWk,14072
|
|
24
25
|
continuo_python_runtime/validation/s3.py,sha256=q8nRrT9R7L1-M4dSlDnkL7CUJMPmq86MHY_UKYFlEf8,1785
|
|
25
|
-
continuo_python_runtime-0.
|
|
26
|
-
continuo_python_runtime-0.
|
|
27
|
-
continuo_python_runtime-0.
|
|
28
|
-
continuo_python_runtime-0.
|
|
29
|
-
continuo_python_runtime-0.
|
|
30
|
-
continuo_python_runtime-0.
|
|
26
|
+
continuo_python_runtime-0.8.0.dist-info/METADATA,sha256=q2tb518F9n_Bo4LIzbhhGSGm5yJPxbrOkWJKJ6y9gxQ,19874
|
|
27
|
+
continuo_python_runtime-0.8.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
28
|
+
continuo_python_runtime-0.8.0.dist-info/entry_points.txt,sha256=ZvIwSm9f9B9ZmZMf6CyF5Zt4QONn8rqaIk-u-B1CF2Y,70
|
|
29
|
+
continuo_python_runtime-0.8.0.dist-info/licenses/LICENSE,sha256=hfXfFCk-8gnps4YvHA6bjCNaSYqOrq2gAdqkXYycAQc,11345
|
|
30
|
+
continuo_python_runtime-0.8.0.dist-info/licenses/NOTICE,sha256=ykgYyQkAMx3uas90FZHzt0aTca9IgJQCLpZ4d74Pl3U,465
|
|
31
|
+
continuo_python_runtime-0.8.0.dist-info/RECORD,,
|
|
File without changes
|
{continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{continuo_python_runtime-0.6.0.dist-info → continuo_python_runtime-0.8.0.dist-info}/licenses/NOTICE
RENAMED
|
File without changes
|