A pluggable server
Reason this release was yanked:
wrong source code packaged
Project description
FPS
FPS
, fast pluggable server, is a framework designed to compose and run a web-server based on plugins.
It is based on top of fastAPI
, uvicorn
, typer
, and pluggy
.
How it works
The main purpose of FPS
is to provide hooks to register endpoints, static mounts, CLI setups/teardowns, etc.
An application can then be composed by multiple plugins providing specific/specialized endpoints. Those can be registered using fps.hooks.register_router
with a fastapi.APIRouter
.
What is coming soon
The most important parts will be to have a nice configuration system and also a logger working through multiprocesses, with homogeneous formatters to give devs/ops/users a smooth experience.
Concepts
Few concepts are extensively used in FPS
:
- a
hook
, orhook
implementation, is a method tagged as implementing ahook
specification- a hook specification is the declaration of the hook
@pluggy.HookspecMarker(HookType.ROUTER.value) def router() -> APIRouter: pass
- hooks are automatically collected by
FPS
using Python'sentry_point
s, and ran at the right time[options.entry_points] fps_router = fps_helloworld_router = fps_helloworld.routes fps_config = fps_helloworld_config = fps_helloworld.config
- multiple
entry_point
s groups are defined (e.g.fps_router
,fps_config
, etc.)- a hook MUST be declared in its corresponding group to be collected
- in the previous example,
HookType.ROUTER.value
equalsfps_router
, so therouter
hook is declared in that group
fps.hooks.register_<hook-name>
helpers are returning such hooksdef register_router(r: APIRouter): def router_callback() -> APIRouter: return r return pluggy.HookimplMarker(HookType.ROUTER.value)( function=router_callback, specname="router" )
- a hook specification is the declaration of the hook
- a
plugin
is a Python module declared in aFPS
'sentry_point
- a plugin may contain zero or more hooks
- in the following
helloworld
example, the hookconfig
is declared but not theplugin_name
one. Both are hooks of thefps_config
group.from fps.config import PluginModel from fps.hooks import register_config class HelloConfig(PluginModel): random: bool = True c = register_config(HelloConfig)
- a
plugins package
is a Python package declaring one or more plugins
Configuration
FPS
now support configuration using toml
format.
Precedence order
For now, the loading sequence of the configuration is: fps.toml
< <plugin-name>.toml
< <cli-passed-file>
< <cli-arg>
.
fps.toml
and <cli-passed-file>
files can contain configuration of any plugin, while <plugin-name>.toml
file
will only be used for that specific plugin.
fps.toml
and <plugin-name>.toml
currently have to be in the current working directory. Support for loading from user home
directory or system-wide application directory will be soon implemented.
Note: the environment variable FPS_CONFIG_FILE
is used to store cli-passed filename and make it available to subprocesses.
Merging strategy
At this time the merging strategy between multiple config sources is pretty simple:
- dict values for higher precedence source win
- no appending/prepending on sequences
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.