Sauve­gar­der Pocket

Je suis toujours dans mes sauve­gardes. Je veux avoir une copie de tout dans mes sauve­garde, données des services en ligne incluses.

Je pensais faire ça faci­le­ment avec Pocket. Ils ont une API, assez simple.

En pratique je me retrouve à faire essen­tiel­le­ment de l’in­gé­nie­rie inverse. La docu­men­ta­tion indique des choses qui n’existent pas ou ne fonc­tionnent pas, et ne donne aucune infor­ma­tion sur des éléments essen­tiels qu’on reçoit (genre la gestion des erreurs).

Authen­ti­fi­ca­tion

Contrai­re­ment aux méca­nismes OAuth habi­tuels, leur autho­rize ne renvoie pas de code tempo­raire à échan­ger. Pour récu­pé­rer l’access_token, il faut le deman­der avec le request_token obtenu lors de l’échange serveur à serveur initial.

Ce request_token semble ne pas avoir de durée de vie. Il n’a en tout cas pas de refresh_token asso­cié.

Méca­nisme de régu­la­tion

L’API indique des limi­ta­tions à 320 appels par heure. C’est d’au­tant plus impor­tant que pour télé­char­ger mes plus de 29 0001 items par pages de 30 maxi­mum, je vais forcé­ment dépas­ser le nombre de requêtes que je peux faire en une heure.

Il y a un méca­nisme auto­ma­tique prévu pour la régu­la­tion mais le serveur n’en­voie pas les entêtes prévues pour ça. Je sais juste qu’au bout d’un moment j’ob­tiens des erreurs 403 et que ça semble venir de là.

Je vais devoir gérer ça à la main. Pour l’ins­tant je note l’heure de chaque requête dans un tableau. Quand mon tableau fait 320 éléments, je retire le premier élément et attend l’heure de cet élément + 1 heure avant de conti­nuer.

Pagi­na­tion

Le méca­nisme pour la pagi­na­tion est assez famé­lique : 30 items maxi­mum par requête, plus un offset pour passer à la page suivante. C’est une mauvaise méthode pour itérer à travers des milliers d’items et ça ne trompe pas : Les requêtes sont effec­ti­ve­ment de plus en plus lentes au fur et à mesure des pages. C’est visible et c’est pénible.

Le serveur prévoit de renvoyer un champ total qui permet de savoir s’il reste encore des éléments. Les réponses du serveur ne me renvoient malheu­reu­se­ment pas ce champ alors je vais juste itérer jusqu’à obte­nir une réponse vide sans erreur.

Il y a aussi un champ since qui permet de limi­ter la recherche aux éléments plus récents qu’une certaine date. J’ima­gi­nais pouvoir me baser là dessus pour la pagi­na­tion : Parcou­rir du plus vieux au plus récent, iden­ti­fier la date du plus récent et repar­tir de là à la prochaine itéra­tion. C’est d’ailleurs la procé­dure recom­man­dée pour beau­coup de services qui veulent éviter les problèmes que pose le parcours par offset. Malheu­reu­se­ment ça n’est pas utili­sable pour la pagi­na­tion : les items retour­nés ne sont correc­te­ment ordon­nés ni par date d’ajout ni par date de modi­fi­ca­tion.

Étran­ge­ment, il semble que la limite de 30 items par page ne soit pas forcée. Il semble que ça fonc­tionne avec beau­coup plus, mais que ça génère aussi plus d’er­reurs. Le meilleur compro­mis semble effec­ti­ve­ment dans les 25 à 30 items par page.

Dernière spéci­fi­cité, j’ai l’im­pres­sion de temps de réponse plus longs et d’er­reurs plus fréquentes quand je vais du plus vieux au plus récent. Je n’ai pas véri­fié cette impres­sion avec des chiffres mais autant rester sur l’ordre par défaut : du plus récent au plus vieux.

Docu­men­ta­tion incom­plète

J’ai dit qu’il me manquait les entêtes de régu­la­tion et le champ total à la racine de la réponse. À l’op­posé, j’ai quelques champs qui ne sont pas dans la docu­men­ta­tion.

Le status semble être un entier avec, 0 pour une erreur, 1 pour OK, 2 quand il n’y a rien à affi­cher depuis une mise à jour. Quand status est à 0, le champ error contient le message d’er­reur.

Il y a aussi un maxAc­tions, dont je ne connais pas le sens.

Données irré­cu­pé­rables sur le serveur

Pour une raison ou une autre, certaines de mes données semblent corrom­pues ou irré­cu­pé­rables sur leur serveur (comme quoi la sauve­garde est utile ;-)..

J’ai 20 items qui provoquent systé­ma­tique­ment une erreur 504. Je peux récu­pé­rer ceux avant, ceux après, mais pas ceux là2. C’est vrai peu importe le sens de parcours (mais les offset ne sont logique­ment pas les mêmes dans les deux sens).

Je n’ai pas plus d’ex­pli­ca­tion. Je ne peux même pas connaitre les iden­ti­fiants concer­nés pour deman­der leur suppres­sion.

Poten­tiel­le­ment ce sont des données qui ne peuvent plus être réhy­dra­tées sur leurs serveurs, soient qu’il manque des infor­ma­tions essen­tielles, soit que leurs compo­sants ne savent pas complé­ter ce qui manque (le serveur du lien sauve­gardé qui répond bizar­re­ment ?).

Erreurs aléa­toires

Même avec une pagi­na­tion basique, dans l’ordre par défaut, j’ai des erreurs fréquentes, aléa­toires.

La plupart des 403 semblent liées à la limi­ta­tion du nombre de requêtes, mais pas forcé­ment toutes.

La plupart des 504 semblent liées à mes données irré­cu­pé­rables mais il est arrivé que ça finisse pas passer quand même.

Les 502, en géné­ral il suffit de relan­cer la même requête, mais parfois l’er­reur semble persis­ter un moment.

Auto­ma­ti­sa­tion

Je parcours fina­le­ment tout par page de 30 et je mets à jour à chaque page le fichier de sauve­garde (pour les données récu­pé­rées) et le fichier de confi­gu­ra­tion (pour le nouvel offset de la prochaine requête). Si j’ai des erreurs inat­ten­dues, je pour­rai relan­cer de là où j’en étais.

Si j’ai une page en erreur, je reprends tous les items de la page mais en allant les cher­cher mais 1 par 1 à partir de leur offset respec­tif. Parfois je ne retrouve pas l’er­reur et ça permet de récu­pé­rer tout. Parfois l’er­reur persiste sur un des éléments. Dans ce dernier cas l’idée c’est de pouvoir récu­pé­rer tous les bons items de la page et d’igno­rer l’unique qui est en erreur.

Ça n’est pas parfait — si j’ai une erreur répé­tée mais tempo­raire sur un item, il sera ignoré silen­cieu­se­ment dans la sauve­garde — mais je n’ai pas mieux.

Une fois le parcours tota­le­ment fait une fois, je peux utili­ser le since pour faire du diffé­ren­tiel.

Le code est sur https://github.com/edas/pocket-backup

RGPD à la rescousse

J’ai quand même prévu de faire une requête RGPD pour deman­der un export de mes données. On verra s’ils arrivent à me récu­pé­rer les 20 items qui sont en erreur perma­nente.

Si oui, je tente­rai de les effa­cer pour reprendre un fonc­tion­ne­ment sans erreur. Sinon, je tente­rai peut-être de réini­tia­li­ser le compte ou migrer ailleurs.


  1. Oui, tout ça. J’en suis moi-même étonné. J’ai tracé des usages depuis au moins fin 2010 mais je me demande si je ne l’uti­li­sais pas au début de mon passage à Yahoo! en 2007–2008 du temps où ça s’ap­pe­lait Read It Later. Ça fait une moyenne de 4 à 6 items par jour suivant la date rete­nue. ↩︎
  2. Je me les note pour moi-même : aujourd’­hui ce sont les offset 14053, 14481, 17689, 18291, 18629, 19389, 20363, 20815, 20996, 20999, 21512, 21923, 22275, 22283, 22346, 23386, 23841, 24189, 24414, 27441. ↩︎

Comments

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *