Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions aiida_restapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"""AiiDA REST API for data queries and workflow managment."""
"""AiiDA REST API for data queries and workflow management."""

__version__ = '0.1.0a1'

from .main import app # noqa: F401
File renamed without changes.
31 changes: 31 additions & 0 deletions aiida_restapi/cli/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os

import click
import uvicorn


@click.group()
def cli() -> None:
"""AiiDA REST API management CLI."""


@cli.command()
@click.option('--host', default='127.0.0.1', show_default=True)
@click.option('--port', default=8000, show_default=True, type=int)
@click.option('--read-only', is_flag=True)
@click.option('--watch', is_flag=True)
def start(read_only: bool, watch: bool, host: str, port: int) -> None:
"""Start the AiiDA REST API service."""

os.environ['AIIDA_RESTAPI_READ_ONLY'] = '1' if read_only else '0'

click.echo(f'Starting REST API (read_only={read_only}, watch={watch}) on {host}:{port}')

uvicorn.run(
'aiida_restapi.main:create_app',
host=host,
port=port,
reload=watch,
reload_dirs=['aiida_restapi'],
factory=True,
)
Empty file.
19 changes: 19 additions & 0 deletions aiida_restapi/common/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Pagination utilities."""

from __future__ import annotations

import typing as t

import pydantic as pdt
from aiida.orm import Entity

ResultType = t.TypeVar('ResultType', bound=Entity.Model)

__all__ = ('PaginatedResults',)


class PaginatedResults(pdt.BaseModel, t.Generic[ResultType]):
total: int
page: int
page_size: int
results: list[ResultType]
62 changes: 62 additions & 0 deletions aiida_restapi/common/query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""REST API query utilities."""

from __future__ import annotations

import json
import typing as t

import pydantic as pdt


class QueryParams(pdt.BaseModel):
filters: dict[str, t.Any] | None = pdt.Field(
None,
description='AiiDA QueryBuilder filters',
examples=[
'{"node_type": "data.core.int.Int."}',
'{"attributes.value": {">": 42}}',
],
)
order_by: str | list[str] | dict[str, t.Any] | None = pdt.Field(
None,
description='Fields to sort by',
examples=[
'pk',
'uuid,label',
'{"attributes.value": "desc"}',
],
)
page_size: pdt.PositiveInt = pdt.Field(
10,
description='Number of results per page',
examples=[10],
)
page: pdt.PositiveInt = pdt.Field(
1,
description='Page number',
examples=[1],
)

@pdt.field_validator('filters', mode='before')
@classmethod
def parse_filters(cls, value: t.Any) -> dict[str, t.Any] | None:
if value:
try:
return json.loads(value)
except Exception as exception:
raise ValueError(f'Could not parse filters as JSON: {exception}') from exception
return None

@pdt.field_validator('order_by', mode='before')
@classmethod
def parse_order_by(cls, value: t.Any) -> str | list[str] | dict[str, t.Any] | None:
if value:
# Due to allowing list[str] on the field, FastAPI will always convert query to a list
raw: str = value[0]
if raw.startswith('{') or raw.startswith('['):
try:
return json.loads(raw)
except Exception as exception:
raise ValueError(f'Could not parse order_by as JSON: {exception}') from exception
return raw.split(',')
return None
13 changes: 13 additions & 0 deletions aiida_restapi/common/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Common type variables."""

from __future__ import annotations

import typing as t

from aiida import orm

EntityType = t.TypeVar('EntityType', bound='orm.Entity')
EntityModelType = t.TypeVar('EntityModelType', bound='orm.Entity.Model')

NodeType = t.TypeVar('NodeType', bound='orm.Node')
NodeModelType = t.TypeVar('NodeModelType', bound='orm.Node.Model')
7 changes: 7 additions & 0 deletions aiida_restapi/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Configuration of API"""

from aiida_restapi import __version__

# to get a string like this run:
# openssl rand -hex 32
SECRET_KEY = '09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7'
Expand All @@ -18,3 +20,8 @@
'disabled': False,
}
}

API_CONFIG = {
'PREFIX': '/api/v0',
'VERSION': __version__,
}
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida.orm import Comment

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str

from .orm_factories import (
ENTITY_DICT_TYPE,
Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/computers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida.orm import Computer

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str
from aiida_restapi.graphql.plugins import QueryPlugin

from .nodes import NodesQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

from lark import Lark, Token, Tree

from . import static
from .utils import parse_date
from .. import static
from ..utils import parse_date

FILTER_GRAMMAR = resources.open_text(static, 'filter_grammar.lark')

Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida.orm import Group

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str
from aiida_restapi.graphql.nodes import NodesQuery
from aiida_restapi.graphql.plugins import QueryPlugin

Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida.orm import Log

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str

from .orm_factories import (
ENTITY_DICT_TYPE,
Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida import orm

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str
from aiida_restapi.graphql.plugins import QueryPlugin

from .comments import CommentsQuery
Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/orm_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from graphql import GraphQLError
from pydantic import Json

from aiida_restapi.aiida_db_mappings import ORM_MAPPING, get_model_from_orm
from aiida_restapi.graphql.aiida_db_mappings import ORM_MAPPING, get_model_from_orm

from .config import ENTITY_LIMIT
from .utils import JSON, selected_field_names_naive
Expand Down
2 changes: 1 addition & 1 deletion aiida_restapi/graphql/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import graphene as gr
from aiida.orm import User

from aiida_restapi.filter_syntax import parse_filter_str
from aiida_restapi.graphql.filter_syntax import parse_filter_str

from .nodes import NodesQuery
from .orm_factories import (
Expand Down
170 changes: 0 additions & 170 deletions aiida_restapi/identifiers.py

This file was deleted.

Loading