Package: easy-entrez
easy-entrezPython REST API for Entrez E-Utilities, aiming to  be easy to use and reliable.Easy-entrez:makes common tasks easy thanks to simple Pythonic API,is typed and integrates well with mypy,is tested on Windows, Mac and Linux across Python 3.7, 3.8, 3.9, 3.10 and 3.11is limited in scope, allowing to focus on the reliability of the core code,does not use the stateful API as it iserror-proneas seen on example of the alternativeentrezpy.Examplesfromeasy_entrezimportEntrezAPIentrez_api=EntrezAPI('your-tool-name','e@mail.com',# optionalreturn_type='json')# find up to 10 000 results for cancer in humanresult=entrez_api.search('cancer AND human[organism]',max_results=10_000)# data will be populated with JSON or XML (depending on the `return_type` value)result.dataSee more in theDemo notebookanddocumentation.For a real-world example (i.e. used forthis publication) see notebooks inmulti-omics-state-of-the-fieldrepository.Fetching genes for a variant from dbSNPFetch the SNP record forrs6311:rs6311=entrez_api.fetch(['rs6311'],max_results=1,database='snp').data[0]rs6311Display the result:fromeasy_entrez.parsingimportxml_to_stringprint(xml_to_string(rs6311))Find the gene names forrs6311:namespaces={'ns0':'https://www.ncbi.nlm.nih.gov/SNP/docsum'}genes=[name.textfornameinrs6311.findall('.//ns0:GENE_E/ns0:NAME',namespaces)]print(genes)['HTR2A']Fetch data for multiple variants at once:result=entrez_api.fetch(['rs6311','rs662138'],max_results=10,database='snp')gene_names={'rs'+document_summary.get('uid'):[element.textforelementindocument_summary.findall('.//ns0:GENE_E/ns0:NAME',namespaces)]fordocument_summaryinresult.data}print(gene_names){'rs6311': ['HTR2A'], 'rs662138': ['SLC22A1']}Obtaining the chromosomal position from SNP rsID numberfrompandasimportDataFrameresult=entrez_api.fetch(['rs6311','rs662138'],max_results=10,database='snp')variant_positions=DataFrame([{'id':'rs'+document_summary.get('uid'),'chromosome':chromosome,'position':position}fordocument_summaryinresult.dataforchrom_and_positionindocument_summary.findall('.//ns0:CHRPOS',namespaces)forchromosome,positionin[chrom_and_position.text.split(':')]])variant_positionsidchromosomeposition0rs631113468973431rs6621386160143444Converting full variation/mutation data to tabular formatParsing utilities can quickly extract the data to aVariantSetobject
holding pandasDataFrames with coordinates and alternative alleles frequencies:fromeasy_entrez.parsingimportparse_dbsnp_variantsvariants=parse_dbsnp_variants(result)variants<VariantSet with 2 variants>To get the coordinates:variants.coordinatesrs_idrefaltschromposchrom_prevpos_prevconsequencers6311CA,T13468973431347471478upstream_transcript_variant,intron_variant,genic_upstream_transcript_variantrs662138CG61601434446160564476intron_variantFor frequencies:variants.alt_frequencies.head(5)# using head to only display first 5 for brevityrs_idallelesource_frequencytotal_countstudycount0rs6311T0.4434922211000Genomes984.9911rs6311T0.4112611585ALSPAC651.8492rs6311T0.3316961486Estonian492.93rs6311T0.3514GENOME_DK4.94rs6311T0.40252956309GnomAD22666Obtaining the SNP rs ID number from chromosomal positionYou can use the query string directly:results=entrez_api.search('13[CHROMOSOME] AND human[ORGANISM] AND 31873085[POSITION]',database='snp',max_results=10)print(results.data['esearchresult']['idlist'])['59296319', '17076752', '7336701', '4']Or pass a dictionary (no validation of arguments is performed,ANDconjunction is used):results=entrez_api.search(dict(chromosome=13,organism='human',position=31873085),database='snp',max_results=10)print(results.data['esearchresult']['idlist'])['59296319', '17076752', '7336701', '4']The base position should use the latest genome assembly (GRCh38 at the time of writing);
you can use the position in previous assembly coordinates by replacingPOSITIONwithPOSITION_GRCH37.
For more information of the arguments accepted by the SNP database see theentrez help pageon NCBI website.Obtaining amino acids change information for variants in given rangeFirst we search for dbSNP rs identifiers for variants in given region:dbsnp_ids=(entrez_api.search('12[CHROMOSOME] AND human[ORGANISM] AND 21178600:21178720[POSITION]',database='snp',max_results=100).data['esearchresult']['idlist'])Then fetch the variant data for identifiers:variant_data=entrez_api.fetch(['rs'+rs_idforrs_idindbsnp_ids],max_results=10,database='snp')And parse the data, extracting the HGVS out of summary:fromeasy_entrez.parsingimportparse_dbsnp_variantsfrompandasimportSeriesdefselect_protein_hgvs(items):return[[sequence,hgvs]forentryinitemsforsequence,hgvsin[entry.split(':')]ifhgvs.startswith('p.')]protein_hgvs=(parse_dbsnp_variants(variant_data).summary.HGVS.apply(select_protein_hgvs).explode().dropna().apply(Series).rename(columns={0:'sequence',1:'hgvs'}))protein_hgvs.head()rs_idsequencehgvsrs1940853486NP_006437.3p.Gly203Terrs1940853414NP_006437.3p.Glu202Glyrs1940853378NP_006437.3p.Glu202Lysrs1940853299NP_006437.3p.Lys201Thrrs1940852987NP_006437.3p.Asp198GluFetching more than 10 000 entriesUsein_batches_ofmethod to fetch more than 10k entries (e.g.variant_ids):snps_result=(entrez.api.in_batches_of(1_000).fetch(variant_ids,max_results=5_000,database='snp'))The result is a dictionary with keys being identifiers used in each batch (because the Entrez API does not always return the indentifiers back) and values representing the result. You can useparse_dbsnp_variantsdirectly on this dictionary.Find PubMed ID from DOIWhen searching GWAS catalog PMID is needed over DOI. You can covert one to the other using:defdoi_term(doi:str)->str:"""Prepare DOI for PubMed search"""doi=(doi.replace('http://','https://').replace('https://doi.org/',''))returnf'"{doi}"[Publisher ID]'result=entrez_api.search(doi_term('https://doi.org/10.3389/fcell.2021.626821'),database='pubmed',max_results=1)result.data['esearchresult']['idlist']['33834021']InstallationRequires Python 3.6+. Install with:pipinstalleasy-entrezIf you wish to enable (optional, tqdm-based) progress bars use:pipinstalleasy-entrez[with_progress_bars]If you wish to enable (optional, pandas-based) parsing utilities use:pipinstalleasy-entrez[with_parsing_utils]AlternativesYou might want to try:biopython.Entrez- biopython is a heavy dependency, but probably good choice if you already use itpubmedpy- provides interesting utilities for parsing the responsesentrez- appears to have a comparable scope but quite different APIentrezpy- this one did not work well for me (hence this package), but may have improved since