{"id":19926375,"url":"https://github.com/fullstackwithlawrence/pydantic-example","last_synced_at":"2025-07-19T22:41:39.541Z","repository":{"id":209521795,"uuid":"724296400","full_name":"FullStackWithLawrence/pydantic-example","owner":"FullStackWithLawrence","description":"Example usage of Pydantic for Python class and data validations","archived":false,"fork":false,"pushed_at":"2025-02-19T00:43:36.000Z","size":383,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T06:05:44.861Z","etag":null,"topics":["ci","ci-cd","dependabot","mergify","pydantic","python"],"latest_commit_sha":null,"homepage":"https://www.youtube.com/@FullStackWithLawrence","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FullStackWithLawrence.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"lpm0073","patreon":"FullStackWithLawrence"}},"created_at":"2023-11-27T19:47:23.000Z","updated_at":"2025-02-01T19:58:36.000Z","dependencies_parsed_at":"2024-01-31T01:49:46.079Z","dependency_job_id":"b42b2fe6-b4a3-44d9-b8e2-53e258bfda2e","html_url":"https://github.com/FullStackWithLawrence/pydantic-example","commit_stats":null,"previous_names":["lpm0073/automatic-grader","fullstackwithlawrence/pydantic-example"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullStackWithLawrence%2Fpydantic-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullStackWithLawrence%2Fpydantic-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullStackWithLawrence%2Fpydantic-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FullStackWithLawrence%2Fpydantic-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FullStackWithLawrence","download_url":"https://codeload.github.com/FullStackWithLawrence/pydantic-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241354994,"owners_count":19949291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci","ci-cd","dependabot","mergify","pydantic","python"],"created_at":"2024-11-12T22:29:02.783Z","updated_at":"2025-03-01T10:43:55.281Z","avatar_url":"https://github.com/FullStackWithLawrence.png","language":"Python","funding_links":["https://github.com/sponsors/lpm0073","https://patreon.com/FullStackWithLawrence"],"categories":[],"sub_categories":[],"readme":"# Pydantic Examples\n\n[![FullStackWithLawrence](https://a11ybadges.com/badge?text=FullStackWithLawrence\u0026badgeColor=orange\u0026logo=youtube\u0026logoColor=282828)](https://www.youtube.com/@FullStackWithLawrence)\u003cbr\u003e\n[![Python](https://a11ybadges.com/badge?logo=python)](https://www.python.org/)\n[![Pydantic](https://a11ybadges.com/badge?text=Pydantic\u0026badgeColor=e92063)](https://www.langchain.com/)\n[![JSON](https://a11ybadges.com/badge?logo=json)](https://www.json.org/json-en.html)\u003cbr\u003e\n[![Release Notes](https://img.shields.io/github/release/FullStackWithLawrence/pydantic-example)](https://github.com/FullStackWithLawrence/pydantic-example/releases)\n![GHA pushMain Status](https://img.shields.io/github/actions/workflow/status/FullStackWithLawrence/pydantic-example/pushMain.yml?branch=main)\n[![AGPL License](https://img.shields.io/github/license/overhangio/tutor.svg?style=flat-square)](https://www.gnu.org/licenses/agpl-3.0.en.html)\n[![hack.d Lawrence McDaniel](https://img.shields.io/badge/hack.d-Lawrence%20McDaniel-orange.svg)](https://lawrencemcdaniel.com)\n\n[Pydantic](https://docs.pydantic.dev/latest/) is the most widely used data validation library for Python. This repo demonstrates three popular use cases for Pydantic:\n\n1. **Validation**. Pydantic ensures that the data your class instances receive matches the expected format/type. It validates the input data types and structures, and raises exceptions when the data is invalid. See the [example Python class](./grader/grader.py) in this repo.\n\n2. **Data Parsing and Serialization**. See the [JSON validator](./grader/langchain.py) in this repo for an example of how to validate a JSON string against a schema. Pydantic can parse complex data types, like JSON, into Python data structures. It can also serialize Python objects back into JSON.\n\n3. **Exception Handling**. See the [custom exceptions](./grader/exceptions.py) in this repo which demonstrate how you catch Pydantic exceptions, analyze them, and then raise your own custom exceptions.\n\n## Installation\n\n```console\ngit clone https://github.com/FullStackWithLawrence/pydantic-example.git\ncd pydantic-example\nmake init\nsource venv/bin/activate\n```\n\n## Usage\n\n```console\n# command-line help\npython3 -m grader.batch -h\n\n# example usage\npython3 -m grader.batch 'path/to/homework/json/files/'\n```\n\n### About This Example\n\nThe code in the repo implements an automated homework grader that I used for an online course that I taught. It analyzes a text file that is supposed to contain a valid JSON object, and then returns a grade based on how closely the JSON object matches the intended schema.\n\n### Rubric\n\nRubric values are expressed as floats between 0 and 1.00, and can be overridden with environment variables.\n\n```console\nAG_INCORRECT_RESPONSE_TYPE_PENALTY_PCT=0.10\nAG_INCORRECT_RESPONSE_VALUE_PENALTY_PCT=0.15\nAG_RESPONSE_FAILED_PENALTY_PCT=0.20\nAG_INVALID_RESPONSE_STRUCTURE_PENALTY_PCT=0.30\nAG_INVALID_JSON_RESPONSE_PENALTY_PCT=0.50\n```\n\n### Expected output\n\n```console\n% done! Graded 10 assignments. Output files are in path/to/homework/json/files/out\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n  \"grade\": 100,\n  \"message\": \"Great job!\",\n  \"message_type\": \"Success\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n    \"grade\": 80,\n    \"message\": \"The assignment's statusCode must be 200. received: 403\",\n    \"message_type\": \"ResponseFailedError\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n    \"grade\": 90,\n    \"message\": \"The assignment's statusCode must be an integer. received: \u003cclass 'str'\u003e\",\n    \"message_type\": \"IncorrectResponseTypeError\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n    \"grade\": 70,\n    \"message\": \"The assignment is missing one or more required keys. missing: {'type', 'example', 'additional_kwargs'}\",\n    \"message_type\": \"InvalidResponseStructureError\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n    \"grade\": 70,\n    \"message\": \"The messages list must contain at least two elements. messages: [{'content': \\\"Oh, how delightful. I can't think of anything I'd rather do than interact with a bunch of YouTube viewers. Just kidding, I'd rather be doing literally anything else. But go ahead, introduce me to your lovely audience. I'm sure they'll be absolutely thrilled to meet me.\\\", 'additional_kwargs': {}, 'type': 'ai', 'example': False}]\",\n    \"message_type\": \"InvalidResponseStructureError\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n  \"grade\": 70,\n  \"message\": \"All elements in the messages list must be dictionaries. messages: ['bad', 'data']\",\n  \"message_type\": \"InvalidResponseStructureError\"\n}\n```\n\n\u003c!-- prettier-ignore --\u003e\n```json\n{\n  \"grade\": 70,\n  \"message\": \"The request_meta_data key lambda_langchain must exist. request_meta_data: {}\",\n  \"message_type\": \"InvalidResponseStructureError\"\n}\n```\n\n## Contributing\n\nThis project uses a mostly automated pull request and unit testing process. See the resources in .github for additional details. You additionally should ensure that pre-commit is installed and working correctly on your dev machine by running the following command from the root of the repo.\n\n```console\npre-commit run --all-files\n```\n\nPull requests should pass these tests before being submitted:\n\n```console\nmake test\n```\n\n### Developer setup\n\n```console\ngit clone https://github.com/lpm0073/automatic-grader.git\ncd automatic-grader\nmake init\nmake activate\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstackwithlawrence%2Fpydantic-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffullstackwithlawrence%2Fpydantic-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffullstackwithlawrence%2Fpydantic-example/lists"}