Skip to content

Conversation

@edan-bainglass
Copy link
Member

@edan-bainglass edan-bainglass commented Aug 24, 2025

This PR addresses several issues with #6255 that came up during updates to the aiida-restapi in aiidateam/aiida-restapi#93.

Major changes

  • All repository file serialization in JSON dumps (via Entity.serialize()) are removed due to impracticality.
  • Node subclass Models no longer extend Node.Model. Instead, Node.Model.attributes is typed as Node.AttributesModel, which is concretely implemented by Node subclasses with explicit attributes definition (see this issue for details). Code models still extend Node.Model here and there for CLI metadata support.
  • Several changes made to support the AttributesModel refactor. Of note is that now node construction from model will pass arguments to Node ORM constructors under the attributes key. As such, constructors are adjusted to account for this. This change also supports Node creation via the RESTAPI.

Note for PR reviewers

There are a few changes that are likely out of scope. These will move to dedicated PRs prior to merge of this PR.


Happy to discuss 🙂

@edan-bainglass edan-bainglass marked this pull request as draft August 24, 2025 08:03
@codecov
Copy link

codecov bot commented Aug 24, 2025

Codecov Report

❌ Patch coverage is 87.44939% with 93 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.65%. Comparing base (c10fef1) to head (e3769eb).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/aiida/orm/nodes/data/array/kpoints.py 59.19% 20 Missing ⚠️
src/aiida/orm/nodes/data/array/array.py 63.05% 17 Missing ⚠️
src/aiida/orm/fields.py 78.13% 14 Missing ⚠️
src/aiida/orm/nodes/data/singlefile.py 61.12% 7 Missing ⚠️
src/aiida/orm/nodes/data/structure.py 85.37% 6 Missing ⚠️
src/aiida/orm/entities.py 91.94% 5 Missing ⚠️
...rc/aiida/storage/psql_dos/orm/querybuilder/main.py 16.67% 5 Missing ⚠️
src/aiida/orm/nodes/data/remote/stash/compress.py 75.00% 4 Missing ⚠️
src/aiida/orm/nodes/data/remote/stash/custom.py 78.58% 3 Missing ⚠️
src/aiida/orm/nodes/data/remote/stash/folder.py 76.93% 3 Missing ⚠️
... and 8 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6990      +/-   ##
==========================================
- Coverage   79.67%   79.65%   -0.01%     
==========================================
  Files         565      565              
  Lines       43710    44061     +351     
==========================================
+ Hits        34820    35094     +274     
- Misses       8890     8967      +77     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@edan-bainglass edan-bainglass force-pushed the fix-node-serialization branch 4 times, most recently from 9b7cfbd to d83ced6 Compare August 24, 2025 11:33
@edan-bainglass
Copy link
Member Author

@khsrali regarding one of the failed tests...

tests/orm/nodes/data/test_remote_stash.py::test_constructor_invalid_folder[stash_mode-copy] - ValueError: `RemoteStashFolderData` can only be used with `stash_mode == StashMode.COPY`

In this PR, I lift some validation to the top of the constructor (of stash data classes - see 91e4ad5), to avoid any operations if the object is bound to fail. However, this seems to introduce failures in testing them. It suggests that perhaps there is some order to the operations, though I don't see it. Can you please comment?

@edan-bainglass
Copy link
Member Author

@khsrali regarding one of the failed tests...

tests/orm/nodes/data/test_remote_stash.py::test_constructor_invalid_folder[stash_mode-copy] - ValueError: `RemoteStashFolderData` can only be used with `stash_mode == StashMode.COPY`

In this PR, I lift some validation to the top of the constructor (of stash data classes - see 91e4ad5), to avoid any operations if the object is bound to fail. However, this seems to introduce failures in testing them. It suggests that perhaps there is some order to the operations, though I don't see it. Can you please comment?

It was checking for TypeError, which is what happens when you delay the stash_mode check and provide a non-Enum type for it. But there is no need for it, as the stash_mode check covers that issue as well. I updated the test to parameterize also over error, checking for ValueError in the case of the invalid stash_mode.

@edan-bainglass
Copy link
Member Author

@GeigerJ2 okay, this is ready for others to inspect. I did my best to isolate the commits and provided comments on each. Happy to discuss further.

Pinging also @agoscinski @superstar54 if interested.

Pinging @sphuber for input/feedback, if he has time.

@edan-bainglass
Copy link
Member Author

It may be possible to rely on the post models of aiida-restapi as a reference for defining ORM constructor parameters, as the post models are intended to represent serialized objects passed to the REST API for object construction. Looking into this.

@edan-bainglass
Copy link
Member Author

edan-bainglass commented Oct 8, 2025

@danielhollas what is this about?

Critical: potential `verdi` speed problem: `aiida.orm.fields` module is imported which is not in: ('aiida.brokers', 'aiida.cmdline', 'aiida.common', 'aiida.manage', 'aiida.plugins', 'aiida.restapi')

Nevermind. I see that importing orm in the cmdline raises alarm bells. Removed...

@edan-bainglass edan-bainglass force-pushed the fix-node-serialization branch from 516a6df to 2c3e5df Compare October 8, 2025 16:54
@danielhollas
Copy link
Collaborator

Nevermind. I see that importing orm in the cmdline raises alarm bells. Removed...

Nice, the system works. :-) Feel free to improve the error message here to make it more obvious that this is about the aiida.cmdline module.

@edan-bainglass edan-bainglass force-pushed the fix-node-serialization branch from d6e44ff to 0b37ef6 Compare October 8, 2025 18:17
@edan-bainglass
Copy link
Member Author

Nevermind. I see that importing orm in the cmdline raises alarm bells. Removed...

Nice, the system works. :-) Feel free to improve the error message here to make it more obvious that this is about the aiida.cmdline module.

#7059

@edan-bainglass
Copy link
Member Author

@danielhollas what do you think about ignoring Ruff N806 - "~variable should be lowercase"? See case below. Model is not an instance, but a class. Naming it model would be misleading, hence I went with Model.

Model = cls.Model.as_input_model()
^^^^^ N806

@danielhollas
Copy link
Collaborator

@danielhollas what do you think about ignoring Ruff N806 - "~variable should be lowercase"?

Do you mean ignoring locally (fine) or globally?

@edan-bainglass
Copy link
Member Author

edan-bainglass commented Oct 8, 2025

@danielhollas what do you think about ignoring Ruff N806 - "~variable should be lowercase"?

Do you mean ignoring locally (fine) or globally?

Global. There are many cases when the variable is a class, not an instance. I've pushed this in my last commit just to verify that it works. Okay with removing it in favor of local handling, but would like to hear the reason against a global N806 rule.

Update

Nice. Ignoring N806 globally raised a whole lot of RUF100 due to the codebase being littered with local N806 rules. I'd say that supports my case 🙂

@edan-bainglass
Copy link
Member Author

@danielhollas done for tonight. Will revisit this in the morning 😴

@danielhollas
Copy link
Collaborator

Nice. Ignoring N806 globally raised a whole lot of RUF100 due to the codebase being littered with local N806 rules. I'd say that supports my case 🙂

Yeah, running git grep N806 indeed does get a lot of hits (although most of them are in tests/).

Seems fine to remove it, or alternatively, use the https://docs.astral.sh/ruff/settings/#lint_pep8-naming_extend-ignore-names configuration to automatically ignore some common patterns (e.g. the one you have here, and common class names produced by factory functions (SinglefileData = DataFactory('core.singlefile')

e.g. something like this in pyproject.toml

[tool.ruff.lint.pep8-naming]
ignore-names = ["[A-Z]*Data", "Model"]

In any case please open a separate PR for that so we don't polute this one with bikeshedding discussion and unrelated changes.

@edan-bainglass
Copy link
Member Author

In any case please open a separate PR for that so we don't polute this one with bikeshedding discussion and unrelated changes.

Thanks @danielhollas. Then for this one, since there are only a few cases in my PR, I will locally ignore them. Will open a PR for the pattern handling shortly after.

@edan-bainglass edan-bainglass force-pushed the fix-node-serialization branch 4 times, most recently from 5faafb0 to a4a5b3e Compare October 9, 2025 06:04
@edan-bainglass
Copy link
Member Author

> qb = orm.QueryBuilder()
> qb.append(orm.CalcJobNode)
> qb.first()[0].serialize()

Works for me 🤔

In [2]: from aiida import orm

In [3]:  qb = orm.QueryBuilder()
   ...:  qb.append(orm.CalcJobNode)
   ...:  qb.first()[0].serialize()
Out[3]: 
{'pk': 695,
 'uuid': '9b2b343b-6840-449e-9c18-813b430b9948',
 'node_type': 'process.calculation.calcjob.CalcJobNode.',
 'process_type': 'aiida.calculations:quantumespresso.pw',
 'repository_metadata': {'o': {'aiida.in': {'k': '01003b25af1aa3c0275f9aceaf472a7a922a1ec411d10b3626d912ab367420b4'},
   '_aiidasubmit.sh': {'k': 'afd93b1fc0488e840188daba0a2535b41c434873a886f4d6091a2a762f9cb63a'},
   '.aiida': {'o': {'job_tmpl.json': {'k': '72340e7a23e0718a803bfbb19c46212c15341382471f338cf77ffdf0ec695989'},
     'calcinfo.json': {'k': 'e44d5ad45a70efdd49bc2eaf716b866d5abaeb5a53fc232970ffded0c2d7e854'}}}}},
 'ctime': '2025-09-14T16:32:17.828434Z',
 'mtime': '2025-09-14T16:33:17.520797Z',
 'label': '',
 'description': '',
 'attributes': {'sealed': True,
  'process_label': 'PwCalculation',
  'process_state': 'finished',
  'exit_status': 0,
  'paused': False,
  'scheduler_state': 'done',
  'remote_workdir': '/home/edanb/.aiida/scratch/presto-1/9b/2b/343b-6840-449e-9c18-813b430b9948',
  'job_id': '42913',
  'scheduler_lastchecktime': '2025-09-14T18:33:17.233906+02:00',
  'last_job_info': {'job_id': '42913',
   'job_state': 'running',
   'job_owner': 'edanb',
   'wallclock_time_seconds': 0},
  'retrieve_list': ['aiida.out',
   'CRASH',
   './out/aiida.save/data-file-schema.xml',
   './out/aiida.save/data-file.xml',
   '_scheduler-stdout.txt',
   '_scheduler-stderr.txt'],
  'retrieve_temporary_list': [['./out/aiida.save/K*[0-9]/eigenval*.xml',
    '.',
    2]],
  'imported': False},
 'extras': {'_aiida_hash': '5176d24c9d2656dd2ec1e55697e4cf745c350f1da447472686fd0c5ce61640c3'},
 'computer': 1,
 'user': 1}

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.

8 participants