fast-feature 0.0.1__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.
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from .app import Application
4
+ from .repository_factory import RepositoryFactory
5
+ from .settings import Settings
6
+
7
+ __all__ = ["Application", "RepositoryFactory", "Settings"]
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from fastapi import FastAPI
4
+
5
+ from fast_feature.ofrep import OfrepRouter
6
+
7
+ from .repository_factory import RepositoryFactory
8
+ from .settings import Settings
9
+
10
+
11
+ class Application:
12
+ """Composition root: wires settings -> repository -> routers into a FastAPI app."""
13
+
14
+ @classmethod
15
+ def create(cls, settings: Settings | None = None) -> FastAPI:
16
+ resolved = settings or Settings()
17
+ repository = RepositoryFactory.from_settings(resolved)
18
+
19
+ app = FastAPI(title="fast-feature")
20
+ app.include_router(OfrepRouter.build(repository))
21
+
22
+ if resolved.admin:
23
+ # Imported lazily so the admin distribution is only needed when enabled.
24
+ from fast_feature.admin import AdminRouter
25
+
26
+ app.include_router(AdminRouter.build(repository), prefix=resolved.admin_prefix)
27
+
28
+ return app
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from collections.abc import Sequence
5
+
6
+ from .app import Application
7
+
8
+
9
+ class Cli:
10
+ """The ``fast-feature`` command-line entry point."""
11
+
12
+ @classmethod
13
+ def run(cls, argv: Sequence[str] | None = None) -> None:
14
+ parser = argparse.ArgumentParser(prog="fast-feature")
15
+ subparsers = parser.add_subparsers(dest="command", required=True)
16
+ serve = subparsers.add_parser("serve", help="Run the OFREP server.")
17
+ serve.add_argument("--host", default="127.0.0.1")
18
+ serve.add_argument("--port", type=int, default=8000)
19
+
20
+ args = parser.parse_args(argv)
21
+ if args.command == "serve":
22
+ cls._serve(args.host, args.port)
23
+
24
+ @staticmethod
25
+ def _serve(host: str, port: int) -> None:
26
+ try:
27
+ import uvicorn
28
+ except ImportError as exc: # pragma: no cover
29
+ raise SystemExit("Install fast-feature[standalone] to run the server.") from exc
30
+ uvicorn.run(Application.create(), host=host, port=port)
File without changes
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from fast_feature.core import FlagRepository
4
+ from fast_feature.storage.inmemory import InMemoryFlagRepository
5
+
6
+ from .settings import Settings
7
+
8
+
9
+ class RepositoryFactory:
10
+ """Builds the configured ``FlagRepository`` for the standalone server."""
11
+
12
+ @staticmethod
13
+ def from_settings(settings: Settings) -> FlagRepository:
14
+ if settings.backend == "postgresql":
15
+ if not settings.database_url:
16
+ raise ValueError("FAST_FEATURE_DATABASE_URL is required for the postgresql backend")
17
+ # Imported lazily so the dependency is only needed with the extra.
18
+ from fast_feature.storage.postgresql import PostgresStorage
19
+
20
+ return PostgresStorage.from_dsn(settings.database_url).repository
21
+ return InMemoryFlagRepository()
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from pydantic_settings import BaseSettings, SettingsConfigDict
6
+
7
+
8
+ class Settings(BaseSettings):
9
+ """Standalone-server configuration, read from ``FAST_FEATURE_*`` env vars."""
10
+
11
+ model_config = SettingsConfigDict(env_prefix="FAST_FEATURE_")
12
+
13
+ backend: Literal["inmemory", "postgresql"] = "inmemory"
14
+ database_url: str | None = None
15
+ admin: bool = False
16
+ admin_prefix: str = "/admin"
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: fast-feature
3
+ Version: 0.0.1
4
+ Summary: A lightweight, async, OpenFeature-compatible (OFREP) feature flag server.
5
+ Keywords: feature-flags,openfeature,ofrep,json-logic,fastapi,async
6
+ Author: byunjuneseok
7
+ Author-email: byunjuneseok <byunjuneseok@gmail.com>
8
+ License-Expression: Apache-2.0
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: FastAPI
11
+ Classifier: Framework :: AsyncIO
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
19
+ Classifier: Typing :: Typed
20
+ Requires-Dist: fast-feature-core==0.0.1
21
+ Requires-Dist: fast-feature-engine==0.0.1
22
+ Requires-Dist: fast-feature-ofrep==0.0.1
23
+ Requires-Dist: fast-feature-storage-inmemory==0.0.1
24
+ Requires-Dist: pydantic-settings>=2.0
25
+ Requires-Dist: fast-feature-admin==0.0.1 ; extra == 'admin'
26
+ Requires-Dist: fast-feature-storage-postgresql==0.0.1 ; extra == 'all'
27
+ Requires-Dist: fast-feature-admin==0.0.1 ; extra == 'all'
28
+ Requires-Dist: uvicorn[standard]>=0.27 ; extra == 'all'
29
+ Requires-Dist: fast-feature-storage-postgresql==0.0.1 ; extra == 'postgresql'
30
+ Requires-Dist: uvicorn[standard]>=0.27 ; extra == 'standalone'
31
+ Requires-Python: >=3.10
32
+ Project-URL: Homepage, https://github.com/byunjuneseok/fast-feature
33
+ Project-URL: Repository, https://github.com/byunjuneseok/fast-feature
34
+ Project-URL: Issues, https://github.com/byunjuneseok/fast-feature/issues
35
+ Provides-Extra: admin
36
+ Provides-Extra: all
37
+ Provides-Extra: postgresql
38
+ Provides-Extra: standalone
39
+ Description-Content-Type: text/markdown
40
+
41
+ # fast-feature
42
+
43
+ The umbrella distribution for [fast-feature](https://github.com/byunjuneseok/fast-feature):
44
+ an async, OpenFeature-compatible (OFREP) feature flag server.
45
+
46
+ ```bash
47
+ pip install "fast-feature[standalone]" # + uvicorn, to run the server
48
+ pip install "fast-feature[postgresql]" # + PostgreSQL backend
49
+ pip install "fast-feature[admin]" # + admin console
50
+ pip install "fast-feature[all]"
51
+ ```
52
+
53
+ Run it:
54
+
55
+ ```bash
56
+ FAST_FEATURE_BACKEND=inmemory fast-feature serve --host 0.0.0.0 --port 8000
57
+ ```
58
+
59
+ Or embed it:
60
+
61
+ ```python
62
+ from fast_feature.server import Application, Settings
63
+
64
+ app = Application.create(Settings(admin=True))
65
+ ```
66
+
67
+ See the [project README](https://github.com/byunjuneseok/fast-feature) for details.
@@ -0,0 +1,10 @@
1
+ fast_feature/server/__init__.py,sha256=qyFYriBQEFe1_zi382yRbH89z8e9d7WV2oh2DlPPL8U,206
2
+ fast_feature/server/app.py,sha256=YzKqE0qSOc7dBwgGFEQBtGEi9CQ63L8vXALISUZBAt4,872
3
+ fast_feature/server/cli.py,sha256=LfTmb11QLOTwmsZVVE35RcycEG-Zen45_-0_I3uVcOs,1038
4
+ fast_feature/server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ fast_feature/server/repository_factory.py,sha256=BG6vwvk68axhRjv7IdpPhYhVYvlnokaS5C10f--2nn0,821
6
+ fast_feature/server/settings.py,sha256=y79qw_zD2hr_54UYoPszVYQyYnyWIPFQnSUSxmUxm3M,462
7
+ fast_feature-0.0.1.dist-info/WHEEL,sha256=8ZlpUMJ7mlDirmlHRhDirEx_nPnARrwDjeE92mlk68E,81
8
+ fast_feature-0.0.1.dist-info/entry_points.txt,sha256=UHFhHTikqmbG4PmtyoS-TnmyphLSdzecMzUg8Wno8fw,66
9
+ fast_feature-0.0.1.dist-info/METADATA,sha256=eIo9M-jRc_0XQXYeL1FzXTdt3E6JPFJQitVBtPwljpc,2550
10
+ fast_feature-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.11.21
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ fast-feature = fast_feature.server.cli:Cli.run
3
+