Skip to content

Commit

Permalink
get_secret() method plus updated docs, refs #46
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Apr 27, 2024
1 parent f5c3fa9 commit a4338f1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
34 changes: 30 additions & 4 deletions datasette_enrichments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def register_secrets():
return secrets


class SecretError(Exception):
pass


class Enrichment(ABC):
_subclasses = []

Expand Down Expand Up @@ -108,6 +112,26 @@ def __init_subclass__(cls, **kwargs):
def __repr__(self):
return "<Enrichment: {}>".format(self.slug)

async def get_secret(self, datasette: "Datasette", config: dict):
if self.secret is None:
breakpoint()
raise SecretError("No secret defined for this enrichment")
secret = await get_secret(datasette, self.secret.name)
if secret is not None:
return secret
# Try the stashed secrets instead
if not hasattr(datasette, "_enrichments_stashed_secrets"):
breakpoint()
raise SecretError("No secrets have been stashed")
stashed_keys = datasette._enrichments_stashed_secrets
stash_key = config.get("enrichment_secret")
if stash_key not in stashed_keys:
breakpoint()
raise SecretError(
"No secret found in stash for {}".format(self.secret.name)
)
return stashed_keys[stash_key]

async def log_error(
self, db: "Database", job_id: int, ids: List[IdType], error: str
):
Expand Down Expand Up @@ -137,7 +161,9 @@ async def _get_config_form(
self, datasette: "Datasette", db: "Database", table: str
):
# Helper method that adds a `_secret` form field if the enrichment has a secret
FormClass = await self.get_config_form(datasette, db, table)
FormClass = await async_call_with_supported_arguments(
self.get_config_form, datasette=datasette, db=db, table=table
)
if self.secret is None:
return FormClass
# If secret is already set, return form unmodified
Expand All @@ -146,10 +172,10 @@ async def _get_config_form(

# Otherwise, return form with secret field
def stash_api_key(form, field):
if not hasattr(datasette, "_enrichments_gpt_stashed_keys"):
datasette._enrichments_gpt_stashed_keys = {}
if not hasattr(datasette, "_enrichments_stashed_secrets"):
datasette._enrichments_stashed_secrets = {}
key = secrets.token_urlsafe(16)
datasette._enrichments_gpt_stashed_keys[key] = field.data
datasette._enrichments_stashed_secrets[key] = field.data
field.data = key

formatted_description = self.secret.description
Expand Down
9 changes: 8 additions & 1 deletion docs/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,14 @@ Configuring your enrichment like this will result in the following behavior:

- If a user sets a `DATASETTE_SECRETS_TRAIN_ENTHUSIASTS_API_KEY` environment variable, that value will be used as the API key. You should mention this in your enrichment's documentation.
- Otherwise, if the user has configured [datasette-secrets](https://datasette.io/plugins/datasette-secrets) to store secrets in the database, admin users with the `manage-secrets` permission will get the option to set that secret as part of the Datasette web UI.
- If neither of the above are true, any time any user tries to run this enrichment they will be prompted to specify a secret which will be used for that run but will not be stored anywhere.
- If neither of the above are true, any time any user tries to run this enrichment they will be prompted to specify a secret which will be used for that run but will not be stored outside of memory used by the code that runs the enrichment.

With a secret configured in this way, your various class methods such as `initialize()`, `enrich_batch()` and `finalize()` can access the secret value using `await self.get_secret(datasette)` like this:

```python
api_key = await self.get_secret(datasette, config)
```
You must pass both the `datasette` and the `config` arguments that were passed to those methods.

## Writing tests for enrichments

Expand Down

0 comments on commit a4338f1

Please sign in to comment.