Skip to content

Commit a219c9e

Browse files
committed
Merge branch 'adding-fast-api-registry' into distracted-shirley
* adding-fast-api-registry: started adding the Fast_API registry classes Update release badge and version file
2 parents 404528a + 9842ed6 commit a219c9e

31 files changed

Lines changed: 542 additions & 3 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OSBot-Fast-API
22

3-
![Current Release](https://img.shields.io/badge/release-v0.32.1-blue)
3+
![Current Release](https://img.shields.io/badge/release-v0.32.2-blue)
44
![Python](https://img.shields.io/badge/python-3.8+-green)
55
![FastAPI](https://img.shields.io/badge/FastAPI-0.100+-red)
66
![Type-Safe](https://img.shields.io/badge/Type--Safe-✓-brightgreen)

osbot_fast_api/services/__init__.py

Whitespace-only changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# Service__Client__Base
3+
# Abstract base class that all service clients must inherit
4+
# Provides the contract for registration with Services__Registry
5+
# ═══════════════════════════════════════════════════════════════════════════════
6+
from osbot_fast_api.services.schemas.registry.Schema__Service__Client__Config import Schema__Service__Client__Config
7+
from osbot_fast_api.services.schemas.registry.collections.List__Env_Vars import List__Env_Vars
8+
from osbot_utils.type_safe.Type_Safe import Type_Safe
9+
10+
11+
12+
# todo: rename this class to Fast_API__Service__Registry__Client__Base
13+
14+
class Service__Client__Base(Type_Safe): # Base class for all service clients
15+
config : Schema__Service__Client__Config # Configuration for this client
16+
17+
def setup_from_env(self) -> 'Service__Client__Base': # Configure from environment variables
18+
raise NotImplementedError("Subclass must implement setup_from_env()")
19+
20+
def requests(self): # Return the *__Requests transport object
21+
raise NotImplementedError("Subclass must implement requests()")
22+
23+
def health(self) -> bool: # Basic health check
24+
raise NotImplementedError("Subclass must implement health()")
25+
26+
@classmethod
27+
def env_vars(cls) -> List__Env_Vars: # Expected env vars for this client
28+
raise NotImplementedError("Subclass must implement env_vars()")
29+
30+
@classmethod
31+
def client_name(cls) -> str: # Human-readable name for errors
32+
return cls.__name__
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# Services__Registry
3+
# Central registry for service client discovery across deployment modes
4+
# Enables zero-code-change switching between IN_MEMORY and REMOTE modes
5+
# ═══════════════════════════════════════════════════════════════════════════════
6+
from osbot_fast_api.services.registry.Service__Client__Base import Service__Client__Base
7+
from osbot_fast_api.services.schemas.registry.collections.Dict__Clients__By_Type import Dict__Clients__By_Type
8+
from osbot_fast_api.services.schemas.registry.collections.List__Client_Types import List__Client_Types
9+
from osbot_utils.type_safe.type_safe_core.decorators.type_safe import type_safe
10+
11+
12+
# todo: rename this class to Fast_API__Service__Registry
13+
# this class needs to be refactored to not use static methods where _clients is an instance variable
14+
# and the main static reference for the shared (singleton method) is retrieve by the "fast_api__service_registry = Services__Registry() " that can be seen at the end of this file
15+
# this means that we can make the Services__Registry a Type_Safe class and remove the None assigment, since Type_Safe will then create that _clients object
16+
# rename '_clients' with 'clients
17+
class Services__Registry: # Static singleton registry for service clients
18+
_clients : Dict__Clients__By_Type = None # Class-level storage (lazy initialized)
19+
20+
@classmethod
21+
def clients(cls) -> Dict__Clients__By_Type: # Lazy initialization of storage
22+
if cls._clients is None:
23+
cls._clients = Dict__Clients__By_Type()
24+
return cls._clients
25+
26+
@classmethod
27+
@type_safe
28+
def register(cls, client: Service__Client__Base) -> None: # Register a client instance
29+
cls.clients()[type(client)] = client # Index by actual type
30+
31+
@classmethod
32+
def client(cls, client_type: type) -> Service__Client__Base: # Retrieve client by type
33+
if client_type not in cls.clients():
34+
return None # Not registered = None
35+
return cls.clients()[client_type] # Return registered client
36+
37+
@classmethod
38+
def is_registered(cls, client_type: type) -> bool: # Check if type is registered
39+
return client_type in cls.clients()
40+
41+
@classmethod
42+
def clear(cls) -> None: # Reset registry for test isolation
43+
cls._clients = None
44+
45+
@classmethod
46+
def registered_types(cls) -> List__Client_Types: # List all registered client types
47+
return List__Client_Types(list(cls.clients().keys()))
48+
49+
fast_api__service_registry = Services__Registry()

osbot_fast_api/services/registry/__init__.py

Whitespace-only changes.

osbot_fast_api/services/schemas/__init__.py

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# Schema__Env_Var
3+
# Defines an environment variable that a service client expects
4+
# ═══════════════════════════════════════════════════════════════════════════════
5+
6+
from osbot_utils.type_safe.Type_Safe import Type_Safe
7+
from osbot_utils.type_safe.primitives.core.Safe_Str import Safe_Str
8+
9+
# todo: refactor this class to be Schema__Fast_API__Registry__Env_Var
10+
# : also:
11+
# name should a type of Schema__Env_Var__Name (which needs to be created)
12+
# we should also create an Schema__Env_Var__Value
13+
# add note to refactor these to the OSbot-Utils project
14+
class Schema__Env_Var(Type_Safe): # Pure data - environment variable definition
15+
name : Safe_Str # Env var name (e.g., "URL__TARGET_SERVER__CACHE")
16+
required : bool = True # Must be present at startup?
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# Schema__Service__Client__Config
3+
# Configuration schema shared by all service clients
4+
# ═══════════════════════════════════════════════════════════════════════════════
5+
6+
from fastapi import FastAPI
7+
from osbot_utils.type_safe.Type_Safe import Type_Safe
8+
from mgraph_ai_service_cache_client.client.requests.schemas.enums.Enum__Client__Mode import Enum__Client__Mode
9+
from osbot_fast_api.services.schemas.registry.safe_str.Safe_Str__API_Key__Name import Safe_Str__API_Key__Name
10+
from osbot_fast_api.services.schemas.registry.safe_str.Safe_Str__API_Key__Value import Safe_Str__API_Key__Value
11+
from osbot_utils.type_safe.primitives.domains.web.safe_str.Safe_Str__Url import Safe_Str__Url
12+
13+
# todo: rename this class to Fast_API__Service__Registry__Client__Config
14+
15+
class Schema__Service__Client__Config(Type_Safe): # Pure data - client configuration
16+
mode : Enum__Client__Mode = None # IN_MEMORY or REMOTE (None = not configured)
17+
fast_api_app : FastAPI = None # FastAPI app for IN_MEMORY mode
18+
base_url : Safe_Str__Url = None # Base URL for REMOTE mode
19+
api_key_name : Safe_Str__API_Key__Name = None # HTTP header name for auth
20+
api_key_value : Safe_Str__API_Key__Value = None # HTTP header value for auth

osbot_fast_api/services/schemas/registry/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ═══════════════════════════════════════════════════════════════════════════════
2+
# Dict__Clients__By_Type
3+
# Type-safe dictionary for storing service clients indexed by their class type
4+
# ═══════════════════════════════════════════════════════════════════════════════
5+
from osbot_fast_api.services.registry.Service__Client__Base import Service__Client__Base
6+
from osbot_utils.type_safe.type_safe_core.collections.Type_Safe__Dict import Type_Safe__Dict
7+
8+
9+
# todo: rename this class to Dict__Fast_API__Service__Clients_By_Type
10+
class Dict__Clients__By_Type(Type_Safe__Dict): # Maps client type → client instance
11+
expected_key_type = type # The client class itself
12+
expected_value_type = Service__Client__Base # Instance of client

0 commit comments

Comments
 (0)