pytest-nhsd-apim 5.0.15__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 (25) hide show
  1. pytest_nhsd_apim-5.0.15/PKG-INFO +122 -0
  2. pytest_nhsd_apim-5.0.15/README.md +81 -0
  3. pytest_nhsd_apim-5.0.15/pyproject.toml +42 -0
  4. pytest_nhsd_apim-5.0.15/setup.cfg +7 -0
  5. pytest_nhsd_apim-5.0.15/setup.py +90 -0
  6. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/__init__.py +3 -0
  7. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/apigee_apis.py +1497 -0
  8. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/apigee_edge.py +605 -0
  9. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/auth_journey.py +181 -0
  10. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/config.py +140 -0
  11. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/identity_service.py +549 -0
  12. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/log.py +95 -0
  13. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/nhsd_apim_authorization.py +116 -0
  14. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/pytest_nhsd_apim.py +159 -0
  15. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/secrets.py +87 -0
  16. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim/token_cache.py +122 -0
  17. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/PKG-INFO +122 -0
  18. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/SOURCES.txt +24 -0
  19. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/dependency_links.txt +1 -0
  20. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/entry_points.txt +2 -0
  21. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/requires.txt +15 -0
  22. pytest_nhsd_apim-5.0.15/src/pytest_nhsd_apim.egg-info/top_level.txt +1 -0
  23. pytest_nhsd_apim-5.0.15/tests/test_apigee_apis.py +478 -0
  24. pytest_nhsd_apim-5.0.15/tests/test_examples.py +426 -0
  25. pytest_nhsd_apim-5.0.15/tests/test_nhsd_apim.py +33 -0
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-nhsd-apim
3
+ Version: 5.0.15
4
+ Summary: Pytest plugin accessing NHSDigital's APIM proxies
5
+ Home-page: https://github.com/NHSDigital/pytest-nhsd-apim
6
+ Author: Adrian Ciobanita
7
+ Author-email: adrian.ciobanita1@nhs.net
8
+ Maintainer: Alex Carrie
9
+ Maintainer-email: alexander.carrie1@nhs.net
10
+ License: MIT
11
+ Classifier: Framework :: Pytest
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: Authlib==1.6.1
15
+ Requires-Dist: cryptography==44.0.1
16
+ Requires-Dist: lxml==5.3.1
17
+ Requires-Dist: pycryptodome==3.20.0
18
+ Requires-Dist: PyJWT==2.8.0
19
+ Requires-Dist: pyotp==2.9.0
20
+ Requires-Dist: pytest==8.2.0
21
+ Requires-Dist: requests==2.32.0
22
+ Requires-Dist: toml==0.10.2
23
+ Requires-Dist: typing-extensions==4.12.2
24
+ Requires-Dist: pydantic==2.9.2
25
+ Requires-Dist: wheel<0.45.0,===0.37.1
26
+ Requires-Dist: pydantic-settings==2.2.1
27
+ Requires-Dist: setuptools==80.0.1
28
+ Requires-Dist: urllib3==2.6.1
29
+ Dynamic: author
30
+ Dynamic: author-email
31
+ Dynamic: classifier
32
+ Dynamic: description
33
+ Dynamic: description-content-type
34
+ Dynamic: home-page
35
+ Dynamic: license
36
+ Dynamic: maintainer
37
+ Dynamic: maintainer-email
38
+ Dynamic: requires-dist
39
+ Dynamic: requires-python
40
+ Dynamic: summary
41
+
42
+ # pytest-nhsd-apim
43
+
44
+ A pytest extension for NHSDigital's API Mangement suite.
45
+
46
+ ## Installation
47
+ In your project's virtual environment
48
+ ```code()
49
+ poetry add pytest-nhsd-apim
50
+ ```
51
+ or if using pip directly
52
+ ```code()
53
+ python -m pip install pytest-nhsd-apim
54
+ ```
55
+
56
+ ## Usage
57
+ - create a python test file
58
+ - write a test using our custom authentication markers!
59
+ - enjoy!?
60
+
61
+
62
+
63
+ ## Testing
64
+ - run `make test` to run test examples, located in this repo
65
+ - after creating your file you can use the plugin as:
66
+ ```code()
67
+ python -m pytest -p pytest_nhsd_apim test_nhsd_apim.py -s --apigee-proxy-name=<your-proxy-name>
68
+ ```
69
+
70
+ ## Available tools
71
+ When installing this library in your project you can access some very handy tools, including our platform authenticators and our apigee api wrapper library.
72
+ ### Autheticators
73
+ We present a variety of authenticators including AuthorizationCodeAuthenticator, ClientCredentialsAuthenticator and TokenExchangeAuthenticator. The way of using them is simple. First you create the configuration object which will validate that your coniguration is correct on creation using pydantic, then pass the config to the authenticator and call get_token() on it.
74
+ ```python
75
+ from pytest_nhsd_apim.identity_service import ClientCredentialsConfig, ClientCredentialsAuthenticator
76
+
77
+ config = ClientCredentialsConfig(
78
+ environment={APIGEE_ENVIRONMENT},
79
+ identity_service_base_url={BASE_URL},
80
+ client_id={CLIENT_ID},
81
+ jwt_private_key={PRIVATE_KEY_PEM},
82
+ jwt_kid={KEY_ID},
83
+ )
84
+
85
+ authenticator=ClientCredentialsAuthenticator(config=config)
86
+ token=authenticator.get_token()
87
+ ```
88
+ For a more detailed implementation on the rest of the authenticators please refer to the examples [here](/tests/test_examples.py#L308).
89
+ ### Apigee APIs
90
+ We also present a variety off Apigee APIs with the benefit of a fully authenticated Apigee client ready to use. Just remember to export the following variables
91
+ ```bash
92
+ # If you want the client to authenticate you...
93
+ export APIGEE_NHSD_NONPROD_USERNAME={my_username}
94
+ export APIGEE_NHSD_NONPROD_PASSWORD={my_password}
95
+ export APIGEE_NHSD_NONPROD_OTP_KEY={my_otp}
96
+ # Or alternatively, if you already have a token you can pass it and the client will use it.
97
+ export APIGEE_ACCESS_TOKEN={access_token}
98
+
99
+ #NOTE: in case both sets of credentials are defined, the username and password take presedence, this is so the Apigee client can keep itself authenticated all the time.
100
+ ```
101
+ ```python
102
+ from pytest_nhsd_apim.apigee_apis import ApigeeNonProdCredentials, DeveloperAppsAPI
103
+
104
+ config = ApigeeNonProdCredentials()
105
+ client = ApigeeClient(config=config)
106
+ apps = DeveloperAppsAPI(client=client)
107
+
108
+ print(apps.list_aps('lucas.fantini@nhs.net'))
109
+ ```
110
+ The APIs we offer at the moment are:
111
+ | API | Methods | Documentation|
112
+ | ------------- | ------------- |-------------|
113
+ | DeveloperAppsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L292) |[Overview](https://apidocs.apigee.com/docs/developer-apps/1/overview)|
114
+ | ApiProductsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L575) |[Overview](https://apidocs.apigee.com/docs/api-products/1/overview)|
115
+ | DebugSessionsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L844) |[Overview](https://apidocs.apigee.com/docs/debug-sessions/1/overview)|
116
+ | AccessTokensAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L983) |[Overview](https://apidocs.apigee.com/docs/oauth-20-access-tokens/1/overview)|
117
+ | AppKeysAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L1243) |[Overview](https://apidocs.apigee.com/docs/developer-app-keys/1/overview)|
118
+
119
+ For a more detailed implementation of the available APIs please refer to the tests [here](/tests/test_apigee_apis.py).
120
+ We will keep adding APIs with time, if you are looking for a particular APIs not listed above please feel free to open a pull request and send it to us.
121
+
122
+
@@ -0,0 +1,81 @@
1
+ # pytest-nhsd-apim
2
+
3
+ A pytest extension for NHSDigital's API Mangement suite.
4
+
5
+ ## Installation
6
+ In your project's virtual environment
7
+ ```code()
8
+ poetry add pytest-nhsd-apim
9
+ ```
10
+ or if using pip directly
11
+ ```code()
12
+ python -m pip install pytest-nhsd-apim
13
+ ```
14
+
15
+ ## Usage
16
+ - create a python test file
17
+ - write a test using our custom authentication markers!
18
+ - enjoy!?
19
+
20
+
21
+
22
+ ## Testing
23
+ - run `make test` to run test examples, located in this repo
24
+ - after creating your file you can use the plugin as:
25
+ ```code()
26
+ python -m pytest -p pytest_nhsd_apim test_nhsd_apim.py -s --apigee-proxy-name=<your-proxy-name>
27
+ ```
28
+
29
+ ## Available tools
30
+ When installing this library in your project you can access some very handy tools, including our platform authenticators and our apigee api wrapper library.
31
+ ### Autheticators
32
+ We present a variety of authenticators including AuthorizationCodeAuthenticator, ClientCredentialsAuthenticator and TokenExchangeAuthenticator. The way of using them is simple. First you create the configuration object which will validate that your coniguration is correct on creation using pydantic, then pass the config to the authenticator and call get_token() on it.
33
+ ```python
34
+ from pytest_nhsd_apim.identity_service import ClientCredentialsConfig, ClientCredentialsAuthenticator
35
+
36
+ config = ClientCredentialsConfig(
37
+ environment={APIGEE_ENVIRONMENT},
38
+ identity_service_base_url={BASE_URL},
39
+ client_id={CLIENT_ID},
40
+ jwt_private_key={PRIVATE_KEY_PEM},
41
+ jwt_kid={KEY_ID},
42
+ )
43
+
44
+ authenticator=ClientCredentialsAuthenticator(config=config)
45
+ token=authenticator.get_token()
46
+ ```
47
+ For a more detailed implementation on the rest of the authenticators please refer to the examples [here](/tests/test_examples.py#L308).
48
+ ### Apigee APIs
49
+ We also present a variety off Apigee APIs with the benefit of a fully authenticated Apigee client ready to use. Just remember to export the following variables
50
+ ```bash
51
+ # If you want the client to authenticate you...
52
+ export APIGEE_NHSD_NONPROD_USERNAME={my_username}
53
+ export APIGEE_NHSD_NONPROD_PASSWORD={my_password}
54
+ export APIGEE_NHSD_NONPROD_OTP_KEY={my_otp}
55
+ # Or alternatively, if you already have a token you can pass it and the client will use it.
56
+ export APIGEE_ACCESS_TOKEN={access_token}
57
+
58
+ #NOTE: in case both sets of credentials are defined, the username and password take presedence, this is so the Apigee client can keep itself authenticated all the time.
59
+ ```
60
+ ```python
61
+ from pytest_nhsd_apim.apigee_apis import ApigeeNonProdCredentials, DeveloperAppsAPI
62
+
63
+ config = ApigeeNonProdCredentials()
64
+ client = ApigeeClient(config=config)
65
+ apps = DeveloperAppsAPI(client=client)
66
+
67
+ print(apps.list_aps('lucas.fantini@nhs.net'))
68
+ ```
69
+ The APIs we offer at the moment are:
70
+ | API | Methods | Documentation|
71
+ | ------------- | ------------- |-------------|
72
+ | DeveloperAppsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L292) |[Overview](https://apidocs.apigee.com/docs/developer-apps/1/overview)|
73
+ | ApiProductsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L575) |[Overview](https://apidocs.apigee.com/docs/api-products/1/overview)|
74
+ | DebugSessionsAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L844) |[Overview](https://apidocs.apigee.com/docs/debug-sessions/1/overview)|
75
+ | AccessTokensAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L983) |[Overview](https://apidocs.apigee.com/docs/oauth-20-access-tokens/1/overview)|
76
+ | AppKeysAPI | [here](/src/pytest_nhsd_apim/apigee_apis.py#L1243) |[Overview](https://apidocs.apigee.com/docs/developer-app-keys/1/overview)|
77
+
78
+ For a more detailed implementation of the available APIs please refer to the tests [here](/tests/test_apigee_apis.py).
79
+ We will keep adding APIs with time, if you are looking for a particular APIs not listed above please feel free to open a pull request and send it to us.
80
+
81
+
@@ -0,0 +1,42 @@
1
+ [tool.poetry]
2
+ name = "pytest-nhsd-apim"
3
+ version = "5.0.15"
4
+ description = "Pytest plugin accessing NHSDigital's APIM proxies"
5
+ authors = ["Adrian Ciobanita <adrian.ciobanita1@nhs.net>", "Alex Carrie <alexander.carrie1@nhs.net>", "Lucas Fantini <lucas.fantini@nhs.net>"]
6
+ maintainers = ["Alex Carrie <alexander.carrie1@nhs.net>", "Alex Hawdon <alex.hawdon1@nhs.net"]
7
+ readme = "README.md"
8
+ repository = "https://github.com/NHSDigital/pytest-nhsd-apim"
9
+ classifiers = ["Framework :: Pytest"]
10
+ license = "MIT"
11
+
12
+ [tool.poetry.dependencies]
13
+ Authlib = "^1.6.1"
14
+ cryptography = ">44.0.1"
15
+ lxml = "^5.3.1"
16
+ python = "^3.13"
17
+ pycryptodome = "^3.20.0"
18
+ PyJWT = "^2.8.0"
19
+ pyotp = "^2.9.0"
20
+ pytest = "^8.2.0"
21
+ requests = "^2.32.0"
22
+ toml = "^0.10.2"
23
+ typing-extensions = "^4.12.2"
24
+ pydantic = "^2.9.2"
25
+ wheel = ">=0.37.1,<0.45.0"
26
+ pydantic-settings = "^2.2.1"
27
+ setuptools = "^80.0.1"
28
+ urllib3 = "^2.6.1"
29
+
30
+ # [tool.poetry.group.dev.dependencies]
31
+
32
+ [tool.pytest.ini_options]
33
+ log_cli = true
34
+ log_cli_level = "INFO"
35
+ log_cli_format = "%(asctime)s - %(name)s.%(module)s.%(funcName)s - %(levelname)s - %(message)s"
36
+ log_file_level = "DEBUG"
37
+ log_file_format = "%(asctime)s - %(name)s.%(module)s.%(funcName)s - %(levelname)s - %(message)s"
38
+ log_file_date_format = "%Y-%m-%d %H:%M:%S"
39
+
40
+ [build-system]
41
+ requires = ["poetry-core>=1.0.0"]
42
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,7 @@
1
+ [flake8]
2
+ max-line-length = 120
3
+
4
+ [egg_info]
5
+ tag_build =
6
+ tag_date = 0
7
+
@@ -0,0 +1,90 @@
1
+ """
2
+ pytest-nhsd-apim setup install.
3
+ """
4
+
5
+ import os
6
+
7
+ import toml
8
+ from setuptools import setup, find_packages
9
+
10
+
11
+ def _read_file(file_name):
12
+ """
13
+ Read a file from disk, given it's `file_name`
14
+ :param file_name: file name, including extension
15
+ :type file_name: str
16
+ :return: file stream
17
+ :rtype: IO stream
18
+ """
19
+ path_to_file = os.path.join(os.path.dirname(__file__), file_name)
20
+ with open(path_to_file) as f_stream:
21
+ return f_stream.read()
22
+
23
+
24
+ def readme():
25
+ """
26
+ Open this project's `README.md`.
27
+ :return: `README.md` file stream
28
+ :rtype: IO stream
29
+ """
30
+ return _read_file("README.md")
31
+
32
+
33
+ def get_pyproject_toml_metadata():
34
+ """
35
+ Read `pyproject.toml`.
36
+ :return: `pyproject.toml` values
37
+ :rtype: dict
38
+ """
39
+ return toml.loads(_read_file("pyproject.toml"))
40
+
41
+
42
+ def get_name_and_email(name_and_email_pair):
43
+ """
44
+ Get name and email from a string of form `FirstName LastName <email_address>`
45
+ :param name_and_email_pair: `FirstName LastName <email_address>`
46
+ :type name_and_email_pair: str
47
+ :return: tuple with name and email address
48
+ :rtype: tuple
49
+ """
50
+ return name_and_email_pair[0].split(' <')[:1][0], name_and_email_pair[0].split(" <")[1:][0][:-1]
51
+
52
+
53
+ def get_package_dependencies(toml_dependencies):
54
+ """
55
+ Read package dependencies from `pyproject.toml`
56
+ :param toml_dependencies: `pyproject.toml` dict containing project dependencies
57
+ :type toml_dependencies: dict
58
+ :return: data needed by setuptools to pass into `install_requires`
59
+ :rtype: list
60
+ """
61
+ install_requires = ["{}=={}".format(pkg_name, pkg_version[1:])
62
+ for pkg_name, pkg_version in toml_dependencies.items() if pkg_name != 'python']
63
+
64
+ return install_requires
65
+
66
+
67
+ PYPROJECT_METADATA = get_pyproject_toml_metadata()
68
+ AUTHOR, AUTHOR_EMAIL = get_name_and_email(PYPROJECT_METADATA['tool']['poetry']['authors'])
69
+ MAINTAINER, MAINTAINER_EMAIL = get_name_and_email(PYPROJECT_METADATA['tool']['poetry']['maintainers'])
70
+
71
+ setup(
72
+ name=PYPROJECT_METADATA['tool']['poetry']['name'],
73
+ version=PYPROJECT_METADATA['tool']['poetry']['version'],
74
+ author=AUTHOR,
75
+ author_email=AUTHOR_EMAIL,
76
+ maintainer=MAINTAINER,
77
+ maintainer_email=MAINTAINER_EMAIL,
78
+ license=PYPROJECT_METADATA['tool']['poetry']['license'],
79
+ url=PYPROJECT_METADATA['tool']['poetry']['repository'],
80
+ description=PYPROJECT_METADATA['tool']['poetry']['description'],
81
+ long_description=readme(),
82
+ long_description_content_type='text/markdown',
83
+ packages=find_packages(where="src"),
84
+ package_dir={"": "src"},
85
+ package_data={"": ["data/*"]},
86
+ python_requires=">=3.8",
87
+ entry_points={"pytest11": ["nhsd_apim = pytest_nhsd_apim.pytest_nhsd_apim"]},
88
+ classifiers=PYPROJECT_METADATA['tool']['poetry']['classifiers'],
89
+ install_requires=get_package_dependencies(PYPROJECT_METADATA['tool']['poetry']['dependencies']),
90
+ )
@@ -0,0 +1,3 @@
1
+ import logging
2
+
3
+ logging.getLogger("urllib3").setLevel(logging.CRITICAL)