python-postman 0.7.0__tar.gz → 0.9.0__tar.gz

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.
Files changed (167) hide show
  1. {python_postman-0.7.0 → python_postman-0.9.0}/.github/workflows/python-publish.yml +64 -64
  2. {python_postman-0.7.0 → python_postman-0.9.0}/PKG-INFO +274 -21
  3. python_postman-0.9.0/README.md +545 -0
  4. python_postman-0.9.0/coverage.json +1 -0
  5. python_postman-0.9.0/docs/README.md +456 -0
  6. python_postman-0.9.0/docs/architecture/execution-layer.md +555 -0
  7. python_postman-0.9.0/docs/architecture/layer-interaction.md +597 -0
  8. python_postman-0.9.0/docs/architecture/model-layer.md +501 -0
  9. python_postman-0.9.0/docs/architecture/overview.md +186 -0
  10. python_postman-0.9.0/docs/examples/description-usage.py +434 -0
  11. python_postman-0.9.0/docs/examples/generate-documentation.py +439 -0
  12. python_postman-0.9.0/docs/examples/parse-inspect-modify-execute.py +325 -0
  13. python_postman-0.9.0/docs/examples/variable-introspection.py +313 -0
  14. python_postman-0.9.0/docs/guides/decision-tree.md +587 -0
  15. python_postman-0.9.0/docs/guides/description-fields.md +425 -0
  16. python_postman-0.9.0/docs/guides/optional-dependencies.md +685 -0
  17. python_postman-0.9.0/docs/guides/troubleshooting.md +810 -0
  18. python_postman-0.9.0/docs/guides/variable-scoping.md +471 -0
  19. python_postman-0.9.0/examples/README.md +308 -0
  20. python_postman-0.9.0/examples/advanced_execution.py +177 -0
  21. python_postman-0.9.0/examples/auth_resolution_example.py +186 -0
  22. python_postman-0.9.0/examples/authentication_examples.py +187 -0
  23. python_postman-0.9.0/examples/basic_execution.py +67 -0
  24. python_postman-0.9.0/examples/cftc_execution_example.py +240 -0
  25. python_postman-0.9.0/examples/complete_workflow.py +440 -0
  26. python_postman-0.9.0/examples/multi_collection_execution.py +185 -0
  27. python_postman-0.9.0/examples/path_parameters_example.py +304 -0
  28. python_postman-0.9.0/examples/projects/README.md +48 -0
  29. python_postman-0.9.0/examples/projects/microservices-testing/README.md +48 -0
  30. python_postman-0.9.0/examples/projects/microservices-testing/collections/auth-service.json +55 -0
  31. python_postman-0.9.0/examples/projects/microservices-testing/collections/order-service.json +60 -0
  32. python_postman-0.9.0/examples/projects/microservices-testing/collections/user-service.json +59 -0
  33. python_postman-0.9.0/examples/projects/microservices-testing/environments/microservices.json +30 -0
  34. python_postman-0.9.0/examples/projects/microservices-testing/main.py +73 -0
  35. python_postman-0.9.0/examples/projects/rest-api-testing/README.md +63 -0
  36. python_postman-0.9.0/examples/projects/rest-api-testing/collections/rest-api.json +110 -0
  37. python_postman-0.9.0/examples/projects/rest-api-testing/environments/dev.json +15 -0
  38. python_postman-0.9.0/examples/projects/rest-api-testing/environments/prod.json +15 -0
  39. python_postman-0.9.0/examples/projects/rest-api-testing/main.py +48 -0
  40. python_postman-0.9.0/examples/projects/rest-api-testing/requirements.txt +2 -0
  41. python_postman-0.9.0/examples/projects/rest-api-testing/tests/test_rest_api.py +39 -0
  42. python_postman-0.9.0/examples/request_convenience_methods.py +175 -0
  43. python_postman-0.9.0/examples/search_example.py +113 -0
  44. python_postman-0.9.0/examples/statistics_example.py +92 -0
  45. python_postman-0.9.0/examples/synchronous_execution.py +134 -0
  46. python_postman-0.9.0/examples/usage_patterns.py +361 -0
  47. python_postman-0.9.0/examples/variable_examples.py +206 -0
  48. {python_postman-0.7.0 → python_postman-0.9.0}/pyproject.toml +16 -2
  49. python_postman-0.9.0/python_postman/__init__.py +195 -0
  50. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/exceptions/__init__.py +2 -0
  51. python_postman-0.9.0/python_postman/exceptions/schema_error.py +35 -0
  52. python_postman-0.9.0/python_postman/execution/__init__.py +64 -0
  53. python_postman-0.9.0/python_postman/execution/auth_handler.py +245 -0
  54. python_postman-0.9.0/python_postman/execution/context.py +341 -0
  55. python_postman-0.9.0/python_postman/execution/exceptions.py +208 -0
  56. python_postman-0.9.0/python_postman/execution/executor.py +781 -0
  57. python_postman-0.9.0/python_postman/execution/extensions.py +420 -0
  58. python_postman-0.9.0/python_postman/execution/response.py +165 -0
  59. python_postman-0.9.0/python_postman/execution/results.py +250 -0
  60. python_postman-0.9.0/python_postman/execution/script_runner.py +468 -0
  61. python_postman-0.9.0/python_postman/execution/variable_resolver.py +339 -0
  62. python_postman-0.9.0/python_postman/introspection/__init__.py +14 -0
  63. python_postman-0.9.0/python_postman/introspection/auth_resolver.py +135 -0
  64. python_postman-0.9.0/python_postman/introspection/variable_tracer.py +475 -0
  65. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/__init__.py +9 -0
  66. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/auth.py +34 -2
  67. python_postman-0.9.0/python_postman/models/collection.py +495 -0
  68. python_postman-0.9.0/python_postman/models/cookie.py +495 -0
  69. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/folder.py +38 -2
  70. python_postman-0.9.0/python_postman/models/item.py +232 -0
  71. python_postman-0.9.0/python_postman/models/request.py +599 -0
  72. python_postman-0.9.0/python_postman/models/response.py +345 -0
  73. python_postman-0.9.0/python_postman/models/schema.py +144 -0
  74. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/url.py +29 -3
  75. python_postman-0.9.0/python_postman/search/__init__.py +7 -0
  76. python_postman-0.9.0/python_postman/search/query.py +285 -0
  77. python_postman-0.9.0/python_postman/statistics/__init__.py +7 -0
  78. python_postman-0.9.0/python_postman/statistics/collector.py +327 -0
  79. python_postman-0.9.0/python_postman/types/__init__.py +13 -0
  80. python_postman-0.9.0/python_postman/types/auth_types.py +41 -0
  81. python_postman-0.9.0/python_postman/types/http_methods.py +39 -0
  82. python_postman-0.9.0/test_execution_summary.md +459 -0
  83. python_postman-0.9.0/tests/execution_tests/CFTC_TEST_SUMMARY.md +342 -0
  84. python_postman-0.9.0/tests/execution_tests/INDEX.md +239 -0
  85. python_postman-0.9.0/tests/execution_tests/QUICK_START_CFTC.md +127 -0
  86. python_postman-0.9.0/tests/execution_tests/README_CFTC_TESTS.md +357 -0
  87. python_postman-0.9.0/tests/execution_tests/example_cftc_usage.py +265 -0
  88. python_postman-0.9.0/tests/execution_tests/test_cftc_comprehensive.py +839 -0
  89. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_auth.py +12 -18
  90. python_postman-0.9.0/tests/test_auth_handler.py +560 -0
  91. python_postman-0.9.0/tests/test_auth_resolver.py +561 -0
  92. python_postman-0.9.0/tests/test_collection.py +329 -0
  93. python_postman-0.9.0/tests/test_cookie.py +574 -0
  94. python_postman-0.9.0/tests/test_data/README_integration_tests.md +160 -0
  95. python_postman-0.9.0/tests/test_data/auth_execution_collection.json +324 -0
  96. python_postman-0.9.0/tests/test_data/cftc.gov.postman_collection.json +99 -0
  97. python_postman-0.9.0/tests/test_data/error_scenarios_collection.json +349 -0
  98. python_postman-0.9.0/tests/test_data/execution_collection.json +285 -0
  99. python_postman-0.9.0/tests/test_data/nested_execution_collection.json +355 -0
  100. python_postman-0.9.0/tests/test_data/performance_collection.json +377 -0
  101. python_postman-0.9.0/tests/test_description_fields.py +389 -0
  102. python_postman-0.9.0/tests/test_edge_cases.py +972 -0
  103. python_postman-0.9.0/tests/test_edge_cases.py.bak +963 -0
  104. python_postman-0.9.0/tests/test_edge_cases_summary.md +121 -0
  105. python_postman-0.9.0/tests/test_execution_context.py +291 -0
  106. python_postman-0.9.0/tests/test_execution_exceptions.py +482 -0
  107. python_postman-0.9.0/tests/test_execution_reporter.py +268 -0
  108. python_postman-0.9.0/tests/test_executor.py +1917 -0
  109. python_postman-0.9.0/tests/test_extensions.py +587 -0
  110. python_postman-0.9.0/tests/test_imports.py +348 -0
  111. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_integration.py +8 -8
  112. python_postman-0.9.0/tests/test_item_clarity.py +221 -0
  113. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_parser.py +33 -10
  114. python_postman-0.9.0/tests/test_request_convenience.py +538 -0
  115. python_postman-0.9.0/tests/test_request_execution.py +279 -0
  116. python_postman-0.9.0/tests/test_request_responses.py +309 -0
  117. python_postman-0.9.0/tests/test_response.py +485 -0
  118. python_postman-0.9.0/tests/test_response_cookies.py +245 -0
  119. python_postman-0.9.0/tests/test_schema.py +289 -0
  120. python_postman-0.9.0/tests/test_script_runner.py +552 -0
  121. python_postman-0.9.0/tests/test_search.py +396 -0
  122. python_postman-0.9.0/tests/test_statistics.py +416 -0
  123. python_postman-0.9.0/tests/test_type_safety.py +192 -0
  124. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_url.py +15 -7
  125. python_postman-0.9.0/tests/test_variable_resolver.py +547 -0
  126. python_postman-0.9.0/tests/test_variable_tracer.py +522 -0
  127. {python_postman-0.7.0 → python_postman-0.9.0}/uv.lock +117 -1
  128. python_postman-0.7.0/README.md +0 -296
  129. python_postman-0.7.0/python_postman/__init__.py +0 -85
  130. python_postman-0.7.0/python_postman/models/collection.py +0 -292
  131. python_postman-0.7.0/python_postman/models/item.py +0 -44
  132. python_postman-0.7.0/python_postman/models/request.py +0 -147
  133. python_postman-0.7.0/tests/test_collection.py +0 -119
  134. {python_postman-0.7.0 → python_postman-0.9.0}/.gitignore +0 -0
  135. {python_postman-0.7.0 → python_postman-0.9.0}/LICENSE +0 -0
  136. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/exceptions/base.py +0 -0
  137. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/exceptions/file_error.py +0 -0
  138. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/exceptions/parse_error.py +0 -0
  139. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/exceptions/validation_error.py +0 -0
  140. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/body.py +0 -0
  141. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/collection_info.py +0 -0
  142. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/event.py +0 -0
  143. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/header.py +0 -0
  144. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/models/variable.py +0 -0
  145. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/parser.py +0 -0
  146. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/utils/__init__.py +0 -0
  147. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/utils/json_parser.py +0 -0
  148. {python_postman-0.7.0 → python_postman-0.9.0}/python_postman/utils/validators.py +0 -0
  149. {python_postman-0.7.0 → python_postman-0.9.0}/tests/__init__.py +0 -0
  150. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_body.py +0 -0
  151. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_collection_info.py +0 -0
  152. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/README.md +0 -0
  153. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/auth_collection.json +0 -0
  154. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/empty_collection.json +0 -0
  155. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/events_collection.json +0 -0
  156. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/invalid_collection.json +0 -0
  157. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/malformed_json.json +0 -0
  158. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/nested_collection.json +0 -0
  159. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_data/simple_collection.json +0 -0
  160. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_event.py +0 -0
  161. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_exceptions.py +0 -0
  162. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_folder.py +0 -0
  163. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_header.py +0 -0
  164. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_item.py +0 -0
  165. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_json_parser.py +0 -0
  166. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_request.py +0 -0
  167. {python_postman-0.7.0 → python_postman-0.9.0}/tests/test_variable.py +0 -0
@@ -1,65 +1,65 @@
1
- # This workflow will upload a Python Package to PyPI when a release is published
2
- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
-
4
- name: Publish Python Package to PyPI
5
-
6
- on:
7
- release:
8
- types: [published]
9
-
10
- permissions:
11
- contents: read
12
-
13
- jobs:
14
- build:
15
- name: Build distribution 📦
16
- runs-on: ubuntu-latest
17
- steps:
18
- - name: Checkout repository
19
- uses: actions/checkout@v5
20
-
21
- - name: Set up Python
22
- uses: actions/setup-python@v6
23
- with:
24
- python-version: "3.x"
25
- cache: pip # Cache pip dependencies for faster runs
26
-
27
- - name: Install build dependencies
28
- run: |
29
- python -m pip install --upgrade pip
30
- python -m pip install build
31
-
32
- - name: Build package
33
- run: python -m build
34
-
35
- - name: Verify build artifacts
36
- run: |
37
- ls -la dist/
38
- python -m pip install twine
39
- python -m twine check dist/*
40
-
41
- - name: Store the distribution packages
42
- uses: actions/upload-artifact@v4
43
- with:
44
- name: python-package-distributions
45
- path: dist/
46
-
47
- publish-to-pypi:
48
- name: Publish Python 🐍 distribution 📦 to PyPI
49
- needs: [build]
50
- runs-on: ubuntu-latest
51
- environment:
52
- name: pypi
53
- url: https://pypi.org/p/${{ github.event.repository.name }}
54
- permissions:
55
- id-token: write # IMPORTANT: mandatory for trusted publishing
56
-
57
- steps:
58
- - name: Download all the dists
59
- uses: actions/download-artifact@v4
60
- with:
61
- name: python-package-distributions
62
- path: dist/
63
-
64
- - name: Publish distribution 📦 to PyPI
1
+ # This workflow will upload a Python Package to PyPI when a release is published
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ name: Publish Python Package to PyPI
5
+
6
+ on:
7
+ release:
8
+ types: [published]
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ build:
15
+ name: Build distribution 📦
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout repository
19
+ uses: actions/checkout@v5
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v6
23
+ with:
24
+ python-version: "3.x"
25
+ cache: pip # Cache pip dependencies for faster runs
26
+
27
+ - name: Install build dependencies
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ python -m pip install build
31
+
32
+ - name: Build package
33
+ run: python -m build
34
+
35
+ - name: Verify build artifacts
36
+ run: |
37
+ ls -la dist/
38
+ python -m pip install twine
39
+ python -m twine check dist/*
40
+
41
+ - name: Store the distribution packages
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: python-package-distributions
45
+ path: dist/
46
+
47
+ publish-to-pypi:
48
+ name: Publish Python 🐍 distribution 📦 to PyPI
49
+ needs: [build]
50
+ runs-on: ubuntu-latest
51
+ environment:
52
+ name: pypi
53
+ url: https://pypi.org/p/${{ github.event.repository.name }}
54
+ permissions:
55
+ id-token: write # IMPORTANT: mandatory for trusted publishing
56
+
57
+ steps:
58
+ - name: Download all the dists
59
+ uses: actions/download-artifact@v4
60
+ with:
61
+ name: python-package-distributions
62
+ path: dist/
63
+
64
+ - name: Publish distribution 📦 to PyPI
65
65
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-postman
3
- Version: 0.7.0
3
+ Version: 0.9.0
4
4
  Summary: A Python library for parsing and working with Postman collection.json files
5
5
  Project-URL: Homepage, https://github.com/python-postman/python-postman
6
6
  Project-URL: Repository, https://github.com/python-postman/python-postman
@@ -25,23 +25,31 @@ Classifier: Topic :: Internet :: WWW/HTTP
25
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Classifier: Topic :: Software Development :: Testing
27
27
  Requires-Python: >=3.9
28
+ Requires-Dist: httpx>=0.28.1
28
29
  Provides-Extra: dev
29
30
  Requires-Dist: black>=23.0.0; extra == 'dev'
30
31
  Requires-Dist: isort>=5.12.0; extra == 'dev'
31
32
  Requires-Dist: mypy>=1.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
32
34
  Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
33
35
  Requires-Dist: pytest>=8.4.2; extra == 'dev'
36
+ Provides-Extra: execution
37
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'execution'
34
38
  Description-Content-Type: text/markdown
35
39
 
36
- # Python Postman Collection Parser
40
+ # Python Postman
37
41
 
38
- A Python library for parsing and working with Postman collection.json files. This library provides a clean, object-oriented interface for reading Postman collections and accessing their components programmatically.
42
+ A comprehensive Python library for working with Postman collections. Parse, execute, search, and analyze Postman collection.json files with a clean, object-oriented interface. Execute HTTP requests with full async/sync support, dynamic variable resolution, and authentication handling.
39
43
 
40
44
  ## Features
41
45
 
42
46
  - **Parse Postman Collections**: Load collections from files, JSON strings, or dictionaries
43
47
  - **Object-Oriented API**: Work with collections using intuitive Python objects
44
- - **Full Collection Support**: Access requests, folders, variables, authentication, and scripts
48
+ - **Full Collection Support**: Access requests, folders, variables, authentication, and events
49
+ - **HTTP Request Execution**: Execute requests using httpx with full async/sync support
50
+ - **Variable Resolution**: Dynamic variable substitution with proper scoping
51
+ - **Authentication Handling**: Automatic auth processing for Bearer, Basic, and API Key
52
+ - **Request Extensions**: Runtime modification of URLs, headers, body, and auth
45
53
  - **Validation**: Built-in validation for collection structure and schema compliance
46
54
  - **Iteration**: Easy iteration through all requests regardless of folder structure
47
55
  - **Search**: Find requests and folders by name
@@ -50,7 +58,13 @@ A Python library for parsing and working with Postman collection.json files. Thi
50
58
  ## Installation
51
59
 
52
60
  ```bash
61
+ # Basic installation (parsing only)
53
62
  pip install python-postman
63
+
64
+ # With HTTP execution support
65
+ pip install python-postman[execution]
66
+ # or
67
+ pip install python-postman httpx
54
68
  ```
55
69
 
56
70
  ## Quick Start
@@ -81,9 +95,13 @@ print(f"Description: {collection.info.description}")
81
95
  print(f"Schema: {collection.info.schema}")
82
96
 
83
97
  # Collection-level variables
84
- for variable in collection.variables:
98
+ for variable in collection.variables: # This requests a list of Variable objects
85
99
  print(f"Variable: {variable.key} = {variable.value}")
86
100
 
101
+ # Collection variables dictionary. This is a quick way to get key-value pairs.
102
+ # You can pass/update these and add them to the execution context.
103
+ collection_variables = collection.get_variables()
104
+
87
105
  # Collection-level authentication
88
106
  if collection.auth:
89
107
  print(f"Auth Type: {collection.auth.type}")
@@ -92,8 +110,16 @@ if collection.auth:
92
110
  ### Working with Requests
93
111
 
94
112
  ```python
113
+ # Get a list of requests by name
114
+ collection.list_requests()
115
+
116
+ # Find specific request by name
117
+ login_request = collection.get_request_by_name("Login Request")
118
+ if login_request:
119
+ print(f"Found request: {login_request.method} {login_request.url}")
120
+
95
121
  # Iterate through all requests (flattens folder structure)
96
- for request in collection.get_all_requests():
122
+ for request in collection.get_requests():
97
123
  print(f"Request: {request.method} {request.name}")
98
124
  print(f"URL: {request.url}")
99
125
 
@@ -105,11 +131,6 @@ for request in collection.get_all_requests():
105
131
  if request.body:
106
132
  print(f"Body Type: {request.body.mode}")
107
133
  print(f"Body Content: {request.body.raw}")
108
-
109
- # Find specific request by name
110
- request = collection.get_request_by_name("Login Request")
111
- if request:
112
- print(f"Found request: {request.method} {request.url}")
113
134
  ```
114
135
 
115
136
  ### Working with Folders
@@ -167,7 +188,7 @@ if collection.auth:
167
188
  print(f"Basic Auth Username: {username}")
168
189
 
169
190
  # Request-level auth (overrides collection auth)
170
- for request in collection.get_all_requests():
191
+ for request in collection.get_requests():
171
192
  if request.auth:
172
193
  print(f"Request '{request.name}' has {request.auth.type} auth")
173
194
  ```
@@ -175,18 +196,19 @@ for request in collection.get_all_requests():
175
196
  ### Events (Scripts)
176
197
 
177
198
  ```python
178
- # Collection-level events
199
+ # Access script content from collection-level events
179
200
  for event in collection.events:
180
201
  print(f"Collection Event: {event.listen}")
181
- print(f"Script: {event.script}")
202
+ print(f"Script Content: {event.script}")
182
203
 
183
- # Request-level events
184
- for request in collection.get_all_requests():
204
+ # Access script content from request-level events
205
+ # Note: JavaScript execution is not supported - scripts are accessible as text only
206
+ for request in collection.get_requests():
185
207
  for event in request.events:
186
208
  if event.listen == "prerequest":
187
- print(f"Pre-request script for {request.name}")
209
+ print(f"Pre-request script for {request.name}: {event.script}")
188
210
  elif event.listen == "test":
189
- print(f"Test script for {request.name}")
211
+ print(f"Test script for {request.name}: {event.script}")
190
212
  ```
191
213
 
192
214
  ### Validation
@@ -219,6 +241,237 @@ collection = PythonPostman.create_collection(
219
241
  print(f"Created collection: {collection.info.name}")
220
242
  ```
221
243
 
244
+ ## HTTP Request Execution
245
+
246
+ The library supports executing HTTP requests from Postman collections using httpx. This feature requires the `httpx` dependency.
247
+
248
+ ### Basic Request Execution
249
+
250
+ ```python
251
+ import asyncio
252
+ from python_postman import PythonPostman
253
+ from python_postman.execution import RequestExecutor, ExecutionContext
254
+
255
+ async def main():
256
+ # Load collection
257
+ collection = PythonPostman.from_file("api_collection.json")
258
+
259
+ # Create executor
260
+ executor = RequestExecutor(
261
+ client_config={"timeout": 30.0, "verify": True},
262
+ global_headers={"User-Agent": "python-postman/1.0"}
263
+ )
264
+
265
+ # Create execution context with variables
266
+ context = ExecutionContext(
267
+ environment_variables={
268
+ "base_url": "https://api.example.com",
269
+ "api_key": "your-api-key"
270
+ }
271
+ )
272
+
273
+ # Execute a single request
274
+ request = collection.get_request_by_name("Get Users")
275
+ result = await executor.execute_request(request, context)
276
+
277
+ if result.success:
278
+ print(f"Status: {result.response.status_code}")
279
+ print(f"Response: {result.response.json}")
280
+ print(f"Time: {result.response.elapsed_ms:.2f}ms")
281
+ else:
282
+ print(f"Error: {result.error}")
283
+
284
+ await executor.aclose()
285
+
286
+ asyncio.run(main())
287
+ ```
288
+
289
+ ### Synchronous Execution
290
+
291
+ ```python
292
+ from python_postman.execution import RequestExecutor, ExecutionContext
293
+
294
+ # Synchronous execution
295
+ with RequestExecutor() as executor:
296
+ context = ExecutionContext(
297
+ environment_variables={"base_url": "https://httpbin.org"}
298
+ )
299
+
300
+ result = executor.execute_request_sync(request, context)
301
+ if result.success:
302
+ print(f"Status: {result.response.status_code}")
303
+ ```
304
+
305
+ ### Collection Execution
306
+
307
+ ```python
308
+ # Execute entire collection
309
+ async def execute_collection():
310
+ executor = RequestExecutor()
311
+
312
+ # Sequential execution
313
+ result = await executor.execute_collection(collection)
314
+ print(f"Executed {result.total_requests} requests")
315
+ print(f"Success rate: {result.successful_requests}/{result.total_requests}")
316
+
317
+ # Parallel execution
318
+ result = await executor.execute_collection(
319
+ collection,
320
+ parallel=True,
321
+ stop_on_error=False
322
+ )
323
+
324
+ # Get the request responses
325
+ for result in result.results:
326
+ print(f"Request: {result.request.name}")
327
+ print(f"Result Text: {result.response.text}")
328
+
329
+ print(f"Parallel execution completed in {result.total_time_ms:.2f}ms")
330
+
331
+ await executor.aclose()
332
+ ```
333
+
334
+ ### Variable Management
335
+
336
+ ```python
337
+ # Variable scoping: request > folder > collection > environment
338
+ context = ExecutionContext(
339
+ environment_variables={"env": "production"},
340
+ collection_variables={"api_version": "v1", "timeout": "30"},
341
+ folder_variables={"endpoint": "/users"},
342
+ request_variables={"user_id": "12345"}
343
+ )
344
+
345
+ # Variables are resolved with proper precedence
346
+ url = context.resolve_variables("{{base_url}}/{{api_version}}{{endpoint}}/{{user_id}}")
347
+ print(url) # "https://api.example.com/v1/users/12345"
348
+
349
+ # Dynamic variable updates
350
+ context.set_variable("session_token", "abc123", "environment")
351
+ ```
352
+
353
+ ### Path Parameters
354
+
355
+ The library supports both Postman-style variables (`{{variable}}`) and path parameters (`:parameter`):
356
+
357
+ ```python
358
+ # Path parameters use :parameterName syntax
359
+ context = ExecutionContext(
360
+ environment_variables={
361
+ "baseURL": "https://api.example.com",
362
+ "userId": "12345",
363
+ "datasetId": "abc123"
364
+ }
365
+ )
366
+
367
+ # Mix Postman variables and path parameters
368
+ url = context.resolve_variables("{{baseURL}}/users/:userId/datasets/:datasetId")
369
+ print(url) # "https://api.example.com/users/12345/datasets/abc123"
370
+
371
+ # Path parameters follow the same scoping rules as Postman variables
372
+ url = context.resolve_variables("{{baseURL}}/:datasetId?$offset=0&$limit=10")
373
+ print(url) # "https://api.example.com/abc123?$offset=0&$limit=10"
374
+ ```
375
+
376
+ ### Request Extensions
377
+
378
+ ```python
379
+ from python_postman.execution import RequestExtensions
380
+
381
+ # Runtime request modifications
382
+ extensions = RequestExtensions(
383
+ # Substitute existing values
384
+ header_substitutions={"Authorization": "Bearer {{new_token}}"},
385
+ url_substitutions={"host": "staging.api.example.com"},
386
+
387
+ # Add new values
388
+ header_extensions={"X-Request-ID": "req-{{timestamp}}"},
389
+ param_extensions={"debug": "true", "version": "v2"},
390
+ body_extensions={"metadata": {"client": "python-postman"}}
391
+ )
392
+
393
+ result = await executor.execute_request(
394
+ request,
395
+ context,
396
+ extensions=extensions
397
+ )
398
+ ```
399
+
400
+ ### Authentication
401
+
402
+ ```python
403
+ # Authentication is handled automatically based on collection/request auth settings
404
+
405
+ # Bearer Token
406
+ context = ExecutionContext(
407
+ environment_variables={"bearer_token": "eyJhbGciOiJIUzI1NiIs..."}
408
+ )
409
+
410
+ # Basic Auth
411
+ context = ExecutionContext(
412
+ environment_variables={
413
+ "username": "admin",
414
+ "password": "secret123"
415
+ }
416
+ )
417
+
418
+ # API Key
419
+ context = ExecutionContext(
420
+ environment_variables={"api_key": "sk-1234567890abcdef"}
421
+ )
422
+
423
+ # Auth is applied automatically during request execution
424
+ result = await executor.execute_request(request, context)
425
+ ```
426
+
427
+ ### Request Methods on Models
428
+
429
+ ```python
430
+ # Execute requests directly from Request objects
431
+ request = collection.get_request_by_name("Health Check")
432
+
433
+ # Async execution
434
+ result = await request.execute(
435
+ executor=executor,
436
+ context=context,
437
+ substitutions={"env": "staging"}
438
+ )
439
+
440
+ # Sync execution
441
+ result = request.execute_sync(
442
+ executor=executor,
443
+ context=context
444
+ )
445
+
446
+ # Execute collections directly
447
+ result = await collection.execute(
448
+ executor=executor,
449
+ parallel=True
450
+ )
451
+ ```
452
+
453
+ ### Error Handling
454
+
455
+ ```python
456
+ from python_postman.execution import (
457
+ ExecutionError,
458
+ RequestExecutionError,
459
+ VariableResolutionError,
460
+ AuthenticationError
461
+ )
462
+
463
+ try:
464
+ result = await executor.execute_request(request, context)
465
+ if not result.success:
466
+ print(f"Request failed: {result.error}")
467
+ except VariableResolutionError as e:
468
+ print(f"Variable error: {e}")
469
+ except AuthenticationError as e:
470
+ print(f"Auth error: {e}")
471
+ except RequestExecutionError as e:
472
+ print(f"Execution error: {e}")
473
+ ```
474
+
222
475
  ## API Reference
223
476
 
224
477
  ### Main Classes
@@ -229,7 +482,7 @@ print(f"Created collection: {collection.info.name}")
229
482
  - **`Folder`**: Container for organizing requests and sub-folders
230
483
  - **`Variable`**: Collection, folder, or request-level variables
231
484
  - **`Auth`**: Authentication configuration
232
- - **`Event`**: Pre-request scripts and test scripts
485
+ - **`Event`**: Pre-request and test script definitions (text only, execution not supported)
233
486
 
234
487
  ### Exception Handling
235
488
 
@@ -316,9 +569,9 @@ This project is licensed under the MIT License - see the LICENSE file for detail
316
569
 
317
570
  ## Changelog
318
571
 
319
- ### 0.7.0 (Updated version)
572
+ ### 0.8.0 (Updated version)
320
573
 
321
- - Updated version to 0.7.0
574
+ - Updated version to 0.8.0
322
575
  - Updated README.md
323
576
  - Updated pyproject.toml
324
577
  - Updated tests