---
# System prepended metadata

title: AiiDA Team Meeting 2025-03-20
tags: [team meetings]

---

# AiiDA Team Meeting 2025-03-20

###### tags: `team meetings`
###### time: 14:00 CET

[TOC]

### Present

- Alex
- Julian
- Giovanni
- Xing
- Kristjan

### Catch-up round

*Max. 3 minutes each*

Ali (on vacation-- please read):
- Discuss with the team:
    - Someone is suggesting we have to update our Readme file, [issue 6790](https://github.com/aiidateam/aiida-core/issues/6790). He found it difficult to locate other AiiDA-related websites from that page. We can discuss what additional information should be included. If someone is interestated please assign yourself to the issue.
COMMENT(Alex): If someone is really not finding the website or doc from this README, I don't think the person is able to use AiiDA. Let's stay focused on important issues.
![image](https://hackmd.io/_uploads/Hyzc6Kuhyg.png)


Alex:
- How to design recource management of sqlalchemy sessions
```python=
engine = create_engine("sqlite:///some_path")
session = sessionmaker(bind=engine)
session.close()
engine.dispose() # ! IMPORTANT !
```
disk object store design
```python=
def create_dos_engine(...)
    engine = create_engine(...)
    session = sessionmaker(bind=engine)
    return session

class Container:

    def get_session(self):
        if self._session is None:
            self._session = create_dos_engine()
        return session
```
Opening resources in stateless function leaves resources without ownership and therefore not closed. Better
```python
class Container:
    def __init__(self):
        self._handler = None

    def __enter__(self) -> ContainerHandler:
        return self.open()
    
    def __exit__(self):
        self.close()

    # sometimes you need usage outside of context
    def open(self):
        self._handler = ContainerHandler(...)
        return self._handler

    # but be sure that it is always closed when deleted
    def __del__(self):
        self._handler.close()
        
    def close():
        self._handler.close()
        
class ContainerHandler:
    def __init__(self):
        self._engine = create_engine(...)
        self._session = sessionmaker(bind=engine)
            
    def do_some_funky_stuff_with_session(self):
        ...
        
    def __del__(self):
        self._session.close()
        self._engine.dispose()
```
I spent ~5 days debugging this. In Rust such bugs would be detected during compile time since it tracks the lifetime of objects.
- Support for nested folder is `PortableCode` https://github.com/aiidateam/aiida-core/pull/6798


Julian:

- Nothing to report on `aiida-core`
- Been working on WorkGraph, SwissTwins, and [project](https://github.com/pyiron-dev/python-workflow-definition/) with devs from pyiron and jobflow
- WG PRs:
    - [[432] Add feature to create Task from AiiDA ProcessBuilder](https://github.com/aiidateam/aiida-workgraph/pull/432)
    - [[411] `WorkGraph` task with proper sub-tasks](https://github.com/aiidateam/aiida-workgraph/pull/411)
- Benchmark performance alerts: https://github.com/aiidateam/aiida-core/issues/6730
    - On tests of Zisen's PR that implements `contains` for SQLite for large JSON -> Used for initial benchmarking of feature, will remove these for now, as very sensitive to GH Runners resources
    - Benchmark infrastructure:
        - https://github.com/aiidateam/aiida-core/tree/main/tests/benchmark
        - https://github.com/aiidateam/aiida-core/blob/main/.github/workflows/benchmark-config.json
        - https://github.com/aiidateam/aiida-core/blob/main/.github/workflows/benchmark.yml
        - Results: https://aiidateam.github.io/aiida-core/dev/bench/ubuntu-22.04/psql_dos/
        -> Part of Zisen's future work

Xing:
- Add `map` zone for dynamic task creation
- Simple syntax!
    - Decorators return wrapper, which return the output sockets when called
    - Add manager for graph and zone, 
    - Implemented operator overloading for Socket to support binary operations
    - (Together with Alex) Drop usage of `{{}}`, instead, using the context namespace, each context variable is now a socket, which can hold intial value, as well as the links to other tasks. 

```python=
"""Sum the even numbers up to N."""
from aiida_workgraph import WorkGraph, task
from aiida_workgraph.manager import active_graph, active_if_zone, active_while_zone

@task.calcfunction
def add(x, y):
    return x + y

N = 5
with active_graph(WorkGraph()) as wg:
    wg.ctx = {"n": 1, "total": 0}
    with active_while_zone(wg.ctx.n < N):
        with active_if_zone(wg.ctx.n % 2 == 0):
            total = add(x=wg.ctx.total, y=wg.ctx.n)
            wg.update_ctx({"total": total})
        n = wg.ctx.n + 1
        wg.update_ctx({"n": n})
        n._waiting_on.add(total)
    wg.run()
```

- Together with Julian, I joined the meeting with Jan (Pyiron), learned they start a [project](https://github.com/pyiron/pyironFlow)  ~ seven months ago, which shares similar idea with the GUI of WorkGraph.

Kristjan:
- Add an html <meta> tag to docs to use Google Search console (gives information about what pages get indexed by google. But also, what search queries people write in google the most)
  - https://github.com/aiidateam/aiida-core/pull/6792 
  - Note: this will take effect after the PR is released
- optimade-maker aiida plugin: https://github.com/materialscloud-org/optimade-maker/pull/72
  - allows to make an optimade API from aiida profile or .aiida file
  - Link properties to structures via a simplified yaml format of the QueryBuilder:
    ```
      - name: band_gap
        title: Band gap
        description: Band gap of the material.
        unit: eV
        type: float
        aiida_query:
          - incoming_node: WorkChainNode
          - outgoing_node: BandsData
          - outgoing_node: CalcFunctionNode
          - outgoing_node: Dict
            edge_filters:
              label: bandgap
          - project: attributes.value
    ```


Jason:
- nothing to report for aiida side.
- For the GSoC if it is not Zisen, any proper candidates expected?