API reference
data_models
Data models for the data extraction evaluation toolkit.
base
Core data models regarding annotations.
AnnotationType
Bases: StrEnum
Enumeration of annotation types.
Source code in deet/data_models/base.py
25 26 27 28 29 | |
Attribute
pydantic-model
Bases: BaseModel
Core attribute definition for data extraction tasks.
Represents a single piece of information to be extracted from documents.
Fields:
-
prompt(str | None) -
output_data_type(AttributeType) -
attribute_id(int) -
attribute_label(str)
Source code in deet/data_models/base.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
enter_custom_prompt(max_tries=5)
Use CLI to add a prompt.
Source code in deet/data_models/base.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
populate_prompt_from_dict(input_dict, *, overwrite=True)
Populate the prompt field in an Attribute instance from a dict.
The dict must contain following fields
- attribute_id
- prompt
and attribute_id(dict) must match self.attribute_id.
NOTE: this would typically be used in a loop to populate prompts for a list of attributes from a csv file where every row represents an attribute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_dict
|
dict[str, Any]
|
An input dict, typically a line in a csv file. |
required |
overwrite
|
bool
|
Overwrite existing val in |
True
|
Source code in deet/data_models/base.py
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
print_tabulated()
Print tabulated version of the contents of this attribute.
Source code in deet/data_models/base.py
213 214 215 216 217 218 | |
write_to_csv(filepath, mode='a')
Write an attribute as a line to a csv file - fields represent columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
outfile destination. |
required |
mode
|
Literal['a', 'w']
|
_w_rite or _a_ppend. |
'a'
|
Source code in deet/data_models/base.py
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
AttributeType
Bases: StrEnum
Enum of permitted attribute data types.
Source code in deet/data_models/base.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
__str__()
Return the string value for JSON serialization.
Source code in deet/data_models/base.py
81 82 83 | |
llm_annotation_response_model()
Return the shared Pydantic sub-model for LLM responses of this type.
One model is built and cached per :class:AttributeType; attributes
with the same type reuse it in :func:build_llm_response_model.
Returns
A Pydantic model class with typed output_data for this type.
Source code in deet/data_models/base.py
97 98 99 100 101 102 103 104 105 106 107 108 | |
missing_annotation_default()
Return default output_data when no gold-standard annotation exists.
Used when synthesizing a placeholder annotation (e.g. comparing LLM output to gold standard where a value was never annotated).
Returns a fresh list or dict for mutable types so callers do not share
state.
Raises:
| Type | Description |
|---|---|
ValueError
|
If this member has no defined default. |
Note
This is not Enum._missing_; that hook resolves unrecognised raw
values when constructing enum members, not per-type defaults.
Source code in deet/data_models/base.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
to_json_type()
Map AttributeType to JS types for the JSON schema.
Source code in deet/data_models/base.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
to_python_type()
Map AttributeType to actual Python types.
Source code in deet/data_models/base.py
85 86 87 88 89 90 91 92 93 94 95 | |
BaseLLMResponse
pydantic-model
Bases: BaseModel
Base for all LLM response models.
Config:
extra:forbid
Source code in deet/data_models/base.py
484 485 486 487 | |
DynamicLLMResponseBase
pydantic-model
Bases: BaseLLMResponse
The base for dynamically generated schemas.
We can expect that each field is typed as a subclass of LLMAnnotationResponse.
Source code in deet/data_models/base.py
508 509 510 511 512 513 514 515 516 517 518 519 520 | |
iter_attribute_responses()
Yield field names and safely typed LLMAnnotationResponses.
Source code in deet/data_models/base.py
515 516 517 518 519 520 | |
GoldStandardAnnotation
pydantic-model
Bases: BaseModel
A single gold standard annotation for an attribute.
raw_data stores the data as it comes from source,
output_data is computed and coerces raw_data into the correct type.
This can change if the AttributeType of the attribute changes.
Fields:
-
attribute(Attribute) -
raw_data(Any) -
annotation_type(AnnotationType) -
additional_text(str | None) -
reasoning(str | None)
Source code in deet/data_models/base.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | |
additional_text = None
pydantic-field
Notes provided by the annotator - usually the citation from the paper containing the context window where the attribute is found
output_data
property
Coerce raw data to correct type based on attribute.
raw_data
pydantic-field
The output data exactly as it was first seen without any coercion to the correct type
reasoning = None
pydantic-field
Reasoning, taken from LLM response
handle_output_data_input(data)
classmethod
Catch instantations with output_data and send this to raw_data.
Source code in deet/data_models/base.py
376 377 378 379 380 381 382 | |
LLMAnnotationResponse
pydantic-model
Bases: BaseModel
LLM response model for a single attribute's annotation.
Used as the base for the per-type sub-models produced by
:meth:AttributeType.llm_annotation_response_model. The attribute identity
is not stored on this model; it is encoded in the parent field name
(attribute_<id>) so the LLM is never asked to repeat (and potentially
mismatch) the id.
output_data is typed Any here and is always overridden with the
attribute's concrete Python type when the per-type sub-model is built.
Config:
extra:forbid
Fields:
-
output_data(Any) -
additional_text(str | None) -
reasoning(str | None)
Source code in deet/data_models/base.py
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | |
additional_text
pydantic-field
Supporting text from document containing the context window where the attribute is found
output_data
pydantic-field
The LLM's annotation for this attribute.
reasoning
pydantic-field
Reasoning or explanation for the annotation decision
LLMInputSchema
pydantic-model
Bases: BaseModel
Schema for data going into the LLM.
Config:
extra:ignore
Fields:
-
prompt(str) -
attribute_id(int) -
output_data_type(AttributeType)
Validators:
Source code in deet/data_models/base.py
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | |
fill_prompt(data, fill_from_field='attribute_label')
pydantic-validator
Fill prompt field if empty.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict
|
the incoming data |
required |
fill_from_field
|
str
|
field to use to fill prompt if empty. Defaults to "attribute_label". |
'attribute_label'
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
the populated data. |
Source code in deet/data_models/base.py
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | |
LLMResponseSchema
pydantic-model
Bases: BaseLLMResponse
Static response schema containing a list of StaticLLMAnnotationResponses.
This structure contains a list of StaticLLMAnnotationResponses, where each response has an attribute_id, and output_data_type is untyped.
Responses of this type are cheaper to request, since the json schema passed to the llm is shorter. However such a schema does not require llms to produce exactly one annotation per attribute, or to make sure that output_data_type matches that defined at the attribute level.
Fields:
Source code in deet/data_models/base.py
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | |
annotations
pydantic-field
List of annotations extracted from the document
StaticLLMAnnotationResponse
pydantic-model
Bases: LLMAnnotationResponse
Untyped LLM annotation response model where attribute_id is defined per annotation.
Fields:
-
output_data(Any) -
additional_text(str | None) -
reasoning(str | None) -
attribute_id(int)
Source code in deet/data_models/base.py
473 474 475 476 477 478 479 480 481 | |
attribute_id
pydantic-field
The ID of the attribute being annotated.
attribute_id_from_response_key(key)
Recover the attribute id from a dynamic-model field name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
A field name such as |
required |
Returns:
| Type | Description |
|---|---|
int
|
The integer attribute id encoded in the key. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deet/data_models/base.py
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | |
attribute_response_key(attribute_id)
Build the dynamic-model field name used for a given attribute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attribute_id
|
int
|
The attribute's unique identifier. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The field name, e.g. |
Source code in deet/data_models/base.py
559 560 561 562 563 564 565 566 567 568 569 570 | |
build_llm_response_model(attributes)
Build a dynamic LLM response model from the selected attributes.
Each attribute becomes a required, correctly typed sub-model keyed by
attribute_<id> on the returned root model. Because every key is required
and extra="forbid" is set at every level, the JSON schema forces the LLM
to return exactly one response per attribute - no missing attributes, no
extra/hallucinated attributes, and output_data constrained to the
attribute's concrete type. This also yields a schema that providers such as
Ollama accept as valid (unlike an Any-typed field).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
list[Attribute]
|
The attributes to extract; must be non-empty. |
required |
Returns:
| Type | Description |
|---|---|
type[DynamicLLMResponseBase]
|
A dynamically created Pydantic model class suitable for use as a |
type[DynamicLLMResponseBase]
|
structured-output schema and for validating the LLM response. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deet/data_models/base.py
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | |
coerce_annotation_to_bool(val)
Coerce an annotation to a bool.
Source code in deet/data_models/base.py
276 277 278 279 280 281 282 283 284 285 286 | |
coerce_annotation_to_float(val)
Coerce an annotation to a float.
Source code in deet/data_models/base.py
303 304 305 306 307 308 309 310 311 312 313 314 | |
coerce_annotation_to_int(val)
Coerce an annotation to a int.
Source code in deet/data_models/base.py
289 290 291 292 293 294 295 296 297 298 299 300 | |
coerce_annotation_to_list(val)
Coerce an annotation to list.
Source code in deet/data_models/base.py
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
coerce_annotation_to_str(val)
Coerce an annotation to a string.
Source code in deet/data_models/base.py
271 272 273 | |
documents
Data models concerning documents and how to represent them in deet.
ContextType
Bases: StrEnum
Types of context that can be provided to the LLM.
Source code in deet/data_models/documents.py
41 42 43 44 45 46 | |
Document
pydantic-model
Bases: BaseModel
Represents a document.
This can be used both for references itemised in a document listing gold standard annotations (e.g. eppi.json) AND for a document coming from a file (e.g. pdf) without linking to a gold standard annotations document with references.
Config:
extra:allowvalidate_assignment:True
Fields:
-
name(str) -
citation(ReferenceFileInput) -
context(str | None) -
context_type(ContextType | None) -
document_id(int | str | None) -
document_identity(DocumentIdentity | None) -
parsed_document(ParsedOutput | None) -
original_doc_filepath(Path | None) -
is_final(bool) -
is_linked(bool)
Source code in deet/data_models/documents.py
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | |
safe_identity
property
Definitely Return an identity. Initialise identity if not set already, or raise an error if this is not possible.
safe_parsed_document
property
Return the parsed_document, or raise an error if document is not linked.
author_year_from_document_identity(substring_strategy)
Create lower-case author_year guess from a Document's
DocumentIdentity field.
The idea is to take the last name of the first author.
NOTE: this can probably improved with more knowledge of how destiny encodes the first_author field.
Returns:
| Name | Type | Description |
|---|---|---|
author_year |
str
|
|
Source code in deet/data_models/documents.py
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | |
init_document_identity(existing_ids=None, *, return_id=True)
Initialise document_identity field using available metadata.
Source code in deet/data_models/documents.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | |
link_parsed_document(parsed_document, original_doc_filepath=None)
Link parsed document and document metadata/reference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parsed_document
|
ParsedOutput
|
the output from the parser |
required |
original_doc_filepath
|
Path
|
full filepath to the original doc. |
None
|
Source code in deet/data_models/documents.py
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | |
load(path)
classmethod
Load linked document from .json.
Source code in deet/data_models/documents.py
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | |
save(path)
Save linked document to .json.
Source code in deet/data_models/documents.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | |
set_abstract_context()
Set the abstract, contained in citation field, as context.
Source code in deet/data_models/documents.py
465 466 467 468 469 470 471 472 473 474 475 476 477 | |
set_context_from_parsed()
Symlink context to parsed_document.text.
Source code in deet/data_models/documents.py
502 503 504 505 506 507 508 | |
validate_final()
Validate Document is permitted to be is_final.
Source code in deet/data_models/documents.py
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | |
validate_linking_complete()
Validate linking is completed if is_linked=True.
Source code in deet/data_models/documents.py
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
DocumentIDSource
Bases: StrEnum
Sources for a given document_id.
Priority is given first to EPPI IDs, or IDs that confirm to the EPPI ID format.
When these do not exist we try strategies that hash information from the document, starting from the external id, and then attempting with other bibliographic information.
Source code in deet/data_models/documents.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
DocumentIdentity
pydantic-model
Bases: BaseModel
A unified identity for a document, deriveable from multiple sources.
document_id:
always int, the canonical internal id assigned by deet.
in current implementation, mirrors eppi item ids.
internal_id:
a symlink to document_id.
external_id:
ID inherited verbatim from source citation/gold standard
data. this can be string or int, no validation is performed on
it.
Fields:
-
document_id(int | None) -
document_id_source(DocumentIDSource | None) -
external_id(str | int | None) -
doi(str | None) -
first_author(str | None) -
year(str | None)
Source code in deet/data_models/documents.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
internal_id
property
Return the internal ID (alias for document_id for backward compatibility).
populate_id(existing_ids=None, hierarchy=None)
Populate document_id using a hierarchical list of ID creation methods.
Tries each method in order until a unique ID is generated. If an ID conflicts with existing_ids, tries the next method. RANDINT always succeeds as fallback.
NOTE: we will have to implement some sort of matching thing, if we are concerned that an id-collision might be becuase we have already parsed&linked a document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
existing_ids
|
set[int] | None
|
List of existing IDs to check for conflicts. |
None
|
hierarchy
|
list[DocumentIDSource] | None
|
Ordered list of DocumentIDSource methods to try. Defaults to [EPPI_ITEM_ID, DOI_AUTHOR_YEAR, DOI_ID, AUTHOR_YEAR_ID, RANDINT]. |
None
|
Raises:
| Type | Description |
|---|---|
BadDocumentIdError
|
If unable to generate unique ID (should never happen as RANDINT is always in hierarchy). |
Source code in deet/data_models/documents.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
GoldStandardAnnotatedDocument
pydantic-model
Bases: BaseModel
A document with its gold standard annotations.
Fields:
-
document(DocumentType) -
annotations(list[GoldStandardAnnotationType])
Source code in deet/data_models/documents.py
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | |
get_attribute_annotation(attribute)
Get the value of the annotation of the corresponding attribute.
Source code in deet/data_models/documents.py
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | |
GoldStandardAnnotatedDocumentList
pydantic-model
Bases: BaseModel
A list of GoldStandardAnnotatedDocuments (or any subclasses thereof). This list is indexed to enable easy retrieval by document_id.
Fields:
-
gold_standard_annotations(Sequence[GoldStandardAnnotatedDocumentType])
Source code in deet/data_models/documents.py
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | |
annotation_index
cached
property
Cached index to enable retrieving annotated documents by id.
get_by_id(document_id)
Get GoldStandardAnnotatedDocuments where document.document_identity matches document_identity.
Source code in deet/data_models/documents.py
616 617 618 619 620 621 622 623 624 625 626 | |
enums
A store for plain enums, so they can quickly be imported in the CLI. We can use these to set argument types and defaults, without needing large imports, that would slow the CLI down during autocomplete, or when asking for --help.
CustomPromptPopulationMethod
Bases: StrEnum
Methods of populating prompts.
Source code in deet/data_models/enums.py
11 12 13 14 15 | |
EvaluationStrategyName
Bases: StrEnum
A list of allowable names for evaluation strategies.
Note: make sure that each of these is in the strategy registry in deet.data_models.evaluation_strategies.init.py.
Source code in deet/data_models/enums.py
18 19 20 21 22 23 24 25 26 27 | |
eppi
EPPI-specific data models extending the core models.
AttributeAnswerCoT
pydantic-model
Bases: BaseModel
Detailed answer format for a single attribute with reasoning.
Fields:
Source code in deet/data_models/eppi.py
403 404 405 406 407 408 409 410 411 412 413 | |
answer
pydantic-field
The answer to the question, 'True' or 'False'
attribute_name
pydantic-field
The name of the attribute being asked about
citation
pydantic-field
The citation from the Research Information to support the answer
reasoning
pydantic-field
The reasoning behind the answer
BatchAnswerFormatCoT
pydantic-model
Bases: BaseModel
Batch answers for all attributes with reasoning.
Fields:
Source code in deet/data_models/eppi.py
416 417 418 419 420 421 | |
answers
pydantic-field
List of answers for each attribute
EppiAttribute
pydantic-model
Bases: Attribute
EPPI-specific attribute with additional fields.
Extends the core Attribute class with EPPI-specific metadata and hierarchy information.
Uses alias generators to automatically map camelCase EPPI JSON fields to snake_case Python fields.
Config:
validate_by_name:Truevalidate_by_alias:True
Fields:
-
prompt(str | None) -
attribute_id(int) -
attribute_selection_type(EppiAttributeSelectionType) -
output_data_type(AttributeType) -
attribute_label(str) -
attribute_set_description(str | None) -
hierarchy_path(str | None) -
hierarchy_level(int) -
is_leaf(bool) -
parent_attribute_id(int | None) -
attribute_description(str | None)
Source code in deet/data_models/eppi.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
attribute_description = None
pydantic-field
Detailed description explaining what this attribute represents
attribute_set_description = None
pydantic-field
Description of the attribute set this attribute belongs to
hierarchy_level = 0
pydantic-field
Numeric level indicating depth in the attribute hierarchy (0 = root level)
hierarchy_path = None
pydantic-field
Dot-separated path showing the hierarchical position of this attribute
is_leaf = True
pydantic-field
Whether this attribute is a leaf node (has no child attributes)
parent_attribute_id = None
pydantic-field
ID of the parent attribute in the hierarchy
EppiAttributeSelectionType
Bases: StrEnum
AttributeType as it appears in eppi json.
Source code in deet/data_models/eppi.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
EppiCodeSet
pydantic-model
Bases: BaseModel
Represents a single CodeSet from EPPI JSON.
CodeSets contain hierarchical attribute definitions used in EPPI-Reviewer.
Fields:
Source code in deet/data_models/eppi.py
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | |
get_attributes_list()
Extract AttributesList from the CodeSet.
Source code in deet/data_models/eppi.py
363 364 365 366 367 | |
EppiDocument
pydantic-model
Bases: Document
EPPI-specific document.
Uses alias generators to automatically map camelCase EPPI JSON fields to snake_case Python fields.
Config:
validate_by_name:Truevalidate_by_alias:True
Fields:
-
citation(ReferenceFileInput) -
context(str | None) -
context_type(ContextType | None) -
document_identity(DocumentIdentity | None) -
parsed_document(ParsedOutput | None) -
original_doc_filepath(Path | None) -
is_final(bool) -
is_linked(bool) -
name(str) -
document_id(int | str) -
parent_title(str | None) -
short_title(str | None) -
date_created(datetime | None) -
created_by(str | None) -
edited_by(str | None) -
year(int | None) -
month(str | None) -
abstract(str | None) -
authors(str | None) -
keywords(str | None) -
doi(str | None)
Validators:
-
empty_year_string_to_none→year -
parse_date_string→date_created -
populate_citation_field
Source code in deet/data_models/eppi.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |
empty_year_string_to_none(value)
pydantic-validator
Parse an empty string year to None or return as is.
Source code in deet/data_models/eppi.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | |
parse_date_string(value)
pydantic-validator
Parse a string datetime to native datetime.
Source code in deet/data_models/eppi.py
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
populate_citation_field(data)
pydantic-validator
Populate the citation field with a Destiny
reference derived from the EPPI data.
Source code in deet/data_models/eppi.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |
EppiGoldStandardAnnotatedDocument
pydantic-model
Bases: GoldStandardAnnotatedDocument[EppiDocument, EppiGoldStandardAnnotation]
EPPI-specific gold standard annotated document.
Fields:
-
document(DocumentType) -
annotations(list[GoldStandardAnnotationType])
Source code in deet/data_models/eppi.py
348 349 350 351 | |
EppiGoldStandardAnnotation
pydantic-model
Bases: GoldStandardAnnotation
EPPI-specific gold standard annotation.
In EPPI-Reviewer context, an "arm" refers to a study group or intervention group within a research study (e.g., "Treatment Group", "Control Group", "Placebo Group"). Each annotation is associated with a specific arm to indicate which study group the extracted information relates to.
Fields:
-
attribute(Attribute) -
raw_data(Any) -
annotation_type(AnnotationType) -
additional_text(str | None) -
reasoning(str | None) -
arm_id(int | None) -
arm_title(str | None) -
arm_description(str | None) -
item_attribute_full_text_details(list[EppiItemAttributeFullTextDetails] | None)
Source code in deet/data_models/eppi.py
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | |
arm_description = None
pydantic-field
Detailed description of the study arm
arm_id = None
pydantic-field
ID of the study arm this annotation relates to
arm_title = None
pydantic-field
Title or name of the study arm
item_attribute_full_text_details = None
pydantic-field
List of detailed text extracts and arm-specific information for this annotation
EppiItemAttributeFullTextDetails
pydantic-model
Bases: BaseModel
EPPI-specific item attribute full text details.
Arm specific information, exact text keywords for the attribute.
Fields:
Validators:
Source code in deet/data_models/eppi.py
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | |
validate_at_least_one_field(data)
pydantic-validator
Ensure at least one field is not None.
Source code in deet/data_models/eppi.py
307 308 309 310 311 312 313 314 315 316 317 | |
EppiRawData
pydantic-model
Bases: BaseModel
Represents the complete EPPI JSON structure.
This model validates and structures the raw EPPI JSON data, making it easier to work with and validate.
Fields:
Source code in deet/data_models/eppi.py
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | |
extract_all_attributes(flatten_hierarchy_func)
Extract and flatten attributes from all CodeSets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flatten_hierarchy_func
|
Callable[[list], list]
|
Function to flatten attribute hierarchy |
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of flattened attribute dictionaries |
Source code in deet/data_models/eppi.py
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | |
parse_citation_to_destiny(reference)
Create a ReferenceFileInput object from document data.
NOTE: we are not using the wrapping parser method in repository as it is for the whole document, and if it fails, we wouldn't be able to map a destiny reference.
See https://github.com/destiny-evidence/destiny-repository/issues/458
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reference
|
dict[str, Any]
|
one reference from the eppi json. |
required |
Source code in deet/data_models/eppi.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
sanitise_doi(doi_candidate, *, raise_on_fail=False)
Clean DOI strings in EPPI jsons.
Source code in deet/data_models/eppi.py
38 39 40 41 42 43 44 45 46 47 48 49 50 | |
evaluation
Data models to help with evaluation.
AttributeCountMetric
dataclass
Bases: AttributeMetric
An integer count metric (e.g. n_gold_instances).
Source code in deet/data_models/evaluation.py
79 80 81 82 83 | |
AttributeMetric
dataclass
Base row for one metric on one attribute in an extraction run.
Source code in deet/data_models/evaluation.py
63 64 65 66 67 68 69 | |
AttributeMetricsReport
pydantic-model
Bases: BaseModel
Per-attribute metrics block for metrics.json / wide metrics.csv.
Reuses :class:~deet.data_models.base.AttributeType for attribute_type.
Count keys are integers; score keys are floats (None means not
computable — omitted from JSON, blank in CSV).
Fields:
-
attribute_id(int) -
attribute_label(str) -
attribute_type(AttributeType) -
counts(dict[str, int]) -
metrics(dict[str, float | None])
Source code in deet/data_models/evaluation.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |
AttributeScoreMetric
dataclass
Bases: AttributeMetric
A float score metric (may be None when not computable).
Source code in deet/data_models/evaluation.py
72 73 74 75 76 | |
RunMetricsReport
pydantic-model
Bases: BaseModel
Machine-readable evaluation report for one extraction run.
Serialises to metrics.json and wide metrics.csv (one entry / row per
attribute, metric names as keys).
Fields:
-
extraction_run_id(str) -
format_version(int) -
attributes(list[AttributeMetricsReport])
Source code in deet/data_models/evaluation.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
from_attribute_metrics(*, extraction_run_id, calculated_metrics, format_version=1)
classmethod
Group row-level metric values into a run report.
:class:AttributeCountMetric values go under counts as integers;
:class:AttributeScoreMetric values go under metrics (including
None for blank CSV cells). :meth:to_json omits None scores.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
extraction_run_id
|
str
|
Run folder / run id. |
required |
calculated_metrics
|
list[AttributeMetric]
|
Flat metric rows from the evaluator. |
required |
format_version
|
int
|
Schema version written to JSON. |
1
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RunMetricsReport
|
class: |
Source code in deet/data_models/evaluation.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
from_json(filepath)
classmethod
Load a report from a metrics.json file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
Path to a JSON file written by :meth: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Validated |
RunMetricsReport
|
class: |
Source code in deet/data_models/evaluation.py
165 166 167 168 169 170 171 172 173 174 175 176 177 | |
to_csv(filepath)
Write this report as a wide metrics.csv (one row per attribute).
None score values become empty cells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
Destination path (must end in |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in deet/data_models/evaluation.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
to_json(filepath)
Write this report to metrics.json.
None score values are omitted so inapplicable keys are absent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
Destination path (must end in |
required |
Source code in deet/data_models/evaluation.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
preferred_metric_column_names()
Preferred wide-CSV metric column order.
Score bases and stratification suffixes are derived from
:data:~deet.evaluators.metrics.METRICS_BY_ATTRIBUTE_TYPE and
:data:~deet.evaluators.source_fidelity.SOURCE_FIDELITY_ATTRIBUTE_TYPES.
Custom metrics passed at evaluate time are not listed here; they are
appended alphabetically when writing CSV (see :meth:RunMetricsReport.to_csv).
Source code in deet/data_models/evaluation.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | |
evaluation_strategies
Public interfact for evaluation strategies.
Exports the base class and concrete strategy implementations, maintains the strategy registry that maps strategy names to their constructors.
base
Evaluation strategy framework: dividing documents between stages for evaluation.
This module defines base classes for managing how documents are partitioned across evaluation stages. This module provides three abstractions:
BaseEvaluationStage: An enum of the concrete stages for a strategy.BaseSplits: A Pydantic model persisting the partition of documents across stages and the current stage of an experiment.BaseEvaluationStrategy: The orchestrator, managing splits and providing interactive and programmatic interfaces for moving documents between stages.
Concrete strategies implement these abstractions and are registered
in the package __init__.py.
BaseEvaluationStage
Bases: StrEnum
Defines the stages of an evaluation strategy.
Each of these stages is mapped to a list of IDs in the splits model below.
Source code in deet/data_models/evaluation_strategies/base.py
36 37 38 39 40 41 | |
BaseEvaluationStrategy
Bases: ABC
Orchestrate how a project's documents are divided into evaluation stages.
An evaluation strategy defines stages (via a BaseEvaluationStage enum)
and how to move documents through them.
When deet.extractors.cli_helpers.run_extraction_pipeline is called, it
filters documents down to those that are assigned to the current stage.
Each subclass implements its own methods for managing splits, but each
must implement a run_splits_wizard method, which is called when a user
runs deet experiments splits.
Source code in deet/data_models/evaluation_strategies/base.py
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
__init__(project)
Initialise and set splits.
Source code in deet/data_models/evaluation_strategies/base.py
163 164 165 166 | |
get_active_ids(project)
Return the document IDs in the current stage to run the pipeline on.
Source code in deet/data_models/evaluation_strategies/base.py
172 173 174 | |
run_splits_wizard(project, *, action=None, size=None, experiment=None)
abstractmethod
Run the interactive workflow for moving documents between stages.
By default (action=None), presents an interactive prompt listing the
actions available in the current stage and strategy, and the user selects
one. Optionally, --action can be passed to skip the prompt (for
scripted use). Unknown or stage-inappropriate actions raise an error rather
than silently failing.
Further details (e.g. how many documents to move) are prompted for
interactively if not provided (size, experiment). Subclasses
implement the concrete stage transitions and validation logic.
Note
The valid actions depend on both the strategy and the current stage,
which are only known at runtime. Static CLI subcommands would
misleadingly list all actions in --help regardless of whether they
apply to the project's configured strategy and current stage. Instead,
the action is discovered interactively (the prompt shows what's valid
now) or specified as an unconstrained string for scripted use.
Source code in deet/data_models/evaluation_strategies/base.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
snapshot(artefacts)
Persist stategy state with an experiment run's artefacts.
Source code in deet/data_models/evaluation_strategies/base.py
176 177 178 | |
BaseSplits
pydantic-model
Bases: BaseModel
Base object for persisting how document IDs are used for an experiment.
An evaluation strategy divides a project's documents into stages (e.g. dev, validation, and test). This model stores that partition, alongside the stage the experiment is currently in, and serialises to/from JSON.
Subclasses define the concrete shape and must:
- declare one model field per stage
- bind StageT to the strategy's stage enum
- set the _STAGE_FIELD_NAMES class var mapping each stage in the enum
to its model field
This contract is enforced on definition, and ensures that generic methods can be defined here for DRYness.
Fields:
-
current_stage(StageT)
Source code in deet/data_models/evaluation_strategies/base.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
active_ids
property
Return the current active ids, based on the current stage.
__pydantic_init_subclass__(**kwargs)
classmethod
Validate whether a subclass honours contract defined by this base class.
Source code in deet/data_models/evaluation_strategies/base.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | |
add_to_stage(stage, project_doc_ids, size)
Sample from unassigned and add to a stage.
Source code in deet/data_models/evaluation_strategies/base.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |
dump_to_json(path)
Persist split state to json.
Source code in deet/data_models/evaluation_strategies/base.py
100 101 102 | |
get_unassigned_ids(project_doc_ids)
Filter a collection of document IDs to those which have not been assigned.
Source code in deet/data_models/evaluation_strategies/base.py
108 109 110 111 112 113 114 | |
dev_val_test
The dynamic dev-val-test splitting strategy.
This is described in detail at https://destiny-evidence.github.io/evaluation-book/index-1/#chunked-evaluation-data
DevValTestEvaluationStage
Bases: BaseEvaluationStage
Describes the possible evaluation stages.
Inherits from BaseEvaluationStage, and defines each of the following stages for the dev-val-test strategy.
- DEVELOPMENT is used to iterate and improve prompts/configuration.
- VALIDATION is used to validate prompts on data they have not been tuned for.
- TEST is used for a final assessment.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
DevValTestEvaluationStrategy
Bases: BaseEvaluationStrategy[DevValTestSplits]
Strategy to manage dynamic splitting into dev-val-test.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
accept_validation(project_doc_ids)
Accept the results of validation run and do final evaluation of test set.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | |
add_to_development(project_doc_ids, size=None)
Add unassigned documents to the development pool.
Randomly samples from the unassigns documents and adds them to the development set.
Persists the updated splits to dist and notifies the user of actions taken.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_doc_ids
|
list[int]
|
All document IDs in the project (to determine which are unassigned) |
required |
size
|
int | None
|
Number of documents to randomly sample and add (prompted for if None). |
None
|
Raises:
| Type | Description |
|---|---|
SplitsValidationError
|
If size exceeds the number of unassigned documents |
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | |
finalise_test(project_doc_ids)
Add all remaining docs to test.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
reject_validation()
Merge validation IDs into development and continue developing.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
340 341 342 343 344 345 | |
run_splits_wizard(project, *, action=None, size=None, experiment=None)
Run the splits wizard.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
run_validation_interactive(project_doc_ids, size, experiment)
Orchestrate validation (prompt for args and dispatch validation).
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | |
validate_run(size, project_doc_ids, experiment)
Evaluate a past experiment config and eval against a fresh validation set.
Randomly samples previously unsassigned documents into the validation set, evaluates given experiment config and prompts against them, and updates the splits state with the validation run ID for later reference
Persists the updated splits and a snapshot of strategy state with the experiment artefacts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
Number of documents to randomly sample |
required |
project_doc_ids
|
list[int]
|
All document IDs in the project (to determine unassigned) |
required |
experiment
|
ExperimentArtefacts
|
The ExperimentArtefacts to evaluate (from a prior run) |
required |
Raises:
| Type | Description |
|---|---|
SplitsValidationError
|
If size exceeds the number of unassigned documents |
Note
The CLI calls choose_experiment() interactively, then passes it here.
For programmatic use, provide the experiment directly.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
DevValTestSplits
pydantic-model
Bases: BaseSplits
Model to record how documents are allocated across dev-val-test splits.
Fields:
-
current_stage(DevValTestEvaluationStage) -
development_ids(list[int]) -
validation_ids(list[int]) -
test_ids(list[int]) -
validation_run_id(str | None)
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
load_or_init(file_path)
classmethod
Load splits from file, or initialise if empty or invalid.
Note
It may be invalid if the evaluation strategy was switched. In this case, it would make sense to start a fresh instantiation
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
EvaluationDecisionSpec
Bases: TypedDict
Definition of the shape of choices presented to user, and how to act on them.
Source code in deet/data_models/evaluation_strategies/dev_val_test.py
89 90 91 92 93 94 95 96 | |
null
Null Evaluation strategy (== state prior to introduction of strategies).
NullEvaluationStrategy
Bases: BaseEvaluationStrategy[NullSplits]
The default evaluation strategy (use all documents).
Source code in deet/data_models/evaluation_strategies/null.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
run_splits_wizard(project, *, action=None, size=None, experiment=None)
Run the splits wizard.
Source code in deet/data_models/evaluation_strategies/null.py
47 48 49 50 51 52 53 54 55 56 57 58 59 | |
NullSplits
pydantic-model
Bases: BaseSplits
Records document IDs used in the null strategy.
Fields:
Source code in deet/data_models/evaluation_strategies/null.py
26 27 28 29 30 31 32 33 34 35 | |
NullStage
Bases: BaseEvaluationStage
Stages of the null strategy.
In this case, the only stage is ALL -> evaluate all documents.
Source code in deet/data_models/evaluation_strategies/null.py
16 17 18 19 20 21 22 23 | |
extraction
Data models for LLM extraction outputs.
DocumentExtractionResult
pydantic-model
Bases: BaseModel
Result of extracting data from a single document via an LLM.
Fields:
-
annotations(list[GoldStandardAnnotation]) -
messages(list[dict[str, Any]]) -
input_tokens(int) -
output_tokens(int) -
model(str | None) -
total_cost_usd(float | None) -
llm_call_seconds(float) -
timestamp(datetime)
Validators:
Source code in deet/data_models/extraction.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
compute_total_cost_usd()
pydantic-validator
Populate total_cost_usd from tokens and model (estimate_cost_usd).
Source code in deet/data_models/extraction.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 | |
DocumentParsingStats
pydantic-model
Bases: BaseModel
Parsing timing for a single document during document preparation.
Fields:
Source code in deet/data_models/extraction.py
78 79 80 81 82 | |
ExtractionPipelineStage
Bases: StrEnum
Named stages timed during an extraction pipeline run.
Source code in deet/data_models/extraction.py
14 15 16 17 18 19 20 21 | |
ExtractionRunMetadata
pydantic-model
Bases: BaseModel
Aggregate metadata for a batch extraction run.
Fields:
-
model(str | None) -
total_input_tokens(int) -
total_output_tokens(int) -
total_cost_usd(float | None) -
per_document(dict[str, PerDocumentExtractionStats]) -
total_pipeline_duration_seconds(float | None) -
stage_durations_seconds(dict[str, float]) -
notes(RunMetadataNotes) -
timestamp(datetime)
Source code in deet/data_models/extraction.py
123 124 125 126 127 128 129 130 131 132 133 134 | |
ExtractionRunOutput
pydantic-model
Bases: BaseModel
Top-level output from a batch extraction run.
Fields:
-
annotated_documents(list[GoldStandardAnnotatedDocument]) -
metadata(ExtractionRunMetadata)
Source code in deet/data_models/extraction.py
137 138 139 140 141 | |
PerDocumentExtractionStats
pydantic-model
Bases: BaseModel
Per-document tokens and timing for an extraction run.
Fields:
-
input_tokens(int) -
output_tokens(int) -
parsing_seconds(float | None) -
parsing_skipped(bool) -
llm_call_seconds(float)
Source code in deet/data_models/extraction.py
85 86 87 88 89 90 91 92 | |
RunMetadataNotes
pydantic-model
Bases: BaseModel
Human-readable notes for timing fields in run metadata.
Fields:
-
total_pipeline_duration_seconds(str) -
stage_durations_seconds(dict[str, str]) -
per_document(dict[str, str])
Source code in deet/data_models/extraction.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
pipeline_stage_notes()
Return human-readable notes keyed by pipeline stage name.
Source code in deet/data_models/extraction.py
44 45 46 47 48 | |
pipeline
Models to employ for implementing DEET jobs in sequential, harmonised pipelines.
BaseExecutor
Bases: ABC
Abstract base class for all executors.
Source code in deet/data_models/pipeline.py
104 105 106 107 108 109 110 111 112 113 114 | |
CodeExecutor
Bases: BaseExecutor
Executor for Python callable.
Source code in deet/data_models/pipeline.py
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | |
EgressMethod
Bases: StrEnum
An enum of egree methods for a PipelineStage.
Source code in deet/data_models/pipeline.py
60 61 62 63 64 | |
Executor
A wrapper for all kinds of executors.
Source code in deet/data_models/pipeline.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
__init__(executor)
Init new executor instance.
Source code in deet/data_models/pipeline.py
325 326 327 | |
execute(job, args=None, kwargs=None)
Execute a job.
Source code in deet/data_models/pipeline.py
329 330 331 332 333 334 335 336 | |
IngressMethod
Bases: StrEnum
An enum of ingress methods for a PipelineStage.
Source code in deet/data_models/pipeline.py
51 52 53 54 55 56 57 | |
Job
pydantic-model
Bases: BaseModel
The attributes describing a specific job.
Config:
arbitrary_types_allowed:True
Fields:
-
name(str) -
job_format(JobFormat) -
job_type(JobType | list[JobType]) -
language(Language) -
ingress_method(IngressMethod | None) -
egress_method(EgressMethod) -
job(Callable | Path) -
script_args(list[str] | None) -
func_args(list[Any] | None) -
func_kwargs(dict[str, Any] | None) -
capture_output(bool) -
executor(Executor)
Source code in deet/data_models/pipeline.py
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
run_job()
Run the job defined in this model instance.
Source code in deet/data_models/pipeline.py
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
JobExecutionError
Bases: Exception
To raise when a job hits a generic error.
Source code in deet/data_models/pipeline.py
47 48 | |
JobFormat
Bases: StrEnum
An enum of job formats.
Jobs are the building blocks of pipeline stages. The job format describes the 'medium' in which the job is provided to the job object.
Source code in deet/data_models/pipeline.py
67 68 69 70 71 72 73 74 75 76 77 | |
JobType
Bases: StrEnum
An enum of job types.
This is a descriptive label of the broad category of what the job is doing.
Source code in deet/data_models/pipeline.py
80 81 82 83 84 85 86 87 88 89 90 91 | |
Language
Bases: StrEnum
An enum of permitted languages a job can be specified in.
Source code in deet/data_models/pipeline.py
94 95 96 97 98 99 100 101 | |
MissingBinaryError
Bases: Exception
To raise when we're missing a binary required to run a script.
Source code in deet/data_models/pipeline.py
43 44 | |
Pipeline
pydantic-model
Bases: BaseModel
A complete pipeline consisting of several PipelineStage objects.
Fields:
-
name(str) -
stages(list[PipelineStage])
Source code in deet/data_models/pipeline.py
472 473 474 475 476 477 478 479 480 481 482 483 484 | |
run()
Run all pipeline stages.
Source code in deet/data_models/pipeline.py
480 481 482 483 484 | |
PipelineStage
pydantic-model
Bases: BaseModel
A stage in a DEET pipeline.
Fields:
-
name(str) -
skip_jobs_if_failed(bool) -
input_file(Path | None) -
data(Any | None) -
jobs(Job | list[Job]) -
logfile(Path | None) -
default_func_args(list[Any] | None) -
default_func_kwargs(dict[str, Any] | None)
Validators:
-
convert_jobs_to_list→jobs
Source code in deet/data_models/pipeline.py
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | |
convert_jobs_to_list(v)
pydantic-validator
Convert jobs to list of jobs if just one job supplied.
Source code in deet/data_models/pipeline.py
395 396 397 398 399 400 401 | |
run_jobs(func_args=None, func_kwargs=None)
Run all jobs in a pipeline stage.
Source code in deet/data_models/pipeline.py
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | |
write_stage_logfile(payload, filepath)
staticmethod
Write logfile for a specific stage.
Source code in deet/data_models/pipeline.py
403 404 405 406 | |
ScriptExecutor
Bases: BaseExecutor
An executor class for different kinds of scripts.
Source code in deet/data_models/pipeline.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
__init__(python_path=None, r_path=None, bash_path=Path('/bin/bash'))
Create ScriptExecutor instance.
Source code in deet/data_models/pipeline.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
bash_executor(script_path, args, *, capture_output=True)
Execute a bash script.
Source code in deet/data_models/pipeline.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
python_executor(script_path, args, *, capture_output=True)
Execute a python script.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
script_path
|
Path
|
file path to script. |
required |
args
|
list[str]
|
args to run with script. |
required |
capture_output
|
bool
|
Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
None | str
|
None | str: output from stdout or None. |
Source code in deet/data_models/pipeline.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | |
r_executor(script_path, args, *, capture_output=True)
Execute an R script.
Source code in deet/data_models/pipeline.py
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
verify_filetype(filename, filetype)
staticmethod
Verify a given file is of a given filetype via checking the ending.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
Name of file. |
required |
filetype
|
Literal[".py", ".R", ".sh"]
|
|
required |
Raises:
| Type | Description |
|---|---|
WrongFiletypeError
|
When ending doesnt match the input. |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if OK. |
Source code in deet/data_models/pipeline.py
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
WrongFiletypeError
Bases: Exception
Raise for wrong filetype.
Source code in deet/data_models/pipeline.py
30 31 32 33 34 35 36 37 38 39 40 | |
__init__(msg='Supplied filetype is not correct.', *args, **kwargs)
Init the exception with default message.
Source code in deet/data_models/pipeline.py
33 34 35 36 37 38 39 40 | |
jobify(name, job_type=JobType.DATA_PROCESSING, func_args=None, func_kwargs=None, *, capture_output=True)
Decorate to wrap a function as a Job instance.
Source code in deet/data_models/pipeline.py
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | |
stage_from_job(job=None, stage_name=None, input_file=None, logfile=None, *, skip_jobs_if_failed=False)
stage_from_job(
job: Job,
stage_name: str | None = None,
input_file: Path | None = None,
logfile: Path | None = None,
*,
skip_jobs_if_failed: bool = False,
) -> PipelineStage
stage_from_job(
job: None = None,
stage_name: str | None = None,
input_file: Path | None = None,
logfile: Path | None = None,
*,
skip_jobs_if_failed: bool = False,
) -> Callable[[Job], PipelineStage]
Create a PipelineStage from a single Job.
Can be used as a function or as a decorator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job
|
Job | None
|
The Job to wrap in a PipelineStage. If None, returns a decorator. |
None
|
stage_name
|
str | None
|
Name for the stage. Defaults to job name if not provided. |
None
|
input_file
|
Path | None
|
Optional input file for the stage. |
None
|
logfile
|
Path | None
|
Optional logfile for the stage. |
None
|
skip_jobs_if_failed
|
bool
|
Whether to skip remaining jobs if one fails. |
False
|
Returns:
| Type | Description |
|---|---|
PipelineStage | Callable[[Job], PipelineStage]
|
PipelineStage or decorator function. |
Examples:
As a function:
>>> stage = stage_from_job(my_job, stage_name="my_stage")
As a decorator:
>>> @stage_from_job(stage_name="my_stage")
... @jobify(name="my_job")
... def my_function():
... pass
Source code in deet/data_models/pipeline.py
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | |
processed_gold_standard_annotations
Data models for procesed annotation data.
ProcessedAnnotationData
pydantic-model
Bases: ProcessedAttributeData[AttributeT]
Structured result from annotation processing.
This model provides a clean, validated structure for all processed annotation data with useful properties and methods.
Fields:
-
attributes(list[AttributeT]) -
documents(list[DocumentType]) -
annotations(list[GoldStandardAnnotationType]) -
annotated_documents(list[GoldStandardAnnotatedDocumentType]) -
attribute_id_to_label(dict[int, str])
Source code in deet/data_models/processed_gold_standard_annotations.py
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
all_doc_ids
property
Return a list of document IDs present in the dataset.
total_annotated_documents
property
Total number of documents with annotations.
total_annotations
property
Total number of annotations processed.
total_documents
property
Total number of documents processed.
export_linkage_mapper_csv(file_path, document_base_dir=None, path_type='file')
Export a csv mapper to link document IDs and filenames.
If document_base_dir is not None, then attempt to pre-populate this.
Source code in deet/data_models/processed_gold_standard_annotations.py
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
filter_documents_by_ids(target_ids)
Filter documents and annotated documents in-place to match target IDs.
Source code in deet/data_models/processed_gold_standard_annotations.py
403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
get_annotations_by_annotation_type(annotation_type)
Get all annotations of a specific type (human/llm).
Source code in deet/data_models/processed_gold_standard_annotations.py
314 315 316 317 318 319 320 | |
get_attribute_by_id(attribute_id)
Get an attribute by its ID.
Source code in deet/data_models/processed_gold_standard_annotations.py
322 323 324 325 326 327 | |
get_attributes_by_attribute_type(attribute_type)
Get all attributes of a specific type.
Source code in deet/data_models/processed_gold_standard_annotations.py
299 300 301 302 303 304 305 | |
get_documents_with_annotations()
Get only documents that have annotations.
Source code in deet/data_models/processed_gold_standard_annotations.py
307 308 309 310 311 312 | |
ProcessedAttributeData
pydantic-model
Bases: BaseModel
Structured result from annotation processing.
Contains only attributes, so the ProcessedAnnotationData class can subclass this
Fields:
-
attributes(list[AttributeT])
Source code in deet/data_models/processed_gold_standard_annotations.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
total_attributes
property
Total number of attributes processed.
export_attributes_csv_file(filepath)
Write a csv file containing all attributes for prompt population.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path
|
outfile path. |
required |
Source code in deet/data_models/processed_gold_standard_annotations.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
populate_custom_prompts(method, filepath=None, **kwargs)
Populate custom prompts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath
|
Path | None
|
infile path. |
None
|
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
if method is file and there's no filepath. |
Source code in deet/data_models/processed_gold_standard_annotations.py
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | |
ProcessedEppiAnnotationData
pydantic-model
Bases: ProcessedAnnotationData[EppiAttribute, EppiDocument, EppiGoldStandardAnnotation, EppiGoldStandardAnnotatedDocument]
Structured result from EPPI annotation processing.
This differs from Base ProcessedAnnotationData by specifying raw_data as an EppiRawData object
Fields:
-
attributes(list[AttributeT]) -
documents(list[DocumentType]) -
annotations(list[GoldStandardAnnotationType]) -
annotated_documents(list[GoldStandardAnnotatedDocumentType]) -
attribute_id_to_label(dict[int, str]) -
raw_data(EppiRawData | None)
Source code in deet/data_models/processed_gold_standard_annotations.py
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | |
populate_custom_prompts(method, filepath=None, **kwargs)
Populate custom prompts, then recompute each annotation's raw_data.
An EPPI Report.json (or similar) only carries EPPI-Reviewer field names;
it does not set each attribute's output_data_type in DEET. Ingested
attributes default to bool from the codeset. The custom prompt
definition file (e.g. a CSV with output_data_type such as
string or bool) is the source of those types, not the JSON. After
the base method updates prompts and types, we re-apply
eppi_output_data_from_eppi_fields so raw_data matches
AdditionalText and the updated type (e.g. "32" for a string count,
not boolean True from initial ingest only).
Source code in deet/data_models/processed_gold_standard_annotations.py
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | |
project
Data models for DeetProject.
DeetProjects handle the one-time definition of configuration options, and create standardised directory structures to store resources like prompt csvs, link maps, experiment results.
DeetProject
pydantic-model
Bases: BaseModel
A deet "project" that lives in a directory. Configuration options are defined here once, and elicited through an interactive wizard.
Config:
json_encoders:{Path: str}extra:ignore
Fields:
-
name(str) -
gold_standard_data_format(SupportedImportFormat) -
gold_standard_data_path(Path) -
pdf_dir(Path | None) -
evaluation_strategy(EvaluationStrategyName) -
created_at(datetime)
Validators:
-
check_suffix→gold_standard_data_path -
_process_pdf_dir→pdf_dir
Source code in deet/data_models/project.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
completed_experiments
property
Return all completed experiments.
config_path
property
Return path to config file.
evaluation_splits_path
property
Return path to file recording evaluation split state.
experiments_dir
property
Return path to experiments directory.
Each time we run data extraction in this project, the results of the experiment will be stored here.
gold_standard_data_abspath
property
Return a usable path to the gold-standard data.
gold_standard_data_path is stored relative to the project root (and
never persisted as an absolute path, so project.yaml stays portable).
This joins it with the root only for I/O.
gold_standard_data_format
pydantic-field
Format of gold standard annotations
gold_standard_data_path
pydantic-field
Path to gold standard annotated data
link_map_path
property
Return path to link map.
linked_documents_path
property
Return path to linked documents folder.
name
pydantic-field
The name of a deet project
pdf_dir = None
pydantic-field
Path to folder containing PDFs
pdf_dir_abspath
property
Return a usable path to the pdf directory, or None if unset.
pdf_dir is stored relative to the project root and joined with it here
only for I/O; it is never persisted as an absolute path.
prompt_csv_path
property
Return path to prompt definition file.
root
property
Return project root.
anchor_to(root, source_dir=None)
Anchor the project to root, re-expressing resource paths relative to it.
Resource paths are authored relative to source_dir (default cwd, i.e.
where the wizard ran). They are rewritten relative to root so they stay
correct when root differs from that directory (as with
deet project new). The stored values remain relative, never absolute.
Source code in deet/data_models/project.py
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
check_suffix(value)
pydantic-validator
Check if extension is supported.
Source code in deet/data_models/project.py
196 197 198 199 200 201 202 203 | |
dump_to_yaml()
Write a minimal project.yaml file to save project options.
Written to the project root by default. Resource paths are stored as their relative values, never resolved to absolute, so the file stays portable.
Source code in deet/data_models/project.py
274 275 276 277 278 279 280 281 282 283 284 285 | |
export_config_template()
Export a default config template.
Source code in deet/data_models/project.py
287 288 289 290 291 292 293 294 295 | |
get_all_doc_ids()
Process the full dataset and return all document IDs.
Source code in deet/data_models/project.py
321 322 323 324 | |
load(project_dir=None)
classmethod
Load the project from project_dir (default: the current directory).
The project root is anchored to that directory; stored resource paths stay relative and are resolved against it. deet commands are run from the project directory.
Source code in deet/data_models/project.py
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | |
load_evaluation_strategy()
Load split state.
Source code in deet/data_models/project.py
326 327 328 329 330 331 332 | |
process_data()
Process the project's gold standard data.
Source code in deet/data_models/project.py
316 317 318 319 | |
setup()
Set a project up.
Create directory structure, process gold-standard data, and create prompt csv and link map
Source code in deet/data_models/project.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | |
validate_resources()
Check that the project's resource paths exist on disk.
Source code in deet/data_models/project.py
230 231 232 233 234 235 236 237 238 239 240 241 242 243 | |
ExperimentArtefacts
dataclass
Defines the structure of a data extraction experiment directory.
Source code in deet/data_models/project.py
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | |
comparison
property
Return location of csv comparing goldstandard to llm extractions.
config_snapshot
property
Return location of csv capturing config used.
evaluation_splits_snapshot
property
Return location of json capturing how docs were split for evaluation.
extraction_metadata
property
Return path to extraction metadata JSON (cost, tokens, timing).
is_complete
property
Verify the experiment directory contains a completed and evaluated run.
llm_annotation_csv
property
Return location of csv containing llm extractions.
llm_annotations
property
Return location of json containing llm extractions.
metrics
property
Return location of experiment metrics.
metrics_json
property
Return location of experiment metrics JSON.
prompts_snapshot
property
Return location of csv capturing prompts used.
run_id
property
Return identifier (based on the directory where the experiment lives).
create(experiments_dir, run_name)
classmethod
Initialise and create a new experiments directory.
Source code in deet/data_models/project.py
341 342 343 344 345 346 347 348 349 350 351 352 353 | |
ui_schema
Definition of data model to add annotations to pydantic model that can be used in automatic wizard generation.
UI
dataclass
Metadata for automatic UI generation. Used with Annotated[Type, UI(help="...")].
Source code in deet/data_models/ui_schema.py
9 10 11 12 13 14 15 16 17 18 19 20 21 | |
evaluators
gold_standard_llm_evaluator
Generalisable evaluation module for comparing data extracted by LLMs with data extracted by hand.
EvaluationRow
dataclass
Per-document values for extraction scoring and comparison export.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
194 195 196 197 198 199 200 201 202 203 204 205 | |
GoldStandardLLMEvaluator
A class to manage the evaluation of LLM-extracted data against "gold-standard" ground truth data.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | |
__init__(gold_standard_annotated_documents, llm_annotated_documents, attributes, extraction_run_id, custom_metrics=None, metric_settings=None)
Initialise GoldStandardLLMEvaluator with a list of ground truth and LLM-generated data to compare, along with the attributes you want to compare.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gold_standard_annotated_documents
|
Sequence[GoldStandardAnnotatedDocument]
|
Human / gold annotations. |
required |
llm_annotated_documents
|
Sequence[GoldStandardAnnotatedDocument]
|
LLM annotations to score. |
required |
attributes
|
Sequence[Attribute]
|
Attributes to evaluate. |
required |
extraction_run_id
|
str
|
Run identifier written into metric rows. |
required |
custom_metrics
|
list[str] | None
|
Optional sklearn metric names to merge in. |
None
|
metric_settings
|
EvaluationMetricSettings | None
|
Thresholds for extraction metrics (e.g. edit
distance). Defaults to :class: |
None
|
Source code in deet/evaluators/gold_standard_llm_evaluator.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
add_custom_metrics(custom_metrics)
Add custom metrics. These must be valid metrics from sklearn.metrics.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |
display_metrics()
Print metrics in a nice table to the command line.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | |
evaluate_llm_annotations()
Compare a list of human annotations to those generated by llms. Return a list of AttributeMetric objects.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | |
export_llm_comparison(filepath)
Export a comparison CSV for gold vs LLM per document and attribute.
Columns include identifiers, EPPI-oriented fields, extractions, LLM verbatim,
fuzzy grounding scores (against the LLM annotated document's context),
and run id.
Column semantics:
attribute_presence: Whether the gold annotation is present.human_additional_text/item_attribute_full_text_details: Taken from the eppi json file when present; empty when absent.citation_page/citation_highlight_text: Parsed from raw EPPI citation markup (Page N:/[¬s]...[¬e]); multiple fragments joined with": ". Empty when markup is absent.human_extraction: Actual ground truth to be extracted.human_verbatim_fuzzy_match_pct: Grounding ofhuman_additional_textagainst the LLM annotated document'scontext.llm_verbatim_text/llm_verbatim_fuzzy_match_pct: LLMadditional_textand its grounding against the samecontext.
Example row (illustrative types): attribute_presence is the string
"True" or "False"; human_verbatim_fuzzy_match_pct and
llm_verbatim_fuzzy_match_pct are decimal strings (e.g. "100.00",
"87.50"); human_extraction / llm_extraction serialize according to
the attribute's coerced value (e.g. bool, int, or str) as written by
:class:csv.DictWriter.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | |
export_llm_csv(filepath)
Write the LLM output to csv.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | |
write_metrics_to_csv(filepath)
Save metrics to csv in wide format via :class:RunMetricsReport.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
594 595 596 597 598 599 600 601 602 603 | |
write_metrics_to_json(filepath)
Save metrics to JSON via :class:RunMetricsReport.
Source code in deet/evaluators/gold_standard_llm_evaluator.py
605 606 607 608 609 610 611 612 613 614 | |
metrics
Metric functions and registries for gold-vs-LLM evaluation.
EvaluationMetricSettings
pydantic-model
Bases: BaseModel
Configurable thresholds for extraction evaluation metrics.
Fields:
Source code in deet/evaluators/metrics.py
27 28 29 30 31 32 33 34 35 36 37 38 | |
edit_distance_match_threshold = DEFAULT_EDIT_DISTANCE_MATCH_THRESHOLD
pydantic-field
Minimum normalised Levenshtein similarity (0-1) for a string pair to count as a match in edit_distance_match_rate.
check_metric_returns_float(metric)
Check whether a metric returns a scalar.
Source code in deet/evaluators/metrics.py
41 42 43 44 45 46 | |
edit_distance_match_rate(y_true, y_pred, *, threshold=DEFAULT_EDIT_DISTANCE_MATCH_THRESHOLD)
Fraction of pairs whose normalised Levenshtein similarity meets a threshold.
Values are normalised with :func:normalize_string_for_match before
comparison. Missing predictions are not dropped: any None in
y_pred raises, matching binary-metric behaviour (the evaluator then
records value=None for the metric).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
y_true
|
Sequence[Any]
|
Gold-standard values. |
required |
y_pred
|
Sequence[Any]
|
Predicted values. |
required |
threshold
|
float
|
Minimum normalised similarity in |
DEFAULT_EDIT_DISTANCE_MATCH_THRESHOLD
|
Returns:
| Type | Description |
|---|---|
float
|
Match rate in |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
TypeError
|
If any prediction is |
Source code in deet/evaluators/metrics.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
get_metrics_for_attribute_type(attribute_type, settings=None)
Return the metric set registered for the given attribute data type.
For STRING attributes, edit_distance_match_rate is rebuilt from
settings.edit_distance_match_threshold (defaults to 0.90).
Some types map to an empty dict when no suitable default metrics are implemented yet (list, dict); callers may still merge in custom metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attribute_type
|
AttributeType
|
Attribute output data type. |
required |
settings
|
EvaluationMetricSettings | None
|
Optional metric settings; defaults used when |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, MetricFunction]
|
Mapping of metric name to callable. |
Source code in deet/evaluators/metrics.py
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
n_labels(y_true, y_pred)
Count the number of positive instances of the class in gold data.
Source code in deet/evaluators/metrics.py
49 50 51 | |
source_fidelity
Helpers for source-fidelity checks and row-level match status.
classify_match_status(*, gold_value, predicted_value, gold_in_context, attribute_type, edit_distance_threshold)
Classify row-level match status for STRING / INTEGER / FLOAT attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gold_value
|
object
|
Gold-standard value. |
required |
predicted_value
|
object | None
|
Model predicted value. |
required |
gold_in_context
|
bool
|
Whether gold is found in parsed context. |
required |
attribute_type
|
AttributeType
|
Attribute output type. |
required |
edit_distance_threshold
|
float
|
Similarity threshold for STRING near-match. |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
One of |
str | None
|
|
str | None
|
for STRING/INTEGER/FLOAT, else |
Source code in deet/evaluators/source_fidelity.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
is_gold_value_in_text(*, gold_value, haystack_text, attribute_type, edit_distance_threshold, allow_string_near_match)
Check whether a gold value can be found in source text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gold_value
|
object
|
Gold-standard output_data. |
required |
haystack_text
|
str | None
|
Citation/context text to search. |
required |
attribute_type
|
AttributeType
|
Attribute output type. |
required |
edit_distance_threshold
|
float
|
Similarity threshold used for optional string near-match. |
required |
allow_string_near_match
|
bool
|
Whether approximate match fallback is enabled. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when the gold value is considered present in the haystack. |
Source code in deet/evaluators/source_fidelity.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
parse_numeric_tokens(text)
Parse standalone numeric tokens from free text.
Tokens must be digit sequences optionally with a decimal point (e.g.
1000, 0.11). Thousand separators such as 1,000 are not
recognised: comma-separated forms are treated as separate tokens, which
is locale-ambiguous (1,015 may mean one thousand fifteen or one
point zero one five).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str | None
|
Source text to scan. |
required |
Returns:
| Type | Description |
|---|---|
list[float]
|
List of parsed float values. Invalid tokens are ignored. |
Source code in deet/evaluators/source_fidelity.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
exceptions
Custom exceptions.
BadDocumentIdError
Bases: Exception
Raise when our Document.document_id field
doesn't satisfy our criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
description |
required |
Source code in deet/exceptions.py
101 102 103 104 105 106 107 108 109 | |
DuplicateAnnotationError
Bases: Exception
Raise when multiple annotations for a single attribute are present.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
16 17 18 19 20 21 22 23 | |
EmptyPdfExtractionError
Bases: Exception
Raise when PDF parsing yields no extractable text.
Occurs when the PDF has no mappable text (e.g. image-only) or when text is represented in a way pdfminer cannot decode.
Source code in deet/exceptions.py
76 77 78 79 80 81 82 83 84 85 86 87 88 | |
FileParserMismatchError
Bases: Exception
Raise when we have an input-file <> parser mismatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
56 57 58 59 60 61 62 63 | |
InvalidFileTypeError
Bases: Exception
Raise when user supplies a not permitted file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
46 47 48 49 50 51 52 53 | |
InvalidInputFileTypeError
Bases: Exception
Raise when user supplies a not permitted input file type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
26 27 28 29 30 31 32 33 | |
InvalidOutputFileTypeError
Bases: Exception
Raise when user supplies a not permitted output file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
36 37 38 39 40 41 42 43 | |
JsonStyleError
Bases: Exception
Raise when a json containing document-reference-linkages is incorrectly formatted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
description |
required |
Source code in deet/exceptions.py
112 113 114 115 116 117 118 119 120 | |
LitellmModelNotMappedError
Bases: Exception
Raised when litellm reports the model is missing from its registry.
litellm.get_max_tokens can raise a bare Exception with a
characteristic message; we translate that to this type so callers can
handle it without a broad except Exception.
Source code in deet/exceptions.py
161 162 163 164 165 166 167 168 | |
MalformedLanguageError
Bases: Exception
Raise when language checker fails.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
description |
required |
Source code in deet/exceptions.py
66 67 68 69 70 71 72 73 | |
MissingCitationElementError
Bases: Exception
Raise when required element of citation is missing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
description |
required |
Source code in deet/exceptions.py
91 92 93 94 95 96 97 98 | |
MissingDocumentError
Bases: Exception
Raise when looking up a document by id fails.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/exceptions.py
6 7 8 9 10 11 12 13 | |
NoAbstractError
Bases: Exception
Raise when we can't find an abstract in our citation info.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
description |
required |
Source code in deet/exceptions.py
123 124 125 126 127 128 129 130 | |
SplitsValidationError
Bases: Exception
Raised when invalid allocation of documents to splits is attemped.
Source code in deet/exceptions.py
171 172 | |
UnsupportedEppiAttributeTypeError
Bases: ValueError
Raised when EPPI AdditionalText / Codes mapping cannot handle an attribute type.
Subclasses :class:ValueError so existing except ValueError call sites remain
valid while allowing targeted handling via UnsupportedEppiAttributeTypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_data_type
|
AttributeType
|
The :class: |
required |
Source code in deet/exceptions.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | |
__init__(output_data_type, *, message=None)
Store output_data_type and build a default message when omitted.
Source code in deet/exceptions.py
147 148 149 150 151 152 153 154 155 156 157 158 | |
extractors
cli_helpers
Helper functions to run extraction via the CLI.
evaluate_extraction_pipeline(processed_annotation_data, run_output, experiment_artefacts)
Evaluate results of an extraction pipeline.
Source code in deet/extractors/cli_helpers.py
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
load_or_init_config(config_path)
Load config from project context or path, or fail informatively.
Source code in deet/extractors/cli_helpers.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
prepare_documents(documents, config, linked_document_path, pdf_dir, link_map_path)
Load documents depending on the context type we want.
NOTE: while there are no arg-defaults defined here, when used in cli.py, we populate defaults via typer arg defaults.
If fulltext, try to load linked documents, or create them if not.
Source code in deet/extractors/cli_helpers.py
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
run_extraction_pipeline(deet_project, prompt_csv_path, config_path=None, prompt_population=CustomPromptPopulationMethod.FILE, run_name='', *, ignore_references=False)
Run the standard data extraction pipeline from the CLI.
Source code in deet/extractors/cli_helpers.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
llm_data_extractor
Generalisable data extraction module for LLM-based document analysis.
DataExtractionConfig
pydantic-model
Bases: BaseModel
Configuration for data extraction tasks.
Fields:
-
provider(LLMProvider) -
model(str) -
temperature(float) -
max_tokens(int | None) -
max_context_tokens(int | None) -
default_context_type(ContextType) -
truncate_on_overflow(bool) -
prompt_config(PromptConfig) -
dynamic_json_schema(bool) -
include_reasoning(bool) -
include_additional_text(bool) -
edit_distance_match_threshold(float)
Validators:
Source code in deet/extractors/llm_data_extractor.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | |
default_context_type = ContextType.FULL_DOCUMENT
pydantic-field
Type of context to provide
dynamic_json_schema = True
pydantic-field
If True, produce dynamic json schema with a key for each attribute and where each attribute response is typed (marginally more expensive but may be more likely to produce valid output).
edit_distance_match_threshold = DEFAULT_EDIT_DISTANCE_MATCH_THRESHOLD
pydantic-field
Minimum normalised Levenshtein similarity (0-1) for a string pair to count as a match in edit_distance_match_rate. Omit from the config YAML to use the default.
include_additional_text = True
pydantic-field
Include additional text/citations in output
include_reasoning = True
pydantic-field
Include reasoning in output
max_tokens = None
pydantic-field
Maximum number of tokens to generate (Leave blank for provider default).
model = 'gpt-4o-mini'
pydantic-field
LLM model identifier used for completions.
prompt_config
pydantic-field
Prompt configuration
provider = LLMProvider.AZURE
pydantic-field
LLM Provider
temperature = 0.1
pydantic-field
Sampling temperature for the LLM.
truncate_on_overflow = False
pydantic-field
When True, automatically truncate context that exceeds max_context_tokens. When False (default), raise ValueError.
from_yaml(path)
classmethod
Load config object from a yaml file.
Source code in deet/extractors/llm_data_extractor.py
232 233 234 235 236 237 238 239 | |
populate_max_context_tokens_from_model()
pydantic-validator
Populate max_context_tokens from model when not set.
Source code in deet/extractors/llm_data_extractor.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
LLMDataExtractor
Generalisable module for LLM-based data extraction from documents.
This module provides a flexible interface for extracting structured data from documents using LLMs, with support for different context types and customizable prompts.
Source code in deet/extractors/llm_data_extractor.py
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 | |
__init__(config, custom_system_prompt_file=None, *, show_litellm_debug_messages=False)
Initialise the data extraction module.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
DataExtractionConfig
|
config obj for data extraction run |
required |
custom_system_prompt_file
|
Path | None
|
path to non-defualt |
None
|
show_litellm_debug_messages
|
bool
|
show verbose litellm logs. |
False
|
Source code in deet/extractors/llm_data_extractor.py
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | |
extract_from_document(attributes, filter_attribute_ids=None, *, payload=None, md_path=None, context_type=None)
Extract data from a single document.
Call with either payload (document text) or md_path (path to markdown file). If md_path is provided, the file is read and used as the payload. Prompt payloads are not written here; the batch entry point extract_from_documents writes them to prompt_outfile when provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
list[Attribute]
|
List of attributes to extract. |
required |
payload
|
str | None
|
Document text to extract from. Required if md_path not set. |
None
|
md_path
|
Path | None
|
Path to a markdown file to read as payload. Required if payload not set. |
None
|
context_type
|
ContextType | None
|
Override config context type; if None, use config default. |
None
|
Returns:
| Type | Description |
|---|---|
DocumentExtractionResult
|
DocumentExtractionResult with annotations, messages, token counts, |
DocumentExtractionResult
|
cost, model name, LLM call duration, and timestamp. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no attributes are selected for extraction after filtering. |
ValueError
|
If neither payload nor md_path provided, or both provided. |
Source code in deet/extractors/llm_data_extractor.py
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | |
extract_from_documents(attributes, documents, filter_attribute_ids=None, output_file=None, context_type=None, prompt_outfile=None, document_parsing=None, *, show_progress=False)
Extract data from all documents.
Loops over documents and extracts data using list of attributes. A document that's missing what it needs for the chosen context_type (e.g. no abstract when using ABSTRACT_ONLY) is skipped with a warning, not raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
list[Attribute]
|
List of attributes to extract. |
required |
documents
|
Sequence[Document]
|
Sequence of Document instances (required). |
required |
filter_attribute_ids
|
list[int] | None
|
Optional list of attribute IDs to filter by. |
None
|
output_file
|
Path | None
|
Optional path to save combined results JSON. |
None
|
context_type
|
ContextType | None
|
Override config context type; if None, use config default. |
None
|
prompt_outfile
|
Path | None
|
Optional path to write a single JSON object: keys are document IDs, values are prompt payload (messages). |
None
|
document_parsing
|
dict[str, DocumentParsingStats] | None
|
Optional per-document parsing stats from preparation. |
None
|
show_progress
|
bool
|
Whether to show a progress bar. |
False
|
Returns:
| Type | Description |
|---|---|
ExtractionRunOutput
|
ExtractionRunOutput containing annotated documents and run metadata. |
Source code in deet/extractors/llm_data_extractor.py
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | |
PromptConfig
pydantic-model
Bases: BaseModel
Configuration for prompts used in data extraction.
Fields:
-
system_prompt(str | Path)
Validators:
Source code in deet/extractors/llm_data_extractor.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | |
system_prompt
pydantic-field
System prompt that defines the task and role
load_system_prompt_file()
pydantic-validator
Load system prompt from file if Path provided.
Source code in deet/extractors/llm_data_extractor.py
79 80 81 82 83 84 85 86 87 88 89 | |
default_system_prompt()
Get default system prompt included in the package.
Source code in deet/extractors/llm_data_extractor.py
64 65 66 | |
logger
Customisations on the loguru logger.
processors
base_converter
Generic classes and functions for converters.
AnnotationConverter
Bases: ABC
Abstract base class to define expected behaviour of an annotationconverter.
OUTFILE_LOADERS maps the outfiles to be read/written to a filename, and a TypeAdapter defining the type of Pydantic Model to read back in.
Source code in deet/processors/base_converter.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
outfile_names
property
Return a dictionary of outfiles to names, using outfile_loaders.
processed_data_type
abstractmethod
property
Return the class to use when instantiating processed data.
__init__(base_output_dir=DEFAULT_BASE_OUTPUT_DIR)
Initialise the converter with configurable output paths.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_dir
|
Base directory for saving processed files |
required | |
attributes_filename
|
Filename for attributes output |
required | |
documents_filename
|
Filename for documents output |
required | |
annotated_documents_filename
|
Filename for annotated documents output |
required | |
attribute_mapping_filename
|
Filename for attribute ID to label mapping |
required |
Source code in deet/processors/base_converter.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | |
process_annotation_file(file_path, set_attribute_type=None)
abstractmethod
Parse a raw input format into processed data.
Source code in deet/processors/base_converter.py
93 94 95 96 97 98 99 100 | |
reload_output(file_path)
Read data back in, using OUTFILE_LOADERS and the subclass's processed_data_type.
Source code in deet/processors/base_converter.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
write_processed_data_to_file(processed_data, output_dir, outfiles_to_write=None)
Save processed data to structured files using Pydantic model serialisation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
processed_data
|
ProcessedAnnotationData
|
The processed data from process_annotation_file |
required |
output_dir
|
str | Path
|
Write all output (json) files from conversion to this |
required |
directory. NOTE
|
we output files will live in a sub-directory |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dictionary mapping data types to saved file paths |
Source code in deet/processors/base_converter.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
Outfiles
Bases: StrEnum
Enum of all outfiles producable by this module. Extend as required.
Source code in deet/processors/base_converter.py
26 27 28 29 30 31 32 | |
converter_register
A register of supported supported annotation formats and a map to their converters.
SupportedImportFormat
Bases: StrEnum
Supported formats to import gold standard annotation data from.
Source code in deet/processors/converter_register.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
get_annotation_converter()
Return an instance of the converter for the given data type.
Converters are imported lazily here, rather than at module load, because they pull in the heavy document/SDK stack. Keeping this module import-light keeps CLI startup fast for commands that only need the enum.
Source code in deet/processors/converter_register.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
csv_annotation_converter
Convert annotation CSV files to Pydantic models.
CSVAnnotationConverter
Bases: AnnotationConverter
A class to convert raw CSV (e.g. Covidence) annotations into structured Pydantic models.
This converter operates on flat CSV columns, infers field/column types, and produces attributes, documents, and annotated document records.
Source code in deet/processors/csv_annotation_converter.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | |
processed_data_type
property
Return ProcessedAnnotationData.
__init__(base_output_dir=DEFAULT_BASE_OUTPUT_DIR, attributes_filename=DEFAULT_ATTRIBUTES_FILENAME, documents_filename=DEFAULT_DOCUMENTS_FILENAME, annotated_documents_filename=DEFAULT_ANNOTATED_DOCUMENTS_FILENAME, attribute_mapping_filename=DEFAULT_ATTRIBUTE_MAPPING_FILENAME, config=None)
Initialize the converter output configurations (base directory + filenames) to save the multiple files created during csv processing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_output_dir
|
str | Path | None
|
Base directory for saving processed files |
DEFAULT_BASE_OUTPUT_DIR
|
attributes_filename
|
str
|
Filename for attributes output |
DEFAULT_ATTRIBUTES_FILENAME
|
documents_filename
|
str
|
Filename for documents output |
DEFAULT_DOCUMENTS_FILENAME
|
annotated_documents_filename
|
str
|
Filename for annotated documents output |
DEFAULT_ANNOTATED_DOCUMENTS_FILENAME
|
attribute_mapping_filename
|
str
|
Filename for attribute ID to label mapping |
DEFAULT_ATTRIBUTE_MAPPING_FILENAME
|
Source code in deet/processors/csv_annotation_converter.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | |
build_attributes(attribute_fields, rows)
Build a list of Attribute objects from CSV rows and specified attribute
columns.
Infers the AttributeType for each attribute field and assigns a unique ID
to each Attribute.
Source code in deet/processors/csv_annotation_converter.py
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | |
build_destiny_reference(row, mapping, source='deet CSV converter')
Convert a CSV row into a ReferenceFileInput for destiny_sdk.reference.
This method extracts bibliographic metadata and abstract content from the
given row using the provided reference field mapping. It constructs
BibliographicMetadataEnhancement and AbstractContentEnhancement
objects, then wraps them in EnhancementFileInput objects, and finally
returns a ReferenceFileInput.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
row
|
dict
|
Dictionary representing a single CSV row. |
required |
mapping
|
dict[str, Any]
|
Dictionary mapping nested keys (dot-separated strings) to CSV column names. |
required |
source
|
str
|
Optional string indicating the source of the data; defaults to "deet CSV converter" |
'deet CSV converter'
|
Returns: ReferenceFileInput object containing all extracted enhancements
Source code in deet/processors/csv_annotation_converter.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | |
build_documents_and_annotations(attributes, reference_fields, rows)
Build Document objects and their corresponding GoldStandardAnnotatedDocument`s
from CSV rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes
|
list[Attribute]
|
|
required |
reference_fields
|
dict
|
Dictionary mapping reference field labels (as defined in destiny_sdk.enhancements) to CSV column names. |
required |
rows
|
list[dict]
|
List of dictionaries representing all CSV rows. |
required |
Returns:
| Type | Description |
|---|---|
tuple[list[Document], list[GoldStandardAnnotatedDocument]]
|
A tuple containing: Document and List[GoldStandardAnnotatedDocument] |
Source code in deet/processors/csv_annotation_converter.py
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | |
load_csv(file_path, attribute_fields=None, reference_fields=None)
Load a CSV, normalize headers, and return all column names, attribute names, reference names, and rows.
Source code in deet/processors/csv_annotation_converter.py
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | |
process_annotation_file(file_path, set_attribute_type=None, attribute_fields=None, reference_fields=None)
Process a complete CSV annotation file and return structured data.
Each row is assumed to represent a document, and columns correspond to different types of fields (metadata, reference information, and attributes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to the CSV annotation file. |
required |
attribute_fields
|
list | None
|
List of column names to be treated as document attributes. |
None
|
reference_fields
|
dict | None
|
Dictionary mapping reference field labels(as defined in |
None
|
Returns:
| Type | Description |
|---|---|
ProcessedAnnotationData
|
ProcessedAnnotationData containing all processed data. |
Source code in deet/processors/csv_annotation_converter.py
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | |
CSVParserConfig
pydantic-model
Bases: BaseModel
Configuration Seetings for parsing CSV.
Fields:
-
author_separator(str) -
auto_assign_reference_fields(Boolean)
Source code in deet/processors/csv_annotation_converter.py
71 72 73 74 75 | |
ColumnTypeInferenceError
Bases: Exception
Raised when column type inference fails due to incompatible types.
Source code in deet/processors/csv_annotation_converter.py
67 68 | |
directory_processor
Tools to create Documents directly from pdf or md files.
create_documents_from_directory(directory_path)
Collect markdown and PDF files and return linked documents with parsing stats.
Collects .md files and .pdf files. PDFs whose stem already has a
matching .md are skipped.
Source code in deet/processors/directory_processor.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
eppi_annotation_converter
Convert annotation JSON files to Pydantic models.
EppiAnnotationConverter
Bases: AnnotationConverter
A class to convert raw EPPI-Reviewer JSON annotations into structured Pydantic models.
This converter handles the complex hierarchical structure of EPPI attributes by flattening them while preserving parent-child relationships through path information.
Source code in deet/processors/eppi_annotation_converter.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | |
processed_data_type
property
Return ProcessedEppiAnnotationData.
__init__(base_output_dir=DEFAULT_BASE_OUTPUT_DIR, attributes_filename=DEFAULT_ATTRIBUTES_FILENAME, documents_filename=DEFAULT_DOCUMENTS_FILENAME, annotated_documents_filename=DEFAULT_ANNOTATED_DOCUMENTS_FILENAME, attribute_mapping_filename=DEFAULT_ATTRIBUTE_MAPPING_FILENAME)
Initialise the converter with configurable output paths. Set self.OUTFILE_LOADERS mapping the outfiles to be read/written to a filename, and a TypeAdapter defining the type of Pydantic Model to read back in when deserialising.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_dir
|
Base directory for saving processed files |
required | |
attributes_filename
|
str
|
Filename for attributes output |
DEFAULT_ATTRIBUTES_FILENAME
|
documents_filename
|
str
|
Filename for documents output |
DEFAULT_DOCUMENTS_FILENAME
|
annotated_documents_filename
|
str
|
Filename for annotated documents output |
DEFAULT_ANNOTATED_DOCUMENTS_FILENAME
|
attribute_mapping_filename
|
str
|
Filename for attribute ID to label mapping |
DEFAULT_ATTRIBUTE_MAPPING_FILENAME
|
Source code in deet/processors/eppi_annotation_converter.py
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | |
convert_to_eppi_annotations(annotations_data, attributes_lookup, attribute_id_to_label=None)
Convert several dicts to a list of EppiGoldStandardAnnotations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
annotations_data
|
list[dict[str, Any]]
|
List of human, gold standard annotation dicts from EPPI JSON |
required |
document
|
The document these annotations belong to |
required | |
attributes_lookup
|
dict[int, EppiAttribute]
|
Lookup dictionary for attributes |
required |
attribute_id_to_label
|
dict[int, str] | None
|
Mapping from attribute ID to label |
None
|
Returns:
| Type | Description |
|---|---|
list[EppiGoldStandardAnnotation]
|
List of EppiGoldStandardAnnotation models |
Source code in deet/processors/eppi_annotation_converter.py
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | |
convert_to_eppi_attributes(flattened_attributes, set_attribute_type=None)
Convert flattened attribute data to EppiAttribute models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flattened_attributes
|
list[dict[str, Any]]
|
List of flattened attribute dictionaries |
required |
Returns:
| Type | Description |
|---|---|
list[EppiAttribute]
|
List of EppiAttribute models |
Source code in deet/processors/eppi_annotation_converter.py
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | |
dedup_annotations(annotations)
Merge annotations with the same attribute id.
Source code in deet/processors/eppi_annotation_converter.py
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | |
flatten_attributes_hierarchy(attributes_list, parent_path='')
Recursively flatten the hierarchical attributes structure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attributes_list
|
list[dict[str, Any]]
|
List of attribute dictionaries from the JSON |
required |
parent_path
|
str
|
Path to the parent attribute (for hierarchy tracking) |
''
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of flattened attribute dictionaries with hierarchy information |
Source code in deet/processors/eppi_annotation_converter.py
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | |
process_annotation_file(file_path, set_attribute_type=None)
Process a complete annotation file and return structured data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to the JSON annotation file |
required |
set_attribute_type
|
str | AttributeType | None
|
custom AttributeType to set for incoming annotations. |
None
|
Returns:
| Type | Description |
|---|---|
ProcessedEppiAnnotationData
|
ProcessedAnnotationData containing all processed data |
Source code in deet/processors/eppi_annotation_converter.py
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | |
eppi_output_data_from_eppi_fields(output_data_type, *, additional_text)
Map EPPI evidence onto typed raw_data for coerced output_data.
Glossary
- Codes: Rows under
References[].Codesin EPPI export JSON. Each row means the reviewer applied that code for the reference (e.g. ticked a box). - raw_data: The value stored on
GoldStandardAnnotationbefore / during coercion to the Python type implied by the attribute. - output_data: The coerced, typed value used in evaluation (derived from
raw_data). For EPPI ingest, booleans reflect code presence; other types come from theAdditionalTextfield.
A Code row exists means the attribute was applied. For boolean attributes that is
True even when AdditionalText is empty (the checkbox alone carries the
positive annotation).
For every non-boolean type, only the info-box AdditionalText is used.
ItemAttributeFullTextDetails is not used for the stored value (it may still be
attached to the model for other uses).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_data_type
|
AttributeType
|
Target attribute type (from codeset or prompt CSV). |
required |
additional_text
|
str
|
EPPI |
required |
Returns:
| Type | Description |
|---|---|
EppiRawDataValue
|
Value to store in |
EppiRawDataValue
|
|
EppiRawDataValue
|
|
Source code in deet/processors/eppi_annotation_converter.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
eppi_citation_parser
Parse raw EPPI citation markup into page and highlight fields.
ParsedEppiCitation
dataclass
Structured fields extracted from a raw EPPI Text citation block.
Attributes:
| Name | Type | Description |
|---|---|---|
page |
int | None
|
Page number from a |
highlight_text |
str
|
Cleaned highlight content (quotes/residual markup removed). |
raw |
str
|
Original input string retained for audit. |
Source code in deet/processors/eppi_citation_parser.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
format_parsed_citations(citations)
Join multiple parsed citations for CSV export.
Uses ": " as the separator (same convention as the raw
item_attribute_full_text_details column).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
citations
|
list[ParsedEppiCitation]
|
Parsed citation list (may be empty). |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
str
|
omitted from the page string; empty highlights are omitted from the |
tuple[str, str]
|
highlight string. |
Source code in deet/processors/eppi_citation_parser.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
parse_eppi_citation_text(raw_text)
Parse raw EPPI item_attribute_full_text_details markup.
Operates on raw markup so [¬s] / [¬e] can be used as structure.
Extracted highlight fragments are cleaned via :func:clean_extracted_text.
Example::
Page 7:
[¬s]"Odds ratio[¬e]"
yields page=7, highlight_text="Odds ratio".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw_text
|
str
|
Raw EPPI |
required |
Returns:
| Type | Description |
|---|---|
ParsedEppiCitation
|
class: |
Source code in deet/processors/eppi_citation_parser.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
parse_eppi_citations_from_details(details)
Parse each EPPI full-text detail entry independently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
details
|
list[EppiItemAttributeFullTextDetails]
|
List of :class: |
required |
Returns:
| Name | Type | Description |
|---|---|---|
One |
list[ParsedEppiCitation]
|
class: |
list[ParsedEppiCitation]
|
Empty input yields |
Source code in deet/processors/eppi_citation_parser.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
linker
Tools for linking references/citations with parsed documents.
DocumentReferenceLinker
Core class for linking references/citations with parsed document text.
Source code in deet/processors/linker.py
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 | |
__init__(references, document_reference_mapping=None, document_base_dir=None, parser=parser, linking_strategies=None)
Initialise DocumentReferenceLinker class.
Source code in deet/processors/linker.py
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | |
guess_file_paths(strategies=None)
Attempt to pre-fill doc-file mappings using LinkingStrategies.
Returns a dict of {document_id: matched_file_path} for documents where a match was found. Unmatched documents are absent from the result.
NOTE: MAPPING_FILE strategy is excluded, obviously.
Source code in deet/processors/linker.py
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | |
link_many_references_parsed_documents(*, return_images=False, return_metadata=False)
Link multiple references to parsed documents using available LinkingStrategy(s).
Iterates over linking strategies in hierarchical order, attempting to link each reference-doc to its corresponding file.
If required, parses files. Creates Document objects where is_linked=True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
return_images
|
bool
|
Whether to include images in parsed output |
False
|
return_metadata
|
bool
|
Whether to include metadata in parsed output |
False
|
Returns:
| Type | Description |
|---|---|
list[Document]
|
List of Document objects successfully linked and parsed |
Source code in deet/processors/linker.py
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 | |
link_reference_parsed_document(reference, parsed_output, original_filepath=None)
staticmethod
Link a reference, in Document format with a parsed document,
in ParsedOutput format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reference
|
Document
|
the reference, e.g. 'document' from eppi json. |
required |
parsed_output
|
ParsedOutput
|
parser output. |
required |
original_filepath
|
Path | None
|
Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Document |
Document
|
a linked Document with |
Document
|
all required fields populated, and is_linked==True, |
|
Document
|
and required fields' presence validated. |
Source code in deet/processors/linker.py
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | |
DocumentReferenceMapping
pydantic-model
Bases: BaseModel
Data model for incoming, manual mappings of references (via integer ids) to documents, via filename.
Fields:
Validators:
-
ensure_valid_doc_id→document_id -
ensure_file_exists
Source code in deet/processors/linker.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
ensure_file_exists()
pydantic-validator
Ensure either md_path or pdf_path are populated, and the associated file exists.
Source code in deet/processors/linker.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
ensure_valid_doc_id(value)
pydantic-validator
Ensure supplied document_id has a valid number of digits.
Source code in deet/processors/linker.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
LinkedInterimPayload
pydantic-model
Bases: DocumentReferenceMapping
Interim output from a linking factory method; extending DocumentReferenceMapping.
Interim as the document may a) still need to be parsed, and b) still needs to be coerced into ParsedOutput.
Fields:
-
document_id(int) -
file_path(Path) -
format(Literal['md', 'pdf'] | None) -
unlinked_document(Document)
Validators:
-
ensure_valid_doc_id→document_id -
ensure_file_exists
Source code in deet/processors/linker.py
89 90 91 92 93 94 95 96 97 98 99 100 | |
LinkingStrategy
Bases: StrEnum
Enum of permitted/implemented ref<>parsed_doc linking strategies.
Source code in deet/processors/linker.py
24 25 26 27 28 29 30 31 | |
MappingImporter
Tool for importing manual mappings from csv/json to list[DocumentReferenceMapping].
Source code in deet/processors/linker.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | |
__init__(mapping_file_path, document_base_dir=None)
Initialise MappingImporter instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping_file_path
|
Path
|
Path to csv/json file containing mappings. |
required |
document_base_dir
|
Path | None
|
Optional directory path |
None
|
Source code in deet/processors/linker.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
import_mapping()
Parse a csv/json file to a list od DocumentReferenceMapping objects.
Source code in deet/processors/linker.py
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | |
merge_partial_paths(parts_a, parts_b)
staticmethod
Merge partial file path components.
Implements the Knuth-Morris-Pratt (KMP) algorithm. Nice! https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parts_a
|
list[str]
|
the longer of the path parts |
required |
parts_b
|
list[str]
|
the shorter of the path parts. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: the merged combined path |
Source code in deet/processors/linker.py
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
parser
Utilities for parsing input files (e.g. pdf) into output files (e.g. md).
DocumentParser
Parse documents from target format to other target format.
Source code in deet/processors/parser.py
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | |
__call__(input_, out_path=None, parser=None, input_type=None, *, return_images=False, return_metadata=False, **kwargs)
Run the parser on one input_.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_
|
str | PathLike
|
File(path) or str of input_. |
required |
out_path
|
str | PathLike | None
|
If None, return parsed content as str. |
None
|
parser
|
ParserLibrary | None
|
Defaults to None. If None, uses the default parser. |
None
|
input_type
|
InputFileType | None
|
Defaults to None.
If None, infers file type using |
None
|
return_images
|
bool
|
Defaults to False. Whether to write
parsed images (JPEG) to file, or not. |
False
|
return_metadata
|
bool
|
Defaults to None. Whether to write parsed metadata (json). |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
ParsedOutput
|
ParsedOutput object. |
Source code in deet/processors/parser.py
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | |
__init__(parsers=DEFAULT_PARSERS)
Initialise instance of DocumentParser with default parsers. Default parsers are in dict.
Source code in deet/processors/parser.py
291 292 293 294 295 296 297 298 299 300 301 302 303 | |
detect_filetype(file, permitted_file_enum_list=None)
staticmethod
Detect file type from a file_path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
str | PathLike
|
description |
required |
Raises:
| Type | Description |
|---|---|
InvalidInputFileTypeError
|
If file extension isn't permitted. |
Returns:
| Name | Type | Description |
|---|---|---|
InputFileType |
str
|
description |
Source code in deet/processors/parser.py
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | |
parse(input_, parser, *, return_metadata=False, return_images=False, **kwargs)
Parse target file. Wraps around specific parser methods.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_
|
str | PathLike
|
|
required |
input_type
|
InputFileType
|
|
required |
parser
|
ParserLibrary
|
|
required |
parse_method
|
Callable[[str | PathLike, ParserLibrary], str]
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
ParsedOutput
|
description |
Source code in deet/processors/parser.py
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | |
write_files(out_path, parser, *, write_metadata, write_images, text, metadata=None, images=None)
staticmethod
Write parsed content to file(s).
NOTE: we are taking existence of out_path as an intention to
write all requested objects to file. out_path can be a file or a dir.
if out_path is a file, we write remaining files to parent dir.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
out_path
|
str | PathLike
|
description |
required |
write_metadata
|
bool
|
description |
required |
write_images
|
bool
|
description |
required |
text
|
str
|
description |
required |
metadata
|
dict | None
|
description. Defaults to None. |
None
|
images
|
dict[str, Image] | None
|
description. Defaults to None. |
None
|
Source code in deet/processors/parser.py
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | |
InputFileType
Bases: StrEnum
Enumeration of permitted input file types.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
StrEnum
|
_type_
|
|
required |
Source code in deet/processors/parser.py
38 39 40 41 42 43 44 45 46 47 48 49 50 | |
MarkerParser
Bases: ParserLibrary
Parser with marker backend.
Source code in deet/processors/parser.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
clear_cache()
classmethod
Clear the cached converter.
Source code in deet/processors/parser.py
190 191 192 193 194 | |
parse(input_, *, return_metadata=False, return_images=False, **kwargs)
classmethod
Parse file using marker.
Source code in deet/processors/parser.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
OutputFileType
Bases: StrEnum
Enumeration of permitted output file types.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
StrEnum
|
_type_
|
|
required |
Source code in deet/processors/parser.py
53 54 55 56 57 58 59 60 61 62 63 64 | |
PandocParser
Bases: ParserLibrary
Parser with pandoc backend.
Source code in deet/processors/parser.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
parse(input_, input_type=None, *, input_is_string=False, return_metadata=False, return_images=False, **kwargs)
classmethod
Parse file using pandoc.
Source code in deet/processors/parser.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
ParsedOutput
pydantic-model
Bases: BaseModel
Output returned from the parser() method of subclasses of ParserLibrary.
Contains
text, str: md-formatted parsed text (required) images, pillow.img: pillow-formatted image(s) (optional) metadata, dict: metadata json (optional) timestamp: datetime: auto-populates with now parser_library: str: name of the ParserLibrary implementation used
Config:
arbitrary_types_allowed:True
Fields:
-
text(str) -
images(dict[str, Image] | None) -
metadata(dict | None) -
timestamp(datetime) -
parser_library(Literal['pandoc', 'marker', 'pdfminer', 'unknown'])
Validators:
-
assess_language_quality→text
Source code in deet/processors/parser.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | |
assess_language_quality(value)
pydantic-validator
Assess language quality.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Parsed text. |
required |
Raises:
| Type | Description |
|---|---|
MalformedLanguageError
|
If threshold not met. |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
parsed text. |
Source code in deet/processors/parser.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | |
ParserLibrary
Bases: ABC
Base parser class.
Source code in deet/processors/parser.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
parse(input_, *, return_metadata=False, return_images=False, **kwargs)
abstractmethod
classmethod
Parse a document. Intentionelly left blank as this should be populated in sub-classes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_
|
str | PathLike
|
Path to input file or string of input string. |
required |
return_metadata
|
bool
|
Return json metadata. Defaults to False. |
False
|
return_images
|
bool
|
Return images in doc. Defaults to False. |
False
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
The default, should never actually come. |
Returns:
| Type | Description |
|---|---|
ParsedOutput
|
str | tuple[str, Any, Any]: There will always be str, but sometimes more. |
Source code in deet/processors/parser.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
PdfminerParser
Bases: ParserLibrary
Parser with pdfminer.six backend. Fast text extraction, no images or metadata.
Source code in deet/processors/parser.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
parse(input_, *, return_metadata=False, return_images=False, **kwargs)
classmethod
Parse file using pdfminer.six (no OCR).
Source code in deet/processors/parser.py
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
scripts
Scripts for data extraction evaluation toolkit.
cli
A CLI app to run deet pipelines.
global_options(typer_context, *, verbose=typer.Option(default=False, help='Display verbose logs.'))
Set global options for all deet commands.
Source code in deet/scripts/cli.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
main()
Run CLI app.
Source code in deet/scripts/cli.py
74 75 76 | |
commands
deprecated
Registry of deprecated commands with instructions on how to use successors.
export_config_template_legacy()
Return deprecation warning for old export config command.
Source code in deet/scripts/commands/deprecated.py
10 11 12 13 14 15 16 17 18 19 20 21 | |
extract_data_legacy()
Return deprecation warning for old extract data command.
Source code in deet/scripts/commands/deprecated.py
66 67 68 69 70 71 72 73 74 75 76 77 78 | |
init_linkage_mapping_file_legacy()
Return deprecation warning for old link map command.
Source code in deet/scripts/commands/deprecated.py
24 25 26 27 28 29 30 31 32 33 34 35 | |
init_prompt_csv_legacy()
Return deprecation warning for old init prompt command.
Source code in deet/scripts/commands/deprecated.py
52 53 54 55 56 57 58 59 60 61 62 63 | |
link_documents_fulltexts_legacy()
Return deprecation warning for old export link documents command.
Source code in deet/scripts/commands/deprecated.py
38 39 40 41 42 43 44 45 46 47 48 49 | |
test_llm_config_legacy()
Return deprecation warning for old test llm command.
Source code in deet/scripts/commands/deprecated.py
81 82 83 84 85 86 87 88 89 90 91 92 | |
experiments
CLI sub-commands for running data extraction experiments (and evaluating them).
evaluate(typer_context, config_path=None, prompt_population=CustomPromptPopulationMethod.FILE, prompt_csv_path=None, run_name='', custom_evaluation_metrics=None)
Extract data from documents and evaluate.
Load gold standard annotation data, and use an LLM to extract data from the documents in your dataset. Evaluate by comparing the results to the gold standard data.
Source code in deet/scripts/commands/experiments.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
predict(typer_context, config_path=None, prompt_population=CustomPromptPopulationMethod.FILE, prompt_csv_path=None, run_name='', ignore_references=typer.Option(default=False, help='Ignore references in gold standard data and justextract from whatever is in your pdf_dir'))
Extract data from documents without evaluating.
Load gold standard annotation data, and use an LLM to extract data from the documents in your dataset. When used with ignore_references = True, documents are created directly from the files contained in pdf_dir.
Source code in deet/scripts/commands/experiments.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
splits(typer_context, action=None, size=None)
Manage evaluation splits for this project.
Source code in deet/scripts/commands/experiments.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
project
Sub-commands for project initialisation and configuration.
edit(typer_context, field=None)
Edit an existing project's configuration.
Re-collects the project fields (pre-filled with the current values) and rewrites
project.yaml WITHOUT regenerating artefacts (prompt CSV, link map, experiment
dirs). Pass a field name to edit just that field; the full edit also lets you
update credentials.
Source code in deet/scripts/commands/project.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | |
init(*, data_path=None, data_type=SupportedImportFormat.EPPI_JSON, pdf_dir=None, force_overwrite=False)
Initialise a new project in the current directory.
The project name is taken from the current directory. Leave the data and pdf options empty to enter the interactive wizard. Use deet project new to create a project in a new directory.
Source code in deet/scripts/commands/project.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | |
link(typer_context)
Link documents to their fulltexts.
This creates a document with the parsed output of the corresponding fulltext for each of the documents in your project.
Linking will be attempted using your project's link_map.csv.
See deet.processors.linker for more details.
Source code in deet/scripts/commands/project.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
new(*, name=None, data_path=None, data_type=SupportedImportFormat.EPPI_JSON, pdf_dir=None, force_overwrite=False)
Create a new project in its own directory, named after name.
Leave the data and pdf options
empty to enter the interactive wizard. Use deet project init to turn the
current directory into a project.
Source code in deet/scripts/commands/project.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
regenerate_config_template(typer_context)
Regenerate config template from a project.
A config template with defaults for each option is created on project.setup(); this re-creates it.
Source code in deet/scripts/commands/project.py
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
regenerate_link_map(typer_context)
Regenerate a "link map" from a project.
A link map is created on project.setup(); this re-creates it.
Source code in deet/scripts/commands/project.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
regenerate_prompt_csv(typer_context)
Regenerate a prompt csv from a project.
A prompt csv is created on project.setup(); this re-creates it.
Source code in deet/scripts/commands/project.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | |
test_llm_config(config_path=None)
Test llm config.
Source code in deet/scripts/commands/project.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | |
project_utils
CLI helpers for the deet project setup/creation commands.
create_project(root, name, *, data_path, data_type, pdf_dir)
Create and set a project named name up at root.
When resource paths are supplied the project is built headlessly from them;
otherwise the interactive wizard collects the remaining fields. The
project is anchored to root and its directory structure written there.
Source code in deet/scripts/project_utils.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
guard_overwrite(target_dir, *, force, interactive)
Guard against overwriting an existing project at target_dir.
Does nothing if force is set or no project exists there. Otherwise prompts
to overwrite when running interactively, or exits with guidance when headless
(where prompting is impossible).
Source code in deet/scripts/project_utils.py
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
prompt_name()
Prompt for a project name.
Source code in deet/scripts/project_utils.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
run_edit(project, field)
Re-collect a project's fields (pre-filled) and rewrite project.yaml.
Does NOT run setup(), so existing artefacts (prompt CSV, link map, experiment
dirs) are preserved. field edits a single field; otherwise the full wizard
runs and credentials may be updated too. Does not validate that resource paths
exist on disk; invalid paths will fail when derived artefacts are regenerated
or the extraction pipeline runs.
Source code in deet/scripts/project_utils.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | |
run_init_wizard(root, name)
Run the interactive project + credentials wizards and set the project up.
Prompts for every project field except name (supplied here), anchors the
project to root (re-expressing resource paths relative to it), then writes
the project structure and credentials into root.
Source code in deet/scripts/project_utils.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
typer_context
decorators to handle typer context in commands.
CLIState
dataclass
Structured data store for typer context.
Source code in deet/scripts/typer_context.py
19 20 21 22 23 | |
project_required(f)
Check typer context for existence of a project, and exit if no project exists.
This is used to decorate cli commands which we want to exit gracefully when they are run outside of a project directory.
Source code in deet/scripts/typer_context.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
settings
App settings using pydantic-settings.
DataExtractionSettings
Bases: BaseSettings
Settings model for data extraction behavior and provider credentials.
All fields are fully typed and documented. Unknown environment variables are forbidden to help catch configuration drift early.
Source code in deet/settings.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
dump_to_env(target_path=Path('.env'))
Serialise settings object to a .env file.
Source code in deet/settings.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
LLMProvider
Bases: StrEnum
Supported LLM Providers.
Source code in deet/settings.py
25 26 27 28 29 | |
LogLevel
Bases: StrEnum
Supported log levels for logging.
Source code in deet/settings.py
32 33 34 35 36 37 38 39 40 41 | |
Runtime
Bases: StrEnum
Permitted runtime environments for DEET.
Source code in deet/settings.py
15 16 17 18 19 20 21 22 | |
get_settings()
cached
Return a cached settings instance for reuse across the process.
Source code in deet/settings.py
116 117 118 119 | |
ui
fail_with_message(message)
Print message and exit CLI.
Source code in deet/ui/messenger.py
18 19 20 21 | |
notify(message, level=LogLevel.INFO)
Send messages to logger and to UIs (currently the console).
Source code in deet/ui/messenger.py
12 13 14 15 | |
messenger
Interface to pass messages to UI(s).
fail_with_message(message)
Print message and exit CLI.
Source code in deet/ui/messenger.py
18 19 20 21 | |
notify(message, level=LogLevel.INFO)
Send messages to logger and to UIs (currently the console).
Source code in deet/ui/messenger.py
12 13 14 15 | |
terminal
continue_after_key(message='Press Enter to continue...')
Pause execution until the user acknowledges.
Source code in deet/ui/terminal/wizards.py
324 325 326 327 328 329 330 | |
render_template(name, **context)
Load and render a markdown template.
Source code in deet/ui/terminal/render.py
108 109 110 111 112 113 | |
render_to_console(message, level)
Render message to terminal using Rich.
Source code in deet/ui/terminal/render.py
38 39 40 41 42 43 44 45 46 47 48 | |
run_model_wizard(model_class, *, prefill=None, defaults=None)
Create a wizard from a pydantic model.
Fields present in prefill are not prompted for; their values are injected
into the model directly. This lets a caller supply a field (e.g. the project
name derived from a directory) instead of asking the user for it.
defaults maps a field name to a display-ready string shown as that field's
editable default, so a caller can pre-fill current values while still prompting
(e.g. deet project edit).
Every field after the first is back-navigable: pressing Ctrl+Left or Option+Left returns to the previous field, which is re-prompted with the answer already given.
Source code in deet/ui/terminal/wizards.py
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | |
components
Rich UI components for the terminal.
deprecation_panel(content)
Return a panel for deprecation warnings.
Source code in deet/ui/terminal/components.py
23 24 25 26 27 28 29 30 31 | |
info_panel(content, title='INFO')
Return a styled box for displaying Markdown content.
Source code in deet/ui/terminal/components.py
10 11 12 13 14 15 16 17 18 19 20 | |
wizard_field_help(field, help_text)
Print help text to the right.
Source code in deet/ui/terminal/components.py
44 45 46 47 48 49 50 51 52 53 54 | |
wizard_header(name, current_step, total_steps)
Create a header at the top of a wizard detailing progress through fields.
Source code in deet/ui/terminal/components.py
34 35 36 37 38 39 40 41 | |
prompts
Re-usable inquirerpy prompts.
select_experiment(project)
Select an experiment from a project's completed experiments.
Source code in deet/ui/terminal/prompts.py
10 11 12 13 14 15 16 17 18 | |
select_from_list(items, item_key, selected_value=None, *, display_key='description', prompt_message='Select an option')
Select an item from a list by key, either by prompt or direct value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
Sequence[ItemT]
|
List of dicts to select from. |
required |
Source code in deet/ui/terminal/prompts.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
render
Single import for the rich console, and methods to write to it.
flow(text)
Clean indentation and collapse single newlines into spaces to allow text wrapping in terminal.
Source code in deet/ui/terminal/render.py
87 88 89 90 91 92 93 94 95 96 97 | |
optional_progress(iterable, *, show_progress=False, label='Processing')
Context manager that yields an iterable. If show_progress is True, uses a Rich progress bar that handles logs gracefully.
Source code in deet/ui/terminal/render.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
render_template(name, **context)
Load and render a markdown template.
Source code in deet/ui/terminal/render.py
108 109 110 111 112 113 | |
render_to_console(message, level)
Render message to terminal using Rich.
Source code in deet/ui/terminal/render.py
38 39 40 41 42 43 44 45 46 47 48 | |
templates
help_text
Help text for CLI commands.
wizards
Module containing interactive wizards for collecting information for the deet cli.
BoolHandler
Bases: WidgetCreator
WidgetCreator to handle boolean fields.
Source code in deet/ui/terminal/wizards.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | |
can_handle(field_info)
Check if field is a boolean.
Source code in deet/ui/terminal/wizards.py
153 154 155 | |
execute(widget_args, field_info, *, allow_back)
Use a inquirer confirm to return boolean.
Source code in deet/ui/terminal/wizards.py
157 158 159 160 161 162 163 164 165 | |
DefaultHandler
Bases: WidgetCreator
Fallback handler (simple text prompt).
Should always be last in the strategy list.
Source code in deet/ui/terminal/wizards.py
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | |
can_handle(field_info)
Return True, handling whatever is not covered by other strategies.
Source code in deet/ui/terminal/wizards.py
175 176 177 | |
execute(widget_args, field_info, *, allow_back)
Execute a text prompt.
Source code in deet/ui/terminal/wizards.py
179 180 181 182 183 | |
EnumHandler
Bases: WidgetCreator
WidgetCreator to handle enums.
Source code in deet/ui/terminal/wizards.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
can_handle(field_info)
Check if the field is an enum.
Source code in deet/ui/terminal/wizards.py
76 77 78 79 80 | |
execute(widget_args, field_info, *, allow_back)
Execute an inquirer.select prompt.
Source code in deet/ui/terminal/wizards.py
82 83 84 85 86 87 88 | |
NumberHandler
Bases: WidgetCreator
WidgetCreator to handle numbers.
Source code in deet/ui/terminal/wizards.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
can_handle(field_info)
Check if the field is a number.
Source code in deet/ui/terminal/wizards.py
108 109 110 111 | |
execute(widget_args, field_info, *, allow_back)
Execute an inquirer.number prompt, adjusted to whether float or not.
If it's optional, use a text prompt.
Source code in deet/ui/terminal/wizards.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
PathHandler
Bases: WidgetCreator
WidgetCreator to handle paths.
Source code in deet/ui/terminal/wizards.py
91 92 93 94 95 96 97 98 99 100 101 102 | |
can_handle(field_info)
Check if the field is a Path.
Source code in deet/ui/terminal/wizards.py
94 95 96 | |
execute(widget_args, field_info, *, allow_back)
Execute an inquirer.filepath prompt.
Source code in deet/ui/terminal/wizards.py
98 99 100 101 102 | |
SecretHandler
Bases: WidgetCreator
Widget creator to handle secrets.
Source code in deet/ui/terminal/wizards.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
can_handle(field_info)
Check if the field is a secretstr.
Source code in deet/ui/terminal/wizards.py
135 136 137 138 | |
execute(widget_args, field_info, *, allow_back)
Execute an inquirer.secret prompt. Leave UNCHANGED_SECRET as None.
Source code in deet/ui/terminal/wizards.py
140 141 142 143 144 145 146 147 | |
WidgetCreator
Bases: ABC
Abstract strategy to create Pyinquirer widgets from pydantic fields.
Source code in deet/ui/terminal/wizards.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
can_handle(field_info)
abstractmethod
Return True if this handler supports the given field.
Source code in deet/ui/terminal/wizards.py
60 61 62 63 | |
execute(widget_args, field_info, *, allow_back)
abstractmethod
Execute the InquirerPy widget and return the validated result.
Source code in deet/ui/terminal/wizards.py
65 66 67 68 69 70 | |
continue_after_key(message='Press Enter to continue...')
Pause execution until the user acknowledges.
Source code in deet/ui/terminal/wizards.py
324 325 326 327 328 329 330 | |
get_ui_metadata(field_info)
Get UI metadata from pydantic model field.
Source code in deet/ui/terminal/wizards.py
196 197 198 | |
inquire_pydantic_field(model_class, field_name, field_info, ui, default_override=None, *, allow_back=False)
Prompt user to provide data for pydantic field.
default_override (a display-ready string: a path, an enum value, or "" for
an unset optional) replaces the field's own default when supplied, so callers
can pre-fill the current value while still prompting (e.g. deet project edit).
allow_back makes the prompt skippable with Ctrl+Left / Option+Left,
returning GO_BACK so a multi-step wizard can return to the
previous field. Standalone prompts leave it False (a single prompt has nowhere
to go back to).
Source code in deet/ui/terminal/wizards.py
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | |
run_model_wizard(model_class, *, prefill=None, defaults=None)
Create a wizard from a pydantic model.
Fields present in prefill are not prompted for; their values are injected
into the model directly. This lets a caller supply a field (e.g. the project
name derived from a directory) instead of asking the user for it.
defaults maps a field name to a display-ready string shown as that field's
editable default, so a caller can pre-fill current values while still prompting
(e.g. deet project edit).
Every field after the first is back-navigable: pressing Ctrl+Left or Option+Left returns to the previous field, which is re-prompted with the answer already given.
Source code in deet/ui/terminal/wizards.py
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | |
utils
assess_text_quality
Tools for text quality assessments.
EmptyTextError
Bases: Exception
Raise when our text passed to is_english is empty.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Exception
|
_type_
|
|
required |
Source code in deet/utils/assess_text_quality.py
41 42 43 44 45 46 47 48 49 50 51 52 | |
__init__(msg='Supplied text is empty.', *args, **kwargs)
Init the exception with default message.
Source code in deet/utils/assess_text_quality.py
50 51 52 | |
Language
Bases: Enum
Enum of languages for quality-checking.
Source code in deet/utils/assess_text_quality.py
16 17 18 19 | |
check_language(text, lang=Language.ENGLISH, threshold=0.2)
Assess if text is in the specified language.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to assess. |
required |
lang
|
Language
|
Language to check against. |
ENGLISH
|
threshold
|
float
|
Threshold for word overlap. |
0.2
|
Raises:
| Type | Description |
|---|---|
EmptyTextError
|
If text is empty. |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if text matches language, False otherwise. |
Source code in deet/utils/assess_text_quality.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
get_bc_brown_words()
Get bc_brown words, cached.
Source code in deet/utils/assess_text_quality.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
is_english(text, threshold=0.2)
Check if text meets minimum English quality.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
the text to check. |
required |
threshold
|
float
|
Defaults to 0.2. |
0.2
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if 'English', false if not. |
Source code in deet/utils/assess_text_quality.py
90 91 92 93 94 95 96 97 98 99 100 101 102 | |
destiny_utils
Utilities for working with destiny data types.
ReferencePresenter
A class to present references in a Streamlit application.
Source code in deet/utils/destiny_utils.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | |
abstract
property
Returns the abstract of the reference.
authors
property
Returns the authors of the reference as a semi-colon-separated string.
bibliographic_metadata
property
Returns the bibliographic metadata enhancement of the reference.
doi
property
Returns the DOI of the reference.
first_author
property
Returns the first author of the reference.
location
property
Returns the location enhancement of the reference.
orcids
property
Returns all available ORCIDs for each author of the reference as a semi-colon-separated string.
publication_date
property
Returns the publication date of the reference in 'dd mmm yyyy' format.
publication_links
property
Returns the publication location links of the reference as a semi-colon-separated string.
publication_locations
property
Returns the publication locations of the reference as a semi-colon-separated string.
publication_types
property
Returns the publication types of the reference as a semi-colon-separated string.
publisher
property
Returns the publisher of the reference.
taxonomy
property
Returns the taxonomy labels of the reference as a semi-colon-separated string of tuples.
title
property
Returns the title of the reference.
topic_domains
property
Returns the topic domain labels of the reference and their id links as a semi-colon-separated string of tuples.
topic_fields
property
Returns the topic field labels of the reference and their id links as a semi-colon-separated string of tuples.
topic_sub_fields
property
Returns the topic sub-field labels of the reference and their id links as a semi-colon-separated string of tuples.
topics
property
Returns the topic labels of the reference and their id links as a semi-colon-separated string of tuples.
year
property
Returns the publication year of the reference.
__init__(reference)
Init the ReferencePresenter class.
Source code in deet/utils/destiny_utils.py
17 18 19 | |
to_dict()
Convert the reference to a dictionary suitable for DataFrame representation.
Source code in deet/utils/destiny_utils.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | |
identifier_utils
Utility functions for creating, validating and manipulating identifiers.
check_if_id_exists(new_id, id_list)
Check if target id (int) is in a list of ids (list[int]).
Source code in deet/utils/identifier_utils.py
55 56 57 | |
hash_n_strings_to_document_id(string_list)
Convert n strings into an integer with MIN_DOCUMENT_ID-MAX_DOCUMENT_ID digits (4-10) using hash-based combination.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
string_list
|
list[str]
|
a list of strings to hash. |
required |
Returns:
| Type | Description |
|---|---|
int
|
An integer with between MIN_DOCUMENT_ID-MAX_DOCUMENT_ID digits |
int
|
(from 1000 to 9999999999). |
Source code in deet/utils/identifier_utils.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
text
Text utilities.
slugify(value)
Turn a string into a filesystem-safe slug (lowercase, hyphen-separated).
Source code in deet/utils/text.py
6 7 8 9 10 11 12 | |
text_normalisation
Shared text normalisation helpers for evaluation and EPPI citation parsing.
clean_extracted_text(text)
Clean an already-parsed highlight or citation fragment.
Removes residual EPPI markup markers ([¬s] / [¬e]), strips surrounding
quotes, and normalises whitespace. Intended for fragments extracted after
markup-aware parsing — not for raw EPPI Text fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Highlight or citation fragment (already separated from page/markup structure). |
required |
Returns:
| Type | Description |
|---|---|
str
|
Cleaned string ready for display or comparison. |
Source code in deet/utils/text_normalisation.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
normalize_list_elements(items)
Apply :func:normalize_string_for_match to each string element.
Non-string elements are passed through unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
list[Any]
|
Mixed list of values (typically strings plus other types). |
required |
Returns:
| Type | Description |
|---|---|
list[Any]
|
New list with string elements normalised (case-insensitive by default). |
Source code in deet/utils/text_normalisation.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
normalize_string_for_match(text, *, case_insensitive=True)
Normalise a string for comparison or search.
Applies :func:normalize_whitespace and, when case_insensitive is True
(the default), lowercases the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Input string to normalise. |
required |
case_insensitive
|
bool
|
If True, lowercase after whitespace normalisation. |
True
|
Returns:
| Type | Description |
|---|---|
str
|
Normalised string suitable for matching. |
Source code in deet/utils/text_normalisation.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
normalize_whitespace(text)
Collapse runs of whitespace to a single space and strip ends.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Input string (may contain newlines, tabs, or repeated spaces). |
required |
Returns:
| Type | Description |
|---|---|
str
|
String with internal whitespace collapsed and leading/trailing whitespace |
str
|
removed. Empty input yields |
Source code in deet/utils/text_normalisation.py
12 13 14 15 16 17 18 19 20 21 22 23 24 | |
timing
Wall-clock timing helpers.
ElapsedSeconds
pydantic-model
Bases: BaseModel
Elapsed wall-clock time in seconds, populated when a timing context exits.
Fields:
-
seconds(float)
Source code in deet/utils/timing.py
10 11 12 13 | |
measure_elapsed()
Yield an ElapsedSeconds model with seconds set on context exit.
Source code in deet/utils/timing.py
16 17 18 19 20 21 22 23 24 | |
tokenisation
Token counting and truncation utilities for LLM context management.
count_tokens(model, text)
Count the number of tokens in text for a given model.
Uses litellm.token_counter with messages format. Falls back to a rough character-based estimate (len/4) for unknown models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Model identifier for tokenizer selection. |
required |
text
|
str
|
Text to count tokens for. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens. |
Source code in deet/utils/tokenisation.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | |
estimate_cost_usd(model, prompt_tokens=0, completion_tokens=0)
Estimate cost in USD for prompt and completion tokens.
Uses litellm's cost_per_token. Returns (prompt_cost_usd, completion_cost_usd).
Either or both may be None if the model is unknown or the call fails.
Any other Exception from litellm (e.g. provider HTTP errors) is logged
at debug and also yields (None, None) so cost estimation stays
best-effort for callers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Model identifier (e.g. "gpt-4o-mini", "azure/gpt-4o-mini"). |
required |
prompt_tokens
|
int
|
Number of input/prompt tokens. |
0
|
completion_tokens
|
int
|
Number of output/completion tokens. |
0
|
Returns:
| Type | Description |
|---|---|
tuple[float | None, float | None]
|
Tuple of (prompt_cost_usd, completion_cost_usd). Either can be None. |
Source code in deet/utils/tokenisation.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | |
get_model_max_tokens(model)
Get the maximum input tokens allowed for a model.
Uses litellm's model registry. Returns None if the model is unknown.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Model identifier (e.g. "gpt-4o-mini", "azure/gpt-4o-mini"). |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
Maximum input tokens, or None if model not found. |
Raises:
| Type | Description |
|---|---|
LitellmModelNotMappedError
|
When litellm raises a bare |
Exception
|
Any other error from litellm is re-raised. |
Source code in deet/utils/tokenisation.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | |
merge_prompt_completion_cost_usd(prompt_cost_usd, completion_cost_usd)
Combine litellm prompt and completion cost parts into a single total.
Either part may be None when the model table lacks that component or estimation failed for that side.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prompt_cost_usd
|
float | None
|
Estimated USD cost for prompt tokens, or None. |
required |
completion_cost_usd
|
float | None
|
Estimated USD cost for completion tokens, or None. |
required |
Returns:
| Type | Description |
|---|---|
float | None
|
Sum when at least one part is known, otherwise None. |
Source code in deet/utils/tokenisation.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
truncate_to_token_limit(text, model, max_tokens)
Truncate text to fit within a token limit.
Encodes text, truncates the token list, decodes back to string. Uses char-based fallback when encode/decode unavailable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to truncate. |
required |
model
|
str
|
Model identifier for tokenizer. |
required |
max_tokens
|
int
|
Maximum tokens allowed for the truncated text. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Truncated text. |
Source code in deet/utils/tokenisation.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |