fastapi-rtk 0.2.27__py3-none-any.whl → 1.0.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. fastapi_rtk/__init__.py +39 -35
  2. fastapi_rtk/_version.py +1 -0
  3. fastapi_rtk/api/model_rest_api.py +476 -221
  4. fastapi_rtk/auth/auth.py +0 -9
  5. fastapi_rtk/backends/generic/__init__.py +6 -0
  6. fastapi_rtk/backends/generic/column.py +21 -12
  7. fastapi_rtk/backends/generic/db.py +42 -7
  8. fastapi_rtk/backends/generic/filters.py +21 -16
  9. fastapi_rtk/backends/generic/interface.py +14 -8
  10. fastapi_rtk/backends/generic/model.py +19 -11
  11. fastapi_rtk/backends/sqla/__init__.py +1 -0
  12. fastapi_rtk/backends/sqla/db.py +77 -17
  13. fastapi_rtk/backends/sqla/extensions/audit/audit.py +401 -189
  14. fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py +15 -12
  15. fastapi_rtk/backends/sqla/filters.py +50 -21
  16. fastapi_rtk/backends/sqla/interface.py +96 -34
  17. fastapi_rtk/backends/sqla/model.py +56 -39
  18. fastapi_rtk/bases/__init__.py +20 -0
  19. fastapi_rtk/bases/db.py +94 -7
  20. fastapi_rtk/bases/file_manager.py +47 -3
  21. fastapi_rtk/bases/filter.py +22 -0
  22. fastapi_rtk/bases/interface.py +49 -5
  23. fastapi_rtk/bases/model.py +3 -0
  24. fastapi_rtk/bases/session.py +2 -0
  25. fastapi_rtk/cli/cli.py +62 -9
  26. fastapi_rtk/cli/commands/__init__.py +23 -0
  27. fastapi_rtk/cli/{db.py → commands/db/__init__.py} +107 -50
  28. fastapi_rtk/cli/{templates → commands/db/templates}/fastapi/env.py +2 -3
  29. fastapi_rtk/cli/{templates → commands/db/templates}/fastapi-multidb/env.py +10 -9
  30. fastapi_rtk/cli/{templates → commands/db/templates}/fastapi-multidb/script.py.mako +3 -1
  31. fastapi_rtk/cli/{export.py → commands/export.py} +12 -10
  32. fastapi_rtk/cli/{security.py → commands/security.py} +73 -7
  33. fastapi_rtk/cli/commands/translate.py +299 -0
  34. fastapi_rtk/cli/decorators.py +9 -4
  35. fastapi_rtk/cli/utils.py +46 -0
  36. fastapi_rtk/config.py +41 -1
  37. fastapi_rtk/const.py +29 -1
  38. fastapi_rtk/db.py +76 -40
  39. fastapi_rtk/decorators.py +1 -1
  40. fastapi_rtk/dependencies.py +134 -62
  41. fastapi_rtk/exceptions.py +51 -1
  42. fastapi_rtk/fastapi_react_toolkit.py +186 -171
  43. fastapi_rtk/file_managers/file_manager.py +8 -6
  44. fastapi_rtk/file_managers/s3_file_manager.py +69 -33
  45. fastapi_rtk/globals.py +22 -12
  46. fastapi_rtk/lang/__init__.py +3 -0
  47. fastapi_rtk/lang/babel/__init__.py +4 -0
  48. fastapi_rtk/lang/babel/cli.py +40 -0
  49. fastapi_rtk/lang/babel/config.py +17 -0
  50. fastapi_rtk/lang/babel.cfg +1 -0
  51. fastapi_rtk/lang/lazy_text.py +120 -0
  52. fastapi_rtk/lang/messages.pot +238 -0
  53. fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.mo +0 -0
  54. fastapi_rtk/lang/translations/de/LC_MESSAGES/messages.po +248 -0
  55. fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.mo +0 -0
  56. fastapi_rtk/lang/translations/en/LC_MESSAGES/messages.po +244 -0
  57. fastapi_rtk/manager.py +355 -37
  58. fastapi_rtk/mixins.py +12 -0
  59. fastapi_rtk/routers.py +208 -72
  60. fastapi_rtk/schemas.py +142 -39
  61. fastapi_rtk/security/sqla/apis.py +39 -13
  62. fastapi_rtk/security/sqla/models.py +8 -23
  63. fastapi_rtk/security/sqla/security_manager.py +369 -11
  64. fastapi_rtk/setting.py +446 -88
  65. fastapi_rtk/types.py +94 -27
  66. fastapi_rtk/utils/__init__.py +8 -0
  67. fastapi_rtk/utils/async_task_runner.py +286 -61
  68. fastapi_rtk/utils/csv_json_converter.py +243 -40
  69. fastapi_rtk/utils/hooks.py +34 -0
  70. fastapi_rtk/utils/merge_schema.py +3 -3
  71. fastapi_rtk/utils/multiple_async_contexts.py +21 -0
  72. fastapi_rtk/utils/pydantic.py +46 -1
  73. fastapi_rtk/utils/run_utils.py +31 -1
  74. fastapi_rtk/utils/self_dependencies.py +1 -1
  75. fastapi_rtk/utils/use_default_when_none.py +1 -1
  76. fastapi_rtk/version.py +6 -1
  77. fastapi_rtk-1.0.13.dist-info/METADATA +28 -0
  78. fastapi_rtk-1.0.13.dist-info/RECORD +133 -0
  79. {fastapi_rtk-0.2.27.dist-info → fastapi_rtk-1.0.13.dist-info}/WHEEL +1 -2
  80. fastapi_rtk/backends/gremlinpython/__init__.py +0 -108
  81. fastapi_rtk/backends/gremlinpython/column.py +0 -208
  82. fastapi_rtk/backends/gremlinpython/db.py +0 -228
  83. fastapi_rtk/backends/gremlinpython/exceptions.py +0 -34
  84. fastapi_rtk/backends/gremlinpython/filters.py +0 -461
  85. fastapi_rtk/backends/gremlinpython/interface.py +0 -734
  86. fastapi_rtk/backends/gremlinpython/model.py +0 -364
  87. fastapi_rtk/backends/gremlinpython/session.py +0 -23
  88. fastapi_rtk/cli/commands.py +0 -295
  89. fastapi_rtk-0.2.27.dist-info/METADATA +0 -23
  90. fastapi_rtk-0.2.27.dist-info/RECORD +0 -126
  91. fastapi_rtk-0.2.27.dist-info/top_level.txt +0 -1
  92. /fastapi_rtk/cli/{templates → commands/db/templates}/fastapi/README +0 -0
  93. /fastapi_rtk/cli/{templates → commands/db/templates}/fastapi/alembic.ini.mako +0 -0
  94. /fastapi_rtk/cli/{templates → commands/db/templates}/fastapi/script.py.mako +0 -0
  95. /fastapi_rtk/cli/{templates → commands/db/templates}/fastapi-multidb/README +0 -0
  96. /fastapi_rtk/cli/{templates → commands/db/templates}/fastapi-multidb/alembic.ini.mako +0 -0
  97. {fastapi_rtk-0.2.27.dist-info → fastapi_rtk-1.0.13.dist-info}/entry_points.txt +0 -0
  98. {fastapi_rtk-0.2.27.dist-info → fastapi_rtk-1.0.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,8 @@
1
+ import typing
2
+
1
3
  from ..bases.file_manager import AbstractFileManager
2
4
  from ..const import logger
5
+ from ..utils import smart_run
3
6
 
4
7
  __all__ = ["S3FileManager"]
5
8
 
@@ -11,20 +14,58 @@ class S3FileManager(AbstractFileManager):
11
14
 
12
15
  def __init__(
13
16
  self,
14
- base_path=None,
15
- allowed_extensions=None,
16
- namegen=None,
17
- permission=None,
18
- bucket_name=None,
19
- bucket_subfolder=None,
20
- access_key=None,
21
- secret_key=None,
17
+ base_path: str | None = None,
18
+ allowed_extensions: list[str] | None = None,
19
+ namegen: typing.Callable[[str], str] | None = None,
20
+ permission: int | None = None,
21
+ bucket_name: str | None = None,
22
+ bucket_subfolder: str | None = None,
23
+ access_key: str | None = None,
24
+ secret_key: str | None = None,
25
+ open_params: dict[str, typing.Any] | None = None,
26
+ boto3_client: typing.Any | None = None,
22
27
  ):
28
+ """
29
+ Initializes the S3FileManager.
30
+
31
+ Args:
32
+ base_path (str | None, optional): URL path to the S3 bucket. Defaults to None.
33
+ allowed_extensions (list[str] | None, optional): Allowed file extensions. Defaults to None.
34
+ namegen (typing.Callable[[str], str] | None, optional): Callable for generating file names. Defaults to None.
35
+ permission (int | None, optional): File permission settings. Defaults to None.
36
+ bucket_name (str | None, optional): Name of the S3 bucket. Defaults to None.
37
+ bucket_subfolder (str | None, optional): Subfolder within the S3 bucket. Defaults to None.
38
+ access_key (str | None, optional): AWS access key. Needed for default boto3 client in order to delete files. Defaults to None.
39
+ secret_key (str | None, optional): AWS secret key. Needed for default boto3 client in order to delete files. Defaults to None.
40
+ open_params (dict[str, typing.Any] | None, optional): Parameters for opening files. Defaults to None.
41
+ boto3_client (typing.Any | None, optional): Boto3 client instance. If None, a new client will be created. Defaults to None.
42
+ Raises:
43
+ ImportError: If required libraries are not installed.
44
+ """
23
45
  super().__init__(base_path, allowed_extensions, namegen, permission)
46
+
47
+ try:
48
+ import boto3
49
+ import smart_open
50
+
51
+ self.smart_open = smart_open
52
+ self.boto3 = boto3
53
+ except ImportError:
54
+ raise ImportError(
55
+ "smart_open is required for S3FileManager. "
56
+ "Please install it with 'pip install smart_open[s3]'."
57
+ )
58
+
24
59
  self.bucket_name = bucket_name
25
60
  self.bucket_subfolder = bucket_subfolder
26
61
  self.access_key = access_key
27
62
  self.secret_key = secret_key
63
+ self.open_params = open_params or {}
64
+ self.boto3_client = boto3_client or self.boto3.client(
65
+ "s3",
66
+ aws_access_key_id=self.access_key,
67
+ aws_secret_access_key=self.secret_key,
68
+ )
28
69
 
29
70
  if not self.bucket_name:
30
71
  logger.warning(
@@ -38,48 +79,41 @@ class S3FileManager(AbstractFileManager):
38
79
  "Files may not be able to be deleted"
39
80
  )
40
81
 
41
- try:
42
- import boto3
43
- import smart_open
44
-
45
- self.smart_open = smart_open
46
- self.boto3 = boto3
47
- except ImportError:
48
- raise ImportError(
49
- "smart_open is required for S3FileManager. "
50
- "Please install it with 'pip install smart_open[s3]'."
51
- )
52
-
53
82
  def get_path(self, filename):
54
83
  return self.base_path + "/" + filename
55
84
 
56
85
  def get_file(self, filename):
57
- with self.smart_open.open(self.get_path(filename), "rb") as f:
86
+ with self.smart_open.open(
87
+ self.get_path(filename), "rb", **self.open_params
88
+ ) as f:
58
89
  return f.read()
59
90
 
60
91
  async def stream_file(self, filename):
61
- with self.smart_open.open(self.get_path(filename), "rb") as f:
62
- while chunk := f.read(8192):
92
+ with self.smart_open.open(
93
+ self.get_path(filename), "rb", **self.open_params
94
+ ) as f:
95
+ while chunk := await smart_run(f.read, 8192):
63
96
  yield chunk
64
97
 
65
98
  def save_file(self, file_data, filename):
66
- with self.smart_open.open(self.get_path(filename), "wb") as f:
99
+ path = self.get_path(filename)
100
+ with self.smart_open.open(path, "wb", **self.open_params) as f:
67
101
  f.write(file_data.file.read())
102
+ return path
68
103
 
69
104
  def save_content_to_file(self, content, filename):
70
- with self.smart_open.open(self.get_path(filename), "wb") as f:
105
+ path = self.get_path(filename)
106
+ with self.smart_open.open(path, "wb", **self.open_params) as f:
71
107
  f.write(content)
108
+ return path
72
109
 
73
110
  def delete_file(self, filename):
74
111
  path = self.get_path(filename)
75
112
  try:
76
- self.smart_open.open(path, "rb").close() # Check if file exists
77
- s3 = self.boto3.client(
78
- "s3",
79
- aws_access_key_id=self.access_key,
80
- aws_secret_access_key=self.secret_key,
81
- )
82
- s3.delete_object(
113
+ self.smart_open.open(
114
+ path, "rb", **self.open_params
115
+ ).close() # Check if file exists
116
+ self.boto3_client.delete_object(
83
117
  Bucket=self.bucket_name,
84
118
  Key=f"{self.bucket_subfolder}/{filename}"
85
119
  if self.bucket_subfolder
@@ -91,7 +125,7 @@ class S3FileManager(AbstractFileManager):
91
125
  def file_exists(self, filename):
92
126
  path = self.get_path(filename)
93
127
  try:
94
- with self.smart_open.open(path, "rb"):
128
+ with self.smart_open.open(path, "rb", **self.open_params):
95
129
  return True
96
130
  except FileNotFoundError:
97
131
  return False
@@ -105,6 +139,8 @@ class S3FileManager(AbstractFileManager):
105
139
  else subfolder,
106
140
  access_key=self.access_key,
107
141
  secret_key=self.secret_key,
142
+ open_params=self.open_params,
143
+ boto3_client=self.boto3_client,
108
144
  *args,
109
145
  **kwargs,
110
146
  )
fastapi_rtk/globals.py CHANGED
@@ -52,8 +52,6 @@ from .const import (
52
52
  BEARER_STRATEGY_CONFIG,
53
53
  COOKIE_CONFIG,
54
54
  COOKIE_STRATEGY_CONFIG,
55
- DEFAULT_ADMIN_ROLE,
56
- DEFAULT_PUBLIC_ROLE,
57
55
  )
58
56
  from .utils import lazy, lazy_import
59
57
 
@@ -85,14 +83,6 @@ class Globals:
85
83
  """
86
84
  The configuration settings for the FastAPI React Toolkit.
87
85
  """
88
- admin_role: str
89
- """
90
- The role key for the admin role. Default is `"Admin"`.
91
- """
92
- public_role: str
93
- """
94
- The role key for the public role. Default is `"Public"`.
95
- """
96
86
  is_migrate: bool
97
87
  """
98
88
  A boolean value to indicate if the application is in migration mode. `True` when you are running a command from `fastapi-rtk` CLI.
@@ -105,6 +95,10 @@ class Globals:
105
95
  """
106
96
  The background tasks object to add tasks to be executed after the response is sent. It will be `None` when not used in a request context.
107
97
  """
98
+ request: Request
99
+ """
100
+ The current request object. It will be `None` when not used in a request context.
101
+ """
108
102
  file_manager: "AbstractFileManager"
109
103
  """
110
104
  The file manager object to manage files in the application. Defaults to `FileManager` from `fastapi_rtk.file_managers.file_manager`.
@@ -119,6 +113,24 @@ class Globals:
119
113
  object.__setattr__(self, "_vars", {})
120
114
  object.__setattr__(self, "_defaults", {})
121
115
 
116
+ @property
117
+ def admin_role(self):
118
+ """
119
+ The role key for the admin role. Default is `"Admin"`.
120
+ """
121
+ from .setting import Setting
122
+
123
+ return Setting.AUTH_ROLE_ADMIN
124
+
125
+ @property
126
+ def public_role(self):
127
+ """
128
+ The role key for the public role. Default is `"Public"`.
129
+ """
130
+ from .setting import Setting
131
+
132
+ return Setting.AUTH_ROLE_PUBLIC
133
+
122
134
  def set_default(self, name: str, default: Any) -> None:
123
135
  """Set a default value for a variable."""
124
136
 
@@ -236,8 +248,6 @@ g.set_default(
236
248
  "auth", lazy_import("fastapi_rtk.auth", lambda mod: mod.AuthConfigurator())
237
249
  )
238
250
  g.set_default("config", Config())
239
- g.set_default("admin_role", DEFAULT_ADMIN_ROLE)
240
- g.set_default("public_role", DEFAULT_PUBLIC_ROLE)
241
251
  g.set_default("is_migrate", False)
242
252
  g.set_default("sensitive_data", {"User": ["password", "hashed_password"]})
243
253
  g.set_default(
@@ -0,0 +1,3 @@
1
+ from .lazy_text import *
2
+
3
+ __all__ = ["lazy_text", "translate", "_"]
@@ -0,0 +1,4 @@
1
+ from .cli import *
2
+ from .config import *
3
+
4
+ __all__ = ["FastAPIRTKBabelCLI", "FastAPIRTKBabelConfigs"]
@@ -0,0 +1,40 @@
1
+ from subprocess import run
2
+
3
+ import fastapi_babel
4
+
5
+ __all__ = ["FastAPIRTKBabelCLI"]
6
+
7
+
8
+ class FastAPIRTKBabelCLI(fastapi_babel.BabelCli):
9
+ """
10
+ Subclass of `fastapi_babel.BabelCli`.
11
+
12
+ - Modified `extract` method to handle custom keywords.
13
+ """
14
+
15
+ def extract(self, watch_dir, keywords: str | None = None):
16
+ """
17
+ Modified version of the default `extract` method to handle custom keywords too.
18
+
19
+ extract all messages that annotated using gettext/_
20
+ in the specified directory.
21
+
22
+ for first time will create messages.pot file into the root
23
+ directory.
24
+
25
+ Args:
26
+ watch_dir (str): directory to extract messages.
27
+ keywords (str | None): custom keywords to extract separated by space.
28
+ """
29
+ args = [
30
+ self.__module_name__,
31
+ "extract",
32
+ "-F",
33
+ self.babel.config.BABEL_CONFIG_FILE,
34
+ "-o",
35
+ self.babel.config.BABEL_MESSAGE_POT_FILE,
36
+ ]
37
+ if keywords:
38
+ args.extend(["-k", keywords])
39
+ args.append(watch_dir)
40
+ run(args)
@@ -0,0 +1,17 @@
1
+ import os
2
+
3
+ import fastapi_babel
4
+
5
+ __all__ = ["FastAPIRTKBabelConfigs"]
6
+
7
+
8
+ class FastAPIRTKBabelConfigs(fastapi_babel.BabelConfigs):
9
+ """
10
+ Subclass of `fastapi_babel.BabelConfigs`.
11
+
12
+ - Modified `ROOT_DIR` to not use its parent directory.
13
+ """
14
+
15
+ def __post_init__(self):
16
+ self.ROOT_DIR = os.path.join(self.ROOT_DIR, "dummy")
17
+ return super().__post_init__()
@@ -0,0 +1 @@
1
+ [python: **/*.py]
@@ -0,0 +1,120 @@
1
+ import fastapi_babel
2
+
3
+ from ..utils import lazy, use_default_when_none
4
+
5
+ __all__ = ["lazy_text", "translate", "_"]
6
+
7
+ logger = None
8
+
9
+
10
+ class lazy_text(lazy[str]):
11
+ """
12
+ Lazily translates a message using FastAPI Babel.
13
+ """
14
+
15
+ def __init__(self, message: str, *args, **kwargs):
16
+ """
17
+ Initializes a lazy_text instance that lazily translates the given message.
18
+
19
+ Args:
20
+ message (str): the message to be translated.
21
+ *args: positional arguments to format the message.
22
+ **kwargs: keyword arguments to format the message.
23
+ """
24
+ super().__init__(
25
+ lambda: translate(message).format(*args, **kwargs),
26
+ cache=False,
27
+ only_instance=True,
28
+ )
29
+
30
+ @classmethod
31
+ def _(cls, message: str, *args, **kwargs):
32
+ """
33
+ Class method to create a lazy_text instance that can be automatically found by `pybabel extract`.
34
+
35
+ Args:
36
+ message (str): the message to be translated.
37
+ *args: positional arguments to format the message.
38
+ **kwargs: keyword arguments to format the message.
39
+
40
+ Returns:
41
+ lazy_text: an instance of lazy_text that will lazily translate the message.
42
+ """
43
+ return cls(message, *args, **kwargs)
44
+
45
+ def __repr__(self):
46
+ """
47
+ When reading it as a string, it should return the formatted message.
48
+
49
+ Returns:
50
+ str: the formatted message.
51
+ """
52
+ return self.__call__()
53
+
54
+
55
+ def translate(
56
+ message: str, *args, ensure_context=False, use_settings_translations=True, **kwargs
57
+ ):
58
+ """
59
+ Translates a message using FastAPI Babel.
60
+
61
+ Args:
62
+ message (str): the message to be translated.
63
+ *args: positional arguments to format the message.
64
+ ensure_context (bool): Whether to ensure the context is already set to know which language to use. If false, it will return the message as is if the translation is not found. Defaults to False.
65
+ use_translations (bool): Whether to use the translations defined in `Setting.TRANSLATIONS` as a fallback if the translation is not found. Defaults to True.
66
+ **kwargs: keyword arguments to format the message.
67
+
68
+ Returns:
69
+ str: the translated message.
70
+ """
71
+ try:
72
+ translated_message = fastapi_babel._(message)
73
+ if translated_message == message and use_settings_translations:
74
+ translated_message = use_default_when_none(
75
+ _use_settings_translations(message), message
76
+ )
77
+ return translated_message.format(*args, **kwargs)
78
+ except LookupError as e:
79
+ if not ensure_context:
80
+ from ..globals import g
81
+
82
+ if g.current_app and g.current_app.started:
83
+ global logger
84
+ if not logger:
85
+ from ..const import logger as base_logger
86
+
87
+ logger = base_logger.getChild("lang")
88
+
89
+ logger.warning(
90
+ f"Translation not found for '{message}'. Returning the original message."
91
+ )
92
+ return message.format(*args, **kwargs)
93
+ raise e
94
+
95
+
96
+ def _use_settings_translations(message: str):
97
+ """
98
+ Use translations defined in `Setting.TRANSLATIONS` as a fallback if the translation is not found.
99
+
100
+ Args:
101
+ message (str): The original message to translate.
102
+
103
+ Returns:
104
+ str | None: The translated message, or None if no translation is found.
105
+ """
106
+ from ..globals import g
107
+ from ..setting import Setting
108
+
109
+ if Setting.TRANSLATIONS and g.request:
110
+ try:
111
+ translated_message = Setting.TRANSLATIONS.get(
112
+ g.request.state.babel.locale, {}
113
+ ).get(message)
114
+ if translated_message:
115
+ return translated_message
116
+ except Exception:
117
+ pass
118
+
119
+
120
+ _ = translate # Alias for convenience
@@ -0,0 +1,238 @@
1
+ # Translations template for PROJECT.
2
+ # Copyright (C) 2025 ORGANIZATION
3
+ # This file is distributed under the same license as the PROJECT project.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2025.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PROJECT VERSION\n"
10
+ "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11
+ "POT-Creation-Date: 2025-10-30 10:07+0100\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=utf-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+ "Generated-By: Babel 2.17.0\n"
19
+
20
+ #: fastapi_rtk/schemas.py:419
21
+ msgid "Columns must be a list"
22
+ msgstr ""
23
+
24
+ #: fastapi_rtk/schemas.py:429
25
+ msgid "Invalid columns: Not a valid JSON string"
26
+ msgstr ""
27
+
28
+ #: fastapi_rtk/schemas.py:452
29
+ msgid "Both 'order_column' and 'order_direction' must be filled or empty"
30
+ msgstr ""
31
+
32
+ #: fastapi_rtk/schemas.py:470
33
+ msgid "Filters must be a list"
34
+ msgstr ""
35
+
36
+ #: fastapi_rtk/schemas.py:485
37
+ msgid "Filter must be an object"
38
+ msgstr ""
39
+
40
+ #: fastapi_rtk/schemas.py:495
41
+ msgid "Invalid filters: Not a valid JSON string"
42
+ msgstr ""
43
+
44
+ #: fastapi_rtk/schemas.py:520
45
+ msgid "Opr Filters must be a list"
46
+ msgstr ""
47
+
48
+ #: fastapi_rtk/schemas.py:535
49
+ msgid "Opr Filter must be an object"
50
+ msgstr ""
51
+
52
+ #: fastapi_rtk/schemas.py:545
53
+ msgid "Invalid opr_filters: Not a valid JSON string"
54
+ msgstr ""
55
+
56
+ #: fastapi_rtk/api/model_rest_api.py:476
57
+ #, python-brace-format
58
+ msgid "List {ModelName}"
59
+ msgstr ""
60
+
61
+ #: fastapi_rtk/api/model_rest_api.py:485
62
+ #, python-brace-format
63
+ msgid "Show {ModelName}"
64
+ msgstr ""
65
+
66
+ #: fastapi_rtk/api/model_rest_api.py:494
67
+ #, python-brace-format
68
+ msgid "Add {ModelName}"
69
+ msgstr ""
70
+
71
+ #: fastapi_rtk/api/model_rest_api.py:503
72
+ #, python-brace-format
73
+ msgid "Edit {ModelName}"
74
+ msgstr ""
75
+
76
+ #: fastapi_rtk/api/model_rest_api.py:1395
77
+ msgid "OK"
78
+ msgstr ""
79
+
80
+ #: fastapi_rtk/api/model_rest_api.py:2411
81
+ #: fastapi_rtk/api/model_rest_api.py:2810
82
+ #, python-brace-format
83
+ msgid "Number of items in '{column}' does not match the number of items found."
84
+ msgstr ""
85
+
86
+ #: fastapi_rtk/api/model_rest_api.py:2432
87
+ #, python-brace-format
88
+ msgid "Could not find related item for column '{column}'"
89
+ msgstr ""
90
+
91
+ #: fastapi_rtk/api/model_rest_api.py:2464
92
+ #, python-brace-format
93
+ msgid "File type from '{filename}' is not allowed."
94
+ msgstr ""
95
+
96
+ #: fastapi_rtk/api/model_rest_api.py:2872
97
+ #, python-brace-format
98
+ msgid "Invalid column: {column}"
99
+ msgstr ""
100
+
101
+ #: fastapi_rtk/api/model_rest_api.py:2882
102
+ #, python-brace-format
103
+ msgid "Invalid filter: {column}"
104
+ msgstr ""
105
+
106
+ #: fastapi_rtk/backends/generic/db.py:66 fastapi_rtk/backends/sqla/db.py:163
107
+ #, python-brace-format
108
+ msgid "Invalid filter operator: {operator}"
109
+ msgstr ""
110
+
111
+ #: fastapi_rtk/backends/generic/db.py:90 fastapi_rtk/backends/sqla/db.py:194
112
+ #, python-brace-format
113
+ msgid "Invalid opr_filter operator: {operator}"
114
+ msgstr ""
115
+
116
+ #: fastapi_rtk/backends/generic/filters.py:81
117
+ #: fastapi_rtk/backends/sqla/filters.py:243
118
+ msgid "Text contains"
119
+ msgstr ""
120
+
121
+ #: fastapi_rtk/backends/generic/filters.py:89
122
+ #: fastapi_rtk/backends/sqla/filters.py:259
123
+ msgid "Equal to"
124
+ msgstr ""
125
+
126
+ #: fastapi_rtk/backends/generic/filters.py:117
127
+ #: fastapi_rtk/backends/sqla/filters.py:277
128
+ msgid "Starts with"
129
+ msgstr ""
130
+
131
+ #: fastapi_rtk/backends/generic/filters.py:126
132
+ #: fastapi_rtk/backends/sqla/filters.py:286
133
+ msgid "Not Starts with"
134
+ msgstr ""
135
+
136
+ #: fastapi_rtk/backends/generic/filters.py:135
137
+ #: fastapi_rtk/backends/sqla/filters.py:295
138
+ msgid "Ends with"
139
+ msgstr ""
140
+
141
+ #: fastapi_rtk/backends/generic/filters.py:144
142
+ #: fastapi_rtk/backends/sqla/filters.py:304
143
+ msgid "Not Ends with"
144
+ msgstr ""
145
+
146
+ #: fastapi_rtk/backends/generic/filters.py:153
147
+ #: fastapi_rtk/backends/sqla/filters.py:313
148
+ msgid "Contains"
149
+ msgstr ""
150
+
151
+ #: fastapi_rtk/backends/generic/filters.py:162
152
+ msgid "Contains (insensitive)"
153
+ msgstr ""
154
+
155
+ #: fastapi_rtk/backends/generic/filters.py:171
156
+ #: fastapi_rtk/backends/sqla/filters.py:322
157
+ msgid "Not Contains"
158
+ msgstr ""
159
+
160
+ #: fastapi_rtk/backends/generic/filters.py:180
161
+ #: fastapi_rtk/backends/sqla/filters.py:331
162
+ msgid "Greater than"
163
+ msgstr ""
164
+
165
+ #: fastapi_rtk/backends/generic/filters.py:189
166
+ #: fastapi_rtk/backends/sqla/filters.py:340
167
+ msgid "Smaller than"
168
+ msgstr ""
169
+
170
+ #: fastapi_rtk/backends/generic/filters.py:198
171
+ #: fastapi_rtk/backends/sqla/filters.py:349
172
+ msgid "Greater equal"
173
+ msgstr ""
174
+
175
+ #: fastapi_rtk/backends/generic/filters.py:207
176
+ #: fastapi_rtk/backends/sqla/filters.py:358
177
+ msgid "Smaller equal"
178
+ msgstr ""
179
+
180
+ #: fastapi_rtk/backends/generic/filters.py:216
181
+ #: fastapi_rtk/backends/sqla/filters.py:367
182
+ msgid "One of"
183
+ msgstr ""
184
+
185
+ #: fastapi_rtk/backends/generic/filters.py:225
186
+ #: fastapi_rtk/backends/sqla/filters.py:470
187
+ msgid "Global Filter"
188
+ msgstr ""
189
+
190
+ #: fastapi_rtk/backends/sqla/filters.py:268
191
+ msgid "Not equal to"
192
+ msgstr ""
193
+
194
+ #: fastapi_rtk/backends/sqla/filters.py:376
195
+ msgid "Between"
196
+ msgstr ""
197
+
198
+ #: fastapi_rtk/backends/sqla/filters.py:389
199
+ msgid "Between filter requires 2 values"
200
+ msgstr ""
201
+
202
+ #: fastapi_rtk/backends/sqla/filters.py:434
203
+ msgid "In"
204
+ msgstr ""
205
+
206
+ #: fastapi_rtk/backends/sqla/filters.py:452
207
+ msgid "Not In"
208
+ msgstr ""
209
+
210
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:83
211
+ msgid "Intersects"
212
+ msgstr ""
213
+
214
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:93
215
+ msgid "Not Intersects"
216
+ msgstr ""
217
+
218
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:103
219
+ msgid "Overlaps"
220
+ msgstr ""
221
+
222
+ #: fastapi_rtk/backends/sqla/extensions/geoalchemy2/filters.py:113
223
+ msgid "Not Overlaps"
224
+ msgstr ""
225
+
226
+ #: fastapi_rtk/bases/db.py:463
227
+ #, python-brace-format
228
+ msgid "Invalid ID: {id}, expected {count} values"
229
+ msgstr ""
230
+
231
+ #: fastapi_rtk/bases/db.py:476
232
+ msgid "Invalid ID"
233
+ msgstr ""
234
+
235
+ #: fastapi_rtk/security/sqla/apis.py:299
236
+ msgid "User updated successfully."
237
+ msgstr ""
238
+