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

More types #3

Open
18 of 20 tasks
samuelcolvin opened this issue Jan 28, 2022 · 6 comments
Open
18 of 20 tasks

More types #3

samuelcolvin opened this issue Jan 28, 2022 · 6 comments

Comments

@samuelcolvin
Copy link
Owner

samuelcolvin commented Jan 28, 2022

@jefftriplett
Copy link

Not sure if these are worth adding, but I was looking for them while reading the docs:

  • IsStream helpful for File IO
  • IsUri to know if something is a value uri/url?
  • IsFile and IsFolder maybe too much overlap with pathlib but seems almost in scope.

These are fresh on my mind from trying to think through some common ways to access "things in strings" https://github.com/jefftriplett/django-fett/blob/main/src/fett.py#L295-L328

@samuelcolvin
Copy link
Owner Author

samuelcolvin commented Feb 25, 2022

ye makes sense.

IsUri would be useful but I'm a bit torn about how to implement it. I don't want to duplicate the masses of URI logic from pydantic, but I also don't want to create another library or make pydantic a dependency of this. Maybe one of those other libraries like yarl could help

The other types i haven't needed since I've always used dirty-equals and equivalent for checking the response from APIs or contents of databases, where you don't get steams or files.

@osintalex
Copy link
Contributor

I think IsUri would be pretty useful if poss. I'm literally about to work on something where I'd use that if it was an option.

Could keep it simple and offload some of the url validation logic to the user?

i.e. something simple like this just with urllib?

def is_uri(uri: str, required: list[str], value: dict[str, str] = None) -> bool:
    parsed: ParseResult = urlparse(url=uri)
    attributes_present: Iterator[str] = (getattr(parsed, x) for x in required)
    if value:
        values_present: Iterator[str] = (getattr(parsed, k) == v for k, v in value.items())
        return all(attributes_present) and all(values_present)
    return all(attributes_present)


is_uri(uri="https://www.example.com", required=["scheme", "netloc"])  # True
is_uri(uri="https://www.example.com", required=["scheme", "netloc", "path"])  # False
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"])  # True
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"], value={"path": "nothing"})  # False
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"], value={"path": "/stuff"})  # True

@samuelcolvin
Copy link
Owner Author

Urllib is definitely not suitable for checking urls, is easy too lenient.

Simplest solution would probably be to copy the regex and logic from pydantic. We know that's widely used and works.

Or we add a dependency like yarl.

@osintalex
Copy link
Contributor

That all makes sense! Would you be interested in a PR on IsUri using the Pydantic logic? Appreciate that might be better to leave to you as the author of Pydantic 😅

I've been working on testing APIs recently and thought some of these types could be useful. Although I may be predisposed to focus on types that would be useful for cybersecurity applications and perhaps less so elsewhere. Anyhow, would you be interested in a PR on any of these?

  • IsIP for v4 and v6, possibly with subnet support
  • IsHash for different hashes, i.e. SHA256, MD5 etc.
  • IsUUID perhaps with options to check different versions
  • I'm not sure if this aligns with your vision for the library, but a way of testing if something matches a Pydantic class could be handy, i.e. IsModel(MyPydanticClass). Even though t's just syntactic sugar for testing a Pydantic class instantiates without errors, I would find it nifty to do something like the below since I so often use Pydantic models to define data/response models in API designs.
class Preferences(BaseModel):
    subscribed: bool
    services: list[str]

   assert user_data == {
       'id': IsPositiveInt, 
       'username': 'samuelcolvin', 
       'avatar_file': IsStr(regex=r'/[a-z0-9\-]{10}/example\.png'), 
       'settings_json': IsJson({'theme': 'dark', 'language': 'en'}), 
       'created_ts': IsNow(delta=3), 
       'preferences': IsModel(Preferences)
   }

@samuelcolvin
Copy link
Owner Author

  • IsUUID is done
  • IsIP yes, PR welcome
  • IsHash yes, PR welcome
  • IsUrl yes, PR welcome, you'll need to make pydantic a dependency, but that's fine by me
  • IsModel I'm not so sure about, I don't think it's necessary, you can always create your own custom type

This was referenced Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants