api-mocker 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- api_mocker/auth_system.py +44 -11
- api_mocker/cli.py +42 -1
- api_mocker/core.py +26 -6
- api_mocker/database_integration.py +35 -13
- api_mocker/graphql_mock.py +12 -3
- api_mocker/ml_integration.py +9 -2
- api_mocker/mock_responses.py +21 -28
- api_mocker/resources.py +176 -0
- api_mocker/server.py +77 -7
- api_mocker-0.5.1.dist-info/METADATA +782 -0
- {api_mocker-0.5.0.dist-info → api_mocker-0.5.1.dist-info}/RECORD +15 -14
- {api_mocker-0.5.0.dist-info → api_mocker-0.5.1.dist-info}/WHEEL +1 -1
- api_mocker-0.5.0.dist-info/METADATA +0 -477
- {api_mocker-0.5.0.dist-info → api_mocker-0.5.1.dist-info}/entry_points.txt +0 -0
- {api_mocker-0.5.0.dist-info → api_mocker-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {api_mocker-0.5.0.dist-info → api_mocker-0.5.1.dist-info}/top_level.txt +0 -0
api_mocker/server.py
CHANGED
|
@@ -4,15 +4,23 @@ import uvicorn
|
|
|
4
4
|
from typing import Optional, Dict, Any
|
|
5
5
|
from .core import CoreEngine, RouteConfig
|
|
6
6
|
from .config import ConfigLoader
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
7
10
|
|
|
8
11
|
class MockServer:
|
|
9
|
-
def __init__(self, config_path: Optional[str] = None):
|
|
12
|
+
def __init__(self, config_path: Optional[str] = None, config_data: Optional[Dict[str, Any]] = None):
|
|
10
13
|
self.app = FastAPI(title="api-mocker")
|
|
11
14
|
self.config_path = config_path
|
|
12
15
|
self.engine = CoreEngine()
|
|
13
16
|
self.config = {}
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
logging.basicConfig(level=logging.INFO)
|
|
19
|
+
|
|
20
|
+
if config_data:
|
|
21
|
+
self.config = config_data
|
|
22
|
+
self._apply_config()
|
|
23
|
+
elif config_path:
|
|
16
24
|
self.load_config(config_path)
|
|
17
25
|
|
|
18
26
|
self._setup_routes()
|
|
@@ -23,15 +31,15 @@ class MockServer:
|
|
|
23
31
|
self.config = ConfigLoader.load(config_path)
|
|
24
32
|
self._apply_config()
|
|
25
33
|
except Exception as e:
|
|
26
|
-
|
|
34
|
+
logger.error(f"Failed to load config {config_path}: {e}")
|
|
27
35
|
|
|
28
36
|
def _apply_config(self):
|
|
29
37
|
"""Apply configuration to the engine."""
|
|
30
38
|
routes_config = self.config.get("routes", [])
|
|
31
|
-
|
|
39
|
+
logger.info(f"Loading {len(routes_config)} routes from config")
|
|
32
40
|
|
|
33
41
|
for route_data in routes_config:
|
|
34
|
-
|
|
42
|
+
logger.info(f"Adding route: {route_data['method']} {route_data['path']}")
|
|
35
43
|
# Create a response function from the config
|
|
36
44
|
response_config = route_data.get("response", {})
|
|
37
45
|
|
|
@@ -51,12 +59,71 @@ class MockServer:
|
|
|
51
59
|
status_code=response_config.get("status_code", 200),
|
|
52
60
|
headers=response_config.get("headers"),
|
|
53
61
|
delay=route_data.get("delay", 0),
|
|
54
|
-
dynamic=route_data.get("dynamic", False)
|
|
62
|
+
dynamic=route_data.get("dynamic", False),
|
|
63
|
+
auth_required=route_data.get("auth", False)
|
|
55
64
|
)
|
|
56
65
|
self.engine.router.add_route(route)
|
|
57
66
|
|
|
58
67
|
print(f"Total routes loaded: {len(self.engine.router.routes)}")
|
|
59
68
|
|
|
69
|
+
# Process resources
|
|
70
|
+
resources_config = self.config.get("resources", [])
|
|
71
|
+
print(f"Loading {len(resources_config)} resources from config")
|
|
72
|
+
|
|
73
|
+
for res_config in resources_config:
|
|
74
|
+
name = res_config['name']
|
|
75
|
+
base_path = res_config['path']
|
|
76
|
+
id_field = res_config.get('id_field', 'id')
|
|
77
|
+
|
|
78
|
+
print(f"Adding resource: {name} at {base_path}")
|
|
79
|
+
|
|
80
|
+
# Import here to avoid circular imports
|
|
81
|
+
from .resources import ResourceHandler
|
|
82
|
+
handler = ResourceHandler(name, id_field)
|
|
83
|
+
|
|
84
|
+
# Add standard CRUD routes
|
|
85
|
+
# LIST
|
|
86
|
+
self.engine.router.add_route(RouteConfig(
|
|
87
|
+
path=base_path,
|
|
88
|
+
method="GET",
|
|
89
|
+
response=handler.list,
|
|
90
|
+
delay=res_config.get('delay', 0)
|
|
91
|
+
))
|
|
92
|
+
# CREATE
|
|
93
|
+
self.engine.router.add_route(RouteConfig(
|
|
94
|
+
path=base_path,
|
|
95
|
+
method="POST",
|
|
96
|
+
response=handler.create,
|
|
97
|
+
delay=res_config.get('delay', 0)
|
|
98
|
+
))
|
|
99
|
+
# GET Item
|
|
100
|
+
self.engine.router.add_route(RouteConfig(
|
|
101
|
+
path=f"{base_path}/{{id}}",
|
|
102
|
+
method="GET",
|
|
103
|
+
response=handler.get,
|
|
104
|
+
delay=res_config.get('delay', 0)
|
|
105
|
+
))
|
|
106
|
+
# UPDATE
|
|
107
|
+
self.engine.router.add_route(RouteConfig(
|
|
108
|
+
path=f"{base_path}/{{id}}",
|
|
109
|
+
method="PUT",
|
|
110
|
+
response=handler.update,
|
|
111
|
+
delay=res_config.get('delay', 0)
|
|
112
|
+
))
|
|
113
|
+
self.engine.router.add_route(RouteConfig(
|
|
114
|
+
path=f"{base_path}/{{id}}",
|
|
115
|
+
method="PATCH",
|
|
116
|
+
response=handler.update,
|
|
117
|
+
delay=res_config.get('delay', 0)
|
|
118
|
+
))
|
|
119
|
+
# DELETE
|
|
120
|
+
self.engine.router.add_route(RouteConfig(
|
|
121
|
+
path=f"{base_path}/{{id}}",
|
|
122
|
+
method="DELETE",
|
|
123
|
+
response=handler.delete,
|
|
124
|
+
delay=res_config.get('delay', 0)
|
|
125
|
+
))
|
|
126
|
+
|
|
60
127
|
def _setup_routes(self):
|
|
61
128
|
"""Set up FastAPI routes using the core engine."""
|
|
62
129
|
|
|
@@ -75,8 +142,11 @@ class MockServer:
|
|
|
75
142
|
except:
|
|
76
143
|
body = await request.body()
|
|
77
144
|
|
|
145
|
+
# Get query parameters
|
|
146
|
+
query_params = dict(request.query_params)
|
|
147
|
+
|
|
78
148
|
# Process request through core engine
|
|
79
|
-
response = self.engine.process_request(path, method, headers, body)
|
|
149
|
+
response = self.engine.process_request(path, method, headers, body, query_params)
|
|
80
150
|
|
|
81
151
|
# Return response
|
|
82
152
|
status_code = response.get("status_code", 200)
|