apifacts 0.1.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.
- apifacts-0.1.0/.gitignore +35 -0
- apifacts-0.1.0/LICENSE +21 -0
- apifacts-0.1.0/LICENSE-DATA +9 -0
- apifacts-0.1.0/PKG-INFO +94 -0
- apifacts-0.1.0/README.en.md +68 -0
- apifacts-0.1.0/apifacts/__init__.py +3 -0
- apifacts-0.1.0/apifacts/api/__init__.py +5 -0
- apifacts-0.1.0/apifacts/api/app.py +487 -0
- apifacts-0.1.0/apifacts/api/facts_index.py +286 -0
- apifacts-0.1.0/apifacts/api/health.py +67 -0
- apifacts-0.1.0/apifacts/api/match.py +194 -0
- apifacts-0.1.0/apifacts/api/models.py +149 -0
- apifacts-0.1.0/apifacts/api/normalize.py +249 -0
- apifacts-0.1.0/apifacts/api/ratelimit.py +67 -0
- apifacts-0.1.0/apifacts/api/schema.sql +42 -0
- apifacts-0.1.0/apifacts/api/seed_hosts.py +323 -0
- apifacts-0.1.0/apifacts/api/store.py +110 -0
- apifacts-0.1.0/apifacts/bot/__init__.py +1 -0
- apifacts-0.1.0/apifacts/bot/cli.py +73 -0
- apifacts-0.1.0/apifacts/bot/collect.py +146 -0
- apifacts-0.1.0/apifacts/bot/pr.py +327 -0
- apifacts-0.1.0/apifacts/bot/token.py +96 -0
- apifacts-0.1.0/apifacts/cli.py +96 -0
- apifacts-0.1.0/apifacts/cli_check.py +94 -0
- apifacts-0.1.0/apifacts/client/__init__.py +6 -0
- apifacts-0.1.0/apifacts/client/offline.py +142 -0
- apifacts-0.1.0/apifacts/client/render.py +117 -0
- apifacts-0.1.0/apifacts/client/request.py +251 -0
- apifacts-0.1.0/apifacts/client/settings.py +26 -0
- apifacts-0.1.0/apifacts/client/snapshot/README.md +6 -0
- apifacts-0.1.0/apifacts/client/transport.py +235 -0
- apifacts-0.1.0/apifacts/fixes/__init__.py +1 -0
- apifacts-0.1.0/apifacts/fixes/templates.py +84 -0
- apifacts-0.1.0/apifacts/pages/__init__.py +5 -0
- apifacts-0.1.0/apifacts/pages/build.py +215 -0
- apifacts-0.1.0/apifacts/pages/cli.py +74 -0
- apifacts-0.1.0/apifacts/pages/errors_index.py +42 -0
- apifacts-0.1.0/apifacts/pages/templates.py +364 -0
- apifacts-0.1.0/apifacts/probe/__init__.py +12 -0
- apifacts-0.1.0/apifacts/probe/assertions.py +170 -0
- apifacts-0.1.0/apifacts/probe/budget.py +131 -0
- apifacts-0.1.0/apifacts/probe/cli.py +145 -0
- apifacts-0.1.0/apifacts/probe/evidence.py +280 -0
- apifacts-0.1.0/apifacts/probe/google_sa.py +148 -0
- apifacts-0.1.0/apifacts/probe/http.py +281 -0
- apifacts-0.1.0/apifacts/probe/keys.py +43 -0
- apifacts-0.1.0/apifacts/probe/ledger.py +90 -0
- apifacts-0.1.0/apifacts/probe/loader.py +93 -0
- apifacts-0.1.0/apifacts/probe/oauth_refresh.py +127 -0
- apifacts-0.1.0/apifacts/probe/redact.py +123 -0
- apifacts-0.1.0/apifacts/probe/results.py +147 -0
- apifacts-0.1.0/apifacts/probe/runner.py +700 -0
- apifacts-0.1.0/apifacts/probe/templating.py +138 -0
- apifacts-0.1.0/apifacts/quorum/__init__.py +2 -0
- apifacts-0.1.0/apifacts/quorum/cli.py +87 -0
- apifacts-0.1.0/apifacts/quorum/draft.py +163 -0
- apifacts-0.1.0/apifacts/quorum/group.py +123 -0
- apifacts-0.1.0/apifacts/quorum/rules.py +82 -0
- apifacts-0.1.0/apifacts/quorum/run.py +132 -0
- apifacts-0.1.0/apifacts/schema/__init__.py +39 -0
- apifacts-0.1.0/apifacts/schema/error_paths.py +44 -0
- apifacts-0.1.0/apifacts/schema/models.py +702 -0
- apifacts-0.1.0/apifacts/schema/registry.py +238 -0
- apifacts-0.1.0/apifacts/schema/substance.py +24 -0
- apifacts-0.1.0/apifacts/schema/validate.py +433 -0
- apifacts-0.1.0/apifacts/schema/yamlio.py +70 -0
- apifacts-0.1.0/facts/github/anonymous-cache-ignores-api-version.yaml +29 -0
- apifacts-0.1.0/facts/github/anonymous-core-rate-limit.yaml +27 -0
- apifacts-0.1.0/facts/github/anonymous-repo-has-no-permissions.yaml +26 -0
- apifacts-0.1.0/facts/github/anonymous-search-rate-limit.yaml +27 -0
- apifacts-0.1.0/facts/github/api-version-2026-drops-has-downloads.yaml +27 -0
- apifacts-0.1.0/facts/github/default-api-version-end-of-support.yaml +22 -0
- apifacts-0.1.0/facts/github/error-status-is-a-string.yaml +28 -0
- apifacts-0.1.0/facts/github/graphql-anonymous-limit-zero.yaml +27 -0
- apifacts-0.1.0/facts/github/missing-repo-404.yaml +30 -0
- apifacts-0.1.0/facts/github/pagination-in-link-header.yaml +27 -0
- apifacts-0.1.0/facts/github/per-page-silently-capped-at-100.yaml +27 -0
- apifacts-0.1.0/facts/github/private-repo-404-not-403.yaml +26 -0
- apifacts-0.1.0/facts/github/rate-object-closing-down.yaml +22 -0
- apifacts-0.1.0/facts/github/renamed-repo-301.yaml +31 -0
- apifacts-0.1.0/facts/github/repository-object-fingerprint.yaml +26 -0
- apifacts-0.1.0/facts/github/search-first-1000-results.yaml +31 -0
- apifacts-0.1.0/facts/github/search-query-longer-than-256.yaml +31 -0
- apifacts-0.1.0/facts/github/secondary-rate-limit-429.yaml +25 -0
- apifacts-0.1.0/facts/github/secondary-rate-limit.yaml +25 -0
- apifacts-0.1.0/facts/github/trailing-slash-404.yaml +31 -0
- apifacts-0.1.0/facts/github/unsupported-api-version-400.yaml +31 -0
- apifacts-0.1.0/facts/github/unsupported-method-404.yaml +24 -0
- apifacts-0.1.0/facts/github/user-agent-required.yaml +24 -0
- apifacts-0.1.0/facts/google-calendar/calendar-get-rejects-api-keys.yaml +31 -0
- apifacts-0.1.0/facts/google-calendar/calendar-not-found-404.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/events-page-default-250.yaml +22 -0
- apifacts-0.1.0/facts/google-calendar/invalid-page-token-400.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/max-results-above-2500-accepted.yaml +29 -0
- apifacts-0.1.0/facts/google-calendar/max-results-zero-refused.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/missing-api-key-403.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/order-by-start-time-needs-single-events.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/public-free-busy-calendar-via-api-key.yaml +28 -0
- apifacts-0.1.0/facts/google-calendar/rate-limit-403-or-429.yaml +24 -0
- apifacts-0.1.0/facts/google-calendar/sync-token-with-time-min-400.yaml +30 -0
- apifacts-0.1.0/facts/google-calendar/time-min-filters-on-end-time.yaml +22 -0
- apifacts-0.1.0/facts/google-calendar/time-min-without-offset-bad-request.yaml +31 -0
- apifacts-0.1.0/facts/google-calendar/unknown-sync-token-410.yaml +30 -0
- apifacts-0.1.0/facts/google-firestore/array-and-map-values-are-wrapped.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/document-envelope-keys.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/document-not-found-404.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/document-size-limit-1mib.yaml +22 -0
- apifacts-0.1.0/facts/google-firestore/empty-collection-returns-empty-object.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/free-quota-resets-midnight-pacific.yaml +22 -0
- apifacts-0.1.0/facts/google-firestore/integer-value-is-a-string.yaml +29 -0
- apifacts-0.1.0/facts/google-firestore/invalid-field-path-400.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/invalid-page-token-400.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/negative-page-size-400.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/null-value-is-json-null.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/order-by-unknown-field-accepted.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/server-access-bypasses-security-rules.yaml +22 -0
- apifacts-0.1.0/facts/google-firestore/subcollection-of-missing-document-is-empty.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/timestamp-value-rfc3339-utc.yaml +28 -0
- apifacts-0.1.0/facts/google-firestore/unauthenticated-read-under-test-mode.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/unknown-database-404.yaml +31 -0
- apifacts-0.1.0/facts/google-firestore/unknown-project-403.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/daily-quota-resets-midnight-pacific.yaml +22 -0
- apifacts-0.1.0/facts/google-gemini/errors-use-google-rpc-envelope.yaml +28 -0
- apifacts-0.1.0/facts/google-gemini/gemini-1-5-models-retired.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/gemini-2-0-flash-served-past-shutdown-date.yaml +29 -0
- apifacts-0.1.0/facts/google-gemini/invalid-api-key-400.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/invalid-page-token-400.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/latest-aliases-v1beta-only.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/leaked-key-403.yaml +27 -0
- apifacts-0.1.0/facts/google-gemini/missing-api-key-403.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/model-not-found-404.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/model-object-fingerprint.yaml +28 -0
- apifacts-0.1.0/facts/google-gemini/models-list-default-page-50.yaml +28 -0
- apifacts-0.1.0/facts/google-gemini/page-size-negative-400.yaml +31 -0
- apifacts-0.1.0/facts/google-gemini/page-size-zero-means-default.yaml +28 -0
- apifacts-0.1.0/facts/google-gemini/rate-limits-per-project.yaml +22 -0
- apifacts-0.1.0/facts/google-gemini/resource-exhausted-429.yaml +25 -0
- apifacts-0.1.0/facts/google-gemini/unknown-query-parameter-400.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/batch-get-fails-whole.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/columns-major-inner-empty-cells.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/date-time-formatted-string.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/default-sheet-name-follows-locale.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/empty-range-omits-values.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/formatted-values-follow-locale.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/formulas-in-locale-syntax.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/invalid-api-key-400.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/invalid-fields-mask-generic-400.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/invalid-value-render-option-400.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/missing-api-key-403.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/new-sheet-grid-1000x26.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/quota-per-project-and-user.yaml +24 -0
- apifacts-0.1.0/facts/google-sheets/range-clipped-to-grid.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/request-timeout-180s.yaml +22 -0
- apifacts-0.1.0/facts/google-sheets/spreadsheet-not-found-404.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/unformatted-dates-are-serial-numbers.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/unknown-sheet-unable-to-parse.yaml +31 -0
- apifacts-0.1.0/facts/google-sheets/value-rows-not-padded.yaml +28 -0
- apifacts-0.1.0/facts/google-sheets/whole-column-range-expanded.yaml +28 -0
- apifacts-0.1.0/facts/pypi/downloads-always-minus-one.yaml +27 -0
- apifacts-0.1.0/facts/pypi/json-api-accepts-unnormalized-name.yaml +26 -0
- apifacts-0.1.0/facts/pypi/json-api-cdn-cache.yaml +27 -0
- apifacts-0.1.0/facts/pypi/json-trailing-slash-301.yaml +28 -0
- apifacts-0.1.0/facts/pypi/no-edge-rate-limit.yaml +22 -0
- apifacts-0.1.0/facts/pypi/project-json-fingerprint.yaml +26 -0
- apifacts-0.1.0/facts/pypi/project-not-found-404.yaml +30 -0
- apifacts-0.1.0/facts/pypi/release-json-has-no-releases-key.yaml +27 -0
- apifacts-0.1.0/facts/pypi/release-metadata-from-first-upload.yaml +22 -0
- apifacts-0.1.0/facts/pypi/release-not-found-404.yaml +30 -0
- apifacts-0.1.0/facts/pypi/releases-key-deprecated.yaml +22 -0
- apifacts-0.1.0/facts/pypi/simple-api-html-unless-accept-json.yaml +27 -0
- apifacts-0.1.0/facts/pypi/simple-not-found-404.yaml +30 -0
- apifacts-0.1.0/facts/pypi/simple-unnormalized-name-301.yaml +29 -0
- apifacts-0.1.0/facts/pypi/simple-without-trailing-slash-301.yaml +28 -0
- apifacts-0.1.0/facts/pypi/xml-rpc-planned-deprecation.yaml +22 -0
- apifacts-0.1.0/facts/salesforce/developer-edition-15000-daily-requests.yaml +28 -0
- apifacts-0.1.0/facts/salesforce/empty-query-result-shape.yaml +28 -0
- apifacts-0.1.0/facts/salesforce/errors-are-a-json-array.yaml +28 -0
- apifacts-0.1.0/facts/salesforce/missing-session-401.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/non-id-path-read-as-external-id.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/record-not-found-404.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/rest-on-login-host-url-not-reset.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/retired-api-version-410.yaml +30 -0
- apifacts-0.1.0/facts/salesforce/sforce-limit-info-header.yaml +28 -0
- apifacts-0.1.0/facts/salesforce/soap-login-needs-use-any-api-auth.yaml +24 -0
- apifacts-0.1.0/facts/salesforce/soap-login-rate-3600-per-hour.yaml +22 -0
- apifacts-0.1.0/facts/salesforce/soap-login-retiring-summer-27.yaml +22 -0
- apifacts-0.1.0/facts/salesforce/soql-fields-all-needs-limit.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/soql-malformed-query-400.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/soql-unknown-field-invalid-field.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/soql-unknown-object-invalid-type.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/unknown-sobject-describe-404.yaml +31 -0
- apifacts-0.1.0/facts/salesforce/version-list-needs-no-session.yaml +28 -0
- apifacts-0.1.0/facts/solana/get-block-commitment-processed.yaml +31 -0
- apifacts-0.1.0/facts/solana/get-confirmed-block-removed.yaml +32 -0
- apifacts-0.1.0/facts/solana/get-confirmed-transaction-removed.yaml +32 -0
- apifacts-0.1.0/facts/solana/get-program-accounts-blocked-403.yaml +31 -0
- apifacts-0.1.0/facts/solana/get-recent-blockhash-removed.yaml +32 -0
- apifacts-0.1.0/facts/solana/invalid-pubkey-wrong-size.yaml +31 -0
- apifacts-0.1.0/facts/solana/jsonrpc-errors-use-http-200.yaml +28 -0
- apifacts-0.1.0/facts/solana/multiple-accounts-max-100.yaml +31 -0
- apifacts-0.1.0/facts/solana/per-method-rate-limit-headers.yaml +26 -0
- apifacts-0.1.0/facts/solana/public-endpoint-403-blocked.yaml +24 -0
- apifacts-0.1.0/facts/solana/public-endpoint-not-for-production.yaml +22 -0
- apifacts-0.1.0/facts/solana/public-mainnet-rate-limits.yaml +24 -0
- apifacts-0.1.0/facts/solana/rent-exemption-minimum-zero-bytes.yaml +26 -0
- apifacts-0.1.0/facts/solana/signatures-for-address-limit-1000.yaml +31 -0
- apifacts-0.1.0/facts/stripe/amount-too-small.yaml +31 -0
- apifacts-0.1.0/facts/stripe/card-declined-generic.yaml +31 -0
- apifacts-0.1.0/facts/stripe/card-expired.yaml +31 -0
- apifacts-0.1.0/facts/stripe/card-incorrect-cvc.yaml +31 -0
- apifacts-0.1.0/facts/stripe/card-insufficient-funds.yaml +31 -0
- apifacts-0.1.0/facts/stripe/card-lost-generic-message.yaml +31 -0
- apifacts-0.1.0/facts/stripe/customer-not-found.yaml +31 -0
- apifacts-0.1.0/facts/stripe/deleted-customer-returns-200.yaml +28 -0
- apifacts-0.1.0/facts/stripe/execution-errors-are-replayed.yaml +31 -0
- apifacts-0.1.0/facts/stripe/expand-not-expandable.yaml +30 -0
- apifacts-0.1.0/facts/stripe/idempotency-key-other-endpoint.yaml +31 -0
- apifacts-0.1.0/facts/stripe/idempotency-key-reuse-different-params.yaml +31 -0
- apifacts-0.1.0/facts/stripe/idempotency-key-too-long.yaml +31 -0
- apifacts-0.1.0/facts/stripe/idempotency-keys-pruned-after-24h.yaml +22 -0
- apifacts-0.1.0/facts/stripe/idempotent-replay-header.yaml +28 -0
- apifacts-0.1.0/facts/stripe/invalid-api-version-400.yaml +30 -0
- apifacts-0.1.0/facts/stripe/limit-not-an-integer.yaml +31 -0
- apifacts-0.1.0/facts/stripe/limit-zero-returns-one.yaml +28 -0
- apifacts-0.1.0/facts/stripe/missing-api-key-401.yaml +30 -0
- apifacts-0.1.0/facts/stripe/parameter-unknown.yaml +31 -0
- apifacts-0.1.0/facts/stripe/payment-method-types-removed.yaml +30 -0
- apifacts-0.1.0/facts/stripe/rate-limited-reason-header.yaml +24 -0
- apifacts-0.1.0/facts/stripe/sandbox-rate-limit-lower.yaml +22 -0
- apifacts-0.1.0/facts/stripe/server-assigned-idempotency-key.yaml +28 -0
- apifacts-0.1.0/facts/stripe/starting-after-missing-object.yaml +31 -0
- apifacts-0.1.0/facts/stripe/validation-errors-are-not-replayed.yaml +31 -0
- apifacts-0.1.0/facts/telegram/chat-id-empty-400.yaml +30 -0
- apifacts-0.1.0/facts/telegram/chat-not-found-400.yaml +30 -0
- apifacts-0.1.0/facts/telegram/error-envelope-ok-false.yaml +29 -0
- apifacts-0.1.0/facts/telegram/flood-control-429-retry-after.yaml +24 -0
- apifacts-0.1.0/facts/telegram/get-updates-blocked-by-webhook.yaml +22 -0
- apifacts-0.1.0/facts/telegram/get-updates-limit-not-validated.yaml +29 -0
- apifacts-0.1.0/facts/telegram/group-migrated-to-supergroup.yaml +22 -0
- apifacts-0.1.0/facts/telegram/invalid-file-id-400.yaml +30 -0
- apifacts-0.1.0/facts/telegram/invalid-token-401.yaml +30 -0
- apifacts-0.1.0/facts/telegram/malformed-token-404.yaml +30 -0
- apifacts-0.1.0/facts/telegram/message-rate-limits.yaml +24 -0
- apifacts-0.1.0/facts/telegram/method-names-case-insensitive.yaml +29 -0
- apifacts-0.1.0/facts/telegram/no-webhook-url-empty-string.yaml +28 -0
- apifacts-0.1.0/facts/telegram/unknown-method-404.yaml +30 -0
- apifacts-0.1.0/facts/telegram/updates-kept-24-hours.yaml +22 -0
- apifacts-0.1.0/facts/telegram/user-not-found-400.yaml +30 -0
- apifacts-0.1.0/pyproject.toml +70 -0
- apifacts-0.1.0/schema/fact.schema.json +182 -0
- apifacts-0.1.0/schema/fix.schema.json +244 -0
- apifacts-0.1.0/schema/observation.schema.json +25 -0
- apifacts-0.1.0/schema/probe.schema.json +181 -0
- apifacts-0.1.0/schema/service.schema.json +215 -0
- apifacts-0.1.0/services/github.yaml +44 -0
- apifacts-0.1.0/services/google-calendar.yaml +34 -0
- apifacts-0.1.0/services/google-firestore.yaml +39 -0
- apifacts-0.1.0/services/google-gemini.yaml +35 -0
- apifacts-0.1.0/services/google-sheets.yaml +33 -0
- apifacts-0.1.0/services/pypi.yaml +34 -0
- apifacts-0.1.0/services/salesforce.yaml +38 -0
- apifacts-0.1.0/services/solana.yaml +44 -0
- apifacts-0.1.0/services/stripe.yaml +41 -0
- apifacts-0.1.0/services/telegram.yaml +39 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# secrets never
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
*.key
|
|
5
|
+
*.pem
|
|
6
|
+
.private_keys/
|
|
7
|
+
|
|
8
|
+
# python
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.pyc
|
|
11
|
+
.venv/
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.mypy_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
|
|
19
|
+
# node
|
|
20
|
+
node_modules/
|
|
21
|
+
coverage/
|
|
22
|
+
|
|
23
|
+
# probe runner state (results.jsonl, probe-state.sqlite): transient, never in git
|
|
24
|
+
var/
|
|
25
|
+
|
|
26
|
+
# local scratch
|
|
27
|
+
.DS_Store
|
|
28
|
+
tmp/
|
|
29
|
+
|
|
30
|
+
# check() API state (never in git)
|
|
31
|
+
observations.sqlite
|
|
32
|
+
observations.sqlite-*
|
|
33
|
+
|
|
34
|
+
# kill switch (spec 04): a host-local file, never committed
|
|
35
|
+
ops/KILL
|
apifacts-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Edouard Baillot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Data license
|
|
2
|
+
|
|
3
|
+
Everything under `facts/` (the registry of verified facts, in YAML) and the
|
|
4
|
+
generated fact pages is licensed under Creative Commons Attribution 4.0
|
|
5
|
+
International (CC BY 4.0): https://creativecommons.org/licenses/by/4.0/
|
|
6
|
+
|
|
7
|
+
Attribution: "apifacts registry (CC BY 4.0)" with a link to the fact's
|
|
8
|
+
page or to the repository. Code is licensed separately under the MIT License
|
|
9
|
+
(see LICENSE). Decision 2026-10-17, docs/decisions.md.
|
apifacts-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: apifacts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Open registry of verified facts about machine interfaces (APIs, SDKs, CLIs) for AI agents.
|
|
5
|
+
Project-URL: Homepage, https://apifacts.dev
|
|
6
|
+
Project-URL: Repository, https://github.com/Illouminus/apifacts
|
|
7
|
+
Project-URL: Issues, https://github.com/Illouminus/apifacts/issues
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: LICENSE-DATA
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Requires-Dist: cryptography>=50.0.2
|
|
17
|
+
Requires-Dist: fastapi>=0.150.0
|
|
18
|
+
Requires-Dist: httpx>=0.28.1
|
|
19
|
+
Requires-Dist: jsonschema>=4.26.0
|
|
20
|
+
Requires-Dist: pydantic>=2.14.1
|
|
21
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
22
|
+
Requires-Dist: ruamel-yaml>=0.19.1
|
|
23
|
+
Requires-Dist: typer>=0.27.3
|
|
24
|
+
Requires-Dist: uvicorn>=0.54.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# apifacts
|
|
28
|
+
|
|
29
|
+
**A verified changelog of reality for AI agents.** An open registry of typed, dated facts about what
|
|
30
|
+
third-party machine interfaces (HTTP APIs, SDK packages, CLIs) actually do today, as opposed to what
|
|
31
|
+
their docs say.
|
|
32
|
+
|
|
33
|
+
## Why
|
|
34
|
+
|
|
35
|
+
Interfaces change, docs lag, and nobody tells the agent. Every session pays tokens to rediscover the
|
|
36
|
+
same traps: a `200` with an empty array instead of a `429`, a rate limit reported as `status: 0` in the
|
|
37
|
+
body, an SDK release that silently dropped a field. Documentation tools answer "give me the right docs";
|
|
38
|
+
apifacts answers "the docs are wrong about this endpoint right now, here is the verified difference".
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install apifacts-pytest # pytest plugin: a test failing on an HTTP error prints the known facts
|
|
44
|
+
uvx apifacts check https://api.stripe.com/v1/charges -X GET --status 401 # CLI (and library)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Both packages are on PyPI, carry the same version and ship together from one tag
|
|
48
|
+
([release](ops/README.md#release-to-pypi)). The plugin sends nothing until a test fails.
|
|
49
|
+
|
|
50
|
+
## How a fact is verified
|
|
51
|
+
|
|
52
|
+
- One fact per YAML file in `facts/<service>/`, with a kind (`error_meaning`, `rate_limit`,
|
|
53
|
+
`breaking_change`, ...), the exact error signal, a one-sentence claim, dimensions (`env`, `plan`,
|
|
54
|
+
`region`, `account_state`) and evidence.
|
|
55
|
+
- Truth comes only from **deterministic probes**: declarative HTTP steps and assertions that our runner
|
|
56
|
+
executes on a schedule. No language model is called anywhere in the verification path.
|
|
57
|
+
- Fixes are **data, not advice**: members of a closed vocabulary with typed parameters (no free text, no
|
|
58
|
+
shell, no foreign URLs), rendered to one English sentence by us.
|
|
59
|
+
- A probe in another environment never refutes a fact; it adds a dimension.
|
|
60
|
+
|
|
61
|
+
## Calling `check()`
|
|
62
|
+
|
|
63
|
+
One endpoint answers and learns at the same time: the request is the contribution. Send the target and,
|
|
64
|
+
optionally, the error you got; receive matching facts with typed fixes and what the probes observe. If
|
|
65
|
+
the target matches a registered template, a normalized observation is stored (no bodies, headers, query
|
|
66
|
+
strings or raw IPs).
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
curl -s https://apifacts.dev/v0/check \
|
|
70
|
+
-H 'Content-Type: application/json' \
|
|
71
|
+
-d '{"target": {"method": "POST", "url": "https://api.stripe.com/v1/payment_intents"},
|
|
72
|
+
"error": {"status": 400, "body_excerpt": "Keys for idempotent requests can only be used with the same parameters they were first used with."}}'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The response is never empty: `facts`, `observed`, and an `unknown.reason` when nothing matches.
|
|
76
|
+
|
|
77
|
+
## Status
|
|
78
|
+
|
|
79
|
+
The API is live at https://apifacts.dev (`/v0/check`, `/v0/services`, `/openapi.json`, `/healthz`;
|
|
80
|
+
`facts.baillot.dev` is a legacy alias). The registry covers the services and facts listed in
|
|
81
|
+
[`pages/index.md`](pages/index.md), each fact page showing how it was established. Design contracts
|
|
82
|
+
live in [`docs/specs/`](docs/specs/README.md).
|
|
83
|
+
|
|
84
|
+
Running your own copy: the API reads `facts/` and `services/` once, at startup, so after a `git pull`
|
|
85
|
+
restart it; [`ops/deploy.sh`](ops/README.md#deploy) checks out, syncs and restarts in one step.
|
|
86
|
+
|
|
87
|
+
## Contributing
|
|
88
|
+
|
|
89
|
+
Calling `check()` is contributing. Pull requests are for humans and API producers: see
|
|
90
|
+
[CONTRIBUTING.md](CONTRIBUTING.md). Producer signatures are always free.
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
Code: [MIT](LICENSE). Data (`facts/` and the generated fact pages): [CC BY 4.0](LICENSE-DATA).
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# apifacts
|
|
2
|
+
|
|
3
|
+
**A verified changelog of reality for AI agents.** An open registry of typed, dated facts about what
|
|
4
|
+
third-party machine interfaces (HTTP APIs, SDK packages, CLIs) actually do today, as opposed to what
|
|
5
|
+
their docs say.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Interfaces change, docs lag, and nobody tells the agent. Every session pays tokens to rediscover the
|
|
10
|
+
same traps: a `200` with an empty array instead of a `429`, a rate limit reported as `status: 0` in the
|
|
11
|
+
body, an SDK release that silently dropped a field. Documentation tools answer "give me the right docs";
|
|
12
|
+
apifacts answers "the docs are wrong about this endpoint right now, here is the verified difference".
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install apifacts-pytest # pytest plugin: a test failing on an HTTP error prints the known facts
|
|
18
|
+
uvx apifacts check https://api.stripe.com/v1/charges -X GET --status 401 # CLI (and library)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Both packages are on PyPI, carry the same version and ship together from one tag
|
|
22
|
+
([release](ops/README.md#release-to-pypi)). The plugin sends nothing until a test fails.
|
|
23
|
+
|
|
24
|
+
## How a fact is verified
|
|
25
|
+
|
|
26
|
+
- One fact per YAML file in `facts/<service>/`, with a kind (`error_meaning`, `rate_limit`,
|
|
27
|
+
`breaking_change`, ...), the exact error signal, a one-sentence claim, dimensions (`env`, `plan`,
|
|
28
|
+
`region`, `account_state`) and evidence.
|
|
29
|
+
- Truth comes only from **deterministic probes**: declarative HTTP steps and assertions that our runner
|
|
30
|
+
executes on a schedule. No language model is called anywhere in the verification path.
|
|
31
|
+
- Fixes are **data, not advice**: members of a closed vocabulary with typed parameters (no free text, no
|
|
32
|
+
shell, no foreign URLs), rendered to one English sentence by us.
|
|
33
|
+
- A probe in another environment never refutes a fact; it adds a dimension.
|
|
34
|
+
|
|
35
|
+
## Calling `check()`
|
|
36
|
+
|
|
37
|
+
One endpoint answers and learns at the same time: the request is the contribution. Send the target and,
|
|
38
|
+
optionally, the error you got; receive matching facts with typed fixes and what the probes observe. If
|
|
39
|
+
the target matches a registered template, a normalized observation is stored (no bodies, headers, query
|
|
40
|
+
strings or raw IPs).
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
curl -s https://apifacts.dev/v0/check \
|
|
44
|
+
-H 'Content-Type: application/json' \
|
|
45
|
+
-d '{"target": {"method": "POST", "url": "https://api.stripe.com/v1/payment_intents"},
|
|
46
|
+
"error": {"status": 400, "body_excerpt": "Keys for idempotent requests can only be used with the same parameters they were first used with."}}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The response is never empty: `facts`, `observed`, and an `unknown.reason` when nothing matches.
|
|
50
|
+
|
|
51
|
+
## Status
|
|
52
|
+
|
|
53
|
+
The API is live at https://apifacts.dev (`/v0/check`, `/v0/services`, `/openapi.json`, `/healthz`;
|
|
54
|
+
`facts.baillot.dev` is a legacy alias). The registry covers the services and facts listed in
|
|
55
|
+
[`pages/index.md`](pages/index.md), each fact page showing how it was established. Design contracts
|
|
56
|
+
live in [`docs/specs/`](docs/specs/README.md).
|
|
57
|
+
|
|
58
|
+
Running your own copy: the API reads `facts/` and `services/` once, at startup, so after a `git pull`
|
|
59
|
+
restart it; [`ops/deploy.sh`](ops/README.md#deploy) checks out, syncs and restarts in one step.
|
|
60
|
+
|
|
61
|
+
## Contributing
|
|
62
|
+
|
|
63
|
+
Calling `check()` is contributing. Pull requests are for humans and API producers: see
|
|
64
|
+
[CONTRIBUTING.md](CONTRIBUTING.md). Producer signatures are always free.
|
|
65
|
+
|
|
66
|
+
## License
|
|
67
|
+
|
|
68
|
+
Code: [MIT](LICENSE). Data (`facts/` and the generated fact pages): [CC BY 4.0](LICENSE-DATA).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"""`check()` service: POST /v0/check (request = contribution), read endpoints, ingestion.
|
|
2
|
+
|
|
3
|
+
Spec: docs/specs/03-check-contract.md. Nothing here calls a model API or the network; the answer
|
|
4
|
+
comes from the facts in git, the observation is a normalized row in sqlite or nothing.
|
|
5
|
+
"""
|