Configuration reference#

pydantic settings ook.config.Configuration#

Configuration for ook.

Parameters:

Show JSON schema
{
   "title": "Configuration",
   "description": "Configuration for ook.",
   "type": "object",
   "properties": {
      "SAFIR_NAME": {
         "default": "ook",
         "description": "The application's name",
         "title": "Safir Name",
         "type": "string"
      },
      "SAFIR_PROFILE": {
         "$ref": "#/$defs/Profile",
         "default": "production",
         "description": "Application logging profile: 'development' or 'production'."
      },
      "SAFIR_LOG_LEVEL": {
         "$ref": "#/$defs/LogLevel",
         "default": "INFO",
         "title": "Log level of the application's logger"
      },
      "SAFIR_PATH_PREFIX": {
         "default": "/ook",
         "description": "The URL prefix where the application's externally-accessible endpoints are hosted.",
         "title": "API URL path prefix",
         "type": "string"
      },
      "OOK_DATABASE_URL": {
         "$ref": "#/$defs/EnvAsyncPostgresDsn",
         "description": "Database URL."
      },
      "OOK_DATABASE_PASSWORD": {
         "description": "Database password.",
         "format": "password",
         "title": "Ook Database Password",
         "type": "string",
         "writeOnly": true
      },
      "kafka": {
         "$ref": "#/$defs/KafkaConnectionSettings",
         "description": "Kafka connection configuration."
      },
      "OOK_ENABLE_CONSUMER": {
         "default": true,
         "description": "Enable Kafka consumer.",
         "title": "Ook Enable Consumer",
         "type": "boolean"
      },
      "OOK_INGEST_KAFKA_TOPIC": {
         "default": "ook.ingest",
         "description": "The name of the Kafka topic for the ingest queue.",
         "title": "Ook Ingest Kafka Topic",
         "type": "string"
      },
      "OOK_LINKCHECK_KAFKA_TOPIC": {
         "default": "ook.linkcheck",
         "description": "The name of the Kafka topic for link-check execution requests.",
         "title": "Ook Linkcheck Kafka Topic",
         "type": "string"
      },
      "OOK_GROUP_ID": {
         "default": "ook",
         "description": "Kafka consumer group ID.",
         "title": "Ook Group Id",
         "type": "string"
      },
      "ALGOLIA_APP_ID": {
         "description": "The Algolia app ID",
         "title": "Algolia App Id",
         "type": "string"
      },
      "ALGOLIA_API_KEY": {
         "description": "The Algolia API key",
         "format": "password",
         "title": "Algolia Api Key",
         "type": "string",
         "writeOnly": true
      },
      "ALGOLIA_DOCUMENT_INDEX": {
         "default": "document_dev",
         "description": "Name of the Algolia document index",
         "title": "Algolia Document Index",
         "type": "string"
      },
      "OOK_GITHUB_APP_ID": {
         "anyOf": [
            {
               "type": "integer"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Ook Github App Id"
      },
      "OOK_GITHUB_APP_PRIVATE_KEY": {
         "anyOf": [
            {
               "format": "password",
               "type": "string",
               "writeOnly": true
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Ook Github App Private Key"
      },
      "OOK_LINKCHECK_REQUEST_TIMEOUT": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "PT30S",
         "description": "Total timeout applied to each link-check HTTP request."
      },
      "OOK_LINKCHECK_MAX_CONCURRENCY": {
         "default": 10,
         "description": "Maximum number of concurrent link-check HTTP requests across all hosts.",
         "minimum": 1,
         "title": "Ook Linkcheck Max Concurrency",
         "type": "integer"
      },
      "OOK_LINKCHECK_HOST_INTERVAL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "PT1S",
         "description": "Minimum politeness interval between link-check requests to the same host."
      },
      "OOK_LINKCHECK_USER_AGENT": {
         "default": "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0 Ook-Linkcheck/0.26.1.dev36+g2bb905bee (+https://github.com/lsst-sqre/ook)",
         "description": "User-Agent header sent on every link-check HTTP request (HEAD, GET fallback, and redirect hops). Defaults to a browser-prefixed hybrid carrying the running Ook version and repo URL so the checker stays identifiable while clearing bot-protection zones that block the bare token.",
         "title": "Ook Linkcheck User Agent",
         "type": "string"
      },
      "OOK_LINKCHECK_FRESHNESS_TTL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "P1D",
         "description": "Age below which a URL's stored check result is considered fresh. URLs submitted with a fresh result are not rechecked; their cached status is reported immediately."
      },
      "OOK_LINKCHECK_MAX_URLS_PER_CHECK": {
         "default": 1000,
         "description": "Maximum number of unique canonical URLs accepted in a single link-check submission.",
         "minimum": 1,
         "title": "Ook Linkcheck Max Urls Per Check",
         "type": "integer"
      },
      "OOK_LINKCHECK_BROKEN_THRESHOLD": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "P2D",
         "description": "Minimum span of consecutive failures before a previously-OK link is declared broken instead of failing."
      },
      "OOK_LINKCHECK_BROKEN_MIN_ATTEMPTS": {
         "default": 3,
         "description": "Minimum number of consecutive failed attempts before a previously-OK link is declared broken instead of failing.",
         "minimum": 1,
         "title": "Ook Linkcheck Broken Min Attempts",
         "type": "integer"
      },
      "OOK_LINKCHECK_RECHECK_INTERVALS": {
         "default": [
            "PT1H",
            "PT4H",
            "P1D",
            "P2D"
         ],
         "description": "Delays until the next recheck of a failing link, indexed by the number of consecutive failures so far. The last interval repeats when the failure streak outlasts this schedule.",
         "items": {
            "$ref": "#/$defs/HumanTimedelta"
         },
         "minItems": 1,
         "title": "Ook Linkcheck Recheck Intervals",
         "type": "array"
      },
      "OOK_LINKCHECK_BROKEN_RECHECK_INTERVAL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "P1D",
         "description": "Delay until the next recheck of a broken link. Broken links are revisited at this slow cadence so a since-fixed link can heal back to ok/redirected without waiting to be resubmitted."
      },
      "OOK_LINKCHECK_BLOCKED_RECHECK_INTERVAL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "PT1H",
         "description": "Delay until the next recheck of a bot-blocked link. A block is inconclusive and tends to flap, so blocked links are revisited at this near-term cadence to re-verify."
      },
      "OOK_LINKCHECK_CHECK_RETENTION": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "P30D",
         "description": "Age beyond which link-check submission records are purged by the scheduled linkcheck-recheck maintenance command."
      },
      "OOK_INTERSPHINX_TTL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "PT1H",
         "description": "Freshness TTL for cached intersphinx inventories. An inventory fetched within this window is served as a fresh cache hit; an older one is served stale on the request path while the background refresh job revalidates it."
      },
      "OOK_INTERSPHINX_NEGATIVE_TTL": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "PT5M",
         "description": "Negative-cache TTL for cold-miss intersphinx inventory fetch failures. When an upstream fetch fails on a cold miss the failure is cached for this window; a repeat request inside it returns the error without re-contacting upstream. After the window a new request re-fetches the origin."
      },
      "OOK_INTERSPHINX_ACTIVE_WINDOW": {
         "$ref": "#/$defs/HumanTimedelta",
         "default": "P30D",
         "description": "Active window for the intersphinx refresh job. The scheduled refresh only revalidates cached inventories requested by a client within this window; inventories last requested longer ago are skipped (not deleted) until a new request reactivates them."
      },
      "OOK_OIDC_AUDIENCE": {
         "description": "Audience required of the GitHub Actions OIDC id-tokens clients present as provenance for contributed link-check results. Set it to this deployment's public base URL (for example ``https://roundtable.lsst.cloud/ook``): the audience is what scopes a minted token to one Ook, so a token minted for the development deployment is not replayable against production. There is no default because a shared one would defeat that, and because only the environment knows its own base URL.",
         "title": "Ook Oidc Audience",
         "type": "string"
      },
      "OOK_SLACK_WEBHOOK": {
         "anyOf": [
            {
               "format": "password",
               "type": "string",
               "writeOnly": true
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Slack webhook for alerts. If set, alerts will be posted to this Slack webhook",
         "title": "Ook Slack Webhook"
      }
   },
   "$defs": {
      "EnvAsyncPostgresDsn": {
         "format": "uri",
         "minLength": 1,
         "type": "string"
      },
      "HumanTimedelta": {
         "format": "duration",
         "type": "string"
      },
      "KafkaConnectionSettings": {
         "additionalProperties": false,
         "description": "Settings for connecting to Kafka.\n\nThis settings model supports different authentication methods, which each\nhave different sets of required settings. All of these settings can be\nprovided in ``KAFKA_`` prefixed environment variables. Instances of this\nmodel have properties that can be used to construct different types of\nkafka clients:\n\n.. code-block:: python\n\n   from faststream.broker import KafkaBroker\n\n   from safir.kafka import KafkaConnectionSettings\n\n   config = KafkaConnectionSettings()\n   kafka_broker = KafkaBroker(**config.faststream_broker_params)\n\nWhen using this model directly, The ``validated`` property enforces at\nruntime that the correct settings were provided for the desired\nauthentication method, and returns models to access those settings in a\ntype-safe way:\n\n.. code-block:: python\n\n   from pathlib import Path\n\n   # ValidationError at runtime: ``client_key_path`` is not provided\n   config = KafkaConnectionSettings(\n       bootstrap_servers=\"something:1234\",\n       security_protocol=KafkaSecurityProtocol.SSL,\n       cluster_ca_path=Path(\"/some/cert.crt\"),\n       client_cert_path=Path(\"/some/other/cert.crt\"),\n   )\n\n   config = KafkaConnectionSettings(\n       bootstrap_servers=\"something:1234\",\n       security_protocol=KafkaSecurityProtocol.SSL,\n       cluster_ca_path=Path(\"/some/path/ca.crt\"),\n       client_cert_path=Path(\"/some/path/user.crt\"),\n       client_key_path=Path(\"/some/path/user.key\"),\n   )\n\n   blah = config.validated.sasl_username  # Static type error",
         "properties": {
            "bootstrapServers": {
               "description": "A comma-separated list of Kafka brokers to connect to. This should be a list of hostnames or IP addresses, each optionally followed by a port number, separated by commas.",
               "examples": [
                  "kafka-1:9092,kafka-2:9092,kafka-3:9092",
                  "kafka:9092"
               ],
               "title": "Kafka bootstrap servers",
               "type": "string"
            },
            "securityProtocol": {
               "$ref": "#/$defs/SecurityProtocol",
               "description": "The authentication and encryption mode for the connection.",
               "title": "Security Protocol"
            },
            "clusterCaPath": {
               "anyOf": [
                  {
                     "format": "file-path",
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The path to the PEM-formatted CA certificate file to use for verifying the broker's certificate. This is only needed for SSL and SASL_SSL security protocols, andeven in those cases, only when the broker's certificate is not signed by a CA trusted by the operating system.",
               "examples": [
                  "/some/dir/ca.crt"
               ],
               "title": "Path to CA certificate file"
            },
            "clientCertPath": {
               "anyOf": [
                  {
                     "format": "file-path",
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The path to the PEM-formated client certificate file to use for authentication. This is only needed if the broker is configured to require SSL client authentication.",
               "examples": [
                  "/some/dir/user.crt"
               ],
               "title": "Path to client certificate file"
            },
            "clientKeyPath": {
               "anyOf": [
                  {
                     "format": "file-path",
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The path to the PEM-formatted client key file to use for authentication. This is only needed if for the SSL securityprotocol.",
               "examples": [
                  "/some/dir/user.key"
               ],
               "title": "Path to client key file"
            },
            "saslMechanism": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/SaslMechanism"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The SASL mechanism to use for authentication. This is only needed for the SASL_SSL and SASL_PLAINTEXT securityprotocols.",
               "title": "SASL mechanism"
            },
            "saslUsername": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The username to use for SASL authentication. This is only needed for the SASL_SSL and SASL_PLAINTEXT securityprotocols.",
               "title": "SASL username"
            },
            "saslPassword": {
               "anyOf": [
                  {
                     "format": "password",
                     "type": "string",
                     "writeOnly": true
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "The password to use for SASL authentication. This is only needed for the SASL_SSL and SASL_PLAINTEXT securityprotocols.",
               "title": "SASL password"
            }
         },
         "required": [
            "bootstrapServers",
            "securityProtocol"
         ],
         "title": "KafkaConnectionSettings",
         "type": "object"
      },
      "LogLevel": {
         "description": "Python logging level.\n\nAny case variation is accepted when converting a string to an enum value\nvia the class constructor.",
         "enum": [
            "DEBUG",
            "INFO",
            "WARNING",
            "ERROR",
            "CRITICAL"
         ],
         "title": "LogLevel",
         "type": "string"
      },
      "Profile": {
         "description": "Logging profile for the application.",
         "enum": [
            "production",
            "development"
         ],
         "title": "Profile",
         "type": "string"
      },
      "SaslMechanism": {
         "description": "Kafka SASL mechanisms.",
         "enum": [
            "PLAIN",
            "SCRAM-SHA-256",
            "SCRAM-SHA-512"
         ],
         "title": "SaslMechanism",
         "type": "string"
      },
      "SecurityProtocol": {
         "description": "Kafka SASL security protocols.",
         "enum": [
            "SASL_PLAINTEXT",
            "SASL_SSL",
            "PLAINTEXT",
            "SSL"
         ],
         "title": "SecurityProtocol",
         "type": "string"
      }
   },
   "additionalProperties": false,
   "required": [
      "OOK_DATABASE_URL",
      "OOK_DATABASE_PASSWORD",
      "ALGOLIA_APP_ID",
      "ALGOLIA_API_KEY",
      "OOK_OIDC_AUDIENCE"
   ]
}

Fields:
Validators:
field algolia_api_key: SecretStr [Required]#

The Algolia API key

field algolia_app_id: str [Required]#

The Algolia app ID

field algolia_document_index_name: str = 'document_dev'#

Name of the Algolia document index

field database_password: SecretStr [Required]#

Database password.

field database_url: EnvAsyncPostgresDsn [Required]#

Database URL.

field enable_kafka_consumer: bool = True#

Enable Kafka consumer.

field github_app_id: int | None = None#

The GitHub App ID, as determined by GitHub when setting up a GitHub App.

field github_app_private_key: SecretStr | None = None#

The GitHub app private key. See https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps

Validated by:
field ingest_kafka_topic: str = 'ook.ingest'#

The name of the Kafka topic for the ingest queue.

field intersphinx_active_window: HumanTimedelta = datetime.timedelta(days=30)#

Active window for the intersphinx refresh job. The scheduled refresh only revalidates cached inventories requested by a client within this window; inventories last requested longer ago are skipped (not deleted) until a new request reactivates them.

field intersphinx_negative_ttl: HumanTimedelta = datetime.timedelta(seconds=300)#

Negative-cache TTL for cold-miss intersphinx inventory fetch failures. When an upstream fetch fails on a cold miss the failure is cached for this window; a repeat request inside it returns the error without re-contacting upstream. After the window a new request re-fetches the origin.

field intersphinx_ttl: HumanTimedelta = datetime.timedelta(seconds=3600)#

Freshness TTL for cached intersphinx inventories. An inventory fetched within this window is served as a fresh cache hit; an older one is served stale on the request path while the background refresh job revalidates it.

field kafka: KafkaConnectionSettings [Optional]#

Kafka connection configuration.

field kafka_consumer_group_id: str = 'ook'#

Kafka consumer group ID.

field linkcheck_blocked_recheck_interval: HumanTimedelta = datetime.timedelta(seconds=3600)#

Delay until the next recheck of a bot-blocked link. A block is inconclusive and tends to flap, so blocked links are revisited at this near-term cadence to re-verify.

field linkcheck_broken_min_attempts: int = 3#

Minimum number of consecutive failed attempts before a previously-OK link is declared broken instead of failing.

Constraints:
  • ge = 1

field linkcheck_broken_recheck_interval: HumanTimedelta = datetime.timedelta(days=1)#

Delay until the next recheck of a broken link. Broken links are revisited at this slow cadence so a since-fixed link can heal back to ok/redirected without waiting to be resubmitted.

field linkcheck_broken_threshold: HumanTimedelta = datetime.timedelta(days=2)#

Minimum span of consecutive failures before a previously-OK link is declared broken instead of failing.

field linkcheck_check_retention: HumanTimedelta = datetime.timedelta(days=30)#

Age beyond which link-check submission records are purged by the scheduled linkcheck-recheck maintenance command.

field linkcheck_freshness_ttl: HumanTimedelta = datetime.timedelta(days=1)#

Age below which a URL’s stored check result is considered fresh. URLs submitted with a fresh result are not rechecked; their cached status is reported immediately.

field linkcheck_host_interval: HumanTimedelta = datetime.timedelta(seconds=1)#

Minimum politeness interval between link-check requests to the same host.

field linkcheck_kafka_topic: str = 'ook.linkcheck'#

The name of the Kafka topic for link-check execution requests.

field linkcheck_max_concurrency: int = 10#

Maximum number of concurrent link-check HTTP requests across all hosts.

Constraints:
  • ge = 1

field linkcheck_max_urls_per_check: int = 1000#

Maximum number of unique canonical URLs accepted in a single link-check submission.

Constraints:
  • ge = 1

field linkcheck_recheck_intervals: tuple[HumanTimedelta, ...] = (datetime.timedelta(seconds=3600), datetime.timedelta(seconds=14400), datetime.timedelta(days=1), datetime.timedelta(days=2))#

Delays until the next recheck of a failing link, indexed by the number of consecutive failures so far. The last interval repeats when the failure streak outlasts this schedule.

Constraints:
  • min_length = 1

field linkcheck_request_timeout: HumanTimedelta = datetime.timedelta(seconds=30)#

Total timeout applied to each link-check HTTP request.

field linkcheck_user_agent: str = 'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0 Ook-Linkcheck/0.26.1.dev36+g2bb905bee (+https://github.com/lsst-sqre/ook)'#

User-Agent header sent on every link-check HTTP request (HEAD, GET fallback, and redirect hops). Defaults to a browser-prefixed hybrid carrying the running Ook version and repo URL so the checker stays identifiable while clearing bot-protection zones that block the bare token.

field log_level: LogLevel = LogLevel.INFO#
field name: str = 'ook'#

The application’s name

field oidc_audience: str [Required]#

Audience required of the GitHub Actions OIDC id-tokens clients present as provenance for contributed link-check results. Set it to this deployment’s public base URL (for example https://roundtable.lsst.cloud/ook): the audience is what scopes a minted token to one Ook, so a token minted for the development deployment is not replayable against production. There is no default because a shared one would defeat that, and because only the environment knows its own base URL.

field path_prefix: str = '/ook'#

The URL prefix where the application’s externally-accessible endpoints are hosted.

field profile: Profile = Profile.production#

Application logging profile: ‘development’ or ‘production’.

field slack_webhook: SecretStr | None = None#

Slack webhook for alerts. If set, alerts will be posted to this Slack webhook

validator validate_none_secret  »  github_app_private_key#

Validate a SecretStr setting which may be “None” that is intended to be None.

This is useful for secrets generated from 1Password or environment variables where the value cannot be null.

Parameters:

v (Optional[SecretStr])

Return type:

Optional[SecretStr]

This page was last modified on .