Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
423cd57
eli-225 adding back in poetry, updating make and readme
eddalmond1 Apr 30, 2025
9db71ad
eli-225 adding placeholders for all other files used in bundling spec
eddalmond1 Apr 30, 2025
ba26abc
eli-225 adding spelling 'mistakes' to allowed list
eddalmond1 Apr 30, 2025
e02578d
eli-225 updating make to ensure folder exists
eddalmond1 Apr 30, 2025
e78e361
eli-225 updating github action
eddalmond1 Apr 30, 2025
e824b25
eli-225 fixing github action
eddalmond1 Apr 30, 2025
8185610
eli-225 filling in template values, best guesses for now
eddalmond1 Apr 30, 2025
3d861a5
eli-225 removing packages from pyproject.toml
eddalmond1 May 1, 2025
b330aa5
eli-225 adding list of envs to readme instructions
eddalmond1 May 1, 2025
ab0ab42
eli-225 adding ability to omit securityScheme from sandbox specification
eddalmond1 May 1, 2025
7d1a941
eli-225 working on getting linting for specification working
eddalmond1 May 1, 2025
22f1e2d
eli-225 amending yq command as github actions uses the python version
eddalmond1 May 1, 2025
0018c0b
eli-225 changing yq command pt 2
eddalmond1 May 1, 2025
5961ca7
eli-225 updating sandbox + readme
eddalmond1 May 1, 2025
8a2eb6d
eli-225 amending readme
eddalmond1 May 1, 2025
befa248
eli-225 removing git ignore for postman collection, adding latest col…
eddalmond1 May 1, 2025
8b931ff
eli-225 updating spec with correct urls
eddalmond1 May 1, 2025
bc28e02
eli-225 sorting out file ending
eddalmond1 May 1, 2025
838ed4c
eli-225 fixing postman output - final line needs to be newline
eddalmond1 May 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/actions/lint-and-validate-specification/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ runs:

- name: Lint OpenAPI Spec with Spectral
shell: bash
run: spectral lint --ruleset .spectral.yaml build/specification/eligibility-signposting-api.yaml
run: |
spectral lint --ruleset .spectral.yaml build/specification/${{ inputs.apim-env }}/eligibility-signposting-api.yaml

- name: Validate OpenAPI Spec with Swagger CLI
shell: bash
run: swagger-cli validate build/specification/eligibility-signposting-api.yaml
run: swagger-cli validate build/specification/${{ inputs.apim-env }}/eligibility-signposting-api.yaml
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pre-commit 3.6.0
vale 3.6.0
poetry 2.1.1

# ==============================================================================
# The section below is reserved for Docker image versions.
Expand All @@ -14,6 +15,7 @@ vale 3.6.0
# docker/ghcr.io/make-ops-tools/gocloc latest@sha256:6888e62e9ae693c4ebcfed9f1d86c70fd083868acb8815fe44b561b9a73b5032 # SEE: https://github.com/make-ops-tools/gocloc/pkgs/container/gocloc
# docker/ghcr.io/nhs-england-tools/github-runner-image 20230909-321fd1e-rt@sha256:ce4fd6035dc450a50d3cbafb4986d60e77cb49a71ab60a053bb1b9518139a646 # SEE: https://github.com/nhs-england-tools/github-runner-image/pkgs/container/github-runner-image
# docker/hadolint/hadolint 2.12.0-alpine@sha256:7dba9a9f1a0350f6d021fb2f6f88900998a4fb0aaf8e4330aa8c38544f04db42 # SEE: https://hub.docker.com/r/hadolint/hadolint/tags
# docker/hashicorp/terraform 1.5.6@sha256:180a7efa983386a27b43657ed610e9deed9e6c3848d54f9ea9b6cb8a5c8c25f5 # SEE: https://hub.docker.com/r/hashicorp/terraform/tags
# docker/jdkato/vale v3.6.0@sha256:0ef22c8d537f079633cfff69fc46f69a2196072f69cab1ab232e8a79a388e425 # SEE: https://hub.docker.com/r/jdkato/vale/tags
# docker/koalaman/shellcheck latest@sha256:e40388688bae0fcffdddb7e4dea49b900c18933b452add0930654b2dea3e7d5c # SEE: https://hub.docker.com/r/koalaman/shellcheck/tags
# docker/mstruebing/editorconfig-checker 2.7.1@sha256:dd3ca9ea50ef4518efe9be018d669ef9cf937f6bb5cfe2ef84ff2a620b5ddc24 # SEE: https://hub.docker.com/r/mstruebing/editorconfig-checker/tags
Expand Down
32 changes: 24 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,12 @@ MAKE_DIR := $(abspath $(shell pwd))

#Installs dependencies using poetry.
install-python:
poetry install
poetry install --no-root

#Installs dependencies using npm.
install-node:
npm install --legacy-peer-deps

#Configures Git Hooks, which are scripts that run given a specified event.
.git/hooks/pre-commit:
cp scripts/pre-commit .git/hooks/pre-commit

#Condensed Target to run all targets above.
install: install-node install-python .git/hooks/pre-commit

Expand All @@ -37,7 +33,7 @@ publish: clean
mkdir -p build
mkdir -p sandbox/specification
npm run publish 2> /dev/null
cp build/eligibility-signposting-api.json sandbox/specification/eligibility-signposting-api.json
cp build/sandbox/eligibility-signposting-api.json sandbox/specification/eligibility-signposting-api.json
#Files to loop over in release
_dist_include="pytest.ini poetry.lock poetry.toml pyproject.toml Makefile build/. tests"

Expand Down Expand Up @@ -66,6 +62,26 @@ get-spec: # Get the most recent specification live in proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec get

get-spec-uat: # Get the most recent specification live in proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec get --uat

publish-spec: # Publish the specification to proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec publish --specification-file build/prod/eligibility-signposting-api.json

publish-spec-uat: # Publish the specification to proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec publish --specification-file build/preprod/eligibility-signposting-api.json --uat

delete-spec: # Delete the specification from proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec delete

delete-spec-uat: # Delete the specification from proxygen
$(MAKE) setup-proxygen-credentials
proxygen spec delete --uat

# Specification

guard-%:
Expand Down Expand Up @@ -107,9 +123,9 @@ endif

construct-spec: guard-APIM_ENV
@ $(MAKE) update-spec-template APIM_ENV=$$APIM_ENV
mkdir -p build/specification && \
mkdir -p build/specification/$(APIM_ENV) && \
npx redocly bundle specification/eligibility-signposting-api.yaml --remove-unused-components --keep-url-references --ext yaml \
> build/specification/eligibility-signposting-api.yaml
> build/specification/$(APIM_ENV)/eligibility-signposting-api.yaml

SPEC_DIR := $(CURDIR)/specification
POSTMAN_DIR := $(SPEC_DIR)/postman
Expand Down
3,174 changes: 3,174 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions poetry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[virtualenvs]
in-project = true
90 changes: 90 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
[project]
name = "eligibility-signposting-api-specification"
version = "0.0.1-alpha"
description = "TODO"
authors = [
#TODO add authors
]
readme = "README.md"
requires-python = ">=3.13"
repository = "https://github.com/NHSDigital/eligibility-signposting-api-specification"
homepage = "https://digital.nhs.uk/developer/api-catalogue"
keywords = ["healthcare", "uk", "nhs", "vaccination", "api"] #TODO add additional keywords
package_mode = false

[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.dependencies]
python = "^3.13"
flask = {extras = ["async"], version = "^3.1.0"}
httpx = "^0.28.1"
yarl = "^1.18.3"
pydantic = "^2.10.6"
asgiref = "^3.8.1"
boto3 = "^1.37.3"
botocore = "^1.37.3"
eval-type-backport = "^0.2.2"
mangum = "^0.19.0"
wireup = "^1.0.1"
python-json-logger = "^3.3.0"
fhir-resources = "^8.0.0"
python-dateutil = "^2.9.0"
pyhamcrest = "^2.1.0"

[tool.poetry.group.dev.dependencies]
ruff = "^0.11.0"
docopt = "^0.6.2"
jsonpath-rw = "^1.4.0"
semver = "^3.0.4"
gitpython = "^3.1.44"
pytest = "^8.3.4"
pytest-asyncio = "^0.26.0"
pytest-cov = "^6.0.0"
pytest-nhsd-apim = "^5.0.0"
aiohttp = "^3.11.12"
awscli = "^1.37.24"
awscli-local = "^0.22.0"
polyfactory = "^2.20.0"
pyright = "^1.1.394"
brunns-matchers = "^2.9.0"
localstack = "^4.1.1"
pytest-docker = "^3.2.0"
stamina = "^25.1.0"
pytest-freezer = "^0.4.9"

[tool.ruff]
line-length = 120
exclude = ["docs/", "scripts/"]

[tool.ruff.lint]
select = ["ALL"]
ignore = ["COM812", "D"]

[tool.ruff.lint.per-file-ignores]
"src/eligibility_signposting_api/repos/*" = ["ANN401"]
"tests/*" = ["ANN", "INP", "S101", "S106"]

[tool.pytest.ini_options]
log_cli = true
log_cli_level = "DEBUG"
log_format = "%(asctime)s %(levelname)s %(message)s"
log_date_format = "%Y-%m-%d %H:%M:%S"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"

[tool.coverage.run]
relative_files = true
branch = true
source = ["sandbox"]

[tool.coverage.report]
show_missing = true
skip_covered = false
exclude_lines = [
"pragma: no cover",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"raise NotImplementedError",
]
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[A-Z]+s
Apigee
Bitwarden
bot
Cyber
Expand All @@ -10,6 +11,7 @@ OAuth
Octokit
onboarding
Podman
preprod
Proxygen
Python
Redocly
Expand All @@ -18,3 +20,4 @@ Syft
Terraform
toolchain
Trufflehog
uat
26 changes: 17 additions & 9 deletions specification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,28 @@ Contains APIM extensions to the OpenAPI specification with deployment requiremen

To build a specification for a specific environment:

1. Set the target environment using the `APIM_ENV` parameter
2. Run `make construct-spec` from the repository root, which:
1. Make sure you've run the initial setup command `make install-node`.
2. Set the target environment using the `APIM_ENV` parameter
Comment thread
eddalmond1 marked this conversation as resolved.
Outdated
3. Run `make construct-spec` from the repository root, which:
- Updates templates with environment-specific values
- Uses Redocly to compile the complete specification to `build/specification/`
3. For the `sandbox` environment, run `make publish` to convert the specification to JSON and save it to `sandbox/specification/` for immediate use
- Uses Redocly to compile the complete specification to `build/specification/$(APIM_ENV)/`
4. For the `sandbox` environment, run `make publish` to convert the specification to JSON and save it to `sandbox/specification/` for immediate use.

### Deploying Environment-Specific Specifications
### Deploying of Environment-Specific Specifications to Apigee

See the [Proxygen CLI user guide](https://nhsd-confluence.digital.nhs.uk/spaces/APM/pages/804495095/Proxygen+CLI+user+guide#ProxygenCLIuserguide-Settingupsettingsandcredentials)

We deploy our specifications using the Proxygen CLI. In order to do this, the following steps need to be performed:

1. Construct the specification for the environment of your choice, following the instructions above.
2. Run `make retrieve-proxygen-key` from the root directory to retrieve the private key needed to authenticate with Proxygen.
3. Run `make setup-proxygen-credentials` from the root directory to set up credentials needed to interact with our API proxy.
4. Run `proxygen instance deploy <environment> eligibility-signposting-api ./build/specification/eligibility-signposting-api.yaml` to deploy the specification to
1. Construct the specification for the environment of your choice, following the instructions above. This will be stored in
2. Activate a poetry environment `poetry env activate` - you may need to run `make install-python` to install poetry etc. first.
3. Run `make retrieve-proxygen-key` from the root directory to retrieve the private key needed to authenticate with Proxygen.
4. Run `make setup-proxygen-credentials` from the root directory to set up credentials needed to interact with our API proxy.
5. Run `proxygen instance deploy <environment> eligibility-signposting-api ./build/specification/eligibility-signposting-api.yaml` to deploy the specification to
a chosen environment.

### Publishing specifications

1. To get the currently published specification run `make get-spec` for production or `make get-spec-uat` for non-production. This will return an error if a specification is not deployed.
2. To publish a specification, generate an appropriate specification (prod for production, preprod for uat) above then run `make publish-spec` for production or `make publish-spec-uat` for non-production.
3. To delete a specification, run `make delete-spec` for production or `make delete-spec-uat` for non-production
1 change: 1 addition & 0 deletions specification/components/security/security-dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9
1 change: 1 addition & 0 deletions specification/components/security/security-preprod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9
1 change: 1 addition & 0 deletions specification/components/security/security-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9
2 changes: 1 addition & 1 deletion specification/components/security/security-sandbox.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
$ref: https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/app-level0
$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/app-level0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately, I think we should remove any auth from the Sandbox version - but I'm not 100% certain.
Does the app-level0 do that for us?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't, it requires an API key in the header. I'll remove here and see what the generated specification looks like

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It becomes tricky as we've hardcoded some of the structure in the main spec, and setting an empty value/object/type here fails validation. Best way I can think to do right now is, when we generate the sandbox json file, remove the securityScheme section completely using yq

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the change

1 change: 1 addition & 0 deletions specification/components/security/security-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/access-dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- title: Eligibility Signposting API (Dev Environment)
grants:
nhs-login-p9: []
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/access-preprod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- title: Eligibility Signposting API (Pre Production Environment)
grants:
nhs-login-p9: []
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/access-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- title: Eligibility Signposting API (Production Environment)
grants:
nhs-login-p9: []
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/access-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- title: Eligibility Signposting API (Test Environment)
grants:
nhs-login-p9: []
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/ratelimit-dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proxy:
limit: 5
timeunit: second
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/ratelimit-preprod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proxy:
limit: 20
timeunit: second
3 changes: 3 additions & 0 deletions specification/x-nhsd-apim/ratelimit-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proxy:
limit: 5
timeunit: second
1 change: 1 addition & 0 deletions specification/x-nhsd-apim/ratelimit-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
6 changes: 6 additions & 0 deletions specification/x-nhsd-apim/target-dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: external
url: "TBC"
healthcheck: /_status
security:
type: mtls
secret: eligibility-signposting-api
6 changes: 6 additions & 0 deletions specification/x-nhsd-apim/target-preprod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: external
url: "TBC"
healthcheck: /_status
security:
type: mtls
secret: eligibility-signposting-api
6 changes: 6 additions & 0 deletions specification/x-nhsd-apim/target-prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: external
url: "TBC"
healthcheck: /_status
security:
type: mtls
secret: eligibility-signposting-api
10 changes: 10 additions & 0 deletions specification/x-nhsd-apim/target-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type: hosted
healthcheck: /_status
containers:
- name: eligibility-signposting-api
image:
name: eligibility-signposting-api
tag: latest
environment:
LOG_LEVEL: info
NODE_ENV: production
Loading