Catalog PyPI
PACKAGE EXPLORERView in registry

3tears-datasources

PyPI

datasource entities, collections, namespace helpers, agent-yaml config model + driver abstraction for postgres/redshift/snowflake/bigquery backends

Versions collected1
Direct dependencies14From release 0.72.0
Last observed20 Oct, 15:37 UTC

README

Version 0.72.0 documentation

3tears-datasources

Datasource entities, three-tier collections, namespace helpers, the agent-yaml-facing DatasourceConfig, and the Driver abstraction (plus concrete asyncpg + Redshift drivers) for the 3tears platform.

This is the single source of truth for "what is a datasource" across every 3tears consumer.

Public surface

Imported via from threetears.datasources import …:

  • entities -- DataSourceEntity, DataSourceTableEntity, DataSourceColumnEntity, DataSourceRelationEntity, TableTemplateEntity + the DataSourceType, DataSourceAccessMode, DataSourceStatus enums.
  • collections -- DataSourceCollection, DataSourceTableCollection, DataSourceColumnCollection, DataSourceRelationCollection, TableTemplateCollection (three-tier SchemaBackedCollection / BaseCollection subclasses with L1/L2/L3 caching + _publish_invalidation on save).
  • namespace -- DATASOURCE_NAMESPACE_TYPE, datasource_namespace_id(uuid) -> uuid, datasource_namespace_name(name) -> str.
  • config -- DatasourceConfig (the agent-yaml-facing model the SDK validates against) plus the per-driver ConnectionConfig discriminated union.
  • query wire -- DatasourceQueryClient, DatasourceQueryRequest, DatasourceQueryResponse, DatasourceQueryResult, DatasourceQueryError. How a process that holds no warehouse credential (a tool pod) queries a hub-served datasource on its own identity: it publishes on {ns}.datasource.{name}.query carrying its hub-minted token, the hub verifies the token, evaluates the caller's grant on the datasource namespace, runs the query on the driver it already holds, and answers with rows or a typed refusal. The client hands back the rows and truncated, set when the hub cut the result at its row cap, so a caller deriving state from a full read can refuse a prefix rather than treat the missing rows as absent. Rows only otherwise -- the model-facing rendering with honesty imperatives is the datasource tool's job.
  • geo config -- GeoConfig, GeoLayerConfig, GeometryConfig, GeometryKind, FeatureBandConfig, AggregateBandConfig, CacheClassConfig, MeasureAggregation, layer_name_fits.

threetears.datasources.__all__ is the full list. The surfaces below are imported from their own modules.

Reading a relation by parts

threetears.datasources.partitioned_read keeps a relation current when the source rebuilds it whole but it divides into parts that change independently (one state's results, one customer's rows):

  • fingerprint_parts fingerprints every part, over the columns it is given.
  • read_parts reads the parts asked for, at most concurrency at a time (DEFAULT_PART_CONCURRENCY); the first part that fails cancels the rest and is raised as itself.
  • read_partitions reads every part of a relation (or the parts asked for) over the query rail, divided by one column, pages read side by side, and hands the parts back one at a time.

A caller compares each part's fingerprint with the one recorded when it was last read and reads only the parts that moved. DatasourceQueryClient gains relation_fingerprint and relation_fingerprint_groups for this, and read_all (in query_client) reads one part whole through the query rail.

Warehouse exports

A large relation read through the query rail costs a round trip per page. A warehouse that can write a query's result to object storage does the same work in seconds, and the reader takes the files from the bucket.

  • threetears.datasources.export -- what may be exported, and where. The caller sends a plain SELECT and a short relative destination, never the UNLOAD or a bucket. ExportConfig (on the datasource's connection config) names the bucket, the prefix and the role; check_destination, check_embeddable and redshift_unload_statement fix the statement around the SELECT; a SELECT that cannot be embedded safely is refused (ExportRefusedError). A datasource with no ExportConfig cannot export.
  • threetears.datasources.export_read -- export_part asks the hub for the export (DatasourceQueryClient.export), fingerprints the part before and after, and reads the parquet files through an object store the caller built. The export is proven whole before a row is handed back (IncompleteExportError otherwise) and is then always deleted through the hub (DatasourceQueryClient.delete_export), on every way out.
  • threetears.datasources.partitioned_export -- export_partitions reads a relation's chosen parts through one export divided by a column, handing the parts back one at a time, with the same proof and the same deletion.

Reading an export needs pip install '3tears-datasources[export]' (pyarrow).

A pod's own exports

A pod deletes each export once its load has proven it. A pod killed in the middle of a load never gets to, and the only other record of what it wrote is the hub's datasource_export_objects table, one row per export the hub ran and has not deleted. DatasourceQueryClient.list_own_exports reads that record back for the calling pod, so the next run can delete what the last one left:

try:
    left = await client.list_own_exports("reports-warehouse")
except DatasourceExportListUnsupportedError:
    # the hub cannot place the ask (it predates it, or has its models and no handler):
    # nothing was listed; log it and clear nothing
    left = []
except DatasourceQueryError as exc:
    if exc.error_code != "ACCESS_DENIED":
        raise
    # only a hub with the models and no handler refuses the list on the read grant, and only
    # for a pod that has lost datasource.read: this pod cannot load either. Log it (the
    # message says which) and clear nothing; the grant, or the hub's handler, is the fix
    left = []
for export in left:
    await client.delete_export("reports-warehouse", destination=export.destination)

It returns every DatasourceExportRecord (destination, object_prefix, date_created), read to the last page; a hub that keeps handing back a next page past max_pages (EXPORT_LIST_MAX_PAGES, 1000) or repeats a cursor is refused MALFORMED_RESPONSE, never cut short. Nothing ends an export but its deletion: there is no timer, and listing changes nothing.

The hub's contract for the ask

The ask rides the datasource's existing query subject ({ns}.datasource.<name>.query) as one more field of DatasourceQueryRequest, beside query, fingerprint, export and export_delete. No subject and no NATS grant is added.

Request (one page):

{"correlation_id": "<uuid>", "identity_token": "<token>", "user_identity_token": null,
 "export_list": {"cursor": null}}

cursor is null for the first page and the previous page's next_cursor, unchanged, for each page after it.

Reply (DatasourceQueryResponse):

{"success": true, "correlation_id": "<the request's>",
 "export_list": {"exports": [{"destination": "enr/r1/VA",
                              "object_prefix": "exports/<namespace id>/enr/r1/VA/",
                              "date_created": "2026-10-13T09:00:00Z"}],
                 "next_cursor": null}}

What the hub does, in order:

  1. Verify the caller, exactly as for every ask on the subject. A token that does not verify is IDENTITY_REFUSED.
  2. Resolve the datasource from the subject. None served there is DATASOURCE_NOT_FOUND.
  3. Admit a tool pod, on its identity alone. A principal that is not a tool pod is EXPORT_NOT_GRANTED. Neither datasource.read nor the export grant is asked, for the reason the delete asks neither: a pod whose grant was withdrawn must still be able to find, and so delete, what it was let write. In the responder that means routing the ask beside the delete, ahead of the datasource.read authorization every other ask passes through. The datasource needs no export configured to answer.
  4. Answer for the verified caller only. The rows returned are those of datasource_export_objects whose datasource_name is the subject's datasource and whose tool_pod_id is the principal the verified token names. The request has no field naming a pod and forbids unknown fields, so there is no way to ask about another pod; the hub must not add one. Beware DatasourceExportObjectCollection.outstanding(): both its filters are optional, and given no tool_pod_id it returns every pod's rows. The handler always passes the verified principal, never a value that can be None; it also reads every row at once, so a paged read is its own statement with both filters bound.
  5. Page by destination. Rows are ordered by destination, ascending (unique within a datasource). The cursor is opaque to the caller; build it with threetears.core.pagination.Keyset(columns=("destination",), descending=False): read page_size + 1 rows after the cursor and let Keyset.page cut the page and mint next_cursor. next_cursor is null on the last page, and a pod with no recorded export gets {"exports": [], "next_cursor": null} with success: true. A page carries at most 200 exports, so the largest reply fits a 1 MiB message. A cursor that does not decode is EXPORT_REFUSED.
  6. Never answer this ask MALFORMED_REQUEST. The responder answers that code to a body that does not parse, to some parsed asks it refuses as malformed (a fingerprint naming something that is not a plain identifier, or filtered by where_in without group_by), and to a parsed request carrying no ask it runs. The client reads MALFORMED_REQUEST in answer to export_list as "this hub cannot place the ask", so a hub that serves it refuses it only with the other codes above.

The hub reads these models from this package, so the hub change that moves its 3tears pin to the release carrying them ships the handler with it.

What each hub answers

Pods and hubs upgrade at different times. The answer to an export_list request depends on which hub it meets (aibots.hub.datasources.broker, process_request and _answer_for_principal):

HubAnswerClient raises
On a release before the ask's modelsIts request model forbids the unknown field, so the parse fails before anything is verified: {"success": false, "error_code": "MALFORMED_REQUEST", "error_message": "malformed datasource query request", "correlation_id": null}DatasourceExportListUnsupportedError
On the ask's models, no handler, pod holds datasource.readVerifies, resolves, authorizes the read, then finds no query, fingerprint, export or delete: MALFORMED_REQUEST, "a datasource request carries exactly one of query or fingerprint", with the correlation idDatasourceExportListUnsupportedError
On the ask's models, no handler, pod without datasource.readVerifies, resolves, and refuses the read before reaching the fallthrough: ACCESS_DENIED, with the correlation idDatasourceQueryError ACCESS_DENIED, logged at WARNING, its message saying the hub has no handler and the pod no read grant
With the handlerThe contract above; never MALFORMED_REQUEST, never ACCESS_DENIEDthe list, or the hub's refusal code

Either earlier state also answers IDENTITY_REFUSED or DATASOURCE_NOT_FOUND first when those fail. The hub pins 3tears>=0.66.0,<1.0.0, so a plain relock reaches the middle two rows: the handler ships with the relock, as above.

DatasourceExportListUnsupportedError (a DatasourceQueryError whose error_code is EXPORT_LIST_UNSUPPORTED) is raised rather than returned as an empty list because the hub named no export: "none recorded" and "could not ask" must not look alike. A caller that lists in order to clear catches it and clears nothing; the leftover exports stay on the operator's surface, as before the ask existed. ACCESS_DENIED is not folded into it: a pod that has lost its read grant is a fault an operator fixes, and the client says so rather than hiding it as an old hub. Part-way through a hub's roll, a later page answered by an older replica raises the same as a first page would, and no part of the list is returned.

Every other ask a newer client sends is unchanged on the wire (export_list is left off a request that does not make it), so pod and hub upgrade in either order.

Reporting reloaded geography layers

threetears.datasources.geo_reload is the tool pod to hub contract for platform geography layers. A pod writes a new generation of a layer's shapes into its own tables, stamping each row with the generation, and reports it with report_geo_layers_reloaded(nats_client, identity_token=..., generations=...). The hub moves each layer's tile version to that generation and answers each layer's LayerVersions (version, previous); generations_to_delete names the stamped generations the pod then deletes, all but those two. Nothing is served for a layer before its first report, and a version only moves forward: a generation below it is refused GENERATION_BEHIND. The request and reply models live in the same module and the hub imports them.

Drivers

The Driver ABC + create_driver(config, *, hub_l3_pool=None) factory are the entry point. Concrete drivers are accessed via the factory, NOT imported directly:

from threetears.datasources.drivers import create_driver
driver = create_driver(config.connection_config)
try:
    rows = await driver.fetch("SELECT * FROM customers WHERE id = $1", customer_id)
finally:
    await driver.close()

Driver implementations live behind extras keys:

  • pip install '3tears-datasources[redshift]' for RedshiftDriver
  • pip install '3tears-datasources[snowflake]' for SnowflakeDriver (stub today; full impl tracked separately)
  • pip install '3tears-datasources[bigquery]' for BigQueryDriver (stub today; full impl tracked separately)

Postgres / Yugabyte / agent_internal coverage uses asyncpg which is a hard dep (no extras key required).

See IMPLEMENTING_DRIVERS.md for the contract every new driver must satisfy.

Versioning policy

3tears-datasources versions in lockstep with the rest of the 3tears monorepo: every package shares one version, which tracks the framework git tag. All packages move together, and every intra-family dependency in pyproject.toml is bounded to that one minor version.

See CHANGELOG.md for the full version history.

Downloads & popularity

109downloads
1-day window · source-reported counts19 Oct 2026
5702850
2026-07-22: 19 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-22–2026-07-222026-07-23: 47 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-23–2026-07-232026-07-24: 245 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-24–2026-07-242026-07-25: 266 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-25–2026-07-252026-07-26: 193 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-26–2026-07-262026-07-27: 195 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-27–2026-07-272026-07-28: 230 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-28–2026-07-282026-07-29: 189 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-29–2026-07-292026-07-30: 242 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-30–2026-07-302026-07-31: 127 · observed 2026-10-20T15:48:57.4860406Z · period 2026-07-31–2026-07-312026-08-01: 181 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-01–2026-08-012026-08-02: 49 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-02–2026-08-022026-08-03: 91 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-03–2026-08-032026-08-04: 120 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-04–2026-08-042026-08-05: 285 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-05–2026-08-052026-08-06: 132 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-06–2026-08-062026-08-07: 59 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-07–2026-08-072026-08-08: 246 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-08–2026-08-082026-08-09: 239 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-09–2026-08-092026-08-10: 326 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-10–2026-08-102026-08-11: 185 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-11–2026-08-112026-08-12: 214 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-12–2026-08-122026-08-13: 208 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-13–2026-08-132026-08-14: 134 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-14–2026-08-142026-08-15: 120 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-15–2026-08-152026-08-16: 93 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-16–2026-08-162026-08-17: 124 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-17–2026-08-172026-08-18: 498 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-18–2026-08-182026-08-19: 129 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-19–2026-08-192026-08-20: 24 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-20–2026-08-202026-08-21: 71 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-21–2026-08-212026-08-22: 129 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-22–2026-08-222026-08-23: 145 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-23–2026-08-232026-08-24: 93 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-24–2026-08-242026-08-25: 147 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-25–2026-08-252026-08-26: 77 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-26–2026-08-262026-08-27: 124 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-27–2026-08-272026-08-28: 10 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-28–2026-08-282026-08-29: 153 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-29–2026-08-292026-08-30: 20 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-30–2026-08-302026-08-31: 119 · observed 2026-10-20T15:48:57.4860406Z · period 2026-08-31–2026-08-312026-09-01: 184 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-01–2026-09-012026-09-02: 97 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-02–2026-09-022026-09-03: 164 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-03–2026-09-032026-09-04: 61 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-04–2026-09-042026-09-05: 116 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-05–2026-09-052026-09-06: 25 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-06–2026-09-062026-09-07: 203 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-07–2026-09-072026-09-08: 79 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-08–2026-09-082026-09-09: 334 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-09–2026-09-092026-09-10: 195 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-10–2026-09-102026-09-11: 112 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-11–2026-09-112026-09-12: 123 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-12–2026-09-122026-09-13: 264 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-13–2026-09-132026-09-14: 458 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-14–2026-09-142026-09-15: 458 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-15–2026-09-152026-09-16: 433 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-16–2026-09-162026-09-17: 409 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-17–2026-09-172026-09-18: 302 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-18–2026-09-182026-09-19: 85 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-19–2026-09-192026-09-20: 174 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-20–2026-09-202026-09-21: 309 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-21–2026-09-212026-09-22: 200 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-22–2026-09-222026-09-23: 299 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-23–2026-09-232026-09-24: 350 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-24–2026-09-242026-09-25: 333 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-25–2026-09-252026-09-26: 223 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-26–2026-09-262026-09-27: 250 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-27–2026-09-272026-09-28: 350 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-28–2026-09-282026-09-29: 434 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-29–2026-09-292026-09-30: 223 · observed 2026-10-20T15:48:57.4860406Z · period 2026-09-30–2026-09-302026-10-01: 59 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-01–2026-10-012026-10-02: 114 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-02–2026-10-022026-10-03: 356 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-03–2026-10-032026-10-04: 570 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-04–2026-10-042026-10-05: 341 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-05–2026-10-052026-10-06: 26 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-06–2026-10-062026-10-07: 81 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-07–2026-10-072026-10-08: 138 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-08–2026-10-082026-10-09: 255 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-09–2026-10-092026-10-10: 143 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-10–2026-10-102026-10-11: 121 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-11–2026-10-112026-10-12: 33 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-12–2026-10-122026-10-13: 170 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-13–2026-10-132026-10-14: 326 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-14–2026-10-142026-10-15: 193 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-15–2026-10-152026-10-16: 228 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-16–2026-10-162026-10-17: 284 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-17–2026-10-172026-10-18: 352 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-18–2026-10-182026-10-19: 109 · observed 2026-10-20T15:48:57.4860406Z · period 2026-10-19–2026-10-19
22 Jul19 Oct

pypistats · 90 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-19 – 2026-10-191092026-10-20T15:48:57.4860406Z
2026-10-18 – 2026-10-183522026-10-20T15:48:57.4860406Z
2026-10-17 – 2026-10-172842026-10-20T15:48:57.4860406Z
2026-10-16 – 2026-10-162282026-10-20T15:48:57.4860406Z
2026-10-15 – 2026-10-151932026-10-20T15:48:57.4860406Z
2026-10-14 – 2026-10-143262026-10-20T15:48:57.4860406Z
2026-10-13 – 2026-10-131702026-10-20T15:48:57.4860406Z
2026-10-12 – 2026-10-12332026-10-20T15:48:57.4860406Z
2026-10-11 – 2026-10-111212026-10-20T15:48:57.4860406Z
2026-10-10 – 2026-10-101432026-10-20T15:48:57.4860406Z
2026-10-09 – 2026-10-092552026-10-20T15:48:57.4860406Z
2026-10-08 – 2026-10-081382026-10-20T15:48:57.4860406Z
2026-10-07 – 2026-10-07812026-10-20T15:48:57.4860406Z
2026-10-06 – 2026-10-06262026-10-20T15:48:57.4860406Z
2026-10-05 – 2026-10-053412026-10-20T15:48:57.4860406Z
2026-10-04 – 2026-10-045702026-10-20T15:48:57.4860406Z
2026-10-03 – 2026-10-033562026-10-20T15:48:57.4860406Z
2026-10-02 – 2026-10-021142026-10-20T15:48:57.4860406Z
2026-10-01 – 2026-10-01592026-10-20T15:48:57.4860406Z
2026-09-30 – 2026-09-302232026-10-20T15:48:57.4860406Z
2026-09-29 – 2026-09-294342026-10-20T15:48:57.4860406Z
2026-09-28 – 2026-09-283502026-10-20T15:48:57.4860406Z
2026-09-27 – 2026-09-272502026-10-20T15:48:57.4860406Z
2026-09-26 – 2026-09-262232026-10-20T15:48:57.4860406Z
2026-09-25 – 2026-09-253332026-10-20T15:48:57.4860406Z
2026-09-24 – 2026-09-243502026-10-20T15:48:57.4860406Z
2026-09-23 – 2026-09-232992026-10-20T15:48:57.4860406Z
2026-09-22 – 2026-09-222002026-10-20T15:48:57.4860406Z
2026-09-21 – 2026-09-213092026-10-20T15:48:57.4860406Z
2026-09-20 – 2026-09-201742026-10-20T15:48:57.4860406Z
2026-09-19 – 2026-09-19852026-10-20T15:48:57.4860406Z
2026-09-18 – 2026-09-183022026-10-20T15:48:57.4860406Z
2026-09-17 – 2026-09-174092026-10-20T15:48:57.4860406Z
2026-09-16 – 2026-09-164332026-10-20T15:48:57.4860406Z
2026-09-15 – 2026-09-154582026-10-20T15:48:57.4860406Z
2026-09-14 – 2026-09-144582026-10-20T15:48:57.4860406Z
2026-09-13 – 2026-09-132642026-10-20T15:48:57.4860406Z
2026-09-12 – 2026-09-121232026-10-20T15:48:57.4860406Z
2026-09-11 – 2026-09-111122026-10-20T15:48:57.4860406Z
2026-09-10 – 2026-09-101952026-10-20T15:48:57.4860406Z
2026-09-09 – 2026-09-093342026-10-20T15:48:57.4860406Z
2026-09-08 – 2026-09-08792026-10-20T15:48:57.4860406Z
2026-09-07 – 2026-09-072032026-10-20T15:48:57.4860406Z
2026-09-06 – 2026-09-06252026-10-20T15:48:57.4860406Z
2026-09-05 – 2026-09-051162026-10-20T15:48:57.4860406Z
2026-09-04 – 2026-09-04612026-10-20T15:48:57.4860406Z
2026-09-03 – 2026-09-031642026-10-20T15:48:57.4860406Z
2026-09-02 – 2026-09-02972026-10-20T15:48:57.4860406Z
2026-09-01 – 2026-09-011842026-10-20T15:48:57.4860406Z
2026-08-31 – 2026-08-311192026-10-20T15:48:57.4860406Z
2026-08-30 – 2026-08-30202026-10-20T15:48:57.4860406Z
2026-08-29 – 2026-08-291532026-10-20T15:48:57.4860406Z
2026-08-28 – 2026-08-28102026-10-20T15:48:57.4860406Z
2026-08-27 – 2026-08-271242026-10-20T15:48:57.4860406Z
2026-08-26 – 2026-08-26772026-10-20T15:48:57.4860406Z
2026-08-25 – 2026-08-251472026-10-20T15:48:57.4860406Z
2026-08-24 – 2026-08-24932026-10-20T15:48:57.4860406Z
2026-08-23 – 2026-08-231452026-10-20T15:48:57.4860406Z
2026-08-22 – 2026-08-221292026-10-20T15:48:57.4860406Z
2026-08-21 – 2026-08-21712026-10-20T15:48:57.4860406Z
2026-08-20 – 2026-08-20242026-10-20T15:48:57.4860406Z
2026-08-19 – 2026-08-191292026-10-20T15:48:57.4860406Z
2026-08-18 – 2026-08-184982026-10-20T15:48:57.4860406Z
2026-08-17 – 2026-08-171242026-10-20T15:48:57.4860406Z
2026-08-16 – 2026-08-16932026-10-20T15:48:57.4860406Z
2026-08-15 – 2026-08-151202026-10-20T15:48:57.4860406Z
2026-08-14 – 2026-08-141342026-10-20T15:48:57.4860406Z
2026-08-13 – 2026-08-132082026-10-20T15:48:57.4860406Z
2026-08-12 – 2026-08-122142026-10-20T15:48:57.4860406Z
2026-08-11 – 2026-08-111852026-10-20T15:48:57.4860406Z
2026-08-10 – 2026-08-103262026-10-20T15:48:57.4860406Z
2026-08-09 – 2026-08-092392026-10-20T15:48:57.4860406Z
2026-08-08 – 2026-08-082462026-10-20T15:48:57.4860406Z
2026-08-07 – 2026-08-07592026-10-20T15:48:57.4860406Z
2026-08-06 – 2026-08-061322026-10-20T15:48:57.4860406Z
2026-08-05 – 2026-08-052852026-10-20T15:48:57.4860406Z
2026-08-04 – 2026-08-041202026-10-20T15:48:57.4860406Z
2026-08-03 – 2026-08-03912026-10-20T15:48:57.4860406Z
2026-08-02 – 2026-08-02492026-10-20T15:48:57.4860406Z
2026-08-01 – 2026-08-011812026-10-20T15:48:57.4860406Z
2026-07-31 – 2026-07-311272026-10-20T15:48:57.4860406Z
2026-07-30 – 2026-07-302422026-10-20T15:48:57.4860406Z
2026-07-29 – 2026-07-291892026-10-20T15:48:57.4860406Z
2026-07-28 – 2026-07-282302026-10-20T15:48:57.4860406Z
2026-07-27 – 2026-07-271952026-10-20T15:48:57.4860406Z
2026-07-26 – 2026-07-261932026-10-20T15:48:57.4860406Z
2026-07-25 – 2026-07-252662026-10-20T15:48:57.4860406Z
2026-07-24 – 2026-07-242452026-10-20T15:48:57.4860406Z
2026-07-23 – 2026-07-23472026-10-20T15:48:57.4860406Z
2026-07-22 – 2026-07-22192026-10-20T15:48:57.4860406Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.72.020 Oct 202614

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

ACCESSIBLE
pacepace/3tears

Shared repository data · GitHub

License detected in repository
MIT
License branch / ref
develop
Last push
20 Oct 2026
Archived
No
Contributor identities
— · partial collection

Public sponsor counts have not been collected. These signals belong to the repository owner.

Downloads & popularity

0count
Gauge · observed snapshots20 Oct 2026
10.50
2026-10-20: 0 · observed 2026-10-20T17:18:19.8928356Z
20 Oct20 Oct

github · 1 observations shown. Missing days are unknown.

View observed values
Date / source periodValueObserved at
2026-10-2002026-10-20T17:18:19.8928356Z

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 15:37 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:0aa9da5a6ec1bd214e4186e1a2d698640b2a7d4c518f9bd354bea3a3d52ffd99