Skip to main content

nota2md

Documentation Status

v0.5.0 (still unreleased) also makes nota2md download all mean all five releases (issues #225, #277): international-treaties, a third such subcommand, puts the scjn-tratados release (every international treaty the SCJN serves) on disk the same way, and all downloads it too; its scjn>= floor is now 0.5.0, the first version to ship download_scjn_tratados_assets. Before that (issue #225): federal-regulations/federal-guidelines, two new subcommands, put the scjn-reglamentos/scjn-lineamientos releases on disk (delegating to scjn.release's own downloaders, keyed by --id rather than --slug — neither collection has an abrev), and all now downloads all four instead of two. nota2md still reads nothing from either corpus itself — this only widens the convenience downloader. Its own scjn>= floor moved to 0.2.0, the first version to ship download_scjn_lineamientos_assets, and all then downloaded four.

v0.5.0 (still unreleased) also carries the SCJN package split (issues #206-#212) alongside the default-source change below — a minor bump, not a patch, on purpose: nota2md.scjn/nota2md.scjn_api are deleted outright, a reader's contract changed (no more download-on-read), and a cache directory moved. It ships as the same v0.5.0 rather than a further v0.6.0 because nothing between 0.4.1 and 0.5.0 has reached PyPI yet — scripts/ check_package_versions.py's single-step-ahead gate (issue #194) blocks a second minor bump before the first one publishes. The four names below keep importing from nota2md unchanged either way.

The scjn-leyes release's own readers moved to the scjn package (scjn.release, issue #209) — nota2md.scjn and nota2md.scjn_api no longer exist. download_scjn_leyes_corpus/download_scjn_leyes_index/ download_scjn_leyes_catalog/iter_current_federal_laws keep working unchanged from nota2md (re-exported), but the release's own on-disk cache moved to scjn.cache.CACHE_DIR — a separate directory from nota2md's own ($SCJN_CACHE_DIR, not $NOTA2MD_CACHE_DIR); an existing ~/.cache/nota2md/scjn-leyes/ is migrated there automatically, once, the first time nota2md download federal-laws/all runs. Every reader is now disk-only: none of them download on demand any more (that is download_scjn_leyes_assets's job alone, via scjn download or nota2md download federal-laws), and a codNota/law not yet cached raises scjn.release.AssetNotCached — legal_provisions still falls back to the DOF for it, exactly as it did for the old KeyError. See the SCJN path and the scjn package for the readers' own docs.

download_legal_provisions_provenance_ids is gone (issue #187). It read the historial-legislativo release, which was built by scraping the Cámara de Diputados' LeyesBiblio; the project now rests on the SCJN and the DOF alone (issue #184). There is no shim and the name is not kept.

A law's reform history is the scjn-leyes release itself: download_scjn_leyes_corpus("<abrev>") gives one entry per reform, oldest first, each with the codNota that published it — which is exactly what reconstruct_legal_provisions takes.

"Reform N" is redefined, once and deliberately: it is now the position of the reform in the SCJN's own chronological reform table, not Diputados' numbering. The two count different things — Diputados filed errata, peso restatements, Court rulings and entry-into-force declarations in the same numbered column — so a saved "reform 139 of the Constitution" may not point at the same decree it used to. This is not measured against the old numbering, and cannot be: its source is gone.

v0.5.0 changes what legal_provisions returns by default, makes its outdir optional, and replaces download_legal_provisions_titles with the legal_provisions_titles stream (issues #117, #165, #166).

Left out, outdir puts the Markdown in nota2md's own cache and returns its Path: legal_provisions(5773097) → <CACHE_DIR>/scjn-leyes/md/ccf-14-11-2025.md. Passing an outdir behaves exactly as before. And by default a codNota the scjn-leyes release covers now comes back as the law's whole consolidated text at that reform (written to outdir/{slug}-{fecha}.md, fuente: scjn header included), not as the reform decree the DOF published. Pass source="dof" — or --source dof — for the previous behaviour, which is unchanged in every other respect. See the SCJN path.

Eight entry points, all re-exported off the package itself (from nota2md import ...), for Mexico's official gazette (DOF, Diario Oficial de la Federación) and the federal laws it publishes:

Entry point Given Returns/writes
legal_provisions a legal provision's codNota (an outdir is optional) the law's consolidated text at that reform, from the SCJN corpus (outdir/{slug}-{fecha}.md) — or, when the corpus does not cover it, the DOF's own Markdown (outdir/nota-{codNota}.md); with no outdir, written into the cache and returned as a Path
reconstruct_legal_provisions a law's reform history (codNota list) its current text, written to outdir/ley-{codNota}.md
fetch_daily_legal_provisions a date (or a day already in hand) that whole day's legal provisions as one flat list, each naming its edicion
get_document a legal provision's codNota, or a get_nota record already in hand that same record, with cadenaContenido holding its Markdown instead of DOF HTML
legal_provisions_titles nothing (reads the whole notas-archivo cache) every legal provision ever published, as a stream of codNota+titulo+fecha+codOrgaUno records
download_scjn_leyes_corpus a law's slug every snapshot of that law in the scjn-leyes release, with its codNota links, in memory
download_scjn_leyes_index nothing (reads one small release asset) the reverse index codNota → (law, snapshot), in memory
download_scjn_leyes_catalog nothing (the index, plus one tarball per law for actualizado) every federal law the release publishes, as abrev+nombre+actualizado+materia+vigencia+resumen

They compose: download_scjn_leyes_corpus gets you the codNota list reconstruct_legal_provisions needs, and reconstruct_legal_provisions gets you a law's current text the same way legal_provisions gets you a single legal provision's — built from nothing but the DOF's own legal provisions, one Markdown file at a time.

from nota2md import download_scjn_leyes_corpus, legal_provisions, reconstruct_legal_provisions

cpeum = download_scjn_leyes_corpus("cpeum")
# one entry per reform, oldest first; `codNota` is None where the link could
# not be established (see `title_link_status` in the same entry).
historial = [s["codNota"] for s in cpeum["snapshots"] if s["codNota"]]

dest = reconstruct_legal_provisions(historial, "output", nombre_ley="CONSTITUCIÓN Política de los Estados Unidos Mexicanos")
print(dest)

Builds the Markdown of a single DOF legal provision, identified by its codNota.

Where document2md converts a whole edition PDF and dofjson is a thin client for SIDOF's JSON service, legal_provisions ties them together to produce the Markdown for one legal provision, from any of four sources:

Source How When
SCJN Reads the law's consolidated text as it read right after this reform out of the scjn-leyes release — no DOF request at all. See the SCJN path. The default, whenever the corpus covers this codNota with a link we are certain of. source="dof" turns it off.
HTML Converts the legal provision's cadenaContenido HTML directly (a DOF-tailored BeautifulSoup converter). The legal provision has digital text. Preferred: clean, already scoped to the one legal provision, no OCR.
Image Downloads the legal provision's scanned page image(s) via dofjson, OCRs them with document2md/mineru, then slices out the one legal provision. Image-only legal provisions — or any legal provision, when you want the certified scanned original.
PDF Downloads the legal provision's own PDF (the edition PDF sliced to the legal provision's pages, via dofjson.download_nota_pdf), OCRs it with document2md/mineru, then slices out the one legal provision. When you'd rather OCR a PDF than page images.

Both OCR paths (image and PDF) mirror the HTML path's output style (#/## headings, **bold**, *italic*, GitHub tables — document2md rewrites mineru's HTML tables to Markdown), so a legal provision's Markdown looks much the same whichever source it came from.

SIDOF is missing whole days of the gazette (see dofjson), and the legal provisions published on them have no SIDOF record at all — no cadenaContenido, and no codDiario or page numbers for the OCR paths to start from. When SIDOF answers {"Nota": []} for a codNota, legal_provisions looks the legal provision up on the DOF's own website instead, which serves the same HTML:

nota2md 4997808 --outdir output   # DOF 03-03-1999, a day SIDOF lost

The HTML path is the only one that can build these legal provisions; asking for --source image or --source pdf on one raises rather than fetching the wrong pages.

A scanned page (or a sliced PDF) usually holds more than one legal provision: it can begin with the tail of the previous legal provision and end with the start of the next. legal_provisions uses the per-day legal provision index — which lists every legal provision's title in order — to locate two boundaries in the OCR'd text (where this legal provision's title appears, and where the next legal provision's title appears) and keeps only what lies between. Matching is fuzzy (accent-folded, marker-stripped, difflib alignment) to tolerate OCR differences, and it also drops the next legal provision's organism header that the DOF prints above its title.

fetch_daily_legal_provisions(date) is the whole day — every legal provision published on it (title, codNota, pagina...) as one flat list in publication order, each note naming the edicion it appeared in, from SIDOF and, when SIDOF has nothing for that day, from the DOF's own website:

from nota2md import fetch_daily_legal_provisions
import datetime as dt

for nota in fetch_daily_legal_provisions(dt.date(2026, 7, 15)):
    print(nota["edicion"], nota["codNota"], nota["titulo"])

It is dofjson.fetch_daily_legal_provisions, re-exported (issue #180, the same pattern as legal_provisions_titles). It also takes a day already in hand instead of a date, in which case nothing is fetched. The underlying dofjson.get_notas() answers the day keyed by edition (NotasMatutinas/NotasVespertinas/NotasExtraordinarias) — the wire shape of both sources — so indexing one of those keys silently drops the rest of the day; this flattens all three, in publication order (issue #169).

get_document — a note whose text is already Markdown

dofjson.get_nota(codNota) answers the note's record with its digital text in cadenaContenido, as DOF HTML. get_document is that same record with cadenaContenido holding the Markdown instead — every other key (codNota, titulo, fecha, fuente, codDiario, page numbers...) passed through untouched, so it can go anywhere a get_nota record can, including as legal_provisions' own nota argument:

from nota2md import get_document

documento = get_document(5793655)
documento["titulo"]            # unchanged
documento["cadenaContenido"]   # Markdown, not HTML

This is the package's single note-to-Markdown step (issue #170): the pairing of cadenaContenido with html_to_markdown is spelled out here and nowhere else. Given a record already in hand, the call is pure and offline, and the dict passed in is never mutated:

documento = get_document(nota=fetch_nota(5793655))

A note with no digital text (scanned, pre-1999ish) comes back with cadenaContenido as it was — None or empty, and no error raised. It is not silently OCR'd: OCR is document2md's heavy path, and legal_provisions already owns the decision of when to take it. html_to_markdown itself stays public, as the string-to-string primitive this is built on.

The SCJN path — a law's consolidated text at each reform

Since v0.5.0, legal_provisions answers the whole law, not the reform decree, whenever it can. The SCJN's legislative database keeps, for every reform of every federal law, a snapshot of the law's consolidated text exactly as it read right after that reform; those snapshots are crawled — through the SCJN's own SCOW JSON API since issue #172, which replaced the legacy WebForms Buscador and, unlike it, indexes laws as new as the LEY FEDERAL DE CINE Y EL AUDIOVISUAL — matched to the DOF codNota that enacted them, and published as the scjn-leyes release (315 laws, 3,724 snapshots). A codNota the release covers is answered straight out of it — which is what reconstruct_legal_provisions otherwise has to infer by replaying every reform decree in order.

The SCJN is not an official source of legal text. dof.gob.mx/SIDOF is. Every file this path writes therefore keeps the corpus' own provenance header (fuente: scjn, ordenamiento, fecha_publicacion, …) intact, and lands under a different name — so the file alone says where it came from:

file written with no outdir (v0.5.0)
SCJN path outdir/{slug}-{fecha}.md (e.g. lfca-05-01-1999.md) <CACHE_DIR>/scjn-leyes/md/{slug}-{fecha}.md
every DOF path outdir/nota-{codNota}.md (unchanged) <CACHE_DIR>/dof/nota-{codNota}.md
from nota2md import legal_provisions

# no outdir at all: written into nota2md's cache, path returned (v0.5.0)
legal_provisions(4967917)     # -> <CACHE_DIR>/scjn-leyes/md/lfca-05-01-1999.md

# default: the whole law at that reform, if the corpus covers this codNota
legal_provisions(4967917, "output")                  # -> output/lfca-05-01-1999.md

# the original source, always — DOF/SIDOF, with OCR/reconstruction as needed
legal_provisions(4967917, "output", source="dof")    # -> output/nota-4967917.md

A codNota whose decree reformed several laws at once resolves to more than one law, and that raises ValueError listing the candidates rather than picking one; say which with instrumento="<slug>". A codNota the corpus does not cover, an asset not published yet, or a network failure reading the release all fall back to the DOF path (the last two with a warnings.warn, so the fallback is never silent).

Three readers of the release are exported for working with the corpus directly:

from nota2md import (
    download_scjn_leyes_catalog,
    download_scjn_leyes_corpus,
    download_scjn_leyes_index,
)

indice = download_scjn_leyes_index()          # codNota -> [{slug, archivo, ...}]
lfca = download_scjn_leyes_corpus("lfca")     # every snapshot of one law

# which federal laws exist, their name and their freshness
catalogo = download_scjn_leyes_catalog(freshness=False)
# -> [{"abrev": "ccf", "nombre": "CÓDIGO Civil Federal"}, ...]  (315 laws)

download_scjn_leyes_catalog is the federal-law catalogue: one {"abrev", "nombre", "actualizado", "materia", "vigencia", "resumen"} dict per law, sorted by abrev. abrev/nombre come from the release's index; actualizado — the date of the law's most recent reform as of the crawl — comes from each law's own estado.json, and is absent rather than null for the three laws that have none (absent means "freshness unknown, always review"). Reading actualizado means opening one tarball per law, so freshness=False answers off the index alone; run nota2md download federal-laws first (see below) and the default costs no request either.

materia/vigencia/resumen (issue #215) are the SCJN's own subject classification, in-force status (VIGENTE, ABROGADO (A), … — seven values, not a boolean) and one-paragraph abstract of the law. One value per law, not per reform, read off the index like nombre, so they survive freshness=False too; each is absent rather than null for a law the SCJN has no value for.

Beware one thing if you are joining this against a catalogue of your own: the release slug is the normalized abrev, so the 14 laws whose abbreviation carries an underscore (lif_2026, pef_2026, ligie_2022, reg_senado, the lrart*/lrf* reglamentarias …) come back hyphenated. Match on scjn.catalog.slug_instrumento and keep your own abrev.

A fourth reader, iter_current_federal_laws, answers a narrower question lazily instead of loading a whole law's history to answer it: not "every snapshot", just the current text of every federal law, one at a time.

from nota2md import iter_current_federal_laws

# run `nota2md download federal-laws` first to avoid downloading on the fly
for ley in iter_current_federal_laws():
    print(ley["slug"], ley["fecha_publicacion"], len(ley["markdown"]))

Each item is {"slug", "nombre", "materia", "vigencia", "resumen", "fecha_publicacion", "codNota", "archivo", "markdown"} — the law's newest snapshot plus that law's own classification (issue #215: stratify by materia, keep only VIGENTE, without a second pass), picked by fecha_publicacion without decoding any of its other snapshots or its notas/. slugs=[...] narrows the laws visited (and their order); left out, it walks every law the release currently ships a tarball for. It is a generator: iterating one law at a time never opens more than one <slug>.tgz, so consuming the whole corpus this way never holds more than one law in memory.

Cache

Since issue #209, the release assets the SCJN path reads live in the scjn package's own cache directory, not nota2md's:

<SCJN_CACHE_DIR>/scjn-leyes/indice-global.json.gz
<SCJN_CACHE_DIR>/scjn-leyes/<slug>.tgz

SCJN_CACHE_DIR defaults to the OS per-user cache directory (~/.cache/scjn on Linux), overridable with $SCJN_CACHE_DIR or by reassigning scjn.cache.CACHE_DIR — see the scjn package for the readers themselves. Every reader is disk-only: none of them download on demand, so a cache_dir passed to legal_provisions/download_scjn_leyes_corpus/etc. either names a directory explicitly (used as-is, both for this release and for nota2md's own output) or is left out, in which case scjn.cache.CACHE_DIR is what gets read — cache_dir=None no longer means "skip the cache, download into memory" for this path (it still does for the DOF path's own cache, see nota2md.cache). refrescar=True is now the downloader's flag (download_scjn_leyes_assets, or scjn download/nota2md download federal-laws) — an asset already on disk is a hit by file name, never revalidated, since this corpus is only ever republished by hand.

Usage

# no --outdir: written into nota2md's cache, path printed
nota2md 5793655

# the law's consolidated text from the SCJN corpus when it covers this
# codNota, otherwise the DOF (HTML when available, else OCR)
nota2md 5793655 --outdir output

# the original source only: DOF/SIDOF, never the SCJN
nota2md 5793655 --source dof --outdir output

# one decree, several laws: say which one
nota2md 5793655 --instrumento lft --outdir output

# cache: a directory of your own, or none at all
nota2md 5793655 --cache-dir /mnt/datos/nota2md --outdir output
nota2md 5793655 --cache-dir none --refrescar --outdir output

# fetch the whole SCJN corpus up front instead of asset by asset on demand
# (see `nota2md download` below)
nota2md download federal-laws

# force the scanned-image + OCR path, sourcing the next legal provision's
# title from a saved notas index (avoids an extra request; works offline)
dofjson 2026-07-15 --outdir output          # writes 15072026-notas.json
nota2md 5793655 --source image --notas output/15072026-notas.json --outdir output

# force the PDF + OCR path (edition PDF sliced to the legal provision's pages)
nota2md 5793655 --source pdf --notas output/15072026-notas.json --outdir output

Programmatically:

from nota2md import legal_provisions

legal_provisions(5793655, "output")                 # SCJN if covered, else DOF
legal_provisions(5793655, "output", source="dof")   # -> output/nota-5793655.md

The HTML path needs only beautifulsoup4; the image and PDF paths additionally need document2md (and mineru), imported lazily so the HTML path works without them.

Left alone, every legal_provisions(..., source="image"|"pdf") call manages its own OCR server as needed. Building many legal provisions in one run (e.g. every legal provision in a law's historial that has no HTML) can instead share one already-warm mineru-api server across all of them, by passing an already-__enter__'d document2md.BatchConverter as converter:

from document2md import BatchConverter
from nota2md import legal_provisions

with BatchConverter() as ins:
    for cod_nota in codigos_sin_html:
        legal_provisions(cod_nota, "output", source="image", converter=ins)

This is the same BatchConverter document2md itself uses to convert any batch of documents — DOF-sourced or not.

Builds a law's current (vigente) text from nothing but its DOF legal provisions: starts from the original publication and replays each reform decree's own "se reforma/adiciona/deroga el artículo N... para quedar como sigue" instruction on top of it, article by article — filling back in, from the article's own previous text, every fracción or inciso a reform elides with "..." instead of repeating. It never reads anyone else's consolidated text of the law: tests/test_leyes_44.py checks it against the SCJN's own consolidated text at each law's most recent reform, over 42 real federal laws, and that test says in full what the check does and does not establish (issue #188).

The SCJN corpus becoming legal_provisions' default source (issue #117) does not retire this function (issue #129's audit): the corpus links 3,291 of its 3,724 leyes snapshots to a codNota (2,474 by title alone, 834 more promoted from their content-diff confirmation in issue #187), only 526 of them pre-1999, and covers nothing outside federal laws — so replaying a law's own reform decrees remains the only route for everything it does not reach, as well as the independent cross-check on what it does.

from nota2md import reconstruct_legal_provisions

# cpeum's own historial: [5592105, 5730586, ...] — oldest first, index 0 the
# original publication (see the `scjn-leyes` readers above for where a law's
# own historial list comes from).
dest = reconstruct_legal_provisions(
    [5592105, 5730586], "output", nombre_ley="LEY de Amnistía",
)
print(dest.read_text(encoding="utf-8"))   # -> output/ley-5592105.md

Each legal provision it needs is fetched through legal_provisions into the same outdir, as nota-{codNota}.md — a legal provision already there from an earlier call (this law's own previous run, or another law's sharing the same outdir) is read back from disk instead of fetched again.

nombre_ley (the catalogue's own nombre, e.g. "LEY de Amnistía") scopes every legal provision to the one instrument among the several a single decree may touch — pass it whenever a legal provision is shared with another law's history, which the release's per-law index does not mark on its own (the reverse index does: download_scjn_leyes_index maps one codNota to every law it reformed). Left out, a legal provision is assumed to concern only this law, which holds for most of them but silently mixes in another law's articles for the rest.

source, min_confidence and keep_pages are the same parameters legal_provisions itself takes, forwarded as-is to the call made for every legal provision in the history. The default here is source="html", not legal_provisions's own "auto": the article-merge this function does (_fusiona_articulo) was designed and checked against HTML-derived Markdown, so a legal provision missing cadenaContenido still fails by default. Passing source="image" or "pdf" OCRs it instead of failing, but the merge's behavior on OCR output has not been validated — review the result before trusting it.

Implemented in dofjson.titulos and re-exported here so it sits alongside the rest of nota2md's entry points. Yields a compact codNota + titulo + fecha + codOrgaUno record for every legal provision published since 1917 (~1.2 million of them), streamed off the notas-archivo cache — nothing is written, and a populated cache means no network at all (issue #166; it used to write a titulos.jsonl.gz dataset):

nota2md download gazette-metadata    # populate the cache, once
from nota2md import legal_provisions_titles

for titulo in legal_provisions_titles():
    ...

nota2md download — putting the releases on disk

Everything above reads from the GitHub releases this project reads, downloading whatever it needs on the fly. nota2md download fetches them ahead of time instead, into the per-user cache directory each package already uses — so a notebook, a batch run or an offline session finds them already there, and no script has to be written first:

nota2md download federal-laws         # the scjn-leyes release (~320 MB, 315 laws)
nota2md download federal-regulations  # the scjn-reglamentos release (~76 MB, 1087 instruments)
nota2md download federal-guidelines   # the scjn-lineamientos release (~1.4 MB, 163 instruments)
nota2md download international-treaties  # the scjn-tratados release (~1,456 instruments)
nota2md download gazette-metadata     # the notas-archivo release (~59 MB, 117 assets)
nota2md download all                  # all five, each into its own cache

federal-laws brings down the reverse index plus one tarball per law. --slug (repeatable) narrows it to the laws you actually want; the index always comes along, since it is what resolves a codNota to a law:

nota2md download federal-laws --slug lft --slug lfca

federal-regulations, federal-guidelines and international-treaties are the same shape, but keyed by id_ordenamiento rather than slug — neither a reglamento, a lineamiento nor a treaty has an abrev (the SCJN reissues one as a brand-new id rather than reforming the previous one), so they take --id (repeatable), never --slug:

nota2md download federal-regulations --id 12345

Every subcommand is idempotent: an asset already on disk is matched by file name and never revalidated, so a second run downloads nothing and finishes in milliseconds. Each line of output says how many assets were downloaded versus already cached, and names the directory written to:

$ nota2md download federal-laws --slug lfca
[1/2] indice-global.json.gz: already cached
[2/2] lfca.tgz: already cached
scjn-leyes: 2 assets in /home/user/.cache/scjn/scjn-leyes (0 downloaded, 2 already cached)

Pass --refrescar to re-download over what is there — the only way a release re-published under the same asset names reaches an already-populated cache.

Where the data lands

The five releases keep two separate cache directories, by package: they have different lifecycles, and clearing one must not clear the other. nota2md download does not merge them; all is a shorthand for five invocations, not a shared destination.

federal-laws (scjn-leyes) federal-regulations (scjn-reglamentos) federal-guidelines (scjn-lineamientos) international-treaties (scjn-tratados) gazette-metadata (notas-archivo)
Package scjn scjn scjn scjn dofjson
Linux ~/.cache/scjn/scjn-leyes/ ~/.cache/scjn/scjn-reglamentos/ ~/.cache/scjn/scjn-lineamientos/ ~/.cache/scjn/scjn-tratados/ ~/.cache/dofjson/
macOS ~/Library/Caches/scjn/scjn-leyes/ ~/Library/Caches/scjn/scjn-reglamentos/ ~/Library/Caches/scjn/scjn-lineamientos/ ~/Library/Caches/scjn/scjn-tratados/ ~/Library/Caches/dofjson/
Windows %LOCALAPPDATA%\scjn\Cache\scjn-leyes\ %LOCALAPPDATA%\scjn\Cache\scjn-reglamentos\ %LOCALAPPDATA%\scjn\Cache\scjn-lineamientos\ %LOCALAPPDATA%\scjn\Cache\scjn-tratados\ %LOCALAPPDATA%\dofjson\Cache\
Override $SCJN_CACHE_DIR, or scjn.cache.CACHE_DIR $SCJN_CACHE_DIR, or scjn.cache.CACHE_DIR $SCJN_CACHE_DIR, or scjn.cache.CACHE_DIR $SCJN_CACHE_DIR, or scjn.cache.CACHE_DIR dofjson.titulos.CACHE_DIR
Per-run override --cache-dir DIR --cache-dir DIR --cache-dir DIR --cache-dir DIR --cache-dir DIR

The four SCJN releases share scjn's own cache directory (a subdirectory each, issue #209 moved them out of nota2md's own cache — not the ~/.cache/nota2md/scjn-leyes/ layout an earlier version of this table used to show), while notas-archivo keeps dofjson's. --cache-dir therefore means a different thing depending on the subcommand — an scjn directory on the first four, a dofjson one on gazette-metadata — which each subcommand's own --help says plainly. --cache-dir none (valid on nota2md <codNota>, where it means "skip the cache, download into memory") is rejected on every download subcommand: each one exists to write a release to disk, and "no cache" has nowhere to write.

nota2md reads nothing from scjn-reglamentos/scjn-lineamientos/ scjn-tratados itself — this verb is a convenience downloader for them, not a sign that nota2md's own build path consumes them (see the scjn package for readers over those corpora).

From Python, the five downloads are scjn.release.download_scjn_leyes_assets, scjn.release.download_scjn_reglamentos_assets, scjn.release.download_scjn_lineamientos_assets, scjn.release.download_scjn_tratados_assets and dofjson.download_dof_assets.

Installation

pip install nota2md          # legal_provisions' HTML path, plus reconstruct_legal_provisions
                              # and the scjn-leyes release readers
pip install nota2md[ocr]     # also pulls in document2md, for legal_provisions' image/PDF OCR paths

dofjson and requests are hard dependencies and install automatically. For development in this monorepo, install the siblings editable instead so local edits are picked up:

pip install -e "packages/dofjson"
pip install document2md          # own repository; only needed for the image/PDF OCR paths
pip install -e "packages/nota2md[test]"

Development

pytest packages/nota2md

Metadata

Release files for nota2md 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nota2md 0.5.0
File Size Uploaded Provenance
nota2md-0.5.0.tar.gz 98.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nota2md 0.5.0
File Interpreter ABI Platform
nota2md-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 155.1 kB

Release files / nota2md-0.5.0.tar.gz

Download URL nota2md-0.5.0.tar.gz
Size 98.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bf53fe904f394896fbdb7ce25fa766d1554a3e830cebb826559174587a610777
BLAKE2b-256 checksum
How to use checksums
54846e0bf3f83a90bfd1c0fefae5fb2aa3fd06e0fed2ac6fca9da3efdb8317bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / nota2md-0.5.0-py3-none-any.whl

Download URL nota2md-0.5.0-py3-none-any.whl
Size 56.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e2460c81c42a324af86fd60ccfa91263ef4f27c10811bad46e8f0afe5bd8a676
BLAKE2b-256 checksum
How to use checksums
d70c256acdde9dead81a466f93e64bc8a6fa62c5ac8ab2caf0cf503d97491ee3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Security for nota2md 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page