class_docstr: Restricts specified DHT keys to match a Pydantic schema.
  This allows to enforce types, min/max values, require a subkey to contain a public key, etc.
class_docstr_tok: ["Restricts","specified","DHT","keys","to","match","a","Pydantic","schema",".","This","allows","to","enforce","types",",","min\/max","values",",","require","a","subkey","to","contain","a","public","key",",","etc","."]
docstr: Validates ``record`` in two steps:
  
  1. Create a Pydantic model and ensure that no exceptions are thrown.
  
  2. Ensure that Pydantic has not made any type conversions [1]_ while creating the model.
     To do this, we check that the value of the model field is equal
     (in terms of == operator) to the source value.
  
     This works for the iterable default types like str, list, and dict
     (they are equal only if the types match) but does not work for numbers
     (they have a special case allowing ``3.0 == 3`` to be true). [2]_
  
     Because of that, you must always use strict types [3]_ for the number fields
     (e.g. to avoid ``3.0`` to be validated successfully for the ``field: int``).
  
     .. [1] https://pydantic-docs.helpmanual.io/usage/models/#data-conversion
     .. [2] https://stackoverflow.com/a/52557261
     .. [3] https://pydantic-docs.helpmanual.io/usage/types/#strict-types
docstr_tok: ["Validates","``","record","``","in","two","steps",":","1",".","Create","a","Pydantic","model","and","ensure","that","no","exceptions","are","thrown",".","2",".","Ensure","that","Pydantic","has","not","made","any","type","conversions","[","1","]","_","while","creating","the","model",".","To","do","this",",","we","check","that","the","value","of","the","model","field","is","equal","(","in","terms","of","==","operator",")","to","the","source","value",".","This","works","for","the","iterable","default","types","like","str",",","list",",","and","dict","(","they","are","equal","only","if","the","types","match",")","but","does","not","work","for","numbers","(","they","have","a","special","case","allowing","``","3.0","==","3","``","to","be","true",")",".","[","2","]","_","Because","of","that",",","you","must","always","use","strict","types","[","3","]","_","for","the","number","fields","(","e.g",".","to","avoid","``","3.0","``","to","be","validated","successfully","for","the","``","field",":","int","``",")",".","..","[","1","]","https",":","\/\/pydantic-docs.helpmanual.io\/usage\/models\/","#","data-conversion","..","[","2","]","https",":","\/\/stackoverflow.com\/a\/52557261","..","[","3","]","https",":","\/\/pydantic-docs.helpmanual.io\/usage\/types\/","#","strict-types"]
code: def validate(self, record: DHTRecord) -> bool:
      """
      Validates ``record`` in two steps:
  
      1. Create a Pydantic model and ensure that no exceptions are thrown.
  
      2. Ensure that Pydantic has not made any type conversions [1]_ while creating the model.
         To do this, we check that the value of the model field is equal
         (in terms of == operator) to the source value.
  
         This works for the iterable default types like str, list, and dict
         (they are equal only if the types match) but does not work for numbers
         (they have a special case allowing ``3.0 == 3`` to be true). [2]_
  
         Because of that, you must always use strict types [3]_ for the number fields
         (e.g. to avoid ``3.0`` to be validated successfully for the ``field: int``).
  
         .. [1] https://pydantic-docs.helpmanual.io/usage/models/#data-conversion
         .. [2] https://stackoverflow.com/a/52557261
         .. [3] https://pydantic-docs.helpmanual.io/usage/types/#strict-types
      """
  
      if record.key not in self._key_id_to_field_name:
          if not self._allow_extra_keys:
              logger.debug(
                  f"Record {record} has a key ID that is not defined in any of the "
                  f"schemas (therefore, the raw key is unknown)"
              )
          return self._allow_extra_keys
  
      try:
          record = self._deserialize_record(record)
      except ValueError as e:
          logger.debug(e)
          return False
      [field_name] = list(record.keys())
  
      n_outside_schema = 0
      validation_errors = []
      for schema in self._schemas:
          try:
              parsed_record = schema.parse_obj(record)
          except pydantic.ValidationError as e:
              if not self._is_failed_due_to_extra_field(e):
                  validation_errors.append(e)
              continue
  
          parsed_value = parsed_record.dict(by_alias=True)[field_name]
          if parsed_value != record[field_name]:
              validation_errors.append(
                  ValueError(
                      f"The record {record} needed type conversions to match "
                      f"the schema: {parsed_value}. Type conversions are not allowed"
                  )
              )
          else:
              return True
  
      logger.debug(
          f"Record {record} doesn't match any of the schemas: {validation_errors}"
      )
      return False
  
file_path: hivemind/hivemind/dht/schema.py
imports: import re
  from typing import Any, Dict, Optional, Type
  import pydantic
  from hivemind.dht.crypto import RSASignatureValidator
  from hivemind.dht.protocol import DHTProtocol
  from hivemind.dht.routing import DHTID
  from hivemind.dht.validation import DHTRecord, RecordValidatorBase
  from hivemind.utils import get_logger
label_desc: Use image node_id 3 for calling the SchemaValidator obj's underlying member method code with example usage: obj.validate(record) and returns: False, self, False, True