Skip to content

Commit

Permalink
Option attente stabilité
Browse files Browse the repository at this point in the history
  • Loading branch information
julienmalard committed Nov 20, 2023
1 parent 81365e4 commit 708ee19
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 11 deletions.
8 changes: 5 additions & 3 deletions constellationPy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from .const import LIEN_SIGNALEMENT_ERREURS
from .serveur import obtenir_contexte
from .utils import à_chameau, à_kebab, fais_rien_asynchrone, une_fois, tableau_exporté_à_pandas
from .utils import à_chameau, à_kebab, fais_rien_asynchrone, une_fois, tableau_exporté_à_pandas, attendre_stabilité


# Idée de https://stackoverflow.com/questions/48282841/in-trio-how-can-i-have-a-background-task-that-lives-as-long-as-my-object-does
Expand Down Expand Up @@ -278,11 +278,12 @@ async def obt_données_tableau(
id_tableau: str,
langues: Optional[str | list[str]] = None,
formatDonnées="constellation",
patience: int | float=1
):
async def f_suivi(f):
return await soimême.tableaux.suivre_données_exportation(id_tableau=id_tableau, f=f, langues=langues)

données = await une_fois(f_suivi, soimême.pouponnière)
données = await une_fois(f_suivi, soimême.pouponnière, attendre_stabilité(patience))

if formatDonnées.lower() == "pandas":
return tableau_exporté_à_pandas(données)
Expand All @@ -294,6 +295,7 @@ async def f_suivi(f):
async def obt_données_tableau_nuée(
soimême, id_nuée: str, clef_tableau: str, n_résultats_désirés: int,
langues: Optional[str | list[str]] = None, formatDonnées="constellation",
patience: int | float=1
):
async def f_suivi(f):
return await soimême.nuées.suivre_données_exportation_tableau(
Expand All @@ -302,7 +304,7 @@ async def f_suivi(f):
n_résultats_désirés=n_résultats_désirés, f=f
)

données = await une_fois(f_suivi, soimême.pouponnière)
données = await une_fois(f_suivi, soimême.pouponnière, attendre_stabilité(patience))

if formatDonnées.lower() == "pandas":
return tableau_exporté_à_pandas(données)
Expand Down
32 changes: 27 additions & 5 deletions constellationPy/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import inspect
from typing import Any, TypedDict, Callable, Coroutine
import json
from typing import Any, TypedDict, Callable, Coroutine, Awaitable, Optional
from typing import TYPE_CHECKING

import pandas as pd
Expand Down Expand Up @@ -34,11 +35,15 @@ async def fais_rien_asynchrone() -> None:

async def une_fois_sans_oublier(
f_suivre: Callable[[Callable[[Any, str], None]], Coroutine],
pouponnière: trio.Nursery
pouponnière: trio.Nursery,
fCond: Optional[Callable[[Any], Awaitable[bool]]] = None,
) -> Any:
canal_envoie, canal_réception = trio.open_memory_channel(0)

async def f_réception(résultat):
if fCond and not await fCond(résultat):
return

async with canal_envoie:
try:
await canal_envoie.send(résultat)
Expand All @@ -60,7 +65,8 @@ async def f_réception(résultat):

async def une_fois(
f_suivi: Callable[[Callable[[Any], None]], Coroutine[None, None]],
pouponnière: trio.Nursery
pouponnière: trio.Nursery,
fCond: Optional[Callable[[Any], Awaitable[bool]]] = None,
) -> Any:
async def f_async(f, task_status=trio.TASK_STATUS_IGNORED):
with trio.CancelScope() as _context:
Expand All @@ -72,19 +78,35 @@ async def annuler():

task_status.started(annuler)

return await une_fois_sans_oublier(f_async, pouponnière)
return await une_fois_sans_oublier(f_async, pouponnière, fCond)

def attendre_stabilité(n: int | float) -> Callable[[Any], Awaitable[bool]]:

précédente = {}
async def stable(val: Any):
chaîne_val = json.dumps(val)
if "val" in précédente and chaîne_val == précédente["val"]:
return False

précédente["val"] = chaîne_val
await trio.sleep(n)
return précédente["val"] == chaîne_val

return stable

type_élément = TypedDict("type_élément", {"empreinte": str, "données": dict[str, Any]})
type_tableau = list[type_élément]
type_tableau_exporté = TypedDict("type_tableau_exporté", {"données": list[dict[str, Any]], "fichiersSFIP": set, "nomTableau": str})
type_tableau_exporté = TypedDict("type_tableau_exporté",
{"données": list[dict[str, Any]], "fichiersSFIP": set, "nomTableau": str})


def tableau_exporté_à_pandas(tableau: type_tableau_exporté):
données = tableau["données"]

données_pandas = pd.DataFrame(données)
return données_pandas


def tableau_à_pandas(tableau: type_tableau, index_empreinte=False) -> pd.DataFrame:
index = [x["empreinte"] for x in tableau] if index_empreinte else None
données = [x["données"] for x in tableau]
Expand Down
53 changes: 50 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import trio

from constellationPy.utils import à_chameau, à_kebab, une_fois_sans_oublier, tableau_à_pandas, pandas_à_constellation, \
une_fois
une_fois, attendre_stabilité


class TestUtils(TestCase):
Expand All @@ -17,7 +17,7 @@ def test_à_kebab(soimême):
kebab = à_kebab("suivreDonnéesTableau")
soimême.assertEqual(kebab, "suivre_données_tableau")

async def test_une_fois(soimême):
async def test_une_fois_sans_oublier(soimême):
async with trio.open_nursery() as pouponnière:
async def f_async(f, task_status=trio.TASK_STATUS_IGNORED):
with trio.CancelScope() as _context:
Expand All @@ -28,7 +28,21 @@ async def f_async(f, task_status=trio.TASK_STATUS_IGNORED):
x = await une_fois_sans_oublier(f_async, pouponnière)
soimême.assertEqual(x, 1)

async def test_une_fois_avec_oublier(soimême):
async def test_une_fois_sans_oublier_avec_condition(soimême):
async with trio.open_nursery() as pouponnière:
async def f_async(f, task_status=trio.TASK_STATUS_IGNORED):
with trio.CancelScope() as _context:
task_status.started(_context.cancel)
await f(1)
await f(2)

async def condition(val):
return val > 1

x = await une_fois_sans_oublier(f_async, pouponnière, condition)
soimême.assertEqual(x, 2)

async def test_une_fois(soimême):
oubl = {"ié": False}
async with trio.open_nursery() as pouponnière:
async def f_suivi(f):
Expand All @@ -43,6 +57,39 @@ async def f_oublier():
soimême.assertEqual(x, 123)
soimême.assertTrue(oubl["ié"])

async def test_une_fois_avec_condition(soimême):
oubl = {"ié": False}
async with trio.open_nursery() as pouponnière:
async def f_suivi(f):
async def f_oublier():
oubl["ié"] = True

pouponnière.start_soon(f, 123)
pouponnière.start_soon(f, 456)
return f_oublier

async def condition(val):
return val > 150

x = await une_fois(f_suivi, pouponnière=pouponnière, fCond=condition)

soimême.assertEqual(x, 456)
soimême.assertTrue(oubl["ié"])

async def test_attendre_stabilité(soimême):
vals = {}
attendre_stable = attendre_stabilité(0.1)
async def f(x: str):
vals[x] = await attendre_stable(x)

async with trio.open_nursery() as pouponnière:
pouponnière.start_soon(f, "a")
await trio.sleep(0.05)
pouponnière.start_soon(f, "b")

soimême.assertFalse(vals["a"])
soimême.assertTrue(vals["b"])

def test_tableau_à_pandas(soimême):
tableau = [{"empreinte": "abc", "données": {"a": 1, "b": 2}}, {"empreinte": "def", "données": {"a": 3}}]
données_pandas = tableau_à_pandas(tableau)
Expand Down

0 comments on commit 708ee19

Please sign in to comment.