-
-
Notifications
You must be signed in to change notification settings - Fork 52
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
Add opt-in strict string format validation #451
Conversation
92dee76
to
a69a432
Compare
47c3aab
to
571edfa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome hard work! thank you! speaking of your gotten knowledges about how to contribute we need to write CONTRIBUTING.md
someday. but this will be separated PR for sure
6ad722a
to
6de9cac
Compare
7bcd93e
to
eb1d28b
Compare
8d7deee
to
1c82c73
Compare
34444be
to
9807a81
Compare
hi @MarshalX - ok all of the cases are passing with no skipping! I found that the spec and test cases in the interop valid/invalid For example, looking at the AT-URI validation, I noticed what appear to be few differences between the regex I added and
let me know if you think i'm missing something here or if you think I should move some of these requirements into the types in also, just in case it comes up: i had a tricky problem with loading the test cases where I was calling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
such an amazing hard work you did! let's move that discussion about different of the AtUri
to different issue; for now we are okay to have 2 validation logic.
i have nothing to add except comments that i left and question about documentation. since we support .format
of the LexString
do we want to show it in the documentation? Right now fields are not show their format at the atproto.blue. We could create separate issue for it to finally merge your great PR
The link to built docs from this PR is https://atproto--451.org.readthedocs.build/en/451/
abda096
to
a1f3e29
Compare
will do! thanks for all the help thus far 🙂 |
I will take a look as soon as I can! |
lint doh appease old python tests n tweaks checkpoint
placate 3.8
bad5512
to
1ea9021
Compare
hi @MarshalX - hrmm can you share more on how you ended up with that? I may be missing something silly but can't directly reproduce that (with an example like this) examplefrom typing import TypedDict
from atproto_client.models import base, string_formats
from pydantic import TypeAdapter, ValidationError
class Params(base.ParamsModelBase):
actor: string_formats.Handle
class ParamsDict(TypedDict):
actor: string_formats.Handle
# Test data
some_good_handle = 'test.bsky.social'
some_bad_handle = 'invalid@ @handle'
# Test both with and without strict validation
strict_context = {'strict_string_format': True}
non_strict_context = {'strict_string_format': False}
# Initialize adapters with explicit types
HandleTypeAdapter: TypeAdapter[str] = TypeAdapter(string_formats.Handle)
ParamsTypeAdapter: TypeAdapter[ParamsDict] = TypeAdapter(ParamsDict)
ParamsModelAdapter: TypeAdapter[Params] = TypeAdapter(Params)
def run_validation_test(context: dict[str, bool]) -> None:
mode = 'strict' if context['strict_string_format'] else 'non-strict'
print(f'\n=== Testing {mode} mode ===')
print('\n1. Direct Handle validation:')
try:
handle_result: str = HandleTypeAdapter.validate_python(some_bad_handle, context=context)
print(f'Validation passed: {handle_result=}')
except ValidationError as e:
print(f'Validation failed: {e!s}')
print('\n2. TypedDict validation:')
try:
params_result: ParamsDict = ParamsTypeAdapter.validate_python({'actor': some_bad_handle}, context=context)
print(f'Validation passed: {params_result=}')
except ValidationError as e:
print(f'Validation failed: {e!s}')
print('\n3. Pydantic Model validation:')
try:
model_result: Params = ParamsModelAdapter.validate_python({'actor': some_bad_handle}, context=context)
print(f'Validation passed: {model_result=}')
except ValidationError as e:
print(f'Validation failed: {e!s}')
run_validation_test(non_strict_context)
run_validation_test(strict_context) stdout» python examples/advanced_usage/validate_string_formats.py
=== Testing non-strict mode ===
1. Direct Handle validation:
Validation passed: handle_result='invalid@ @handle'
2. TypedDict validation:
Validation passed: params_result={'actor': 'invalid@ @handle'}
3. Pydantic Model validation:
Validation passed: model_result=Params(actor='invalid@ @handle')
=== Testing strict mode ===
1. Direct Handle validation:
Validation failed: 1 validation error for function-before[wrapper(), str]
Value error, Invalid handle: must be a domain name (e.g. user.bsky.social) with max length 253 [type=value_error, input_value='invalid@ @handle', input_type=str]
For further information visit https://errors.pydantic.dev/2.10/v/value_error
2. TypedDict validation:
Validation failed: 1 validation error for typed-dict
actor
Value error, Invalid handle: must be a domain name (e.g. user.bsky.social) with max length 253 [type=value_error, input_value='invalid@ @handle', input_type=str]
For further information visit https://errors.pydantic.dev/2.10/v/value_error
3. Pydantic Model validation:
Validation failed: 1 validation error for Params
actor
Value error, Invalid handle: must be a domain name (e.g. user.bsky.social) with max length 253 [type=value_error, input_value='invalid@ @handle', input_type=str]
For further information visit https://errors.pydantic.dev/2.10/v/value_error |
@zzstoatzz i mean does it rly need to be complex type with pydantic validation for TypedDict? Speaking of the highlighted problem on the screenshot, probably PyCharm (Intellij + Python plugin in my case) is just dumb xD I do not say that it won't work. It will. But IDE`s analyzers struggle with it. We use TypedDict only to help the users with field suggestions in IDE. And for static type analyzers (for someone who cares). When the user uses dict-based params instead of proper model. But under the hood, we will use proper model. So this is just a syntax sugar for the users who want to write it fast in unsafe dict-driven Python manure tl;dr no problems with it; we just do not use TypedDict directly (only for type annotating); my IDE could not handle it |
oh ok! I was using pylance strict but I probably missed something and I'm happy to take a stab at any further type-smoothing that would be helpful! thanks again for all your help 🙂 |
adds pydantic validation per #406 (comment). see the usage example
did
did:plc:z72i7hdynmk6r22z27h6tvur
did:[a-z]+:[a-zA-Z0-9._%-]+
(max 2KB, no /?#[]@)handle
alice.bsky.social
at-uri
at://alice.bsky.social/app.bsky.feed.post/3jxtb5w2hkt2m
at://
+ handle/DID + optional/collection/rkey
. Max 8KB. No query/fragment in Lexicon.datetime
2024-11-24T06:02:00Z
nsid
app.bsky.feed.post
tid
3jxtb5w2hkt2m
record-key
3jxtb5w2hkt2m
uri
https://example.com/path
did:plc
did:plc:z72i7hdynmk6r22z27h6tvur
does not address open questions regarding the language types or
re2
. happy to chat on those if they'd be blocking heremay close #406
notes
I ran this to generate models
and this to update docs
and this to run the new tests
if desirable, I can follow up this PR to add contribution instructions to the current README section (for
uv
at least, and perhaps a TODO for properpoetry
usage, since I don't really use that) - let me know!in/valid examples for tests are sourced from https://github.com/bluesky-social/atproto/tree/main/interop-test-files/syntax