apache-airflow-providers-fab 3.1.1rc1__py3-none-any.whl → 3.2.0rc1__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 (49) hide show
  1. airflow/providers/fab/__init__.py +1 -1
  2. airflow/providers/fab/auth_manager/api_endpoints/user_endpoint.py +3 -1
  3. airflow/providers/fab/auth_manager/api_fastapi/datamodels/roles.py +13 -7
  4. airflow/providers/fab/auth_manager/api_fastapi/datamodels/users.py +68 -0
  5. airflow/providers/fab/auth_manager/api_fastapi/openapi/v2-fab-auth-manager-generated.yaml +485 -18
  6. airflow/providers/fab/auth_manager/api_fastapi/routes/login.py +2 -4
  7. airflow/providers/fab/auth_manager/api_fastapi/routes/users.py +133 -0
  8. airflow/providers/fab/auth_manager/api_fastapi/services/login.py +1 -2
  9. airflow/providers/fab/auth_manager/api_fastapi/services/users.py +219 -0
  10. airflow/providers/fab/auth_manager/cli_commands/db_command.py +2 -2
  11. airflow/providers/fab/auth_manager/cli_commands/user_command.py +3 -3
  12. airflow/providers/fab/auth_manager/fab_auth_manager.py +18 -51
  13. airflow/providers/fab/auth_manager/models/__init__.py +6 -6
  14. airflow/providers/fab/auth_manager/security_manager/override.py +90 -77
  15. airflow/providers/fab/auth_manager/views/user.py +12 -0
  16. airflow/providers/fab/cli/__init__.py +18 -0
  17. airflow/providers/fab/{auth_manager/cli_commands → cli}/definition.py +50 -2
  18. airflow/providers/fab/get_provider_info.py +8 -0
  19. airflow/providers/fab/www/app.py +2 -7
  20. airflow/providers/fab/www/extensions/init_appbuilder.py +3 -2
  21. airflow/providers/fab/www/package-lock.json +669 -531
  22. airflow/providers/fab/www/package.json +9 -9
  23. airflow/providers/fab/www/static/dist/{743.0c0bf201ae17e66a9a3f.js → 743.8fb7d21632ed892227fe.js} +2 -2
  24. airflow/providers/fab/www/static/dist/{airflowDefaultTheme.ef6fc04c9b6920cd75c9.js → airflowDefaultTheme.51e5d14856ee1ebc83ca.js} +1 -1
  25. airflow/providers/fab/www/static/dist/{flash.eaaf777ec1b3628cf7be.js → flash.865b6940c00b2a9041b3.js} +1 -1
  26. airflow/providers/fab/www/static/dist/{loadingDots.76f4332c0a932c3dc08f.js → loadingDots.07f5b9805847242736e1.js} +1 -1
  27. airflow/providers/fab/www/static/dist/main.8cffe40bcf7cca998f4e.js +2 -0
  28. airflow/providers/fab/www/static/dist/manifest.json +13 -13
  29. airflow/providers/fab/www/static/dist/{materialIcons.ad07a489b2f0fc1a96bf.js → materialIcons.4fe84ae36604d84dec78.js} +1 -1
  30. airflow/providers/fab/www/static/dist/moment.0ec3ee3fb60dc999b1fd.js +1 -0
  31. airflow/providers/fab/www/static/js/main.js +11 -0
  32. airflow/providers/fab/www/templates/airflow/main.html +1 -0
  33. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/METADATA +10 -10
  34. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/RECORD +47 -43
  35. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/licenses/3rd-party-licenses/LICENSES-ui.txt +1 -1
  36. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/licenses/NOTICE +1 -1
  37. airflow/providers/fab/www/static/dist/main.bc1f701c3d133e2a3bab.js +0 -2
  38. airflow/providers/fab/www/static/dist/moment.5b85b4f6be2fe9c405ac.js +0 -1
  39. /airflow/providers/fab/www/static/dist/{743.0c0bf201ae17e66a9a3f.js.LICENSE.txt → 743.8fb7d21632ed892227fe.js.LICENSE.txt} +0 -0
  40. /airflow/providers/fab/www/static/dist/{airflowDefaultTheme.ef6fc04c9b6920cd75c9.css → airflowDefaultTheme.51e5d14856ee1ebc83ca.css} +0 -0
  41. /airflow/providers/fab/www/static/dist/{flash.eaaf777ec1b3628cf7be.css → flash.865b6940c00b2a9041b3.css} +0 -0
  42. /airflow/providers/fab/www/static/dist/{loadingDots.76f4332c0a932c3dc08f.css → loadingDots.07f5b9805847242736e1.css} +0 -0
  43. /airflow/providers/fab/www/static/dist/{main.bc1f701c3d133e2a3bab.css → main.8cffe40bcf7cca998f4e.css} +0 -0
  44. /airflow/providers/fab/www/static/dist/{main.bc1f701c3d133e2a3bab.js.LICENSE.txt → main.8cffe40bcf7cca998f4e.js.LICENSE.txt} +0 -0
  45. /airflow/providers/fab/www/static/dist/{materialIcons.ad07a489b2f0fc1a96bf.css → materialIcons.4fe84ae36604d84dec78.css} +0 -0
  46. /airflow/providers/fab/www/static/dist/{runtime.254c277d91ce3ac79c64.js → runtime.45b36fb8335446865b53.js} +0 -0
  47. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/WHEEL +0 -0
  48. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/entry_points.txt +0 -0
  49. {apache_airflow_providers_fab-3.1.1rc1.dist-info → apache_airflow_providers_fab-3.2.0rc1.dist-info}/licenses/LICENSE +0 -0
@@ -17,6 +17,7 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import textwrap
20
+ from typing import TYPE_CHECKING
20
21
 
21
22
  from airflow.cli.cli_config import (
22
23
  ARG_DB_FROM_REVISION,
@@ -35,6 +36,9 @@ from airflow.cli.cli_config import (
35
36
  lazy_load_command,
36
37
  )
37
38
 
39
+ if TYPE_CHECKING:
40
+ import argparse
41
+
38
42
  ############
39
43
  # # ARGS # #
40
44
  ############
@@ -143,7 +147,7 @@ USERS_COMMANDS = (
143
147
  ),
144
148
  epilog=(
145
149
  "examples:\n"
146
- 'To create an user with "Admin" role and username equals to "admin", run:\n'
150
+ 'To create a user with "Admin" role and username equals to "admin", run:\n'
147
151
  "\n"
148
152
  " $ airflow users create \\\n"
149
153
  " --username admin \\\n"
@@ -168,7 +172,7 @@ USERS_COMMANDS = (
168
172
  ),
169
173
  epilog=(
170
174
  "examples:\n"
171
- 'To reset an user with username equals to "admin", run:\n'
175
+ 'To reset a user with username equals to "admin", run:\n'
172
176
  "\n"
173
177
  " $ airflow users reset-password \\\n"
174
178
  " --username admin"
@@ -336,3 +340,47 @@ DB_COMMANDS = (
336
340
  args=(ARG_YES, ARG_DB_SKIP_INIT, ARG_VERBOSE),
337
341
  ),
338
342
  )
343
+
344
+
345
+ def get_fab_cli_commands():
346
+ """Return CLI commands for FAB auth manager."""
347
+ import packaging.version
348
+
349
+ from airflow import __version__ as airflow_version
350
+ from airflow.cli.cli_config import GroupCommand
351
+
352
+ commands = [
353
+ GroupCommand(
354
+ name="users",
355
+ help="Manage users",
356
+ subcommands=USERS_COMMANDS,
357
+ ),
358
+ GroupCommand(
359
+ name="roles",
360
+ help="Manage roles",
361
+ subcommands=ROLES_COMMANDS,
362
+ ),
363
+ SYNC_PERM_COMMAND, # not in a command group
364
+ PERMISSIONS_CLEANUP_COMMAND, # single command for permissions cleanup
365
+ ]
366
+ # If Airflow version is 3.0.0 or higher, add the fab-db command group
367
+ if packaging.version.parse(
368
+ packaging.version.parse(airflow_version).base_version
369
+ ) >= packaging.version.parse("3.0.0"):
370
+ commands.append(GroupCommand(name="fab-db", help="Manage FAB", subcommands=DB_COMMANDS))
371
+ return commands
372
+
373
+
374
+ def get_parser() -> argparse.ArgumentParser:
375
+ """
376
+ Generate documentation; used by Sphinx argparse.
377
+
378
+ :meta private:
379
+ """
380
+ from airflow.cli.cli_parser import AirflowHelpFormatter, DefaultHelpParser, _add_command
381
+
382
+ parser = DefaultHelpParser(prog="airflow", formatter_class=AirflowHelpFormatter)
383
+ subparsers = parser.add_subparsers(dest="subcommand", metavar="GROUP_OR_COMMAND")
384
+ for group_command in get_fab_cli_commands():
385
+ _add_command(subparsers, group_command)
386
+ return parser
@@ -177,8 +177,16 @@ def get_provider_info():
177
177
  "example": None,
178
178
  "default": "1",
179
179
  },
180
+ "cache_ttl": {
181
+ "description": "Number of seconds after which the user cache will expire to refetch updated user and\npermissions.\n",
182
+ "version_added": "3.2.0",
183
+ "type": "integer",
184
+ "example": None,
185
+ "default": "30",
186
+ },
180
187
  },
181
188
  }
182
189
  },
183
190
  "auth-managers": ["airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager"],
191
+ "cli": ["airflow.providers.fab.cli.definition.get_fab_cli_commands"],
184
192
  }
@@ -31,7 +31,7 @@ from airflow.api_fastapi.app import get_auth_manager
31
31
  from airflow.configuration import conf
32
32
  from airflow.exceptions import AirflowConfigException
33
33
  from airflow.logging_config import configure_logging
34
- from airflow.providers.fab.www.extensions.init_appbuilder import AirflowAppBuilder
34
+ from airflow.providers.fab.www.extensions.init_appbuilder import init_appbuilder
35
35
  from airflow.providers.fab.www.extensions.init_jinja_globals import init_jinja_globals
36
36
  from airflow.providers.fab.www.extensions.init_manifest_files import configure_manifest_files
37
37
  from airflow.providers.fab.www.extensions.init_security import init_api_auth
@@ -93,12 +93,7 @@ def create_app(enable_plugins: bool):
93
93
  init_api_auth(flask_app)
94
94
 
95
95
  with flask_app.app_context():
96
- AirflowAppBuilder(
97
- app=flask_app,
98
- session=db.session(),
99
- base_template="airflow/main.html",
100
- enable_plugins=enable_plugins,
101
- )
96
+ init_appbuilder(flask_app, enable_plugins=enable_plugins)
102
97
  init_error_handlers(flask_app)
103
98
  # In two scenarios a Flask application can be created:
104
99
  # - To support Airflow 2 plugins relying on Flask (``enable_plugins`` is True)
@@ -49,6 +49,7 @@ if TYPE_CHECKING:
49
49
  from flask_appbuilder import BaseView
50
50
  from flask_appbuilder.security.manager import BaseSecurityManager
51
51
  from sqlalchemy.orm import Session
52
+ from sqlalchemy.orm.scoping import scoped_session
52
53
 
53
54
 
54
55
  # This product contains a modified portion of 'Flask App Builder' developed by Daniel Vaz Gaspar.
@@ -102,7 +103,7 @@ class AirflowAppBuilder:
102
103
  def __init__(
103
104
  self,
104
105
  app=None,
105
- session: Session | None = None,
106
+ session: scoped_session | None = None,
106
107
  menu=None,
107
108
  indexview=None,
108
109
  base_template="airflow/main.html",
@@ -597,7 +598,7 @@ def init_appbuilder(app: Flask, enable_plugins: bool) -> AirflowAppBuilder:
597
598
  raise RuntimeError("Session not configured. Call configure_orm() first.")
598
599
  return AirflowAppBuilder(
599
600
  app=app,
600
- session=settings.Session(),
601
+ session=settings.Session,
601
602
  base_template="airflow/main.html",
602
603
  enable_plugins=enable_plugins,
603
604
  )