Aller au contenu

omnilab/uniprot

Omnilab UniProt: a protein of UniProtKB by accession or entry name - its names, gene, organism, function, length, mass and sequence, cofactors, ligands, location and keywords, its NCBI Gene and Ensembl genes as cross-references, its organism, PDB structures and ligands as related things - and UniProt's search, through the UniProt REST API, no key needed.

Étage
Fournisseur · Omnilab
Version
1.x
Suite de conformité
non branchée
Vérifié en réel
Son README ne le dit pas
Licence
MIT
composer require omnilab/uniprot:1.x-dev

UniProtKB through UniProt's REST API (https://rest.uniprot.org/uniprotkb/) for omnisense/omnilab: proteins by accession or entry name - function, gene, organism, sequence, mass, cofactors, ligands - with their genes in NCBI Gene and Ensembl as cross-references, their structures, cofactors and ligands as related things, as entities; a search in UniProt's query syntax. No key.

Installation

composer require omnilab/uniprot
use Omnilab\UniProt\UniProtSourceFactory;

$uniprot = (new UniProtSourceFactory($httpClient))->create([
    'mailto' => 'support@glitchr.io',  // optional
    'sequence' => 2000,                // optional
    'structures' => 20,                // optional
]);

With the Symfony bundle, the factory is registered as uniprot (see the core's docs).

Credentials

None: UniProt's REST API takes no key and no account. Give mailto, the address UniProt writes to before it blocks a caller.

Options

The factory's options, with the defaults it applies (UniProtSourceFactory):

Option Type Default Required Effect
sequence int 2000 no the longest sequence given as the sequence property, in residues; 0: none
structures int 20 no how many PDB structures to keep in related('structure'), in UniProt's order; 0: none
mailto ?string null no a contact address, in the User-Agent: whom UniProt writes to before it blocks a caller
user_agent ?string null no the whole User-Agent, in place of the one made from mailto
throttle float 0 no seconds left between two calls: UniProt publishes no figure
base_uri string https://rest.uniprot.org/uniprotkb/ no the API the source calls

Capabilities

capabilities() answers entity, search, cross_references; an operation it does not answer throws NotSupportedException before any call.

Capability Supported
entity yes an accession (P68871, uniprot:, uniprotkb:, its page) or an entry name (HBB_HUMAN); a merged accession follows its target; another scheme refused before any call; one call
search yes UniProt's query syntax (gene:HBB AND organism_id:9606), 500 a page at most, the next page by the Link header's cursor, the total from X-Total-Results; a domain other than biology answers an empty page
series no
products no
occurrences no
datasets no
jobs no
open no
structure no
cross_references yes its genes in NCBI Gene and Ensembl; its structures, cofactors, ligands and organism are related
forecast no
historical no
area no
station no
cloud_cover no

Which API

The UniProt REST API, https://rest.uniprot.org/uniprotkb/, in JSON. Each call names the fields it wants (fields=): an entry whole runs to hundreds of kilobytes (hemoglobin beta: 342 kB, most of it variants, references and 348 PDB lines); the fields read here make 59 kB of it.

The source sends Accept-Encoding: identity. Asked for gzip alone - what Symfony's HTTP client asks when it decompresses by itself - UniProt compresses the body twice (seen on 2026-10-15): the client undoes one layer, the JSON stays compressed. gzip, deflate, br or identity are answered right.

Calls

Method Reads UniProt
entity() an accession (P68871, uniprot:P68871, uniprotkb:P68871, UniProt's page, identifiers.org) GET {accession}.json?fields=
an entry name (HBB_HUMAN) GET search?query=id:HBB_HUMAN AND active:true
search() Query::$text in UniProt's query syntax (hemoglobin beta, gene:HBB AND organism_id:9606); a domain other than biology answers nothing GET search?query=&size=&cursor=

A bare string of an accession's shape is read as one: Q60235 is a UniProt protein here (a type III secretion protein of Pseudomonas syringae), not the Wikidata item of caffeine - give an Identifier or wikidata:Q60235 for that, which the source refuses. Anything else (a protein's name, a gene, a ChEBI id) is refused before any call; search for a name.

An accession that was merged into another is answered 303 to that other: an HTTP client that follows redirections (Symfony's does) brings the entry whole, its fields dropped on the way; one that does not gives the inactive record (MERGED, mergeDemergeTo), and the source asks the target. An entry demerged into several (P02023, an old accession of hemoglobin beta, now three entries) or deleted is null, as is an unknown accession (404).

The search pages by a cursor UniProt gives in the Link header of its answer (rel="next"), the total in X-Total-Results; Page::$next is that cursor.

What an entity holds

id (its primary accession), label (the recommended name; an unreviewed entry's submitted name), domain biology, kind protein, synonyms (its alternative names, full and short), description (its function, as UniProt writes it, the PubMed citations in the text taken out; the functions of the peptides it is cleaved into left out), url (its page), and these properties:

Key UniProt Value
gene the gene's name (else its ordered locus or ORF name) text
organism, organism_common_name organism text
sequence_length sequence.length Quantity, aa
mass sequence.molWeight (the canonical sequence) Quantity, Da
sequence sequence.value, when no longer than the sequence option text
reviewed Swiss-Prot (reviewed) or TrEMBL boolean
protein_existence proteinExistence, without its rank text
annotation_score annotationScore, 1 to 5 number
ec_number the recommended name's EC numbers text
subcellular_location the SUBCELLULAR LOCATION comments' locations text
cofactor the COFACTOR comments' cofactors text
ligand the ligands of the binding sites that have a ChEBI id, each once text
keyword the keywords text

identifiers: its NCBI Gene id (GeneID), then its Ensembl gene ids (each once, without their version) - the gene is what UniProt, NCBI and Wikidata share. related: organism (its NCBI taxon), cofactor and ligand (their ChEBI ids), structure (its PDB entries, in UniProt's order, 20 by default). These are other things than the protein: the Collector does not follow them, the Merger does not join two proteins of one organism.

A search result holds the names, gene, organism, function, length, mass, existence, score and genes: entity() reads the rest.

What UniProt does not give here

No Wikidata item (UniProt keeps no cross-reference to it: Wikidata finds the protein by its accession, P352). Not read: the secondary accessions (not among the fields one can ask), the isoforms, the features other than binding sites (variants, domains, modified residues), the diseases, interactions, GO terms, references, the HGNC and OMIM cross-references (schemes the core has, not read here: omnilab/hgnc gives them) and those of schemes it does not know (RefSeq, DrugBank, AlphaFold DB...). The ChEMBL target an entry names (CHEMBL4331 for hemoglobin beta) is not taken: the core's chembl scheme names molecules. UniRef, UniParc, proteomes and the ID mapping service are not used.

The Collector

Hemoglobin beta from UniProt into NCBI Gene and Wikidata, answered on 2026-10-15: see the core's docs/merging.md. UniProt gives the gene (GeneID 3043), NCBI's gene report gives the accession back (swiss_prot_accessions), Wikidata's protein item (Q424422) carries it in P352.

Example

<?php

require __DIR__.'/vendor/autoload.php';

use Omnilab\Model\Scheme;
use Omnilab\Source\Query;
use Omnilab\UniProt\UniProtSourceFactory;
use Symfony\Component\HttpClient\HttpClient;

$uniprot = (new UniProtSourceFactory(HttpClient::create()))->create(['mailto' => 'you@example.org', 'sequence' => 0, 'structures' => 3]);

$hbb = $uniprot->entity('HBB_HUMAN');   // by its entry name
echo $hbb->label, ' (', $hbb->id, '): gene ', $hbb->value('gene'), ', ', $hbb->value('organism'), ', ', $hbb->property('sequence_length'), ', ', $hbb->property('mass'), "\n";
echo '  NCBI Gene ', $hbb->identifier(Scheme::NCBI_GENE), ', Ensembl ', $hbb->identifier(Scheme::ENSEMBL), '; structures ', implode(', ', $hbb->related('structure')->values(Scheme::PDB)), '; ligands ', implode(', ', array_map('strval', $hbb->properties('ligand'))), "\n";

$page = $uniprot->search(new Query('gene:HBB AND organism_id:9606', limit: 3));
printf("%d entries for gene:HBB in human; the first %d: %s\n", $page->total, count($page), implode(', ', array_map(static fn ($e) => $e->id->value.' '.$e->label, $page->items)));
Hemoglobin subunit beta (uniprot:P68871): gene HBB, Homo sapiens, 147 aa, 15998 Da
  NCBI Gene 3043, Ensembl ENSG00000244734; structures 1A00, 1A01, 1A0U; ligands (2R)-2,3-bisphosphoglycerate, heme b
18 entries for gene:HBB in human; the first 3: P68871 Hemoglobin subunit beta, F8W6P5 Hemoglobin subunit beta, Q7Z2K5 Beta-globin

(as answered on 2026-10-27: three calls - the search by entry name, the entry, the search)

# config/packages/omnilab.yaml
omnilab:
    sources:
        uniprot: { factory: uniprot, options: { mailto: '%env(OMNILAB_MAILTO)%', sequence: 2000, structures: 20 } }

Errors

Every call goes through HttpSource: a 404 or a 410 (and a 204) is null - an empty page for a list -; a 429 is a RateLimitedException (retryAfter from Retry-After); a 5xx, a time-out or a host that does not answer an UnavailableException; any other 4xx a ProviderException with its status and what the service said; an answer that is not JSON a ProviderException, a web page answered for JSON an UnavailableException.

UniProt's own: its messages are read into the message of a ProviderException (a query it cannot parse: its 400); an unknown accession is its 404, null; an accession demerged into several or deleted is null; a merge is followed (three at most). Before any call: a name, a gene, any other scheme (NotSupportedException): search for a name.

Verified, and not

Against the real service on 2026-10-15 (UniProt release 2026_03), without a key: hemoglobin beta by its accession, its entry name and an accession merged into it (A4GX73: 303 to P68871); its names, gene, organism, length (147 aa), mass (15998 Da), sequence, ligands (heme b, 2,3-bisphosphoglycerate), 20 keywords, its gene 3043 and ENSG00000244734, its 348 PDB structures; carbonic anhydrase 2 (P00918: zinc and cobalt as cofactors, EC 4.2.1.1, cytoplasm and cell membrane, 1200 PDB structures); a demerged accession (P02023), a deleted one (Q9ZZZ9), an unknown one (A0A0A0A0A0: 404); an unreviewed entry (D9YZU5, TrEMBL: its submitted name "Beta-globin", the same gene 3043, existence inferred from homology, score 1); a search for "hemoglobin beta" (57554 entries, three a page) and its second page by the cursor of the Link header; the double compression of a body asked for gzip alone. The fixtures in Tests/Fixtures/ are its answers, carbonic anhydrase 2's PDB lines cut to 30.

Again on 2026-10-27: hemoglobin beta by its entry name, its gene, structures and ligands, the search for gene:HBB AND organism_id:9606 (18 entries; the example above).

Not verified: UniProt's answer to a client that calls too fast (no 429 met outside the stream endpoint - the handling is the core's); an obsolete entry merged twice over (the source follows three merges at most).

Responsibility

This package is an independent, unofficial client: it is not affiliated with, endorsed by or sponsored by the UniProt Consortium. UniProt's data are under CC BY 4.0: cite UniProt where they are shown, as the README's Terms of use says. Whoever runs the package is responsible for complying with it and for any use made of what it returns: see the README's Responsibility section.

Proposer une modification docs/index.md