Skip to content

Commit be2e227

Browse files
committed
Merge dev into main
2 parents 402bf34 + 5822c53 commit be2e227

10 files changed

Lines changed: 102 additions & 37 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.27.0-blue)
3+
![Current Release](https://img.shields.io/badge/release-v0.27.1-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/api/routes/type_safe/Type_Safe__Route__Analyzer.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import inspect
2-
from typing import get_type_hints, Callable
2+
from typing import get_type_hints, Callable, Type
33
from osbot_utils.type_safe.Type_Safe import Type_Safe
44
from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
55
from osbot_utils.type_safe.type_safe_core.decorators.type_safe import type_safe
@@ -42,10 +42,11 @@ def analyze_function(self, function : Callable # Function
4242
# Will be populated by converter
4343
pass
4444

45-
return_type = type_hints.get('return', None) # Analyze return type
45+
return_type = type_hints.get('return', None) # Analyze return type
4646
if return_type and return_type != inspect.Parameter.empty:
47-
signature.return_type = return_type
48-
signature.return_needs_conversion = self.is_type_safe_class(return_type) and not self.is_primitive_class(return_type)
47+
if isinstance(return_type, (type, Type)): # Only set return_type if it's an actual class, not a typing construct
48+
signature.return_type = return_type
49+
signature.return_needs_conversion = self.is_type_safe_class(return_type) and not self.is_primitive_class(return_type)
4950

5051
return signature
5152

osbot_fast_api/api/schemas/Schema__Fast_API__Config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from osbot_fast_api.api.schemas.safe_str.Safe_Str__Fast_API__Route__Prefix import Safe_Str__Fast_API__Route__Prefix
1+
from osbot_fast_api.api.schemas.safe_str.Safe_Str__Fast_API__Route__Prefix import Safe_Str__Fast_API__Route__Prefix
22
from osbot_fast_api.utils.Version import version__osbot_fast_api
33
from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Text import Safe_Str__Text
44
from osbot_utils.type_safe.primitives.domains.common.safe_str.Safe_Str__Version import Safe_Str__Version
5-
from osbot_fast_api.api.schemas.safe_str.Safe_Str__Fast_API__Name import Safe_Str__Fast_API__Name
5+
from osbot_fast_api.api.schemas.safe_str.Safe_Str__Fast_API__Name import Safe_Str__Fast_API__Name
66
from osbot_utils.type_safe.Type_Safe import Type_Safe
77

88

osbot_fast_api/client/Fast_API__Contract__Extractor.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import re
22
import inspect
3-
from typing import List, Any, Optional
4-
from osbot_fast_api.api.schemas.Schema__Fast_API__Tag__Classes_And_Routes import Schema__Fast_API__Tag__Classes_And_Routes
5-
from osbot_fast_api.api.schemas.Schema__Fast_API__Tags__Classes_And_Routes import Schema__Fast__API_Tags__Classes_And_Routes
6-
from osbot_fast_api.api.schemas.routes.Schema__Fast_API__Route import Schema__Fast_API__Route
7-
from osbot_utils.decorators.methods.cache_on_self import cache_on_self
8-
from osbot_fast_api.client.Fast_API__Route__Extractor import Fast_API__Route__Extractor
9-
from osbot_utils.type_safe.Type_Safe import Type_Safe
10-
from osbot_utils.helpers.ast import Ast_Module
11-
from osbot_utils.helpers.ast.Ast_Visit import Ast_Visit
12-
from osbot_fast_api.api.Fast_API import Fast_API
13-
from osbot_fast_api.client.schemas.Schema__Endpoint__Contract import Schema__Endpoint__Contract
14-
from osbot_fast_api.client.schemas.Schema__Endpoint__Param import Schema__Endpoint__Param
15-
from osbot_fast_api.client.schemas.Schema__Routes__Module import Schema__Routes__Module
16-
from osbot_fast_api.client.schemas.Schema__Service__Contract import Schema__Service__Contract
17-
from osbot_fast_api.client.schemas.enums.Enum__Param__Location import Enum__Param__Location
18-
from osbot_utils.type_safe.primitives.domains.http.enums.Enum__Http__Method import Enum__Http__Method
3+
from typing import List, Any, Optional
4+
from osbot_fast_api.api.schemas.Schema__Fast_API__Tag__Classes_And_Routes import Schema__Fast_API__Tag__Classes_And_Routes
5+
from osbot_fast_api.api.schemas.Schema__Fast_API__Tags__Classes_And_Routes import Schema__Fast__API_Tags__Classes_And_Routes
6+
from osbot_fast_api.api.schemas.routes.Schema__Fast_API__Route import Schema__Fast_API__Route
7+
from osbot_utils.decorators.methods.cache_on_self import cache_on_self
8+
from osbot_fast_api.client.Fast_API__Route__Extractor import Fast_API__Route__Extractor
9+
from osbot_utils.type_safe.Type_Safe import Type_Safe
10+
from osbot_utils.helpers.ast import Ast_Module
11+
from osbot_utils.helpers.ast.Ast_Visit import Ast_Visit
12+
from osbot_fast_api.api.Fast_API import Fast_API
13+
from osbot_fast_api.client.schemas.Schema__Endpoint__Contract import Schema__Endpoint__Contract
14+
from osbot_fast_api.client.schemas.Schema__Endpoint__Param import Schema__Endpoint__Param
15+
from osbot_fast_api.client.schemas.Schema__Routes__Module import Schema__Routes__Module
16+
from osbot_fast_api.client.schemas.Schema__Service__Contract import Schema__Service__Contract
17+
from osbot_fast_api.client.schemas.enums.Enum__Param__Location import Enum__Param__Location
18+
from osbot_utils.type_safe.primitives.domains.http.enums.Enum__Http__Method import Enum__Http__Method
1919
from osbot_utils.type_safe.primitives.domains.identifiers.safe_str.Safe_Str__Python__Module import Safe_Str__Python__Module
2020

2121

osbot_fast_api/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.27.0
1+
v0.27.1

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "osbot_fast_api"
3-
version = "v0.27.0"
3+
version = "v0.27.1"
44
description = "OWASP Security Bot - Fast API"
55
authors = ["Dinis Cruz <dinis.cruz@owasp.org>"]
66
license = "MIT"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from unittest import TestCase
2+
3+
class test_Fast_API__Routes__bugs(TestCase):
4+
5+
pass
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing import Union
2+
from unittest import TestCase
3+
from osbot_fast_api.client.Fast_API__Route__Extractor import Fast_API__Route__Extractor
4+
from osbot_utils.type_safe.Type_Safe import Type_Safe
5+
from osbot_fast_api.api.Fast_API import Fast_API
6+
7+
8+
class test_Fast_API__Routes__regression(TestCase):
9+
10+
def test__regression__error_with_union_return_type(self): # Test that Union return types are handled gracefully (no error, but return_type not set)
11+
12+
def an_union_return_type() -> Union[str, int]:
13+
return "test"
14+
15+
with Fast_API() as fast_api:
16+
fast_api.add_route_get(an_union_return_type) # Should not raise an error anymore
17+
18+
routes = fast_api.routes() # Verify the route was added successfully
19+
assert len(routes) > 0
20+
21+
our_route = None # Find our route
22+
for route in routes:
23+
if route.get('method_name') == 'an_union_return_type':
24+
our_route = route
25+
break
26+
27+
assert our_route is not None, "Route should be registered"
28+
29+
# Verify that return_type is None (Union types are skipped)
30+
assert our_route.get('return_type') is None, "Union return types should be skipped, resulting in None return_type"
31+
32+
client = fast_api.client() # Verify the route still works
33+
response = client.get('/an-union-return-type')
34+
assert response.status_code == 200
35+
36+
def test__regression__concrete_return_type_works(self): # Test that concrete return types still work correctly
37+
38+
class Schema__Response(Type_Safe):
39+
message: str
40+
41+
def concrete_return_type() -> Schema__Response:
42+
return Schema__Response(message="test")
43+
44+
with Fast_API() as fast_api:
45+
fast_api.add_route_get(concrete_return_type)
46+
47+
extractor = Fast_API__Route__Extractor(app=fast_api.app(), include_default=False) # Use Fast_API__Route__Extractor to get full route schemas
48+
routes_collection = extractor.extract_routes()
49+
50+
our_route = None # Find our route
51+
for route in routes_collection.routes:
52+
if route.method_name == 'concrete_return_type':
53+
our_route = route
54+
break
55+
56+
assert our_route is not None, "Route should be registered"
57+
58+
assert our_route.http_path == '/concrete-return-type' # Verify the route structure
59+
assert 'GET' in [m.value for m in our_route.http_methods]
60+
61+
assert our_route.return_type is not None, "Concrete return types should be captured" # Verify that return_type IS set for concrete types
62+
assert our_route.return_type == Schema__Response, "Return type should match the Type_Safe class"
63+
64+
client = fast_api.client() # Verify the route works
65+
response = client.get('/concrete-return-type')
66+
assert response.status_code == 200
67+
assert response.json() == {"message": "test"}

tests/unit/client/test_Fast_API__Client__Generator.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import tempfile
22
from pathlib import Path
33
from unittest import TestCase
4-
5-
import pytest
6-
from osbot_utils.testing.__ import __, __SKIP__
7-
8-
from osbot_fast_api.api.schemas.Schema__Fast_API__Config import Schema__Fast_API__Config
9-
from osbot_utils.testing.Stdout import Stdout
10-
from osbot_utils.utils.Misc import list_set
11-
4+
from osbot_fast_api.api.schemas.Schema__Fast_API__Config import Schema__Fast_API__Config
5+
from osbot_utils.testing.Stdout import Stdout
6+
from osbot_utils.utils.Misc import list_set
127
from osbot_fast_api.client.Fast_API__Client__Generator import Fast_API__Client__Generator
138
from osbot_fast_api.client.Fast_API__Contract__Extractor import Fast_API__Contract__Extractor
149
from osbot_fast_api.client.schemas.Schema__Service__Contract import Schema__Service__Contract
15-
from osbot_fast_api.utils.Version import version__osbot_fast_api
10+
from osbot_fast_api.utils.Version import version__osbot_fast_api
1611
from osbot_utils.utils.Objects import base_classes
1712
from osbot_utils.type_safe.Type_Safe import Type_Safe
1813
from osbot_fast_api.api.Fast_API import Fast_API

tests/unit/client/test_Fast_API__Contract__Extractor.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
from unittest import TestCase
22
from fastapi import HTTPException
3-
4-
from osbot_fast_api.api.routes.Fast_API__Routes import Fast_API__Routes
5-
from osbot_fast_api.api.schemas.Schema__Fast_API__Config import Schema__Fast_API__Config
63
from osbot_fast_api.client.schemas.Schema__Endpoint__Param import Schema__Endpoint__Param
74
from osbot_fast_api.api.schemas.Schema__Fast_API__Tag__Classes_And_Routes import Schema__Fast_API__Tag__Classes_And_Routes
85
from osbot_fast_api.api.schemas.Schema__Fast_API__Tags__Classes_And_Routes import Schema__Fast__API_Tags__Classes_And_Routes

0 commit comments

Comments
 (0)