API reference

PaperPush is primarily a command-line tool, but its core is a plain Python package you can import and drive directly.

The public API is deliberately small — the names exported from paperpush (its __all__): the two data models, the submission-file toolkit, and the two workflow operations that have a library-level entry point.

import paperpush

venue = paperpush.get_venue("biorxiv")
sub = paperpush.load("biorxiv.sub")
issues = paperpush.validate(sub, venue)

Note

The login and submit steps are exposed only as CLI commands — paperpush login and paperpush submit — not as importable functions. They drive a real browser and orchestrate interactive sign-in, so they live in the CLI rather than the library API.

Lower-level helpers (autofill extraction internals, credential storage, logging setup) are intentionally not part of the public API. They remain importable from their submodules if you need them (e.g. from paperpush import credentials), but are not covered by compatibility guarantees.

Package metadata

paperpush.__version__

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

paperpush.__url__

str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.

Venues

Look up venue definitions and their fields.

paperpush.get_venue(slug)[source]

Return a single venue by slug (case-insensitive).

Matching is done against the lowercase slug or display name, so callers may pass "biorxiv", "bioRxiv", or "BIORXIV" interchangeably.

Raises KeyError if no venue matches.

Parameters:

slug (str)

Return type:

Venue

paperpush.list_venues(include_deprecated=False)[source]

Return supported venues, sorted by lowercase slug.

Venues are keyed by their lowercase slug, so any case variants in the database (e.g. "bioRxiv" and "biorxiv") collapse to a single entry rather than being listed twice.

Deprecated venues are omitted unless include_deprecated is true. They remain reachable via get_venue so any wired-up login flow still works.

Parameters:

include_deprecated (bool)

Return type:

list[Venue]

class paperpush.Venue(slug, name='', fields=<factory>, full_name='', submission_url='', venue_type='journal', site_url='', submission_guide='', description='', file_type_options=None, max_upload_mb=None, anonymous=False, deprecated=False, inherits='')[source]

Bases: object

A supported venue and the fields it requires.

Parameters:
  • slug (str)

  • name (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Display name. Defaults to the slug when omitted.')])

  • fields (Annotated[list[Field], FieldInfo(annotation=NoneType, required=True, description='The fields this venue asks for during submission.')])

  • full_name (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Full, unabbreviated venue name.')])

  • submission_url (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Submission/portal URL.')])

  • venue_type (Annotated[Literal['preprint', 'journal', 'conference'], FieldInfo(annotation=NoneType, required=True, description='Kind of venue: a preprint server, a journal, or a conference.')])

  • site_url (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Public homepage URL.')])

  • submission_guide (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='URL of the author/submission guide.')])

  • description (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Short description of the venue.')])

  • file_type_options (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description="Labels offered by the portal's per-file 'file type' dropdown (venue-level because the same dropdown applies to every upload).")])

  • max_upload_mb (Annotated[float | None, FieldInfo(annotation=NoneType, required=True, description='Maximum combined size, in megabytes, of all files in one submission.')])

  • anonymous (Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Anonymous (double-blind) review: validate checks the attached files and linked anonymous.4open.science repositories for information identifying the authors.')])

  • deprecated (Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Hidden from listings but still reachable by get_venue.')])

  • inherits (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Slug this venue inherits its field schema from. Empty/absent for a standalone venue. Distinct from submission sharing (which portal/runner/login a venue submits through), which is defined in code, not here.')])

slug: str
name: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Display name. Defaults to the slug when omitted.')] = ''
fields: Annotated[list[Field], FieldInfo(annotation=NoneType, required=True, description='The fields this venue asks for during submission.')]
full_name: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Full, unabbreviated venue name.')] = ''
submission_url: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Submission/portal URL.')] = ''
venue_type: Annotated[Literal['preprint', 'journal', 'conference'], FieldInfo(annotation=NoneType, required=True, description='Kind of venue: a preprint server, a journal, or a conference.')] = 'journal'
site_url: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Public homepage URL.')] = ''
submission_guide: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='URL of the author/submission guide.')] = ''
description: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Short description of the venue.')] = ''
file_type_options: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description="Labels offered by the portal's per-file 'file type' dropdown (venue-level because the same dropdown applies to every upload).")] = None
max_upload_mb: Annotated[float | None, FieldInfo(annotation=NoneType, required=True, description='Maximum combined size, in megabytes, of all files in one submission.')] = None
anonymous: Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Anonymous (double-blind) review: validate checks the attached files and linked anonymous.4open.science repositories for information identifying the authors.')] = False
deprecated: Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Hidden from listings but still reachable by get_venue.')] = False
inherits: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Slug this venue inherits its field schema from. Empty/absent for a standalone venue. Distinct from submission sharing (which portal/runner/login a venue submits through), which is defined in code, not here.')] = ''
classmethod from_dict(slug, data)[source]
Parameters:
Return type:

Venue

class paperpush.Field(id, label, type, required=False, help='', options=None, options_file=None, options_recommended=False, default=None, accept=None, fields=None, type_options=None, min_count=None, max_count=None, word_count=None, character_count=None, min_character_count=None, require_url=None, max_words_before_refs=None, max_pages_before_refs=None, main_text_end_headings=None, max_words=None, max_pages=None, max_words_before_refs_by=None, max_pages_before_refs_by=None, max_words_by=None, max_pages_by=None, min_value=None, max_value=None, max_file_size_mb=None, autofill='', confirm=False, required_if=None)[source]

Bases: object

A single field a venue asks for during submission.

The per-attribute descriptions below are attached with Annotated[..., pydantic.Field(description=...)] so they serve double duty: documentation for readers of this class and the field descriptions in the generated venues.schema.json (see paperpush.schema_models). The annotations are inert at runtime – this is a plain stdlib dataclass and performs no validation.

Parameters:
  • id (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Stable identifier, unique within the venue; the key used in the .sub file and for inheritance merges.')])

  • label (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Human-readable prompt shown for the field.')])

  • type (Annotated[Literal['text', 'textarea', 'choice', 'multichoice', 'boolean', 'int', 'file', 'filelist', 'authorlist'], FieldInfo(annotation=NoneType, required=True, description='Widget/value kind.')])

  • required (Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Whether submission requires a value.')])

  • help (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Guidance shown alongside the field.')])

  • options (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Allowed values for `choice`/`multichoice`.')])

  • options_file (Annotated[str | None, FieldInfo(annotation=NoneType, required=True, description="Name of a newline-separated keyword file under `venues/_assets/` whose lines become this field's `options`. Lets a long controlled vocabulary live in one shared text file instead of being inlined (and duplicated) in the database. When set, it supersedes any inline `options`.")])

  • options_recommended (Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='For a `choice`/`multichoice` field, whether `options` is advisory (a value outside the list is a WARNING, not an ERROR) rather than a closed set.')])

  • default (Annotated[Any, FieldInfo(annotation=NoneType, required=True, description='Default value (any JSON type).')])

  • accept (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Permitted file extensions for `file`/`filelist`, e.g. [".pdf", ".docx"]. Omit (not []) when the upload imposes no extension restriction.')])

  • fields (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Sub-field (column) names for a structured multi-item field such as an `authorlist` or a pipe-delimited `textarea` (funding, suggested reviewers). Each item line is `|`-delimited in this order. A trailing `?` marks an optional column (e.g. `department?`); every other column is required -- validation flags an item whose required column is blank. Author name and the `corresponding` flag have their own checks and are always effectively required regardless of marker.')])

  • type_options (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description="Per-file 'file type' dropdown choices applied to this field's uploads.")])

  • min_count (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive lower bound on item count for a multi-item field (multichoice selections, filelist/authorlist/list-textarea lines).')])

  • max_count (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive upper bound on item count for a multi-item field.')])

  • word_count (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Maximum length in words for a `text`/`textarea` value.')])

  • character_count (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Maximum length in characters for a `text`/`textarea` value, or for the free text of a `choice` with `options_recommended`.')])

  • min_character_count (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Minimum length in characters for a `text`/`textarea` value (the lower-bound counterpart to `character_count`).')])

  • require_url (Annotated[bool | None, FieldInfo(annotation=NoneType, required=True, description='For a `text`/`textarea`, require each non-blank line of the value to be a valid http/https URL.')])

  • max_words_before_refs (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum word count of the main text before the reference list.')])

  • max_pages_before_refs (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file` (PDF), the maximum page count before the reference list.')])

  • main_text_end_headings (Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, headings *other than the reference list* that end the main text for the `*_before_refs` limits (e.g. `Appendix`, `Ethics Statement`) -- sections the venue excludes from its word/page count. Each is a heading phrase matched on a line of its own; the earliest match, references included, ends the main text. When set, a heading that starts its own page (only a running head or page number ahead of it) counts the main text as ending on the previous page.')])

  • max_words (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum word count of the whole document (references included).')])

  • max_pages (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum page count of the whole document. Verified for PDF; for .docx a best-effort cached count.')])

  • max_words_before_refs_by (Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_words_before_refs` selected by a sibling field's value (e.g. by article type).")])

  • max_pages_before_refs_by (Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_pages_before_refs` selected by a sibling field's value.")])

  • max_words_by (Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_words` selected by a sibling field's value.")])

  • max_pages_by (Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_pages` selected by a sibling field's value (e.g. Bioinformatics' page cap by article type).")])

  • min_value (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive lower bound on the numeric value of an `int` field.')])

  • max_value (Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive upper bound on the numeric value of an `int` field.')])

  • max_file_size_mb (Annotated[float | None, FieldInfo(annotation=NoneType, required=True, description='Maximum size, in megabytes, of each individual file uploaded for a `file`/`filelist` field. Distinct from the venue-level max_upload_mb.')])

  • autofill (Annotated[Literal['extract', 'classify', 'filemap', 'never', ''], FieldInfo(annotation=NoneType, required=True, description='How an autofill engine may populate the field: extract | classify | filemap | never. Empty string means infer from `type`.')])

  • confirm (Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='For a required `boolean`, whether it is a consent checkbox that must be affirmative (vs. an informational yes/no question).')])

  • required_if (Annotated[str | None, FieldInfo(annotation=NoneType, required=True, description='Id of another field in the same venue; when that field has a non-empty value, this field becomes required. A `boolean` target triggers only on an affirmative answer, since "no" means the dependent fields do not apply. Combined with `required` (unconditional).')])

id: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Stable identifier, unique within the venue; the key used in the .sub file and for inheritance merges.')]
label: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Human-readable prompt shown for the field.')]
type: Annotated[Literal['text', 'textarea', 'choice', 'multichoice', 'boolean', 'int', 'file', 'filelist', 'authorlist'], FieldInfo(annotation=NoneType, required=True, description='Widget/value kind.')]
required: Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='Whether submission requires a value.')] = False
help: Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Guidance shown alongside the field.')] = ''
options: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Allowed values for `choice`/`multichoice`.')] = None
options_file: Annotated[str | None, FieldInfo(annotation=NoneType, required=True, description="Name of a newline-separated keyword file under `venues/_assets/` whose lines become this field's `options`. Lets a long controlled vocabulary live in one shared text file instead of being inlined (and duplicated) in the database. When set, it supersedes any inline `options`.")] = None
default: Annotated[Any, FieldInfo(annotation=NoneType, required=True, description='Default value (any JSON type).')] = None
accept: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Permitted file extensions for `file`/`filelist`, e.g. [".pdf", ".docx"]. Omit (not []) when the upload imposes no extension restriction.')] = None
fields: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='Sub-field (column) names for a structured multi-item field such as an `authorlist` or a pipe-delimited `textarea` (funding, suggested reviewers). Each item line is `|`-delimited in this order. A trailing `?` marks an optional column (e.g. `department?`); every other column is required -- validation flags an item whose required column is blank. Author name and the `corresponding` flag have their own checks and are always effectively required regardless of marker.')] = None
type_options: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description="Per-file 'file type' dropdown choices applied to this field's uploads.")] = None
min_count: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive lower bound on item count for a multi-item field (multichoice selections, filelist/authorlist/list-textarea lines).')] = None
max_count: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive upper bound on item count for a multi-item field.')] = None
word_count: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Maximum length in words for a `text`/`textarea` value.')] = None
character_count: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Maximum length in characters for a `text`/`textarea` value, or for the free text of a `choice` with `options_recommended`.')] = None
min_character_count: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Minimum length in characters for a `text`/`textarea` value (the lower-bound counterpart to `character_count`).')] = None
require_url: Annotated[bool | None, FieldInfo(annotation=NoneType, required=True, description='For a `text`/`textarea`, require each non-blank line of the value to be a valid http/https URL.')] = None
max_words_before_refs: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum word count of the main text before the reference list.')] = None
max_pages_before_refs: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file` (PDF), the maximum page count before the reference list.')] = None
main_text_end_headings: Annotated[list[str] | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, headings *other than the reference list* that end the main text for the `*_before_refs` limits (e.g. `Appendix`, `Ethics Statement`) -- sections the venue excludes from its word/page count. Each is a heading phrase matched on a line of its own; the earliest match, references included, ends the main text. When set, a heading that starts its own page (only a running head or page number ahead of it) counts the main text as ending on the previous page.')] = None
max_words: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum word count of the whole document (references included).')] = None
max_pages: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='For a manuscript `file`, the maximum page count of the whole document. Verified for PDF; for .docx a best-effort cached count.')] = None
max_words_before_refs_by: Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_words_before_refs` selected by a sibling field's value (e.g. by article type).")] = None
max_pages_before_refs_by: Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_pages_before_refs` selected by a sibling field's value.")] = None
max_words_by: Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_words` selected by a sibling field's value.")] = None
max_pages_by: Annotated[ConditionalLimit | None, FieldInfo(annotation=NoneType, required=True, description="`max_pages` selected by a sibling field's value (e.g. Bioinformatics' page cap by article type).")] = None
min_value: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive lower bound on the numeric value of an `int` field.')] = None
max_value: Annotated[int | None, FieldInfo(annotation=NoneType, required=True, description='Inclusive upper bound on the numeric value of an `int` field.')] = None
max_file_size_mb: Annotated[float | None, FieldInfo(annotation=NoneType, required=True, description='Maximum size, in megabytes, of each individual file uploaded for a `file`/`filelist` field. Distinct from the venue-level max_upload_mb.')] = None
autofill: Annotated[Literal['extract', 'classify', 'filemap', 'never', ''], FieldInfo(annotation=NoneType, required=True, description='How an autofill engine may populate the field: extract | classify | filemap | never. Empty string means infer from `type`.')] = ''
confirm: Annotated[bool, FieldInfo(annotation=NoneType, required=True, description='For a required `boolean`, whether it is a consent checkbox that must be affirmative (vs. an informational yes/no question).')] = False
required_if: Annotated[str | None, FieldInfo(annotation=NoneType, required=True, description='Id of another field in the same venue; when that field has a non-empty value, this field becomes required. A `boolean` target triggers only on an affirmative answer, since "no" means the dependent fields do not apply. Combined with `required` (unconditional).')] = None
classmethod from_dict(data)[source]
Parameters:

data (dict[str, Any])

Return type:

Field

Submission files

Read, write, and render .sub files.

class paperpush.SubFile(venue, values)[source]

Bases: object

Parsed contents of a .sub file.

Parameters:
venue: str
values: dict[str, str]
paperpush.load(path)[source]

Read and parse a .sub file from disk.

Parameters:

path (str | Path)

Return type:

SubFile

paperpush.parse(text)[source]

Parse the text of a .sub file into a SubFile.

Parameters:

text (str)

Return type:

SubFile

paperpush.render_template(venue, fill_defaults=False, values=None)[source]

Build the text of a .sub template for venue.

When values is given, a field whose id appears there is pre-populated with that value (this is how autofill carries extracted values into the template). Otherwise, when fill_defaults is True, fields with a declared default are pre-populated; failing both, value slots are left empty. values takes precedence over fill_defaults for any field it names.

Parameters:
Return type:

str

paperpush.write_template(venue, path=None, fill_defaults=False, overwrite=False)[source]

Write a .sub template for venue and return its path.

Parameters:
Return type:

Path

Autofill

Apply extracted submission field values to a .sub file. See paperpush autofill for the CLI equivalent.

paperpush.autofill(text, venue, extraction, manuscript_dir=None, min_confidence='low')[source]

Apply extraction to the .sub text for venue.

Returns an AutofillResult holding the rewritten text and an Outcome for every proposed field. The original text is never mutated; fields that are skipped keep whatever value they already carried (typically the template default).

min_confidence is the floor below which a proposal is not written at all ("low" writes everything proposed; "high" writes only sure things). manuscript_dir is used to resolve relative file paths in filemap fields against the directory the files actually live in.

Parameters:
  • text (str)

  • venue (Venue)

  • extraction (Extraction)

  • manuscript_dir (str | Path | None)

  • min_confidence (str)

Return type:

AutofillResult

Validate

Run the pre-submission checks against a loaded .sub file and its venue. See paperpush validate for the CLI equivalent.

paperpush.validate(subfile, venue, *, check_sensitive=True, check_links=True, check_references=True, check_manuscript=True, check_anonymous=None, check_hidden_text=True, check_openreview=True)[source]

Return all issues found in subfile against venue.

Combines schema-level checks (allowed options, file types, booleans, and stray fields, via pydantic) with required-field, file-existence, and author-list checks. Every problem is reported, so the author can fix them in one pass.

When check_sensitive is set (the default), the referenced upload files are scanned for information that was never meant to be shared – secrets, GPS metadata, editable-document links, and LaTeX source comments (see _sensitive_issues()) – and reported as advisory WARNINGs. When check_links is set (also the default), the URLs those files cite are probed and any that are unreachable (404/gone, including a still-private GitHub repo) are likewise flagged. When check_references is set (also the default), the DOIs in the submission’s bibliography – its .bib files and the manuscript’s own reference list – are resolved and compared against the title, author, and year each reference claims (see _reference_issues()). Both make network requests. When check_manuscript is set (also the default), the manuscript, figures, and other uploads are measured against the venue’s author guidelines as recorded in manuscript_requirements.json – formats, length, required sections and statements, title-page items, figure resolution, reference count (see paperpush.requirements_check); a LaTeX manuscript is compiled to a scratch PDF for its page count.

check_anonymous scans the submission for information identifying its authors, including every linked anonymous.4open.science repository (see _anonymity_issues(); network access is needed for the repositories). It defaults to the venue’s anonymous flag, so double-blind venues are always checked; pass True to check any venue.

check_hidden_text (default on) looks for white, invisible, microscopic, or off-page text in the uploads and reports hidden instructions to AI reviewers as errors (see _hidden_text_issues()). check_openreview (default on; network) looks up each author’s OpenReview profile for venues submitted through OpenReview (see _openreview_profile_issues()).

Parameters:
  • subfile (SubFile)

  • venue (Venue)

  • check_sensitive (bool)

  • check_links (bool)

  • check_references (bool)

  • check_manuscript (bool)

  • check_anonymous (bool | None)

  • check_hidden_text (bool)

  • check_openreview (bool)

Return type:

list[Issue]

Manuscript requirements

What a venue’s author guidelines require of the manuscript itself, read from manuscript_requirements.json. validate applies these through paperpush.requirements_check.check_manuscript_requirements(); see paperpush requirements for the CLI that prints them.

paperpush.requirements.get_requirements(slug)[source]

The requirements for slug (case-insensitive), or None if none are recorded.

A venue without an entry is not an error: paperpush validate simply has no manuscript rules to apply for it.

Parameters:

slug (str)

Return type:

ManuscriptRequirements | None

paperpush.requirements.resolve(reqs, values)[source]

The requirements that apply to the article type a .sub selects.

When the entry names an article_type_field and the filled value matches one of its article_types keys, that type’s overrides are merged onto the top-level rules. Otherwise the top-level rules apply unchanged. The result carries no article_types of its own.

Parameters:
Return type:

ManuscriptRequirements

class paperpush.requirements.ManuscriptRequirements(slug, source_urls=<factory>, retrieved='', inherits='', article_type_field='', article_types=<factory>, manuscript=ManuscriptRules(formats=None, max_file_size_mb=None, max_words=None, max_words_before_refs=None, max_pages=None, max_pages_before_refs=None, main_text_end_headings=None, count_excludes=None, count_includes=None, max_display_items=None, line_numbers=None, double_spacing=None, page_numbers=None, font=None, font_size_pt=None, margins_mm=None, page_size=None, single_file=None, figures_placement=None, tables_placement=None, anonymized=None, template_required=None, template_url=None, latex_class=None, template_layout=None, language=None, notes=[]), title_page=TitlePageRules(required_items=None, separate_file=None, title_max_characters=None, title_max_words=None, running_title_max_characters=None, notes=[]), abstract=AbstractRules(max_words=None, min_words=None, max_characters=None, structured=None, structured_headings=None, no_references=None, no_abbreviations=None, notes=[]), keywords=KeywordRules(min=None, max=None, notes=[]), sections=SectionRules(required=None, optional=None, order=None, combined_allowed=None, notes=[]), statements=StatementRules(required=None, optional=None, notes=[]), figures=FigureRules(formats=None, vector_formats=None, min_dpi=None, min_dpi_line_art=None, min_dpi_combination=None, max_file_size_mb=None, max_count=None, single_column_width_mm=None, double_column_width_mm=None, max_width_mm=None, max_height_mm=None, color_mode=None, min_font_size_pt=None, max_font_size_pt=None, font=None, legend_max_words=None, legends_location=None, multipanel_labels=None, color_charge=None, placement=None, notes=[]), tables=TableRules(formats=None, editable=None, max_count=None, placement=None, notes=[]), supplementary=SupplementaryRules(formats=None, max_file_size_mb=None, max_count=None, combined_single_pdf=None, notes=[]), references=ReferenceRules(style=None, numbered=None, max_count=None, include_titles=None, doi_required=None, unpublished_allowed=None, preprints_allowed=None, notes=[]), cover_letter=CoverLetterRules(required=None, formats=None, max_words=None, notes=[]), upload=UploadRules(max_total_mb=None, max_file_mb=None, notes=[]), notes=<factory>)[source]

One venue’s manuscript requirements, with inheritance already applied.

article_types holds the raw per-type override mappings; call resolve() with the filled .sub values to obtain the requirements that apply to the selected article type (the top-level sections merged with that type’s overrides).

Parameters:
  • slug (str)

  • source_urls (Annotated[list[str], FieldInfo(annotation=NoneType, required=True, description='Guideline pages the entry was taken from.')])

  • retrieved (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Date (YYYY-MM-DD) the guidelines were last read.')])

  • inherits (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Slug whose requirements this entry starts from. Empty for a standalone entry.')])

  • article_type_field (Annotated[str, FieldInfo(annotation=NoneType, required=True, description='Id of the .sub field whose value selects an `article_types` override.')])

  • article_types (Annotated[dict[str, dict[str, Any]], FieldInfo(annotation=NoneType, required=True, description='Per-article-type overrides, keyed by the exact option string; each value carries the same section keys as the top level.')])

  • manuscript (ManuscriptRules)

  • title_page (TitlePageRules)

  • abstract (AbstractRules)

  • keywords (KeywordRules)

  • sections (SectionRules)

  • statements (StatementRules)

  • figures (FigureRules)

  • tables (TableRules)

  • supplementary (SupplementaryRules)

  • references (ReferenceRules)

  • cover_letter (CoverLetterRules)

  • upload (UploadRules)

  • notes (Annotated[list[str], FieldInfo(annotation=NoneType, required=True, description='Venue-wide rules that fit no section.')])

to_dict()[source]

The requirements as plain JSON-able data, omitting unset keys.

Return type:

dict[str, Any]

paperpush.requirements_check.check_manuscript_requirements(venue, values)[source]

Every issue the venue’s manuscript requirements raise for values.

Returns an empty list when the venue has no entry in manuscript_requirements.json. Files that do not exist are skipped here (their absence is reported by the generic file checks).

Parameters:
Return type:

list[Issue]