Skip to content

feat(melodi): tests, docstrings, fix measures parsing#308

Open
GrasClement wants to merge 10 commits into
InseeFrLab:feat/melodifrom
GrasClement:feature/melodi-tests-docs
Open

feat(melodi): tests, docstrings, fix measures parsing#308
GrasClement wants to merge 10 commits into
InseeFrLab:feat/melodifrom
GrasClement:feature/melodi-tests-docs

Conversation

@GrasClement

Copy link
Copy Markdown

Draft contribution aux JDOS : cible la branche #306

  • Fix _parse_dataset_observations (voir package R Melodi)
  • Docstrings manquantes
  • Tests des 4 fonctions publiques

Signed-off-by: GrasClement <gras.clement@orange.fr>
Signed-off-by: GrasClement <gras.clement@orange.fr>
Signed-off-by: GrasClement <gras.clement@orange.fr>
Signed-off-by: GrasClement <gras.clement@orange.fr>
Signed-off-by: GrasClement <gras.clement@orange.fr>
@GrasClement GrasClement marked this pull request as ready for review June 17, 2026 15:33
@GrasClement

Copy link
Copy Markdown
Author

Hi,

The JDOS are done, here is a quick closure summary for this PR,

Bug Fixes

  • Fixed hardcoded measure key in _parse_dataset_observations
  • Added guard for observations without "measures" field (prevents crashes)
  • Corrected language filter logic in get_idbank
  • Improved handling of non-MELODI idbanks → returns empty DataFrame

New Content

  • Docstrings for 4 public MELODI functions + 2 internal helpers
  • Tests: 14 tests covering parsing, edge cases, and all public functions
  • Example notebook: example_internet_usage_melodi.ipynb
  • Updated MELODI docs integration and DDL deprecation warning

Code Maintenance

  • Added update and silent parameters to all 4 public functions
  • Updated imports and version (0.2.6)
  • Updated .gitignore for development files

Cheers

@tfardet

tfardet commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Thanks @GrasClement !
@tgrandje may I let you have a look at this since it targets your previous PR?
I'm not sure I'll have the time to look at this any time soon...

@tgrandje

tgrandje commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Hi @GrasClement , sorry I took so long to review this, I was overloaded at work.

So I finally took the time to do it, with the exception of testing the documentation (I'm in a train on a personnal windows machine...) though it looks ok to me. I've made some comments: depending of your available time, feel free to let me know if you haven't the time to check all of this.

In any case, thank you for both your great work and the effort to uniformize the API with the silent/update kwargs ❤️ !

@GrasClement

Copy link
Copy Markdown
Author

Hi @tgrandje, no worries about the timing, and thanks for taking the time to review the PR!

I don't seem to see any review comments or additional commits attached to the PR yet. Whenever you have a chance, could you check whether the comments were actually submitted? Or maybe the issue is on my side and I'm looking in the wrong place.

I'd be happy to go through your feedback and update the PR once this is sorted out 😎

@tgrandje tgrandje left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @GrasClement I forgot to submit the review 😳 !

Comment thread pynsee/melodi/data.py
Comment on lines +115 to +116
# déplie toutes les clés de mesure dynamiquement
# (le nom varie selon le dataset : OBS_VALUE_NIVEAU, OBS_VALUE_INDICE_DE_PRIX, etc.)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we switch the comments to english?

Comment thread pynsee/melodi/data.py
Comment on lines +117 to +121
measures_expanded = pd.DataFrame(
obs["measures"]
.apply(lambda m: {k: v.get("value") for k, v in m.items()})
.tolist()
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the key unique in a dataset? If that's the case maybe we could avoid the whole apply process, what do you think?

Comment thread pynsee/melodi/data.py
@@ -664,8 +764,9 @@ def get_idbank(
# test = get_range("DS_TICM_PRATIQUES", include_values=True)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you're at it, would you mind removing the tailing tests under the if __name__ == "__main__" block?

Comment on lines +16 to +18
# Exception here: the bugs fixed in melodi/data/py live inside parsing helpers
# called inside get_dataset. Testing them through the real API would
# require downloading DS_IPC_PRINC on every test run.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanations! As pynsee was never (yet) released with MELODI api, what do you think of removing the comments detailing the tests' purposes as fixes to my original branch? In case you're ok, I'll flag the involved comments I've seen.


def test_get_catalog_known_datasets_present(self):
# dataset_identifier is not unique (one dataset can have multiple products).
# Assert presence of stable, long-running datasets rather than len > 0.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while to understand what you meant with the "rather tan len > 0". Maybe we could also remove that part, as it doesn't bring anything useful (I think): I let you be the judge on that 😉 ! (Note: it might very well just me being daft...)

self.assertTrue(test)

def test_parse_observations_no_measures_column(self):
# Regression: observations without "measures" must not crash.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update commentary in context with pynsee's release with brand new MELODI api? (maybe just remove the regression part?)


def test_get_idbank_series_history_stable(self):
# 010770930 = DS_ICA monthly series, sector 46.19A (non-food purchasing
# centres), base 2021. Open series: do NOT assert len (grows monthly).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it we shouldn't check the len, but that does'nt mean we couldn't check wether it's still updated. I was thinking of something like (df.groupby(df["TIME_PERIOD"].str[:4])["dataset"].count()[:-1]==12).all(), what do you think?

Comment on lines +245 to +246
# Regression: "key2 in {'all', language}" was backwards: _fr columns
# were absent when language="fr". Fixed to "language in {'all', key2}".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update commentary in context with pynsee's release with brand new MELODI api?


def test_get_idbank_dead_bdm_ids(self):
# BDM series with no MELODI dataset yet -> HTTP 200 + empty list -> empty df.
df = get_idbank("001565530+001565531")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking this would be better yet to do something quite explicit with a df = get_idbank("spam+eggs"); for those of us outside INSEE, it's not the most convenient of things to retrieve idbanks and check if they have associated data 😉 . By the way, should we log a warning stating that no data was retrieved and that is not a pynsee error?

Comment thread docs/modules.rst
Comment on lines +51 to +56

MELODI
------

.. automodule:: pynsee.melodi
:members:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of putting MELODI before utils? I'd even go as far as setting it where METADATA was (and setting METADATA at the latest position in regard of it's deprecation).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants