Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add JSON Schema Property helpers for allowed_values (enum) and examples #1098

Merged
merged 28 commits into from
Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9f56e96
chore: initial refactor for readability
aaronsteers Oct 20, 2022
b85760a
feat: add Meltano rendering logic in private helper module
aaronsteers Oct 20, 2022
8d95b22
feat: add `secret=True` support in JSON Schema type helpers
aaronsteers Oct 20, 2022
2820b91
change: update examples to use 'secret=True' for protected settings
aaronsteers Oct 20, 2022
e74be3f
chore: flake8 fix
aaronsteers Oct 20, 2022
e0239b5
add unit tests for type helpers
aaronsteers Oct 20, 2022
17905b1
fix missing secret flag on unit test
aaronsteers Oct 20, 2022
9d6a364
chore: get tests passing
aaronsteers Oct 20, 2022
8ad7727
chore: add test for description
aaronsteers Oct 20, 2022
2792aa1
chore: remove commented code
aaronsteers Oct 20, 2022
b86cfc4
chore: remove files related to #1094
aaronsteers Oct 20, 2022
2b83266
chore: revert --about updates
aaronsteers Oct 20, 2022
f8c734a
Merge branch 'main' into 77-feat-secrets-support-in-config-and-streams
aaronsteers Oct 20, 2022
0160f01
use constants for annotation keys
aaronsteers Oct 21, 2022
d9647bd
chore: bump validator to Draft7
aaronsteers Oct 21, 2022
40041ed
chore: add testing for is_secret_type
aaronsteers Oct 21, 2022
839b165
chore: add tests
aaronsteers Oct 21, 2022
a82851e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 21, 2022
c2b64d7
chore: more tests
aaronsteers Oct 21, 2022
f0b680b
Merge branch '77-feat-secrets-support-in-config-and-streams' of https…
aaronsteers Oct 21, 2022
372fc34
docs: add info to FAQ
aaronsteers Oct 21, 2022
8eb0026
chore: add test for integer type
aaronsteers Oct 21, 2022
0704930
Merge remote-tracking branch 'origin/main' into aj-more-type-helpers
aaronsteers Oct 21, 2022
65207ee
feat: add `allowed_values` and `examples` to Property class
aaronsteers Oct 21, 2022
ebfd711
chore: add tests and samples
aaronsteers Oct 21, 2022
28dd4c3
chore: fix missing typing import
aaronsteers Oct 21, 2022
e640769
docs: updated usage examples in typing module ref
aaronsteers Oct 21, 2022
a48c7a2
Merge branch 'main' into aj-more-type-helpers
aaronsteers Oct 24, 2022
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
4 changes: 3 additions & 1 deletion samples/sample_tap_google_analytics/ga_tap.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class SampleTapGoogleAnalytics(Tap):
name: str = "sample-tap-google-analytics"
config_jsonschema = PropertiesList(
Property("view_id", StringType(), required=True),
Property("client_email", StringType(), required=True),
Property(
"client_email", StringType(), required=True, examples=["[email protected]"]
),
Property("private_key", StringType(), required=True, secret=True),
).to_dict()

Expand Down
1 change: 1 addition & 0 deletions samples/sample_tap_sqlite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class SQLiteTap(SQLTap):
DB_PATH_CONFIG,
th.StringType,
description="The path to your SQLite database file(s).",
examples=["./path/to/my.db", "/absolute/path/to/my.db"],
)
).to_dict()

Expand Down
28 changes: 22 additions & 6 deletions singer_sdk/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
.. code-block:: python

jsonschema = PropertiesList(
Property("username", StringType, required=True),
Property("password", StringType, required=True, secret=True),

Property("id", IntegerType, required=True),
Property("name", StringType),
Property("tags", ArrayType(StringType)),
Property("ratio", NumberType),
Property("foo_or_bar", StringType, allowed_values=["foo", "bar"]),
Property("ratio", NumberType, examples=[0.25, 0.75, 1.0]),
Property("days_active", IntegerType),
Property("updated_on", DateTimeType),
Property("is_deleted", BooleanType),

Property(
"author",
ObjectType(
Property("id", StringType),
Property("name", StringType),
)
),
Property("tags", ArrayType(StringType)),
Property(
"groups",
ArrayType(
Expand All @@ -42,7 +46,7 @@
from __future__ import annotations

import sys
from typing import Generic, Mapping, TypeVar, Union, cast
from typing import Any, Generic, Mapping, TypeVar, Union, cast

import sqlalchemy
from jsonschema import validators
Expand Down Expand Up @@ -356,8 +360,10 @@ def __init__(
wrapped: W | type[W],
required: bool = False,
default: _JsonValue = None,
description: str = None,
secret: bool = False,
description: str | None = None,
secret: bool | None = False,
allowed_values: list[Any] | None = None,
examples: list[Any] | None = None,
) -> None:
"""Initialize Property object.

Expand All @@ -374,13 +380,19 @@ def __init__(
default: Default value in the JSON Schema.
description: Long-text property description.
secret: True if this is a credential or other secret.
allowed_values: A list of allowed value options, if only specific values
are permitted. This will define the type as an 'enum'.
examples: Optional. A list of one or more sample values. These may be
displayed to the user as hints of the expected format of inputs.
"""
self.name = name
self.wrapped = wrapped
self.optional = not required
self.default = default
self.description = description
self.secret = secret
self.allowed_values = allowed_values or None
self.examples = examples or None

@property
def type_dict(self) -> dict: # type: ignore # OK: @classproperty vs @property
Expand Down Expand Up @@ -423,6 +435,10 @@ def to_dict(self) -> dict:
JSONSCHEMA_ANNOTATION_WRITEONLY: True,
}
)
if self.allowed_values:
type_dict.update({"enum": self.allowed_values})
if self.examples:
type_dict.update({"examples": self.examples})
return {self.name: type_dict}


Expand Down
16 changes: 16 additions & 0 deletions tests/core/test_jsonschema_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@ def test_inbuilt_type(json_type: JSONTypeHelper, expected_json_schema: dict):
},
{is_integer_type},
),
(
Property(
"my_prop9",
IntegerType,
allowed_values=[1, 2, 3, 4, 5, 6, 7, 8, 9],
examples=[1, 2, 3],
),
{
"my_prop9": {
"type": ["integer", "null"],
"enum": [1, 2, 3, 4, 5, 6, 7, 8, 9],
"examples": [1, 2, 3],
}
},
{is_integer_type},
),
],
)
def test_property_creation(
Expand Down