Skip to content
Snippets Groups Projects
Commit 541ff0ee authored by Joscha Schmiedt's avatar Joscha Schmiedt
Browse files

Merge branch 'dev' into 'f-mypy'

# Conflicts:
#   unittests/docker/Dockerfile
parents 9a857ee3 1ecb0883
Branches
Tags
2 merge requests!143Release 0.15.0,!66F mypy
Pipeline #48461 passed with warnings
Showing with 180 additions and 875 deletions
...@@ -13,6 +13,7 @@ __pycache__/ ...@@ -13,6 +13,7 @@ __pycache__/
dist/ dist/
build/ build/
src/caosdb/version.py src/caosdb/version.py
src/linkahead/version.py
# documentation # documentation
_apidoc _apidoc
......
# #
# This file is a part of the CaosDB Project. # This file is a part of the LinkAhead Project.
# #
# Copyright (C) 2018 Research Group Biomedical Physics, # Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
...@@ -44,7 +44,7 @@ code_style: ...@@ -44,7 +44,7 @@ code_style:
- make style - make style
allow_failure: true allow_failure: true
# pylint tests for pycaosdb # pylint tests for pylinkahead
pylint: pylint:
tags: [ docker ] tags: [ docker ]
stage: linting stage: linting
...@@ -68,7 +68,7 @@ unittest_py3.7: ...@@ -68,7 +68,7 @@ unittest_py3.7:
image: python:3.7 image: python:3.7
script: &python_test_script script: &python_test_script
# Python docker has problems with tox and pip so use plain pytest here # Python docker has problems with tox and pip so use plain pytest here
- touch ~/.pycaosdb.ini - touch ~/.pylinkahead.ini
- pip install nose pytest pytest-cov python-dateutil jsonschema>=4.4.0 - pip install nose pytest pytest-cov python-dateutil jsonschema>=4.4.0
- pip install . - pip install .
- python -m pytest unittests - python -m pytest unittests
...@@ -89,7 +89,7 @@ unittest_py3.9: ...@@ -89,7 +89,7 @@ unittest_py3.9:
script: script:
# verify that this actually is Python 3.9 # verify that this actually is Python 3.9
- python3 -c "import sys; assert sys.version.startswith('3.9')" - python3 -c "import sys; assert sys.version.startswith('3.9')"
- touch ~/.pycaosdb.ini - touch ~/.pylinkahead.ini
- make unittest - make unittest
...@@ -156,7 +156,7 @@ pages_prepare: &pages_prepare ...@@ -156,7 +156,7 @@ pages_prepare: &pages_prepare
refs: refs:
- /^release-.*$/i - /^release-.*$/i
script: script:
- echo "Deploying" - echo "Deploying documentation"
- make doc - make doc
- cp -r build/doc/html public - cp -r build/doc/html public
artifacts: artifacts:
......
...@@ -9,6 +9,52 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -9,6 +9,52 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### ### Added ###
### Changed ###
### Deprecated ###
### Removed ###
### Fixed ###
### Security ###
### Documentation ###
## [0.14.0] - 2024-02-20
### Added ###
* `utils.merge_entities` now has a `merge_id_with_resolved_entity` keyword
which allows to identify property values with each other in case that one is
an id and the other is an Entity with this id. Default is ``False``, so no
change to the default behavior.
* `apiutils.escape_quoted_text` for escaping text in queries.
### Changed ###
* `cached_query()` now also caches uniqueness related exceptions.
## [0.13.2] - 2023-12-15
### Fixed ###
* [#113](https://gitlab.com/linkahead/linkahead-pylib/-/issues/113) Container could fail to delete when there were reference properties.
* HTTP status 431 (Headers too long) now also raises an URI too long exception.
## [0.13.1] - 2023-10-11 ##
### Fixed ###
* no Error when no configuration file is used
[Issue](https://gitlab.com/linkahead/linkahead-pylib/-/issues/107)
## [0.13.0] - 2023-10-10 ##
### Added ###
* New `page_length` parameter for `caosdb.execute_query` and
`caosdb.Query.execute`. See docstrings for more details.
* `Entity.remove_value_from_property` function that removes a given value from a * `Entity.remove_value_from_property` function that removes a given value from a
property and optionally removes the property if it is empty afterwards. property and optionally removes the property if it is empty afterwards.
...@@ -18,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -18,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `Message.__init__` signature changed and `type` defaults to "Info" now. * `Message.__init__` signature changed and `type` defaults to "Info" now.
* `Message.__eq__` changed. Equality is equality of `type`, `code`, and * `Message.__eq__` changed. Equality is equality of `type`, `code`, and
`description` now. `description` now.
* Rename from CaosDB to LinkAhead. For proper migration, follow the instructions
in `migration_to_linkahead.md` and check the documentation at [docs.indiscale.com](https://docs.indiscale.com/caosdb-pylib/README_SETUP.html#migration).
### Deprecated ### ### Deprecated ###
...@@ -25,16 +73,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -25,16 +73,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
messages have been deprecated. Warnings are raised correspondingly. messages have been deprecated. Warnings are raised correspondingly.
* `Message.get_code`. Use the `code` property instead. * `Message.get_code`. Use the `code` property instead.
### Removed ###
### Fixed ### ### Fixed ###
- Detection for cyclic references when converting entites using the high level API. - Detection for cyclic references when converting entites using the high level API.
### Security ###
### Documentation ###
## [0.12.0] - 2023-06-02 ## ## [0.12.0] - 2023-06-02 ##
### Added ### ### Added ###
......
...@@ -20,6 +20,6 @@ authors: ...@@ -20,6 +20,6 @@ authors:
given-names: Stefan given-names: Stefan
orcid: https://orcid.org/0000-0001-7214-8125 orcid: https://orcid.org/0000-0001-7214-8125
title: CaosDB - Pylib title: CaosDB - Pylib
version: 0.12.0 version: 0.14.0
doi: 10.3390/data4020083 doi: 10.3390/data4020083
date-released: 2023-06-02 date-released: 2024-02-20
\ No newline at end of file
* caosdb-server >= 0.8.0 * caosdb-server >= 0.12.0
* Python >= 3.8 * Python >= 3.8
* pip >= 20.0.2 * pip >= 20.0.2
......
# ** header v3.0 # ** header v3.0
# This file is a part of the CaosDB Project. # This file is a part of the LinkAhead Project.
# #
# Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2020 IndiScale GmbH <info@indiscale.com>
# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> # Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com>
...@@ -40,7 +40,7 @@ style: ...@@ -40,7 +40,7 @@ style:
.PHONY: style .PHONY: style
lint: lint:
pylint --unsafe-load-any-extension=y -d all -e E,F src/caosdb/common pylint --unsafe-load-any-extension=y -d all -e E,F src/linkahead/common
.PHONY: lint .PHONY: lint
unittest: unittest:
......
...@@ -41,7 +41,7 @@ the preferred way is also a merge request as describe above (the documentation r ...@@ -41,7 +41,7 @@ the preferred way is also a merge request as describe above (the documentation r
However, you can also create an issue for it. However, you can also create an issue for it.
* You can also contact us at **info (AT) caosdb.org** and join the * You can also contact us at **info (AT) caosdb.org** and join the
CaosDB community on CaosDB community on
[#caosdb:matrix.org](https://matrix.to/#/!unwwlTfOznjEnMMXxf:matrix.org). [#linkahead:matrix.org](https://matrix.to/#/!unwwlTfOznjEnMMXxf:matrix.org).
## License ## License
......
...@@ -128,3 +128,6 @@ Build documentation in `build/` with `make doc`. ...@@ -128,3 +128,6 @@ Build documentation in `build/` with `make doc`.
### Troubleshooting ### ### Troubleshooting ###
If the client is to be executed directly from the `/src` folder, an initial `.\setup.py install --user` must be called. If the client is to be executed directly from the `/src` folder, an initial `.\setup.py install --user` must be called.
## Migration ##
TODO
# Release Guidelines for the CaosDB Python Client Library # Release Guidelines for the CaosDB Python Client Library
This document specifies release guidelines in addition to the general release This document specifies release guidelines in addition to the general release
guidelines of the CaosDB Project guidelines of the LinkAhead Project
([RELEASE_GUIDELINES.md](https://gitlab.com/caosdb/caosdb/blob/dev/RELEASE_GUIDELINES.md)) ([RELEASE_GUIDELINES.md](https://gitlab.com/caosdb/caosdb/blob/dev/RELEASE_GUIDELINES.md))
## General Prerequisites ## General Prerequisites
......
#!/usr/bin/env python3
# encoding: utf-8
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2021 Indiscale GmbH <info@indiscale.com>
# Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
import os
base_root = "src/linkahead/"
initcontent = """
from {module} import *
from warnings import warn
warn(("CaosDB was renamed to LinkAhead. Please import this library as `import {module}`. Using the"
" old name, starting with caosdb, is deprecated."), DeprecationWarning)
"""
for root, dirs, files in os.walk(base_root, topdown=False):
if root.endswith("__pycache__"):
continue
cdir = os.path.join("src/caosdb", root[len(base_root):])
os.makedirs(cdir, exist_ok=True)
for fi in files:
if not fi.endswith(".py"):
continue
path = os.path.join(cdir, fi)
with open(path, 'w') as cur:
if fi == "__init__.py":
cur.write(initcontent.format(module=".".join(
os.path.join(root, fi[:-3]).split('/')[1:-1])))
else:
cur.write(initcontent.format(module=".".join(
os.path.join(root, fi[:-3]).split('/')[1:])))
#!/usr/bin/env python3 #!/usr/bin/env python3
"""A small example to get started with caosdb-pylib. """A small example to get started with caosdb-pylib.
Make sure that a `pycaosdb.ini` is readable at one of the expected locations. Make sure that a `pylinkahead.ini` is readable at one of the expected locations.
""" """
import random import random
......
# To be found be the caosdb package, the INI file must be located either in # To be found be the caosdb package, the INI file must be located either in
# - $CWD/pycaosdb.ini # - $CWD/pylinkahead.ini
# - $HOME/.pycaosdb.ini # - $HOME/.pylinkahead.ini
# - the location given in the env variable PYCAOSDBINI # - the location given in the env variable PYCAOSDBINI
[Connection] [Connection]
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# ** header v3.0 # ** header v3.0
# This file is a part of the CaosDB Project. # This file is a part of the LinkAhead Project.
# #
# Copyright (C) 2018 Research Group Biomedical Physics, # Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
......
#!/usr/bin/env python3 #!/usr/bin/env python3
# ** header v3.0 # ** header v3.0
# This file is a part of the CaosDB Project. # This file is a part of the LinkAhead Project.
# #
# Copyright (c) 2019 IndiScale GmbH # Copyright (c) 2019 IndiScale GmbH
# Copyright (c) 2019 Daniel Hornung <d.hornung@indiscale.com> # Copyright (c) 2019 Daniel Hornung <d.hornung@indiscale.com>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
As a result, only a specific user or group may access it. As a result, only a specific user or group may access it.
This script assumes that the user specified in the pycaosdb.ini This script assumes that the user specified in the pylinkahead.ini
configuration can create new entities. configuration can create new entities.
""" """
......
git merge linkahead-rename-step-1
# resolve potential conflicts and commit
rm -rf src/linkahead
git mv src/caosdb/ src/linkahead
rm -rf src/caosdb
python3 create_slim_linkahead_wrapper.py
git add src
git ci -m "MAINT: rename caosdb to linkahead (module)"
git merge linkahead-rename-step-2
# resolve potential conflicts and commit
git merge dev
#!/bin/bash #!/bin/bash
rm -rf dist/ build/ .eggs/ rm -rf dist/ build/ .eggs/
python setup.py sdist bdist_wheel python setup.py sdist bdist_wheel
export PKGNAME=caosdb
python setup.py sdist bdist_wheel
python -m twine upload dist/* python -m twine upload dist/*
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
# #
# #
"""caosdb""" """linkahead"""
import os import os
import re
import subprocess import subprocess
import sys import sys
...@@ -47,13 +48,13 @@ from setuptools import find_packages, setup ...@@ -47,13 +48,13 @@ from setuptools import find_packages, setup
ISRELEASED = False ISRELEASED = False
MAJOR = 0 MAJOR = 0
MINOR = 12 MINOR = 14
MICRO = 1 MICRO = 1
# Do not tag as pre-release until this commit # Do not tag as pre-release until this commit
# https://github.com/pypa/packaging/pull/515 # https://github.com/pypa/packaging/pull/515
# has made it into a release. Probably we should wait for pypa/packaging>=21.4 # has made it into a release. Probably we should wait for pypa/packaging>=21.4
# https://github.com/pypa/packaging/releases # https://github.com/pypa/packaging/releases
PRE = "" # "dev" # e.g. rc0, alpha.1, 0.beta-23 PRE = "" # "dev" # e.g. rc0, alpha.1, 0.beta-23
if PRE: if PRE:
VERSION = "{}.{}.{}-{}".format(MAJOR, MINOR, MICRO, PRE) VERSION = "{}.{}.{}-{}".format(MAJOR, MINOR, MICRO, PRE)
...@@ -91,25 +92,26 @@ def git_version(): ...@@ -91,25 +92,26 @@ def git_version():
def get_version_info(): def get_version_info():
# Adding the git rev number needs to be done inside write_version_py(), # Adding the git rev number needs to be done inside write_version_py(),
# otherwise the import of caosdb.version messes up the build under # otherwise the import of linkahead.version messes up the build under
# Python 3. # Python 3.
FULLVERSION = VERSION FULLVERSION = VERSION
# Magic which is only really needed in the pipelines. Therefore: a lot of dark pipeline magic.
GIT_REVISION = "Unknown"
if os.path.exists('.git'): if os.path.exists('.git'):
GIT_REVISION = git_version() GIT_REVISION = git_version()
elif os.path.exists('caosdb_pylib_commit'): elif os.path.exists('linkahead_pylib_commit'):
with open('caosdb_pylib_commit', 'r') as f: with open('linkahead_pylib_commit', 'r') as f:
GIT_REVISION = f.read().strip() GIT_REVISION = f.read().strip()
elif os.path.exists('src/caosdb/version.py'): elif os.path.exists('src/linkahead/version.py'):
# must be a source distribution, use existing version file # must be a source distribution, use existing version file
try: with open('src/linkahead/version.py') as fi:
from caosdb.version import git_revision as GIT_REVISION rev_pattern = re.compile(r"^git_revision = '(?P<rev>.*)'$")
except ImportError: for line in fi.readlines():
raise ImportError("Unable to import git_revision. Try removing " match = rev_pattern.match(line)
"src/caosdb/version.py and the build directory " if match is not None:
"before building.") GIT_REVISION = match.group('rev')
else: break
GIT_REVISION = "Unknown"
if not ISRELEASED: if not ISRELEASED:
FULLVERSION += '.dev0+' + GIT_REVISION[:7] FULLVERSION += '.dev0+' + GIT_REVISION[:7]
...@@ -117,9 +119,9 @@ def get_version_info(): ...@@ -117,9 +119,9 @@ def get_version_info():
return FULLVERSION, GIT_REVISION return FULLVERSION, GIT_REVISION
def write_version_py(filename='src/caosdb/version.py'): def write_version_py(filename='src/linkahead/version.py'):
cnt = """ cnt = """
# THIS FILE IS GENERATED FROM caosdb SETUP.PY # THIS FILE IS GENERATED FROM linkahead SETUP.PY
# #
short_version = '%(version)s' short_version = '%(version)s'
version = '%(version)s' version = '%(version)s'
...@@ -153,15 +155,21 @@ def setup_package(): ...@@ -153,15 +155,21 @@ def setup_package():
# Rewrite the version file everytime # Rewrite the version file everytime
write_version_py() write_version_py()
if 'PKGNAME' in os.environ and os.environ['PKGNAME'] == 'caosdb':
pname = 'caosdb'
pdesc = 'Deprecated! Please install linkahead.'
else:
pname = 'linkahead'
pdesc = 'Python Interface for LinkAhead'
metadata = dict( metadata = dict(
name='caosdb', name=pname,
version=get_version_info()[0], version=get_version_info()[0],
description='Python Interface for CaosDB', description=pdesc,
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
author='Timm Fitschen', author='Timm Fitschen',
author_email='t.fitschen@indiscale.com', author_email='t.fitschen@indiscale.com',
url='https://www.caosdb.org', url='https://www.linkahead.org',
license="AGPLv3+", license="AGPLv3+",
classifiers=[ classifiers=[
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
...@@ -178,16 +186,19 @@ def setup_package(): ...@@ -178,16 +186,19 @@ def setup_package():
"python-dateutil>=2.8.2", "python-dateutil>=2.8.2",
'PyYAML>=5.4.1', 'PyYAML>=5.4.1',
'future', 'future',
], ],
extras_require={'keyring': ['keyring>=13.0.0'], extras_require={'keyring': ['keyring>=13.0.0'],
'jsonschema': ['jsonschema>=4.4.0']}, 'jsonschema': ['jsonschema>=4.4.0']},
setup_requires=["pytest-runner>=2.0,<3dev"], setup_requires=["pytest-runner>=2.0,<3dev"],
tests_require=["pytest", "pytest-cov", "coverage>=4.4.2", tests_require=["pytest", "pytest-cov", "coverage>=4.4.2",
"jsonschema>=4.4.0"], "jsonschema>=4.4.0"],
package_data={ package_data={
'caosdb': ['cert/indiscale.ca.crt', 'schema-pycaosdb-ini.yml'], 'linkahead': ['cert/indiscale.ca.crt', 'schema-pycaosdb-ini.yml'],
}, },
scripts=["src/caosdb/utils/caosdb_admin.py"] scripts=[
"src/linkahead/utils/caosdb_admin.py",
"src/linkahead/utils/linkahead_admin.py"
]
) )
try: try:
setup(**metadata) setup(**metadata)
......
# -*- coding: utf-8 -*-
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
"""CaosDB Python bindings. from linkahead import *
from warnings import warn
Tries to read from the inifile specified in the environment variable `PYCAOSDBINI` or alternatively warn(("CaosDB was renamed to LinkAhead. Please import this library as `import linkahead`. Using the"
in `~/.pycaosdb.ini` upon import. After that, the ini file `pycaosdb.ini` in the current working " old name, starting with caosdb, is deprecated."), DeprecationWarning)
directory will be read additionally, if it exists.
"""
from os import environ, getcwd
# Import of the connection function (which is used to connect to the DB):
from os.path import expanduser, join
# Import of convenience methods:
import caosdb.apiutils
from caosdb.common import administration
from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
LIST, REFERENCE, TEXT)
from caosdb.common.state import State, Transition
# Import of the basic API classes:
from caosdb.common.models import (ACL, ALL, FIX, NONE, OBLIGATORY, RECOMMENDED,
SUGGESTED, Container, DropOffBox, Entity,
File, Info, Message, Permissions, Property,
Query, QueryTemplate, Record, RecordType,
delete, execute_query, get_global_acl,
get_known_permissions, raise_errors)
from caosdb.utils.get_entity import get_entity_by_name, get_entity_by_path, get_entity_by_id
from caosdb.configuration import _read_config_files, configure, get_config
from caosdb.connection.connection import configure_connection, get_connection
from caosdb.exceptions import *
try:
from caosdb.version import version as __version__
except ModuleNotFoundError:
version = "uninstalled"
__version__ = version
_read_config_files()
This diff is collapsed.
# -*- coding: utf-8 -*-
#
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2023 IndiScale GmbH <info@indiscale.com>
# Copyright (C) 2023 Henrik tom Wörden <h.tomwoerden@indiscale.com>
# Copyright (C) 2023 Daniel Hornung <d.hornung@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
""" from linkahead.cached import *
This module provides some cached versions of functions that retrieve Entities from a remote server. from warnings import warn
See also warn(("CaosDB was renamed to LinkAhead. Please import this library as `import linkahead.cached`. Using the"
======== " old name, starting with caosdb, is deprecated."), DeprecationWarning)
- ``cache_initialize(...)`` : Re-initialize the cache.
- ``cache_clear()`` : Clear the cache.
- ``cached_query(query)`` : A cached version of ``execute_query(query)``.
- ``cached_get_entity_by(...)`` : Get an Entity by name, id, ...
"""
from enum import Enum
from functools import lru_cache
from typing import Union
from .utils import get_entity
from .common.models import execute_query, Entity, Container
# roughly 1GB for typical entity sizes
DEFAULT_SIZE = 33333
# This dict cache is solely for filling the real cache manually (e.g. to reuse older query results)
_DUMMY_CACHE = {}
class AccessType(Enum):
"""Different access types for cached queries. Needed for filling the cache manually with
:func:`cache_fill` .
"""
QUERY = 1
PATH = 2
EID = 3
NAME = 4
def cached_get_entity_by(eid: Union[str, int] = None, name: str = None, path: str = None, query:
str = None) -> Entity:
"""Return a single entity that is identified uniquely by one argument.
You must supply exactly one argument.
If a query phrase is given, the result must be unique. If this is not what you need, use
:func:`cached_query` instead.
"""
count = 0
if eid is not None:
count += 1
if name is not None:
count += 1
if path is not None:
count += 1
if query is not None:
count += 1
if count != 1:
raise ValueError("You must supply exactly one argument.")
if eid is not None:
return _cached_access(AccessType.EID, eid, unique=True)
if name is not None:
return _cached_access(AccessType.NAME, name, unique=True)
if path is not None:
return _cached_access(AccessType.PATH, path, unique=True)
if query is not None:
return _cached_access(AccessType.QUERY, query, unique=True)
raise ValueError("Not all arguments may be None.")
def cached_query(query_string) -> Container:
"""A cached version of :func:`caosdb.execute_query<caosdb.common.models.execute_query>`.
All additional arguments are at their default values.
"""
return _cached_access(AccessType.QUERY, query_string, unique=False)
@lru_cache(maxsize=DEFAULT_SIZE)
def _cached_access(kind: AccessType, value: Union[str, int], unique=True):
# This is the function that is actually cached.
# Due to the arguments, the cache has kind of separate sections for cached_query and
# cached_get_entity_by with the different AccessTypes. However, there is only one cache size.
# The dummy dict cache is only for filling the cache manually, it is deleted afterwards.
if value in _DUMMY_CACHE:
return _DUMMY_CACHE[value]
if kind == AccessType.QUERY:
return execute_query(value, unique=unique)
if kind == AccessType.NAME:
return get_entity.get_entity_by_name(value)
if kind == AccessType.EID:
return get_entity.get_entity_by_id(value)
if kind == AccessType.PATH:
return get_entity.get_entity_by_path(value)
raise ValueError(f"Unknown AccessType: {kind}")
def cache_clear() -> None:
"""Empty the cache that is used by `cached_query` and `cached_get_entity_by`."""
_cached_access.cache_clear()
def cache_info():
"""Return info about the cache that is used by `cached_query` and `cached_get_entity_by`.
Returns
-------
out: named tuple
See the standard library :func:`functools.lru_cache` for details."""
return _cached_access.cache_info()
def cache_initialize(maxsize=DEFAULT_SIZE) -> None:
"""Create a new cache with the given size for `cached_query` and `cached_get_entity_by`.
This implies a call of :func:`cache_clear`, the old cache is emptied.
"""
cache_clear()
global _cached_access
_cached_access = lru_cache(maxsize=maxsize)(_cached_access.__wrapped__)
def cache_fill(items: dict, kind: AccessType = AccessType.EID, unique: bool = True) -> None:
"""Add entries to the cache manually.
This allows to fill the cache without actually submitting queries. Note that this does not
overwrite existing entries with the same keys.
Parameters
----------
items: dict
A dictionary with the entries to go into the cache. The keys must be compatible with the
AccessType given in ``kind``
kind: AccessType, optional
The AccessType, for example ID, name, path or query.
unique: bool, optional
If True, fills the cache for :func:`cached_get_entity_by`, presumably with
:class:`caosdb.Entity<caosdb.common.models.Entity>` objects. If False, the cache should be filled
with :class:`caosdb.Container<caosdb.common.models.Container>` objects, for use with
:func:`cached_query`.
"""
# 1. add the given items to the corresponding dummy dict cache
_DUMMY_CACHE.update(items)
# 2. call the cache function with each key (this only results in a dict look up)
for key in items.keys():
_cached_access(kind, key, unique=unique)
# 3. empty the dummy dict cache again
_DUMMY_CACHE.clear()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment