From 79afcb361c5e7021a238873070becbeb9215189d Mon Sep 17 00:00:00 2001 From: Rafael Marques Date: Sat, 20 Jul 2024 17:03:23 -0300 Subject: [PATCH 1/2] docs --- docs/examples/secrets-manager.md | 56 ++++++++++++++++++++++++++++++++ docs/index.md | 12 +++++-- docs/stylesheets/extra.css | 8 +++++ mkdocs.yml | 13 ++++++++ pyproject.toml | 4 +++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 docs/examples/secrets-manager.md create mode 100644 docs/stylesheets/extra.css diff --git a/docs/examples/secrets-manager.md b/docs/examples/secrets-manager.md new file mode 100644 index 0000000..d9bde67 --- /dev/null +++ b/docs/examples/secrets-manager.md @@ -0,0 +1,56 @@ +# :fontawesome-brands-aws:{ .aws } Secrets Manager + +You can use `pydantic-settings-aws` to create your settings with data located in AWS Secrets Manager. + +!!! info "Secrets Manager content" + The content of the Secrets Manager **must** be a valid JSON. + +## :fontawesome-brands-aws:{ .aws } Secrets Manager options + +There is only one required setting that you must especify: `secrets_name`. + +### SettingsConfigDict options + +| Option | Required? | +| :------------- | :--------------------------------------------- | +| `secrets_name` | :fontawesome-solid-triangle-exclamation: required | +| `PUT` | :material-check-all: Update resource | +| `DELETE` | :material-close: Delete resource | + +## Using your boto3 client + +You can use an already created `boto3 client`. + +All you need to do is to add `secrets_client` to your `SettingsConfigDict`. + +```py title="user_settings.py" linenums="1" +import boto3 +from pydantic_settings_aws import SecretsManagerBaseSettings + +client = boto3.client("secretsmanager") + + +class AWSSecretsSettings(SecretsManagerBaseSettings): + model_config = SettingsConfigDict( + secrets_name="my/secret", + secrets_client=client + ) + + username: str + password: str +``` + +And now, **if** your secrets has the format: + +```json +{ + "username": "my-awesome-user-name", + "password": "really-strong-password" +} +``` + +You can just create your settings, and everything will be allright: + +```python +settings = AWSSecretsSettings() +``` diff --git a/docs/index.md b/docs/index.md index 0c0b76e..7334438 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,16 @@ # Pydantic Settings AWS -Pydantic Settings AWS is an extension of the great [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) library. +[![CI](https://github.com/ceb10n/pydantic-settings-aws/actions/workflows/ci.yml/badge.svg)](https://github.com/ceb10n/pydantic-settings-aws/actions) +[![codecov](https://codecov.io/github/ceb10n/pydantic-settings-aws/graph/badge.svg?token=K77HYDZR3P)](https://codecov.io/github/ceb10n/pydantic-settings-aws) +[![PyPI - Implementation](https://img.shields.io/pypi/implementation/pydantic-settings-aws)](https://pypi.org/project/pydantic-settings-aws) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pydantic-settings-aws)](https://pypi.org/project/pydantic-settings-aws) +[![Pydantic v2 only](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pydantic/pydantic/main/docs/badge/v2.json)](https://docs.pydantic.dev/latest/contributing/#badges) +[![PyPI - License](https://img.shields.io/pypi/l/pydantic-settings-aws)](https://pypi.org/project/pydantic-settings-aws) +[![Downloads](https://static.pepy.tech/badge/pydantic-settings-aws/month)](https://pepy.tech/project/pydantic-settings-aws) -It offers an easy way to load AWS settings from [Secrets Manager](https://aws.amazon.com/secrets-manager/). +Pydantic Settings AWS is an extension of the great 🚀 [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) library. + +It offers an easy way to load your settings hosted in ☁️ AWS [Secrets Manager](https://aws.amazon.com/secrets-manager/) and [Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html). ## Installation diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..6031603 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,8 @@ +.aws { + color: #fd6500; + } + +.yellow { + color: #fffec0 +} + diff --git a/mkdocs.yml b/mkdocs.yml index d39bcf6..0ed205f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,7 @@ site_name: Pydantic Settings AWS +site_description: AWS Secrets Manger & Parameter Store for Pydantic Settings repo_url: https://github.com/ceb10n/pydantic-settings-aws +site_url: https://ceb10n.github.io/pydantic-settings-aws/ theme: name: "material" @@ -31,6 +33,11 @@ plugins: branch: master markdown_extensions: + - admonition + - attr_list + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.highlight: anchor_linenums: true line_spans: __span @@ -40,7 +47,13 @@ markdown_extensions: - pymdownx.superfences - pymdownx.tabbed: alternate_style: true + - tables nav: - Pydantic Settings AWS Docs: index.md + - Examples: + - Secrets Manager: examples/secrets-manager.md - Reference: reference.md + +extra_css: + - stylesheets/extra.css diff --git a/pyproject.toml b/pyproject.toml index a1590cd..e017700 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,6 +43,10 @@ dependencies = [ ] dynamic = ['version'] +[project.urls] +Homepage = "https://github.com/ceb10n/pydantic-settings-aws" +Documentation = "https://ceb10n.github.io/pydantic-settings-aws/" +Repository = "https://github.com/ceb10n/pydantic-settings-aws" [tool.pytest.ini_options] testpaths = 'tests' From 3d6fbb3a7e687f9bb98551a15bb2a96239285d05 Mon Sep 17 00:00:00 2001 From: Rafael Marques Date: Sat, 20 Jul 2024 18:21:36 -0300 Subject: [PATCH 2/2] Add parameter store docs and added examples for secrets manager --- docs/configuration/parameter-store.md | 50 ++++++++++++++ docs/configuration/secrets-manager.md | 29 +++++++++ docs/examples/parameter-store.md | 56 ++++++++++++++++ docs/examples/secrets-manager.md | 94 ++++++++++++++++++++++----- docs/explanation.md | 0 docs/how-to-guides.md | 0 docs/reference.md | 3 + docs/stylesheets/extra.css | 1 - docs/tutorials.md | 0 mkdocs.yml | 6 ++ 10 files changed, 220 insertions(+), 19 deletions(-) create mode 100644 docs/configuration/parameter-store.md create mode 100644 docs/configuration/secrets-manager.md create mode 100644 docs/examples/parameter-store.md delete mode 100644 docs/explanation.md delete mode 100644 docs/how-to-guides.md delete mode 100644 docs/tutorials.md diff --git a/docs/configuration/parameter-store.md b/docs/configuration/parameter-store.md new file mode 100644 index 0000000..9ca27d6 --- /dev/null +++ b/docs/configuration/parameter-store.md @@ -0,0 +1,50 @@ +# :fontawesome-brands-aws:{ .aws } Parameter Store + +You can use `pydantic-settings-aws` to create your settings with data located in [Systems Manager: Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html). + +!!! info "Parameter Store content" + The content of the the parameter store **must** be a `string`. + +## :fontawesome-solid-screwdriver-wrench: SettingsConfigDict options + +There is no required setting that you must especify. + +### :fontawesome-solid-toolbox: Settings for boto3 client usage + +| Option | Required? | Description | +| :---------------------- | :--------------------------------- | :---------------------------------------------------------------------------- | +| `ssm_client` | :fontawesome-solid-xmark: optional | An existing boto3 client for Parameter Store if you already have one | +| `aws_region` | :fontawesome-solid-xmark: optional | The region your Parameter Store lives. Used only if you don't inform a client | +| `aws_profile` | :fontawesome-solid-xmark: optional | An existing aws configured profile. Used only if you don't inform a client | +| `aws_access_key_id` | :fontawesome-solid-xmark: optional | A valid Access Key Id. Used only if you don't inform a client | +| `aws_secret_access_key` | :fontawesome-solid-xmark: optional | A valid Secret Access Key Id. Used only if you don't inform a client | +| `aws_session_token` | :fontawesome-solid-xmark: optional | A valid Session Token. Used only if you don't inform a client | + +## :fontawesome-solid-tags: Configure your Parameter Store with Annotated + +You can declare your settings without any annotated field. In case you this, `pydantic-settings-aws` will look for a parater store with the same name as your field. + +### :fontawesome-solid-quote-right: Specify the name of the parameter + +In case all your parameters are in the same AWS account and region, you can just annotate you field with a string: + +```py linenums="1" +class MongoDBSettings(ParameterStoreBaseSettings): + model_config = SettingsConfigDict( + ssm_client=my_ssm_client + ) + + server_host: Annotated[str, "/databases/mongodb/host"] +``` + +### :fontawesome-regular-comments: Multiple regions and accounts + +If you need to work with multiple accounts and/or regions, you can create a client for each account: + +```py linenums="1" +class MongoDBSettings(ParameterStoreBaseSettings): + + prod_host: Annotated[str, {"ssm": "/prod/databases/mongodb/host", "ssm_client": prod_client}] + release_host: Annotated[str, {"ssm": "/release/databases/mongodb/host", "ssm_client": release_client}] + development_host: Annotated[str, {"ssm": "/development/databases/mongodb/host", "ssm_client": development_client}] +``` diff --git a/docs/configuration/secrets-manager.md b/docs/configuration/secrets-manager.md new file mode 100644 index 0000000..e45fff0 --- /dev/null +++ b/docs/configuration/secrets-manager.md @@ -0,0 +1,29 @@ +# :fontawesome-brands-aws:{ .aws } Secrets Manager + +You can use `pydantic-settings-aws` to create your settings with data located in AWS Secrets Manager. + +!!! info "Secrets Manager content" + The content of the Secrets Manager **must** be a valid JSON. + +## :fontawesome-solid-screwdriver-wrench: SettingsConfigDict options + +There is only one required setting that you must especify: `secrets_name`. + +### :fontawesome-solid-toolbox: Settings for boto3 client usage + +| Option | Required? | Description | +| :---------------------- | :------------------------------------------------ | :---------------------------------------------------------------------------- | +| `secrets_client` | :fontawesome-solid-xmark: optional | An existing boto3 client for Secrets Manager if you already have one | +| `aws_region` | :fontawesome-solid-xmark: optional | The region your Secrets Manager lives. Used only if you don't inform a client | +| `aws_profile` | :fontawesome-solid-xmark: optional | An existing aws configured profile. Used only if you don't inform a client | +| `aws_access_key_id` | :fontawesome-solid-xmark: optional | A valid Access Key Id. Used only if you don't inform a client | +| `aws_secret_access_key` | :fontawesome-solid-xmark: optional | A valid Secret Access Key Id. Used only if you don't inform a client | +| `aws_session_token` | :fontawesome-solid-xmark: optional | A valid Session Token. Used only if you don't inform a client | + +### :fontawesome-solid-user-secret: Settings for Secrets Manager + +| Option | Required? | Description | +| :---------------- | :------------------------------------------------ | :------------------------------- | +| `secrets_name` | :fontawesome-solid-triangle-exclamation: required | The name of your Secrets Manager | +| `secrets_version` | :fontawesome-solid-xmark: optional | The version of your secret | +| `secrets_stage` | :fontawesome-solid-xmark: optional | The stage of your secret | diff --git a/docs/examples/parameter-store.md b/docs/examples/parameter-store.md new file mode 100644 index 0000000..9e25bfc --- /dev/null +++ b/docs/examples/parameter-store.md @@ -0,0 +1,56 @@ +# :fontawesome-brands-aws:{ .aws } Parameter Store + +When working with `ParameterStoreBaseSettings`, you can work with parameters living in the same account and region, or with multiple accounts / regions. + + +## :fontawesome-solid-chart-simple: Simplest way + +The simplest way you can work with `ParameterStoreBaseSettings` is to leaving it all to boto3 and create your fields with the same name as your parameters: + +```py linenums="1" +class ParameterStoreSettings(ParameterStoreBaseSettings): + # no SettingsConfigDict + + mongodb_host: str + mongodb_db_name: str +``` + +In this case, `pydantic-settings-aws` will leave to boto3 to try to identify how he can connect to AWS, and then will look for the parameters with name `mongodb_host` and `mongodb_db_name`. + +!!! warning "We don't shadow pydantic and boto3 errors" + In the above case, if for some reason mongodb_host is `None`, it will raise a pydantic's `ValidationError`. + + +## :fontawesome-solid-quote-right: Specifying the name of the parameter + +For almost all cases, your parameter's name will be different from your field name. + +To deal with these cases, you must use `Annotated` and add the name of your parameter: + +```py linenums="1" +class DynamoDBSettings(ParameterStoreBaseSettings): + model_config = SettingsConfigDict( + ssm_client=my_ssm_client + ) + + db_name: Annotated[str, "/databases/dynamodb/payments/dbname"] +``` + +## :fontawesome-solid-viruses: Multiple accounts and regions + +If you need to work with multiple accounts or regions, you can use `Annotated` and specify a `dict`: + +```py +{ + "ssm": "parameter name", + "ssm_client": my_boto3_client +} +``` + +```py linenums="1" +class MongoDBSettings(ParameterStoreBaseSettings): + + prod_host: Annotated[str, {"ssm": "/prod/databases/mongodb/host", "ssm_client": prod_client}] + release_host: Annotated[str, {"ssm": "/release/databases/mongodb/host", "ssm_client": release_client}] + development_host: Annotated[str, {"ssm": "/development/databases/mongodb/host", "ssm_client": development_client}] +``` diff --git a/docs/examples/secrets-manager.md b/docs/examples/secrets-manager.md index d9bde67..83db30b 100644 --- a/docs/examples/secrets-manager.md +++ b/docs/examples/secrets-manager.md @@ -1,29 +1,14 @@ # :fontawesome-brands-aws:{ .aws } Secrets Manager -You can use `pydantic-settings-aws` to create your settings with data located in AWS Secrets Manager. +For more information about all the options and settings, refer to [Configuring Secrets Manager](../configuration/secrets-manager.md) -!!! info "Secrets Manager content" - The content of the Secrets Manager **must** be a valid JSON. - -## :fontawesome-brands-aws:{ .aws } Secrets Manager options - -There is only one required setting that you must especify: `secrets_name`. - -### SettingsConfigDict options - -| Option | Required? | -| :------------- | :--------------------------------------------- | -| `secrets_name` | :fontawesome-solid-triangle-exclamation: required | -| `PUT` | :material-check-all: Update resource | -| `DELETE` | :material-close: Delete resource | - -## Using your boto3 client +## :fontawesome-solid-toolbox: Using your boto3 client You can use an already created `boto3 client`. All you need to do is to add `secrets_client` to your `SettingsConfigDict`. -```py title="user_settings.py" linenums="1" +```py linenums="1" import boto3 from pydantic_settings_aws import SecretsManagerBaseSettings @@ -54,3 +39,76 @@ You can just create your settings, and everything will be allright: ```python settings = AWSSecretsSettings() ``` + +## :fontawesome-solid-toolbox: Getting specific version and stage of the secret + +```py linenums="1" +from pydantic_settings_aws import SecretsManagerBaseSettings + +class AWSSecretsSettings(SecretsManagerBaseSettings): + model_config = SettingsConfigDict( + secrets_name="my/secret", + secrets_version="2", + secrets_stage="AWSCURRENT" + ) + + username: str + password: str +``` + +## :fontawesome-solid-id-card: With AWS profile name + +```py linenums="1" +from pydantic_settings_aws import SecretsManagerBaseSettings + +class AWSSecretsSettings(SecretsManagerBaseSettings): + model_config = SettingsConfigDict( + secrets_name="my/secret", + aws_profile="DEV", + aws_region="sa-east-1" + ) + + username: str + password: str +``` + +## :fontawesome-solid-gears: With access key + +```py linenums="1" +from pydantic_settings_aws import SecretsManagerBaseSettings + +class AWSSecretsSettings(SecretsManagerBaseSettings): + model_config = SettingsConfigDict( + secrets_name="my/secret", + aws_region="us-east-1", + aws_access_key_id="my_aws_access_key_id", + aws_secret_access_key="my_aws_secret_access_key", + aws_session_token="my_aws_session_token" + ) + + username: str + password: str +``` + + +## :fontawesome-solid-gears: With IAM Identity Center (SSO) + +Just login with sso: + +```shell +aws sso login --profile DEV +``` + +And then you can leave all empty: + +```py linenums="1" +from pydantic_settings_aws import SecretsManagerBaseSettings + +class AWSSecretsSettings(SecretsManagerBaseSettings): + model_config = SettingsConfigDict( + secrets_name="my/secret" + ) + + username: str + password: str +``` diff --git a/docs/explanation.md b/docs/explanation.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/how-to-guides.md b/docs/how-to-guides.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/reference.md b/docs/reference.md index dbad461..0ba5f29 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -1,2 +1,5 @@ +!!! warning "🚧 Work in Progress" + This page is a work in progress. + ::: pydantic_settings_aws.settings.SecretsManagerBaseSettings diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 6031603..e62c344 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -5,4 +5,3 @@ .yellow { color: #fffec0 } - diff --git a/docs/tutorials.md b/docs/tutorials.md deleted file mode 100644 index e69de29..0000000 diff --git a/mkdocs.yml b/mkdocs.yml index 0ed205f..196a0d4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,8 @@ theme: - search.highlight - search.share - search.suggest + palette: + primary: orange plugins: - mkdocstrings @@ -51,7 +53,11 @@ markdown_extensions: nav: - Pydantic Settings AWS Docs: index.md + - Configuration: + - Parameter Store: configuration/parameter-store.md + - Secrets Manager: configuration/secrets-manager.md - Examples: + - Parameter Store: examples/parameter-store.md - Secrets Manager: examples/secrets-manager.md - Reference: reference.md