Overview¶
HARP’s architecture is designed around modularity, loose coupling, and extensibility. This page provides a high-level overview of the architecture and core concepts.
Codebase structure¶
The codebase is divided into two main parts:
- Core (
harppackage) Provides the base functionality and tools for building proxy services. The core is framework code that applications build upon.
- Applications (
harp_appspackage) Independent modules that provide features. Both built-in and user-provided applications use the same integration mechanism.
Core packages¶
ASGI (
harp.asgi) - Building blocks for ASGI (Asynchronous Server Gateway Interface)Command line (
harp.commandline) - Core commands and building blocks for application-specific commandsConfig (
harp.config) - Configuration management system supporting various formats and sourcesControllers (
harp.controllers) - Building blocks for web controllers, turning requests into responsesErrors (
harp.errors) - Exception classes and error handling toolsEvent dispatcher (
harp.event_dispatcher) - Event handling system based onwhistleHTTP (
harp.http) - Building blocks for HTTPMeta (
harp.meta) - Metadata management toolsModels (
harp.models) - Data modeling for core objects (plain old Python objects, not tied to storage)Typing (
harp.typing) - Type and interface definitionsUtils (
harp.utils) - Collection of utility functions and helper classesViews (
harp.views) - Presentation layer for controllers
Core concepts¶
HARP employs several software engineering patterns to organize the codebase and ensure components work together while remaining loosely coupled.
Dependency injection and inversion of control¶
Dependency Injection (DI) is a design pattern where an object’s dependencies are provided by an external source rather than the object creating them itself.
Inversion of Control (IoC) is a design principle where the control of object creation and management is transferred from the application code to a container or framework.
Both principles make the code more modular and easier to test. HARP uses rodi for dependency injection.
Event-driven architecture¶
An Event-Driven Architecture (EDA) allows components to communicate and extend each other without tight coupling. Events can be network-based (like in microservice architectures) or internal to a process (like in HARP).
HARP uses Whistle, a simple Python event dispatcher, allowing applications to easily expose or hook
into system events.
Pluggable applications¶
Applications are independent modules that integrate with HARP through a standard protocol. Both core features and third-party extensions use the same mechanism.
Applications hook into the system through lifecycle events (on_bind, on_bound, on_ready, on_shutdown) and can register services, listen to events, and extend functionality.
Request flow¶
When an HTTP request comes into HARP, the following sequence of operations happens:
Once the Services Provider is initialized, most services are instantiated lazily, on demand, just in time.