stoobly-agent 0.21.0__py3-none-any.whl → 0.22.3__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.
- stoobly_agent/__init__.py +2 -1
- stoobly_agent/app/api/bodies_controller.py +2 -2
- stoobly_agent/app/api/requests_controller.py +51 -29
- stoobly_agent/app/api/simple_http_request_handler.py +1 -1
- stoobly_agent/app/cli/ca_cert_installer.py +16 -5
- stoobly_agent/app/cli/config_cli.py +225 -135
- stoobly_agent/app/cli/dev_tools_cli.py +3 -1
- stoobly_agent/app/cli/helpers/__init__.py +2 -1
- stoobly_agent/app/cli/helpers/context.py +7 -0
- stoobly_agent/app/cli/helpers/handle_mock_service.py +14 -0
- stoobly_agent/app/cli/helpers/print_service.py +8 -0
- stoobly_agent/app/cli/helpers/scenario_facade.py +10 -28
- stoobly_agent/app/cli/intercept.py +46 -2
- stoobly_agent/app/cli/main_group.py +8 -9
- stoobly_agent/app/cli/project_cli.py +10 -27
- stoobly_agent/app/cli/request_cli.py +14 -18
- stoobly_agent/app/cli/scenario_cli.py +94 -87
- stoobly_agent/app/models/adapters/mitmproxy/__init__.py +2 -0
- stoobly_agent/app/models/adapters/mitmproxy/request/__init__.py +12 -0
- stoobly_agent/app/models/adapters/mitmproxy/request/python_adapter.py +16 -0
- stoobly_agent/app/models/adapters/mitmproxy/response/__init__.py +12 -0
- stoobly_agent/app/models/adapters/mitmproxy/response/python_adapter.py +24 -0
- stoobly_agent/app/models/adapters/python/__init__.py +2 -0
- stoobly_agent/app/models/adapters/python/request/__init__.py +18 -0
- stoobly_agent/app/models/adapters/python/request/mitmproxy_adapter.py +53 -0
- stoobly_agent/app/models/adapters/python/request/stoobly_adapter.py +49 -0
- stoobly_agent/app/models/adapters/python/response/__init__.py +13 -0
- stoobly_agent/app/models/adapters/{mitmproxy_response_adapter.py → python/response/mitmproxy_adapter.py} +15 -7
- stoobly_agent/app/models/adapters/raw_http_request_adapter.py +19 -12
- stoobly_agent/app/models/adapters/raw_http_response_adapter.py +22 -12
- stoobly_agent/app/models/adapters/stoobly/request/__init__.py +11 -0
- stoobly_agent/app/models/adapters/stoobly/request/mitmproxy_adapter.py +32 -0
- stoobly_agent/app/models/body_model.py +2 -2
- stoobly_agent/app/models/factories/__init__.py +0 -0
- stoobly_agent/app/models/factories/resource/__init__.py +0 -0
- stoobly_agent/app/models/{adapters/body_adapter_factory.py → factories/resource/body.py} +1 -1
- stoobly_agent/app/models/{adapters/header_adapter_factory.py → factories/resource/header.py} +1 -1
- stoobly_agent/app/models/factories/resource/local_db/__init__.py +0 -0
- stoobly_agent/app/models/{adapters → factories/resource}/local_db/header_adapter.py +2 -2
- stoobly_agent/app/models/{adapters → factories/resource}/local_db/replayed_response_adapter.py +1 -2
- stoobly_agent/app/models/{adapters → factories/resource}/local_db/request_adapter.py +15 -8
- stoobly_agent/app/models/{adapters → factories/resource}/local_db/scenario_adapter.py +13 -7
- stoobly_agent/app/models/{adapters/query_param_adapter_factory.py → factories/resource/query_param.py} +1 -1
- stoobly_agent/app/models/{adapters/replayed_response_adapter_factory.py → factories/resource/replayed_response.py} +1 -1
- stoobly_agent/app/models/{adapters/request_adapter_factory.py → factories/resource/request.py} +2 -2
- stoobly_agent/app/models/{adapters/response_adapter_factory.py → factories/resource/response.py} +1 -1
- stoobly_agent/app/models/{adapters/response_header_adapter_factory.py → factories/resource/response_header.py} +1 -1
- stoobly_agent/app/models/{adapters/scenario_adapter_factory.py → factories/resource/scenario.py} +2 -2
- stoobly_agent/app/models/factories/resource/stoobly/__init__.py +0 -0
- stoobly_agent/app/models/{adapters/stoobly_request_adapter.py → factories/resource/stoobly/request_adapter.py} +1 -2
- stoobly_agent/app/models/{adapters/stoobly_scenario_adapter.py → factories/resource/stoobly/scenario_adapter.py} +1 -2
- stoobly_agent/app/models/header_model.py +2 -2
- stoobly_agent/app/models/query_param_model.py +2 -2
- stoobly_agent/app/models/replayed_response_model.py +2 -2
- stoobly_agent/app/models/request_model.py +4 -5
- stoobly_agent/app/models/response_header_model.py +2 -2
- stoobly_agent/app/models/response_model.py +2 -2
- stoobly_agent/app/models/scenario_model.py +4 -4
- stoobly_agent/app/models/schemas/request.py +8 -1
- stoobly_agent/app/models/types/__init__.py +6 -0
- stoobly_agent/app/proxy/__init__.py +0 -5
- stoobly_agent/app/proxy/handle_mock_service.py +0 -3
- stoobly_agent/app/proxy/handle_test_service.py +1 -1
- stoobly_agent/app/proxy/intercept_handler.py +0 -1
- stoobly_agent/app/proxy/mitmproxy/flow_mock.py +35 -0
- stoobly_agent/app/proxy/mitmproxy/request_facade.py +11 -2
- stoobly_agent/app/proxy/mock/hashed_request_decorator.py +2 -2
- stoobly_agent/app/proxy/replay/replay_request_service.py +58 -40
- stoobly_agent/app/proxy/simulate_intercept_service.py +30 -0
- stoobly_agent/app/proxy/test/__init__.py +1 -0
- stoobly_agent/app/proxy/test/context.py +2 -1
- stoobly_agent/app/proxy/test/context_abc.py +155 -0
- stoobly_agent/app/proxy/test/matchers/context.py +1 -1
- stoobly_agent/app/proxy/test/matchers/contract.py +1 -1
- stoobly_agent/app/proxy/test/matchers/custom.py +1 -1
- stoobly_agent/app/proxy/test/matchers/diff.py +1 -1
- stoobly_agent/app/proxy/test/matchers/fuzzy.py +1 -1
- stoobly_agent/app/proxy/test/test_service.py +1 -1
- stoobly_agent/app/proxy/upload/joined_request.py +0 -1
- stoobly_agent/app/proxy/upload/proxy_request.py +4 -1
- stoobly_agent/app/proxy/upload/request_string.py +1 -1
- stoobly_agent/app/settings/constants/mode.py +3 -0
- stoobly_agent/app/settings/data_settings.py +3 -1
- stoobly_agent/cli.py +89 -11
- stoobly_agent/config/constants/env_vars.py +2 -1
- stoobly_agent/config/data_dir.py +29 -8
- stoobly_agent/config/settings.yml.sample +1 -1
- stoobly_agent/db/migrations/2022_12_12_092437_align_requests.py +4 -4
- stoobly_agent/lib/api/api.py +4 -4
- stoobly_agent/lib/api/keys/organization_key.py +2 -0
- stoobly_agent/lib/api/keys/project_key.py +13 -0
- stoobly_agent/lib/api/keys/resource_key.py +5 -3
- stoobly_agent/lib/api/scenarios_resource.py +4 -12
- stoobly_agent/lib/api/stoobly_api.py +9 -5
- stoobly_agent/lib/orm/__init__.py +1 -1
- stoobly_agent/lib/orm/migrate_service.py +28 -13
- stoobly_agent/lib/orm/replayed_response.py +3 -3
- stoobly_agent/lib/orm/request.py +25 -5
- stoobly_agent/lib/orm/transformers/orm_to_stoobly_request_transformer.py +15 -24
- stoobly_agent/mock.py +94 -0
- stoobly_agent/public/{2-es2015.3d54569af612a07a2e06.js → 1-es2015.37917aa26708d8f35d36.js} +1 -1
- stoobly_agent/public/{2-es5.3d54569af612a07a2e06.js → 1-es5.37917aa26708d8f35d36.js} +1 -1
- stoobly_agent/public/10-es2015.e9556b0d0f0e92fb548b.js +1 -0
- stoobly_agent/public/10-es5.e9556b0d0f0e92fb548b.js +1 -0
- stoobly_agent/public/11-es2015.bc6212fccbe72a623f81.js +1 -0
- stoobly_agent/public/11-es5.bc6212fccbe72a623f81.js +1 -0
- stoobly_agent/public/{13-es2015.76b6c147b0c46f995cd7.js → 12-es2015.d0768894ddffd6efa5e5.js} +1 -1
- stoobly_agent/public/{13-es5.76b6c147b0c46f995cd7.js → 12-es5.d0768894ddffd6efa5e5.js} +1 -1
- stoobly_agent/public/13-es2015.8a044490a76fd298162d.js +1 -0
- stoobly_agent/public/13-es5.8a044490a76fd298162d.js +1 -0
- stoobly_agent/public/{15-es2015.60c3b41c385f5bdedb7b.js → 14-es2015.1cd1a021e51ca0e62e1c.js} +1 -1
- stoobly_agent/public/{15-es5.60c3b41c385f5bdedb7b.js → 14-es5.1cd1a021e51ca0e62e1c.js} +1 -1
- stoobly_agent/public/{16-es2015.5d395009a77978db4405.js → 15-es2015.587781d19864ff0eb4f5.js} +1 -1
- stoobly_agent/public/{16-es5.5d395009a77978db4405.js → 15-es5.587781d19864ff0eb4f5.js} +1 -1
- stoobly_agent/public/16-es2015.ec6a175b1f9578203cd8.js +1 -0
- stoobly_agent/public/16-es5.ec6a175b1f9578203cd8.js +1 -0
- stoobly_agent/public/17-es2015.ad9c4756c96a15bd29d7.js +1 -0
- stoobly_agent/public/17-es5.ad9c4756c96a15bd29d7.js +1 -0
- stoobly_agent/public/{19-es2015.517f68e08f4c582dae66.js → 18-es2015.8583df0f8eccb3e47c0b.js} +1 -1
- stoobly_agent/public/{19-es5.517f68e08f4c582dae66.js → 18-es5.8583df0f8eccb3e47c0b.js} +1 -1
- stoobly_agent/public/{20-es2015.473486aabfa4d4a6431b.js → 19-es2015.d0225852a844dc03a09f.js} +1 -1
- stoobly_agent/public/{20-es5.473486aabfa4d4a6431b.js → 19-es5.d0225852a844dc03a09f.js} +1 -1
- stoobly_agent/public/{3-es5.1dad290844ea619e4c16.js → 2-es2015.8f184ac63348ba447b1f.js} +1 -1
- stoobly_agent/public/{3-es2015.1dad290844ea619e4c16.js → 2-es5.8f184ac63348ba447b1f.js} +1 -1
- stoobly_agent/public/{21-es2015.56aa10803cc1348a55a3.js → 20-es2015.f7c107847935264d58aa.js} +1 -1
- stoobly_agent/public/{21-es5.56aa10803cc1348a55a3.js → 20-es5.f7c107847935264d58aa.js} +1 -1
- stoobly_agent/public/{22-es2015.46d81010003b2a50eeab.js → 21-es2015.dd358e1edaf3d32dd2c0.js} +1 -1
- stoobly_agent/public/{22-es5.46d81010003b2a50eeab.js → 21-es5.dd358e1edaf3d32dd2c0.js} +1 -1
- stoobly_agent/public/26-es2015.6332c32f1b7c8c288f2f.js +1 -0
- stoobly_agent/public/26-es5.6332c32f1b7c8c288f2f.js +1 -0
- stoobly_agent/public/27-es2015.af505e744b0c869a93d1.js +1 -0
- stoobly_agent/public/27-es5.af505e744b0c869a93d1.js +1 -0
- stoobly_agent/public/28-es2015.7c7c0f64e4af29d2e4d4.js +1 -0
- stoobly_agent/public/28-es5.7c7c0f64e4af29d2e4d4.js +1 -0
- stoobly_agent/public/32-es2015.2ab8267be7275dee9059.js +1 -0
- stoobly_agent/public/32-es5.2ab8267be7275dee9059.js +1 -0
- stoobly_agent/public/{34-es2015.ef24f6f7630620a38b19.js → 33-es2015.5b575f3a87c6c2c6b93b.js} +1 -1
- stoobly_agent/public/{34-es5.ef24f6f7630620a38b19.js → 33-es5.5b575f3a87c6c2c6b93b.js} +1 -1
- stoobly_agent/public/{35-es2015.0667e742725cc828f59f.js → 34-es2015.6a1160649c718cdb9338.js} +1 -1
- stoobly_agent/public/{35-es5.0667e742725cc828f59f.js → 34-es5.6a1160649c718cdb9338.js} +1 -1
- stoobly_agent/public/35-es2015.1b9dc7a46a6d5296c3ae.js +1 -0
- stoobly_agent/public/35-es5.1b9dc7a46a6d5296c3ae.js +1 -0
- stoobly_agent/public/{37-es2015.50d0c2d3fe4d0a74fc8f.js → 36-es2015.2fc9151fe6a5ff2bff31.js} +1 -1
- stoobly_agent/public/{37-es5.50d0c2d3fe4d0a74fc8f.js → 36-es5.2fc9151fe6a5ff2bff31.js} +1 -1
- stoobly_agent/public/{38-es2015.c14bde0b8d0cc14e915e.js → 37-es2015.ac7108c3625fd6e1d981.js} +1 -1
- stoobly_agent/public/{38-es5.c14bde0b8d0cc14e915e.js → 37-es5.ac7108c3625fd6e1d981.js} +1 -1
- stoobly_agent/public/38-es2015.9c183b14373c0e449932.js +1 -0
- stoobly_agent/public/38-es5.9c183b14373c0e449932.js +1 -0
- stoobly_agent/public/39-es2015.4624cdeb29fe9850b216.js +1 -0
- stoobly_agent/public/39-es5.4624cdeb29fe9850b216.js +1 -0
- stoobly_agent/public/40-es2015.24d981230c0c8f369cde.js +1 -0
- stoobly_agent/public/40-es5.24d981230c0c8f369cde.js +1 -0
- stoobly_agent/public/{46-es2015.abc7e4fd207d54277fcb.js → 45-es2015.c76937ed45d460bcd36f.js} +1 -1
- stoobly_agent/public/{46-es5.abc7e4fd207d54277fcb.js → 45-es5.c76937ed45d460bcd36f.js} +1 -1
- stoobly_agent/public/6-es2015.53acc5d2ca7f48ef857f.js +1 -0
- stoobly_agent/public/6-es5.53acc5d2ca7f48ef857f.js +1 -0
- stoobly_agent/public/7-es2015.1c6b3d315d50ccd228cb.js +1 -0
- stoobly_agent/public/7-es5.1c6b3d315d50ccd228cb.js +1 -0
- stoobly_agent/public/{9-es2015.ef0f7cb32f5fadb085d0.js → 8-es2015.0fe7492f7b61eb4699b6.js} +1 -1
- stoobly_agent/public/{9-es5.ef0f7cb32f5fadb085d0.js → 8-es5.0fe7492f7b61eb4699b6.js} +1 -1
- stoobly_agent/public/common-es2015.86f70de6df2c705a87f6.js +1 -0
- stoobly_agent/public/common-es5.86f70de6df2c705a87f6.js +1 -0
- stoobly_agent/public/dashboard.agent-alpha-0.22.3.tar.gz +0 -0
- stoobly_agent/public/index.html +1 -1
- stoobly_agent/public/main-es2015.aceb967cb4cccc0bc521.js +1 -0
- stoobly_agent/public/main-es5.aceb967cb4cccc0bc521.js +1 -0
- stoobly_agent/public/{polyfills-es2015.2b40b2ecdf98a9210572.js → polyfills-es2015.580f7a6e775c2c348c9d.js} +1 -1
- stoobly_agent/public/{polyfills-es5.d9fb2eee68607c3f7f64.js → polyfills-es5.4c3461a071d35be3dd81.js} +1 -1
- stoobly_agent/public/runtime-es2015.49eaebd2913fa7fe2b97.js +1 -0
- stoobly_agent/public/runtime-es5.49eaebd2913fa7fe2b97.js +1 -0
- stoobly_agent/test/test_helper.py +4 -5
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/METADATA +1 -1
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/RECORD +186 -168
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/WHEEL +1 -1
- stoobly_agent/app/models/adapters/mitmproxy_request_adapter.py +0 -60
- stoobly_agent/app/models/adapters/types/__init__.py +0 -3
- stoobly_agent/public/11-es2015.b85bdc528bab0ee542fe.js +0 -1
- stoobly_agent/public/11-es5.b85bdc528bab0ee542fe.js +0 -1
- stoobly_agent/public/12-es2015.72399d40488de533bb97.js +0 -1
- stoobly_agent/public/12-es5.72399d40488de533bb97.js +0 -1
- stoobly_agent/public/14-es2015.7cedfd0829bd7a64677a.js +0 -1
- stoobly_agent/public/14-es5.7cedfd0829bd7a64677a.js +0 -1
- stoobly_agent/public/17-es2015.f6f28ba9f681063632a8.js +0 -1
- stoobly_agent/public/17-es5.f6f28ba9f681063632a8.js +0 -1
- stoobly_agent/public/18-es2015.b0cd6822ebd1090b0d60.js +0 -1
- stoobly_agent/public/18-es5.b0cd6822ebd1090b0d60.js +0 -1
- stoobly_agent/public/27-es2015.4635450ff709f7868796.js +0 -1
- stoobly_agent/public/27-es5.4635450ff709f7868796.js +0 -1
- stoobly_agent/public/28-es2015.1b29b35529772ab108f1.js +0 -1
- stoobly_agent/public/28-es5.1b29b35529772ab108f1.js +0 -1
- stoobly_agent/public/32-es2015.862b67803e6242451976.js +0 -1
- stoobly_agent/public/32-es5.862b67803e6242451976.js +0 -1
- stoobly_agent/public/33-es2015.4ff4325d1aec37e1b43c.js +0 -1
- stoobly_agent/public/33-es5.4ff4325d1aec37e1b43c.js +0 -1
- stoobly_agent/public/36-es2015.cd370fdf8990019d0c8e.js +0 -1
- stoobly_agent/public/36-es5.cd370fdf8990019d0c8e.js +0 -1
- stoobly_agent/public/39-es2015.4ec5fc16202c4759eac4.js +0 -1
- stoobly_agent/public/39-es5.4ec5fc16202c4759eac4.js +0 -1
- stoobly_agent/public/40-es2015.25287ce77b40050f3471.js +0 -1
- stoobly_agent/public/40-es5.25287ce77b40050f3471.js +0 -1
- stoobly_agent/public/45-es2015.fd110741ac0fbaada177.js +0 -1
- stoobly_agent/public/45-es5.fd110741ac0fbaada177.js +0 -1
- stoobly_agent/public/6-es2015.7219d596e3545ebaed3a.js +0 -1
- stoobly_agent/public/6-es5.7219d596e3545ebaed3a.js +0 -1
- stoobly_agent/public/7-es2015.98b085349ebd9d246060.js +0 -1
- stoobly_agent/public/7-es5.98b085349ebd9d246060.js +0 -1
- stoobly_agent/public/8-es2015.335fd5c122ad083aec65.js +0 -1
- stoobly_agent/public/8-es5.335fd5c122ad083aec65.js +0 -1
- stoobly_agent/public/common-es2015.81f870bf87411a04446d.js +0 -1
- stoobly_agent/public/common-es5.81f870bf87411a04446d.js +0 -1
- stoobly_agent/public/dashboard.agent-alpha-0.21.0.tar.gz +0 -0
- stoobly_agent/public/main-es2015.575c1d17fc866d3a6649.js +0 -1
- stoobly_agent/public/main-es5.575c1d17fc866d3a6649.js +0 -1
- stoobly_agent/public/runtime-es2015.8915d042dc9b55368999.js +0 -1
- stoobly_agent/public/runtime-es5.8915d042dc9b55368999.js +0 -1
- /stoobly_agent/app/models/adapters/{local_db → stoobly}/__init__.py +0 -0
- /stoobly_agent/app/models/{adapters → factories/resource}/local_db/body_adapter.py +0 -0
- /stoobly_agent/app/models/{adapters → factories/resource}/local_db/query_param_adapter.py +0 -0
- /stoobly_agent/app/models/{adapters → factories/resource}/local_db/response_adapter.py +0 -0
- /stoobly_agent/app/models/{adapters → factories/resource}/local_db/response_header_adapter.py +0 -0
- /stoobly_agent/app/models/{adapters/types → types}/replayed_response.py +0 -0
- /stoobly_agent/app/models/{adapters/types → types}/request_create_params.py +0 -0
- /stoobly_agent/app/models/{adapters/types → types}/request_show_params.py +0 -0
- /stoobly_agent/app/models/{adapters/types → types}/scenario_create_params.py +0 -0
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/LICENSE +0 -0
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/entry_points.txt +0 -0
- {stoobly_agent-0.21.0.dist-info → stoobly_agent-0.22.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
from io import BytesIO
|
2
|
+
import requests
|
3
|
+
|
4
|
+
from mitmproxy.http import Response as MitmproxyResponse
|
5
|
+
from urllib3 import HTTPResponse
|
6
|
+
|
7
|
+
class PythonResponseAdapter():
|
8
|
+
|
9
|
+
def __init__(self, response: MitmproxyResponse):
|
10
|
+
self.__response = response
|
11
|
+
|
12
|
+
def adapt(self) -> requests.Response:
|
13
|
+
response = requests.Response()
|
14
|
+
response.status_code = self.__response.status_code
|
15
|
+
response.headers = self.__response.headers
|
16
|
+
|
17
|
+
response.raw = HTTPResponse(
|
18
|
+
body=BytesIO(self.__response.raw_content),
|
19
|
+
decode_content=False,
|
20
|
+
headers=self.__response.headers,
|
21
|
+
preload_content=False
|
22
|
+
)
|
23
|
+
|
24
|
+
return response
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import pdb
|
2
|
+
import requests
|
3
|
+
|
4
|
+
from urllib.parse import parse_qs, urlparse
|
5
|
+
|
6
|
+
from .mitmproxy_adapter import MitmproxyRequestAdapter
|
7
|
+
from .stoobly_adapter import StooblyRequestAdapter
|
8
|
+
|
9
|
+
class PythonRequestAdapterFactory():
|
10
|
+
|
11
|
+
def __init__(self, request: requests.Request):
|
12
|
+
self.__request = request
|
13
|
+
|
14
|
+
def mitmproxy_request(self, http_version: str = 'HTTP/1.1'):
|
15
|
+
return MitmproxyRequestAdapter(http_version, self.__request).adapt()
|
16
|
+
|
17
|
+
def stoobly_request(self):
|
18
|
+
return StooblyRequestAdapter(self.__request).adapt()
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import pdb
|
2
|
+
import requests
|
3
|
+
|
4
|
+
from mitmproxy.http import Headers, Request as MitmproxyRequest
|
5
|
+
from urllib.parse import urlparse
|
6
|
+
|
7
|
+
class MitmproxyRequestAdapter():
|
8
|
+
|
9
|
+
def __init__(self, http_version, request: requests.Request):
|
10
|
+
self.__http_version = http_version
|
11
|
+
self.__request = request
|
12
|
+
|
13
|
+
@property
|
14
|
+
def url(self):
|
15
|
+
parsed_url = urlparse(self.__request.url)
|
16
|
+
|
17
|
+
if not parsed_url.netloc:
|
18
|
+
parsed_url = parsed_url._replace(netloc=parsed_url.path, path='')
|
19
|
+
|
20
|
+
if not parsed_url.scheme:
|
21
|
+
parsed_url = parsed_url._replace(scheme='https')
|
22
|
+
|
23
|
+
return parsed_url.geturl()
|
24
|
+
|
25
|
+
@property
|
26
|
+
def headers(self):
|
27
|
+
return Headers(**self.__decode_dict(self.__request.headers))
|
28
|
+
|
29
|
+
@property
|
30
|
+
def data(self):
|
31
|
+
_data = self.__request.data
|
32
|
+
|
33
|
+
# If no data is provided to python requests.Request, it is sent to []
|
34
|
+
if _data == []:
|
35
|
+
return b''
|
36
|
+
|
37
|
+
return _data
|
38
|
+
|
39
|
+
def adapt(self):
|
40
|
+
request = MitmproxyRequest.make(
|
41
|
+
self.__request.method,
|
42
|
+
self.url,
|
43
|
+
self.data,
|
44
|
+
self.headers,
|
45
|
+
)
|
46
|
+
request.http_version = self.__http_version
|
47
|
+
return request
|
48
|
+
|
49
|
+
def __decode_dict(self, d):
|
50
|
+
new_d = {}
|
51
|
+
for k, v in d.items():
|
52
|
+
new_d[k.decode() if isinstance(k, bytes) else k] = v.decode() if isinstance(v, bytes) else v
|
53
|
+
return new_d
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import pdb
|
2
|
+
import requests
|
3
|
+
|
4
|
+
from urllib.parse import parse_qs, urlparse
|
5
|
+
|
6
|
+
class StooblyRequestAdapter():
|
7
|
+
|
8
|
+
def __init__(self, request: requests.Request):
|
9
|
+
self.__request = request
|
10
|
+
|
11
|
+
def adapt(self):
|
12
|
+
parsed_url = urlparse(self.__request.url)
|
13
|
+
|
14
|
+
return {
|
15
|
+
'body': self.__request.data,
|
16
|
+
'headers': self.adapt_headers(),
|
17
|
+
'method': self.__request.method,
|
18
|
+
'path': parsed_url.path,
|
19
|
+
'query_params': self.adapt_query_params(parsed_url.query),
|
20
|
+
'url': self.__request.url,
|
21
|
+
}
|
22
|
+
|
23
|
+
def adapt_query_params(self, query = None):
|
24
|
+
if not query:
|
25
|
+
parsed_url = urlparse(self.__request.url)
|
26
|
+
query = parsed_url.query
|
27
|
+
|
28
|
+
_query_params = parse_qs(query)
|
29
|
+
|
30
|
+
query_params = []
|
31
|
+
for k, v in _query_params.items():
|
32
|
+
for param in v:
|
33
|
+
query_params.append({
|
34
|
+
'name': k,
|
35
|
+
'value': param,
|
36
|
+
})
|
37
|
+
|
38
|
+
return query_params
|
39
|
+
|
40
|
+
def adapt_headers(self):
|
41
|
+
headers = []
|
42
|
+
|
43
|
+
for k, v in self.__request.headers.items():
|
44
|
+
headers.append({
|
45
|
+
'name': k,
|
46
|
+
'value': v
|
47
|
+
})
|
48
|
+
|
49
|
+
return headers
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import http
|
2
|
+
import pdb
|
3
|
+
import requests
|
4
|
+
|
5
|
+
from .mitmproxy_adapter import MitmproxyResponseAdapter
|
6
|
+
|
7
|
+
class PythonResponseAdapterFactory():
|
8
|
+
|
9
|
+
def __init__(self, response: requests.Response):
|
10
|
+
self.__response = response
|
11
|
+
|
12
|
+
def mitmproxy_response(self):
|
13
|
+
return MitmproxyResponseAdapter(self.__response).adapt()
|
@@ -1,13 +1,21 @@
|
|
1
|
-
|
1
|
+
import pdb
|
2
2
|
import requests
|
3
3
|
|
4
4
|
from mitmproxy.http import Headers, Response as MitmproxyResponse
|
5
|
+
from time import time
|
6
|
+
|
7
|
+
from stoobly_agent.app.models.adapters.raw_http_request_adapter import DEFAULT_HTTP_VERSION
|
5
8
|
|
6
9
|
class MitmproxyResponseAdapter():
|
7
10
|
|
8
|
-
def __init__(self,
|
11
|
+
def __init__(self, response: requests.Response):
|
9
12
|
self.__timestamp_start = time()
|
10
|
-
|
13
|
+
|
14
|
+
if hasattr(response, 'raw'):
|
15
|
+
self.__http_version = f"HTTP/{response.raw.version / 10.0}"
|
16
|
+
else:
|
17
|
+
self.__http_version = DEFAULT_HTTP_VERSION
|
18
|
+
|
11
19
|
self.__latency = 0 # Seconds
|
12
20
|
self.__response = response
|
13
21
|
|
@@ -41,11 +49,11 @@ class MitmproxyResponseAdapter():
|
|
41
49
|
|
42
50
|
def adapt(self):
|
43
51
|
body = b''
|
44
|
-
|
45
|
-
|
46
|
-
body = self.__response.raw.data
|
47
|
-
except:
|
52
|
+
|
53
|
+
if self.__response._content_consumed or not hasattr(self.__response, 'raw'):
|
48
54
|
body = self.__response.content
|
55
|
+
else:
|
56
|
+
body = self.__response.raw.data
|
49
57
|
|
50
58
|
return MitmproxyResponse(
|
51
59
|
self.__http_version,
|
@@ -1,5 +1,8 @@
|
|
1
|
+
import pdb
|
1
2
|
import requests
|
2
3
|
|
4
|
+
from typing import Union
|
5
|
+
|
3
6
|
CRLF = b'\r\n'
|
4
7
|
DEFAULT_HTTP_VERSION = b'HTTP/1.1'
|
5
8
|
|
@@ -14,29 +17,33 @@ class RawHttpRequestAdapter():
|
|
14
17
|
colon_ind = req_lines[ind].find(b':')
|
15
18
|
header_key = req_lines[ind][:colon_ind]
|
16
19
|
header_value = req_lines[ind][colon_ind + 1:]
|
17
|
-
self.headers[header_key] = header_value
|
20
|
+
self.headers[self.__decode(header_key)] = self.__decode(header_value).strip()
|
18
21
|
ind += 1
|
19
22
|
ind += 1
|
20
23
|
data_lines = req_lines[ind:] if ind < len(req_lines) else None
|
21
24
|
self.body = CRLF.join(data_lines)
|
22
25
|
|
26
|
+
def to_request(self):
|
27
|
+
req = requests.Request(
|
28
|
+
method=self.method,
|
29
|
+
url=self.url,
|
30
|
+
headers=self.headers,
|
31
|
+
data=self.body
|
32
|
+
)
|
33
|
+
|
34
|
+
return req
|
35
|
+
|
23
36
|
def __parse_request_line(self, request_line):
|
24
37
|
request_parts = request_line.split(b' ')
|
25
|
-
self.method = request_parts[0]
|
26
|
-
self.url = request_parts[1]
|
27
|
-
self.protocol = request_parts[2] if len(request_parts) > 2 else DEFAULT_HTTP_VERSION
|
38
|
+
self.method = self.__decode(request_parts[0])
|
39
|
+
self.url = self.__decode(request_parts[1])
|
40
|
+
self.protocol = self.__decode(request_parts[2]) if len(request_parts) > 2 else DEFAULT_HTTP_VERSION
|
28
41
|
|
29
42
|
def __str__(self):
|
30
43
|
headers = CRLF.join(f'{key}: {self.headers[key]}' for key in self.headers)
|
31
44
|
return f'{self.method} {self.url} {self.protocol}{CRLF}' \
|
32
45
|
f'{headers}{CRLF}{CRLF}{self.body}'
|
33
46
|
|
34
|
-
def to_request(self):
|
35
|
-
req = requests.Request(
|
36
|
-
method=self.method,
|
37
|
-
url=self.url,
|
38
|
-
headers=self.headers,
|
39
|
-
data=self.body
|
40
|
-
)
|
41
47
|
|
42
|
-
|
48
|
+
def __decode(self, s: Union[bytes, str]) -> str:
|
49
|
+
return s if isinstance(s, str) else s.decode()
|
@@ -6,6 +6,7 @@ from io import BytesIO
|
|
6
6
|
from mitmproxy.net import encoding
|
7
7
|
from requests.structures import CaseInsensitiveDict
|
8
8
|
from typing import Union
|
9
|
+
from urllib3 import HTTPResponse
|
9
10
|
|
10
11
|
from stoobly_agent.app.proxy.mitmproxy.response import Response
|
11
12
|
from stoobly_agent.lib.orm.utils.response_parse_handler import Response as ResponseDict, ResponseParseHandler
|
@@ -17,28 +18,36 @@ class RawHttpResponseAdapter():
|
|
17
18
|
|
18
19
|
def __init__(self, req_text):
|
19
20
|
self.__req_text = req_text
|
20
|
-
|
21
|
-
def to_response(self):
|
22
21
|
req_lines = self.__req_text.split(CRLF)
|
22
|
+
|
23
23
|
self.__parse_response_line(req_lines[0])
|
24
|
+
|
24
25
|
ind = 1
|
25
|
-
headers = CaseInsensitiveDict()
|
26
|
+
self.headers = CaseInsensitiveDict()
|
26
27
|
while ind < len(req_lines) and len(req_lines[ind]) > 0:
|
27
28
|
colon_ind = req_lines[ind].find(b':')
|
28
29
|
header_key = req_lines[ind][:colon_ind]
|
29
30
|
header_value = req_lines[ind][colon_ind + 1:]
|
30
|
-
headers[self.__decode(header_key)] = self.__decode(header_value).strip()
|
31
|
+
self.headers[self.__decode(header_key)] = self.__decode(header_value).strip()
|
31
32
|
ind += 1
|
32
33
|
ind += 1
|
34
|
+
|
33
35
|
data_lines = req_lines[ind:] if ind < len(req_lines) else None
|
36
|
+
self.body = CRLF.join(data_lines)
|
34
37
|
|
38
|
+
def to_response(self):
|
35
39
|
response = requests.Response()
|
36
40
|
response.status_code = self.status
|
37
|
-
response.headers = headers
|
41
|
+
response.headers = self.headers
|
42
|
+
|
43
|
+
response.raw = HTTPResponse(
|
44
|
+
body=BytesIO(self.body),
|
45
|
+
decode_content=False,
|
46
|
+
headers=self.headers,
|
47
|
+
preload_content=False
|
48
|
+
)
|
38
49
|
|
39
|
-
|
40
|
-
body = CRLF.join(data_lines)
|
41
|
-
response.raw = self.__decode_body(body, content_encoding)
|
50
|
+
#response.raw = self.__decode_body(self.body, content_encoding)
|
42
51
|
|
43
52
|
return response
|
44
53
|
|
@@ -67,12 +76,13 @@ class RawHttpResponseAdapter():
|
|
67
76
|
|
68
77
|
def __parse_response_line(self, response_line):
|
69
78
|
response_parts = response_line.split(b' ')
|
70
|
-
self.protocol = response_parts[0] if len(response_parts) > 2 else DEFAULT_HTTP_VERSION
|
71
|
-
self.status = response_parts[1]
|
79
|
+
self.protocol = self.__decode(response_parts[0]) if len(response_parts) > 2 else DEFAULT_HTTP_VERSION
|
80
|
+
self.status = int(self.__decode(response_parts[1]))
|
81
|
+
self.reason = self.__decode(response_parts[2]) if len(response_parts) > 2 else ''
|
72
82
|
|
73
83
|
def __str__(self):
|
74
84
|
headers = CRLF.join(f'{key}: {self.headers[key]}' for key in self.headers)
|
75
|
-
return f'{self.
|
85
|
+
return f'{self.protocol} {self.status} {self.reason}{CRLF}' \
|
76
86
|
f'{headers}{CRLF}{CRLF}{self.body}'
|
77
87
|
|
78
88
|
def __new_parser(self, response_dict):
|
@@ -81,7 +91,7 @@ class RawHttpResponseAdapter():
|
|
81
91
|
parser.feed_data(memoryview(self.__req_text))
|
82
92
|
return parser
|
83
93
|
|
84
|
-
def __decode(self, s: Union[bytes, str]):
|
94
|
+
def __decode(self, s: Union[bytes, str]) -> str:
|
85
95
|
return s if isinstance(s, str) else s.decode()
|
86
96
|
|
87
97
|
def __decode_body(self, body: bytes, content_encoding):
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from lib.api.interfaces.requests import RequestShowResponse
|
2
|
+
|
3
|
+
from .mitmproxy_adapter import MitmproxyRequestAdapter
|
4
|
+
|
5
|
+
class StooblyRequestAdapterFactory():
|
6
|
+
|
7
|
+
def __init__(self, request: RequestShowResponse):
|
8
|
+
self.__request = request
|
9
|
+
|
10
|
+
def mitmproxy_request(self):
|
11
|
+
return MitmproxyRequestAdapter(self.__request)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import pdb
|
2
|
+
import requests
|
3
|
+
|
4
|
+
from mitmproxy.http import Headers, Request as MitmproxyRequest
|
5
|
+
|
6
|
+
from stoobly_agent.app.models.schemas.request import Request
|
7
|
+
|
8
|
+
class MitmproxyRequestAdapter():
|
9
|
+
|
10
|
+
def __init__(self, request: Request):
|
11
|
+
self.__http_version = 'HTTP/1.1'
|
12
|
+
self.__request = request
|
13
|
+
|
14
|
+
@property
|
15
|
+
def headers(self):
|
16
|
+
return Headers(**self.__decode_dict(self.__request.headers))
|
17
|
+
|
18
|
+
def adapt(self):
|
19
|
+
request = MitmproxyRequest.make(
|
20
|
+
self.__request.method,
|
21
|
+
self.__request.url,
|
22
|
+
self.__request.body,
|
23
|
+
self.headers,
|
24
|
+
)
|
25
|
+
request.http_version = self.__http_version
|
26
|
+
return request
|
27
|
+
|
28
|
+
def __decode_dict(self, d):
|
29
|
+
new_d = {}
|
30
|
+
for k, v in d.items():
|
31
|
+
new_d[k.decode() if isinstance(k, bytes) else k] = v.decode() if isinstance(v, bytes) else v
|
32
|
+
return new_d
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import pdb
|
2
2
|
import requests
|
3
3
|
|
4
|
-
from stoobly_agent.app.models.adapters.body_adapter_factory import BodyAdapterFactory
|
5
4
|
from stoobly_agent.app.settings import Settings
|
6
5
|
from stoobly_agent.lib.logger import Logger
|
7
6
|
|
7
|
+
from .factories.resource.body import BodyResourceFactory
|
8
8
|
from .model import Model
|
9
9
|
|
10
10
|
class BodyModel(Model):
|
@@ -13,7 +13,7 @@ class BodyModel(Model):
|
|
13
13
|
super().__init__(settings)
|
14
14
|
|
15
15
|
def as_local(self):
|
16
|
-
self.adapter =
|
16
|
+
self.adapter = BodyResourceFactory(self.settings.remote).local_db()
|
17
17
|
|
18
18
|
def as_remote(self):
|
19
19
|
# 'Not yet supported.'
|
File without changes
|
File without changes
|
File without changes
|
stoobly_agent/app/models/{adapters → factories/resource}/local_db/replayed_response_adapter.py
RENAMED
@@ -1,14 +1,13 @@
|
|
1
1
|
import pdb
|
2
2
|
import requests
|
3
3
|
|
4
|
+
from stoobly_agent.app.models.types import ReplayedResponseIndexQueryParams
|
4
5
|
from stoobly_agent.lib.api.interfaces.requests import RequestShowResponse
|
5
6
|
from stoobly_agent.lib.orm.replayed_response import ReplayedResponse
|
6
7
|
from stoobly_agent.lib.orm.transformers.orm_to_requests_response_transformer import ORMToRequestsResponseTransformer
|
7
8
|
from stoobly_agent.lib.orm.transformers.orm_to_stoobly_request_transformer import ORMToStooblyRequestTransformer
|
8
9
|
from stoobly_agent.lib.orm.utils.response_parse_handler import Response
|
9
10
|
|
10
|
-
from ..types.replayed_response import ReplayedResponseIndexQueryParams
|
11
|
-
|
12
11
|
class LocalDBReplayedResponseAdapter():
|
13
12
|
__replayed_response_orm = None
|
14
13
|
|
@@ -3,13 +3,12 @@ from urllib.parse import urlparse
|
|
3
3
|
import requests
|
4
4
|
|
5
5
|
from mitmproxy.http import HTTPFlow as MitmproxyHTTPFlow, Request as MitmproxyRequest
|
6
|
-
from typing import List
|
7
6
|
|
7
|
+
from stoobly_agent.app.models.types import RequestCreateParams, RequestShowParams
|
8
8
|
from stoobly_agent.app.proxy.mock.custom_not_found_response_builder import CustomNotFoundResponseBuilder
|
9
9
|
from stoobly_agent.app.proxy.mock.hashed_request_decorator import HashedRequestDecorator
|
10
10
|
from stoobly_agent.app.proxy.mitmproxy.request_facade import MitmproxyRequestFacade
|
11
11
|
from stoobly_agent.app.proxy.upload.joined_request import JoinedRequest
|
12
|
-
|
13
12
|
from stoobly_agent.lib.orm import ORM
|
14
13
|
from stoobly_agent.lib.orm.request import Request
|
15
14
|
from stoobly_agent.lib.orm.response import Response
|
@@ -19,8 +18,6 @@ from stoobly_agent.lib.orm.types.response_columns import ResponseColumns
|
|
19
18
|
from stoobly_agent.lib.orm.transformers import ORMToRequestsResponseTransformer, ORMToStooblyResponseTransformer
|
20
19
|
from stoobly_agent.lib.api.interfaces import RequestsIndexQueryParams, RequestsIndexResponse, RequestShowResponse
|
21
20
|
|
22
|
-
from ..types import RequestCreateParams, RequestShowParams
|
23
|
-
|
24
21
|
class LocalDBRequestAdapter():
|
25
22
|
__request_orm = None
|
26
23
|
__response_orm = None
|
@@ -73,14 +70,23 @@ class LocalDBRequestAdapter():
|
|
73
70
|
def show(self, request_id: str, **options: RequestShowParams) -> RequestShowResponse:
|
74
71
|
request = self.__request_orm.find(request_id)
|
75
72
|
|
73
|
+
if not request:
|
74
|
+
return CustomNotFoundResponseBuilder().build()
|
75
|
+
|
76
76
|
return ORMToStooblyRequestTransformer(request, options).transform()
|
77
77
|
|
78
78
|
def response(self, **query_params: RequestColumns) -> requests.Response:
|
79
|
-
|
80
|
-
|
79
|
+
request = None
|
80
|
+
|
81
|
+
if not query_params.get('request_id'):
|
82
|
+
request_columns = { **query_params }
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
+
self.__filter_request_response_columns(request_columns)
|
85
|
+
|
86
|
+
# Find most recent matching record
|
87
|
+
request = self.__request_orm.where_for(**request_columns).get().last()
|
88
|
+
else:
|
89
|
+
request = self.__request_orm.find(query_params.get('request_id'))
|
84
90
|
|
85
91
|
if not request:
|
86
92
|
return CustomNotFoundResponseBuilder().build()
|
@@ -107,6 +113,7 @@ class LocalDBRequestAdapter():
|
|
107
113
|
|
108
114
|
if scenario_id:
|
109
115
|
requests = requests.where('scenario_id', int(scenario_id))
|
116
|
+
sort_order = query_params.get('sort_order') or 'asc'
|
110
117
|
|
111
118
|
if starred:
|
112
119
|
requests = requests.where('starred', starred)
|
@@ -1,13 +1,11 @@
|
|
1
1
|
import pdb
|
2
2
|
|
3
|
-
from stoobly_agent.app.models.
|
3
|
+
from stoobly_agent.app.models.types import ScenarioCreateParams
|
4
4
|
from stoobly_agent.lib.api.interfaces import ScenariosIndexQueryParams, ScenariosIndexResponse, ScenarioShowResponse
|
5
5
|
from stoobly_agent.lib.api.keys.scenario_key import ScenarioKey
|
6
6
|
from stoobly_agent.lib.orm import ORM
|
7
7
|
from stoobly_agent.lib.orm.scenario import Scenario
|
8
8
|
|
9
|
-
from ..types import ScenarioCreateParams
|
10
|
-
|
11
9
|
class LocalDBScenarioAdapter():
|
12
10
|
__scenario_orm = None
|
13
11
|
|
@@ -30,13 +28,21 @@ class LocalDBScenarioAdapter():
|
|
30
28
|
sort_by = query_params.get('sort_by') or 'id'
|
31
29
|
sort_order = query_params.get('sort_order') or 'desc'
|
32
30
|
|
33
|
-
|
34
|
-
|
31
|
+
filter = query_params.get('filter')
|
32
|
+
is_deleted = filter == 'is_deleted'
|
35
33
|
|
36
34
|
scenarios = Scenario.where('is_deleted', is_deleted)
|
37
35
|
|
38
|
-
if starred:
|
39
|
-
scenarios = scenarios.where('starred',
|
36
|
+
if filter == 'starred':
|
37
|
+
scenarios = scenarios.where('starred', True)
|
38
|
+
elif filter == 'high_priority':
|
39
|
+
scenarios = scenarios.where('priority', 3)
|
40
|
+
elif filter == 'medium_priority':
|
41
|
+
scenarios = scenarios.where('priority', 2)
|
42
|
+
elif filter == 'low_priority':
|
43
|
+
scenarios = scenarios.where('priority', 1)
|
44
|
+
elif filter == 'none_priority':
|
45
|
+
scenarios = scenarios.where('priority', 0)
|
40
46
|
|
41
47
|
if query:
|
42
48
|
scenarios = self.__search(scenarios, query)
|
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
|
|
3
3
|
|
4
4
|
from .local_db.query_param_adapter import LocalDBQueryParamAdapter
|
5
5
|
|
6
|
-
class
|
6
|
+
class QueryParamResourceFactory():
|
7
7
|
|
8
8
|
def __init__(self, settings: RemoteSettings):
|
9
9
|
self.__remote_settings = settings
|
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.replayed_response import ReplayedResponse
|
|
3
3
|
|
4
4
|
from .local_db.replayed_response_adapter import LocalDBReplayedResponseAdapter
|
5
5
|
|
6
|
-
class
|
6
|
+
class ReplayedResponseResourceFactory():
|
7
7
|
|
8
8
|
def __init__(self, settings: RemoteSettings):
|
9
9
|
self.__remote_settings = settings
|
stoobly_agent/app/models/{adapters/request_adapter_factory.py → factories/resource/request.py}
RENAMED
@@ -3,9 +3,9 @@ from stoobly_agent.lib.api.requests_resource import RequestsResource
|
|
3
3
|
from stoobly_agent.app.settings import RemoteSettings
|
4
4
|
|
5
5
|
from .local_db.request_adapter import LocalDBRequestAdapter
|
6
|
-
from .
|
6
|
+
from .stoobly.request_adapter import StooblyRequestAdapter
|
7
7
|
|
8
|
-
class
|
8
|
+
class RequestResourceFactory():
|
9
9
|
|
10
10
|
def __init__(self, settings: RemoteSettings):
|
11
11
|
self.__remote_settings = settings
|
stoobly_agent/app/models/{adapters/response_adapter_factory.py → factories/resource/response.py}
RENAMED
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
|
|
3
3
|
|
4
4
|
from .local_db.response_adapter import LocalDBResponseAdapter
|
5
5
|
|
6
|
-
class
|
6
|
+
class ResponseResourceFactory():
|
7
7
|
|
8
8
|
def __init__(self, settings: RemoteSettings):
|
9
9
|
self.__remote_settings = settings
|
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
|
|
3
3
|
|
4
4
|
from .local_db.response_header_adapter import LocalDBResponseHeaderAdapter
|
5
5
|
|
6
|
-
class
|
6
|
+
class ResponseHeaderResourceFactory():
|
7
7
|
|
8
8
|
def __init__(self, settings: RemoteSettings):
|
9
9
|
self.__remote_settings = settings
|
stoobly_agent/app/models/{adapters/scenario_adapter_factory.py → factories/resource/scenario.py}
RENAMED
@@ -3,9 +3,9 @@ from stoobly_agent.lib.api.scenarios_resource import ScenariosResource
|
|
3
3
|
from stoobly_agent.app.settings import RemoteSettings
|
4
4
|
|
5
5
|
from .local_db.scenario_adapter import LocalDBScenarioAdapter
|
6
|
-
from .
|
6
|
+
from .stoobly.scenario_adapter import StooblyScenarioAdapter
|
7
7
|
|
8
|
-
class
|
8
|
+
class ScenarioResourceFactory():
|
9
9
|
|
10
10
|
def __init__(self, settings: RemoteSettings):
|
11
11
|
self.__remote_settings = settings
|
File without changes
|
@@ -1,11 +1,10 @@
|
|
1
1
|
import pdb
|
2
2
|
import requests
|
3
3
|
|
4
|
+
from stoobly_agent.app.models.types import RequestCreateParams, RequestShowParams
|
4
5
|
from stoobly_agent.lib.api.requests_resource import RequestsResource
|
5
6
|
from stoobly_agent.lib.api.interfaces import RequestShowResponse, RequestsIndexResponse
|
6
7
|
|
7
|
-
from .types import RequestCreateParams, RequestShowParams
|
8
|
-
|
9
8
|
class StooblyRequestAdapter():
|
10
9
|
|
11
10
|
def __init__(self, __api: RequestsResource):
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import pdb
|
2
2
|
|
3
|
+
from stoobly_agent.app.models.types import ScenarioCreateParams
|
3
4
|
from stoobly_agent.lib.api.scenarios_resource import ScenariosResource
|
4
5
|
from stoobly_agent.lib.api.interfaces.scenarios import ScenarioShowResponse, ScenariosIndexResponse
|
5
6
|
|
6
|
-
from .types import ScenarioCreateParams
|
7
|
-
|
8
7
|
class StooblyScenarioAdapter():
|
9
8
|
|
10
9
|
def __init__(self, __api: ScenariosResource):
|