Skip to content

luoshuijs/Persica

Repository files navigation

Persica

code_style

Introduction

The name "Persica" is derived from the Latin name of the author's favorite character, known for her distinctive appearance.

"Plum blossoms bloom after the snow, butterflies fly with the spring breeze."

Design Inspiration

The design inspiration for this framework comes from the Spring Framework. I am especially impressed by its powerful automatic assembly feature.

Quick Start

build() is synchronous and only constructs the application object. run() uses the configured event loop, creating one only when needed, and keeps the application alive until it is stopped. If you pass your own loop, it must not already be running.

from persica.applicationbuilder import ApplicationBuilder

app = ApplicationBuilder().set_scanner_package("example_app").build()

# Blocks until the application is stopped, for example with Ctrl+C.
app.run()
# example_app/components.py
from persica.factory.component import AsyncInitializingComponent


class HelloComponent(AsyncInitializingComponent):
    async def initialize(self):
        print("Persica is running")

    async def shutdown(self):
        print("Persica stopped")

App-level resources can be published through Application.provide_objects() and injected the same way as component-published resources. They are available as soon as the app is built, before run() starts creating components.

# example_app/application.py
from persica import inject
from persica.application import Application
from persica.applicationbuilder import ApplicationBuilder


class GreetingService:
    def greet(self) -> str:
        return "hello from the application"


class ExampleApplication(Application):
    def __init__(self, *args, **kwargs):
        self.greeting_service = GreetingService()
        super().__init__(*args, **kwargs)

    def provide_objects(self) -> list[GreetingService]:
        return [self.greeting_service]


class ExampleApplicationBuilder(ApplicationBuilder):
    _application_class = ExampleApplication
# example_app/components.py
from persica import inject
from persica.factory.component import AsyncInitializingComponent

from example_app.application import ExampleApplicationBuilder, GreetingService


class GreetingPrinter(AsyncInitializingComponent):
    greeting_service: GreetingService = inject()

    async def initialize(self):
        print(self.greeting_service.greet())
# example_app/main.py
from example_app.application import ExampleApplicationBuilder


app = ExampleApplicationBuilder().set_scanner_package("example_app").build()

# build() is still synchronous; run() starts initialization and blocks.
app.run()

Future

  • Support full path scanning
  • Support custom factory assembly

Packages

 
 
 

Contributors

Languages