|
338 | 338 | "outputs": [],
|
339 | 339 | "source": [
|
340 | 340 | "#| export\n",
|
| 341 | + "custom_types = {Path}\n", |
| 342 | + "\n", |
341 | 343 | "def _handle_type(t, defs):\n",
|
342 | 344 | " \"Handle a single type, creating nested schemas if necessary\"\n",
|
343 | 345 | " if t is NoneType: return {'type': 'null'}\n",
|
344 |
| - " if isinstance(t, type) and not issubclass(t, (int, float, str, bool)):\n", |
| 346 | + " if t in custom_types: return {'type':'string', 'format':t.__name__}\n", |
| 347 | + " if isinstance(t, type) and not issubclass(t, (int, float, str, bool)) or inspect.isfunction(t):\n", |
345 | 348 | " defs[t.__name__] = _get_nested_schema(t)\n",
|
346 | 349 | " return {'$ref': f'#/$defs/{t.__name__}'}\n",
|
347 | 350 | " return {'type': _types(t)[0]}"
|
348 | 351 | ]
|
349 | 352 | },
|
| 353 | + { |
| 354 | + "cell_type": "code", |
| 355 | + "execution_count": null, |
| 356 | + "id": "16dbf080", |
| 357 | + "metadata": {}, |
| 358 | + "outputs": [ |
| 359 | + { |
| 360 | + "data": { |
| 361 | + "text/plain": [ |
| 362 | + "({'type': 'integer'}, {'type': 'string', 'format': 'Path'})" |
| 363 | + ] |
| 364 | + }, |
| 365 | + "execution_count": null, |
| 366 | + "metadata": {}, |
| 367 | + "output_type": "execute_result" |
| 368 | + } |
| 369 | + ], |
| 370 | + "source": [ |
| 371 | + "_handle_type(int, None), _handle_type(Path, None)" |
| 372 | + ] |
| 373 | + }, |
350 | 374 | {
|
351 | 375 | "cell_type": "code",
|
352 | 376 | "execution_count": null,
|
|
500 | 524 | {
|
501 | 525 | "cell_type": "code",
|
502 | 526 | "execution_count": null,
|
503 |
| - "id": "bfaa1712", |
| 527 | + "id": "38b0f97e", |
504 | 528 | "metadata": {},
|
505 | 529 | "outputs": [],
|
506 | 530 | "source": [
|
507 |
| - "#| export\n", |
| 531 | + "# exports\n", |
508 | 532 | "def _get_nested_schema(obj):\n",
|
509 | 533 | " \"Generate nested JSON schema for a class or function\"\n",
|
510 | 534 | " d = docments(obj, full=True)\n",
|
|
616 | 640 | {
|
617 | 641 | "cell_type": "code",
|
618 | 642 | "execution_count": null,
|
619 |
| - "id": "700298e3", |
| 643 | + "id": "23f54386", |
620 | 644 | "metadata": {},
|
621 | 645 | "outputs": [],
|
622 | 646 | "source": [
|
|
643 | 667 | {
|
644 | 668 | "cell_type": "code",
|
645 | 669 | "execution_count": null,
|
646 |
| - "id": "23c75a4a", |
| 670 | + "id": "e7311af9", |
647 | 671 | "metadata": {},
|
648 | 672 | "outputs": [
|
649 | 673 | {
|
|
696 | 720 | {
|
697 | 721 | "cell_type": "code",
|
698 | 722 | "execution_count": null,
|
699 |
| - "id": "0e6f7789", |
| 723 | + "id": "80203962", |
700 | 724 | "metadata": {},
|
701 | 725 | "outputs": [
|
702 | 726 | {
|
|
730 | 754 | "id": "e3f36f8a",
|
731 | 755 | "metadata": {},
|
732 | 756 | "source": [
|
733 |
| - "This also works with class methods:" |
| 757 | + "This also works with instance methods:" |
734 | 758 | ]
|
735 | 759 | },
|
736 | 760 | {
|
|
783 | 807 | {
|
784 | 808 | "cell_type": "code",
|
785 | 809 | "execution_count": null,
|
786 |
| - "id": "89664bc9", |
| 810 | + "id": "ce3be915", |
787 | 811 | "metadata": {},
|
788 | 812 | "outputs": [
|
789 | 813 | {
|
|
799 | 823 | " 'required': ['turns'],\n",
|
800 | 824 | " '$defs': {'Turn': {'type': 'object',\n",
|
801 | 825 | " 'properties': {'speaker_a': {'type': 'string',\n",
|
802 |
| - " 'description': \"First speaker to speak's message\"},\n", |
| 826 | + " 'description': \"First speaker's message\"},\n", |
803 | 827 | " 'speaker_b': {'type': 'string',\n",
|
804 |
| - " 'description': \"Second speaker to speak's message\"}},\n", |
| 828 | + " 'description': \"Second speaker's message\"}},\n", |
805 | 829 | " 'title': 'Turn',\n",
|
806 | 830 | " 'required': ['speaker_a', 'speaker_b']}}}}"
|
807 | 831 | ]
|
|
816 | 840 | " \"Turn between two speakers\"\n",
|
817 | 841 | " def __init__(\n",
|
818 | 842 | " self,\n",
|
819 |
| - " speaker_a:str, # First speaker to speak's message\n", |
820 |
| - " speaker_b:str, # Second speaker to speak's message\n", |
| 843 | + " speaker_a:str, # First speaker's message\n", |
| 844 | + " speaker_b:str, # Second speaker's message\n", |
821 | 845 | " ): store_attr()\n",
|
822 | 846 | "\n",
|
823 | 847 | "class Conversation:\n",
|
|
850 | 874 | " 'required': ['turns'],\n",
|
851 | 875 | " '$defs': {'Turn': {'type': 'object',\n",
|
852 | 876 | " 'properties': {'speaker_a': {'type': 'string',\n",
|
853 |
| - " 'description': \"First speaker to speak's message\"},\n", |
| 877 | + " 'description': \"First speaker's message\"},\n", |
854 | 878 | " 'speaker_b': {'type': 'string',\n",
|
855 |
| - " 'description': \"Second speaker to speak's message\"}},\n", |
| 879 | + " 'description': \"Second speaker's message\"}},\n", |
856 | 880 | " 'title': 'Turn',\n",
|
857 | 881 | " 'required': ['speaker_a', 'speaker_b']}}}}"
|
858 | 882 | ]
|
|
893 | 917 | " 'required': ['turns'],\n",
|
894 | 918 | " '$defs': {'Turn': {'type': 'object',\n",
|
895 | 919 | " 'properties': {'speaker_a': {'type': 'string',\n",
|
896 |
| - " 'description': \"First speaker to speak's message\"},\n", |
| 920 | + " 'description': \"First speaker's message\"},\n", |
897 | 921 | " 'speaker_b': {'type': 'string',\n",
|
898 |
| - " 'description': \"Second speaker to speak's message\"}},\n", |
| 922 | + " 'description': \"Second speaker's message\"}},\n", |
899 | 923 | " 'title': 'Turn',\n",
|
900 | 924 | " 'required': ['speaker_a', 'speaker_b']}}}}"
|
901 | 925 | ]
|
|
916 | 940 | "get_schema(SetConversation)"
|
917 | 941 | ]
|
918 | 942 | },
|
| 943 | + { |
| 944 | + "cell_type": "code", |
| 945 | + "execution_count": null, |
| 946 | + "id": "8cf3f35c", |
| 947 | + "metadata": {}, |
| 948 | + "outputs": [], |
| 949 | + "source": [ |
| 950 | + "#| exports\n", |
| 951 | + "def PathArg(\n", |
| 952 | + " path: str # A filesystem path\n", |
| 953 | + "): return Path(path)" |
| 954 | + ] |
| 955 | + }, |
| 956 | + { |
| 957 | + "cell_type": "markdown", |
| 958 | + "id": "169212a6", |
| 959 | + "metadata": {}, |
| 960 | + "source": [ |
| 961 | + "Paths are a special case, since they only take `*args` and `**kwargs` as params, but normally we'd use them in a schema by just passing a str. So we create a custom param type for that." |
| 962 | + ] |
| 963 | + }, |
| 964 | + { |
| 965 | + "cell_type": "code", |
| 966 | + "execution_count": null, |
| 967 | + "id": "e9135dfa", |
| 968 | + "metadata": {}, |
| 969 | + "outputs": [ |
| 970 | + { |
| 971 | + "data": { |
| 972 | + "text/plain": [ |
| 973 | + "{'name': 'path_test',\n", |
| 974 | + " 'description': 'Mandatory docstring',\n", |
| 975 | + " 'input_schema': {'type': 'object',\n", |
| 976 | + " 'properties': {'a': {'type': 'object',\n", |
| 977 | + " 'description': 'a type hint',\n", |
| 978 | + " '$ref': '#/$defs/PathArg'},\n", |
| 979 | + " 'b': {'type': 'object',\n", |
| 980 | + " 'description': 'b type hint',\n", |
| 981 | + " '$ref': '#/$defs/PathArg'}},\n", |
| 982 | + " 'title': None,\n", |
| 983 | + " 'required': ['a', 'b'],\n", |
| 984 | + " '$defs': {'PathArg': {'type': 'object',\n", |
| 985 | + " 'properties': {'path': {'type': 'string',\n", |
| 986 | + " 'description': 'A filesystem path'}},\n", |
| 987 | + " 'title': None,\n", |
| 988 | + " 'required': ['path']}}}}" |
| 989 | + ] |
| 990 | + }, |
| 991 | + "execution_count": null, |
| 992 | + "metadata": {}, |
| 993 | + "output_type": "execute_result" |
| 994 | + } |
| 995 | + ], |
| 996 | + "source": [ |
| 997 | + "def path_test(\n", |
| 998 | + " a: PathArg, # a type hint\n", |
| 999 | + " b: PathArg # b type hint\n", |
| 1000 | + "):\n", |
| 1001 | + " \"Mandatory docstring\"\n", |
| 1002 | + " return a/b\n", |
| 1003 | + "\n", |
| 1004 | + "get_schema(path_test)" |
| 1005 | + ] |
| 1006 | + }, |
| 1007 | + { |
| 1008 | + "cell_type": "markdown", |
| 1009 | + "id": "c6d1d0c8", |
| 1010 | + "metadata": {}, |
| 1011 | + "source": [ |
| 1012 | + "Alternatively, use `Path` as usual, and handle the `format` key in the json to use that as a callable:" |
| 1013 | + ] |
| 1014 | + }, |
| 1015 | + { |
| 1016 | + "cell_type": "code", |
| 1017 | + "execution_count": null, |
| 1018 | + "id": "bdb69462", |
| 1019 | + "metadata": {}, |
| 1020 | + "outputs": [ |
| 1021 | + { |
| 1022 | + "data": { |
| 1023 | + "text/plain": [ |
| 1024 | + "{'name': 'path_test2',\n", |
| 1025 | + " 'description': 'Mandatory docstring',\n", |
| 1026 | + " 'input_schema': {'type': 'object',\n", |
| 1027 | + " 'properties': {'a': {'type': 'string',\n", |
| 1028 | + " 'description': 'a type hint',\n", |
| 1029 | + " 'format': 'Path'},\n", |
| 1030 | + " 'b': {'type': 'string', 'description': 'b type hint', 'format': 'Path'}},\n", |
| 1031 | + " 'title': None,\n", |
| 1032 | + " 'required': ['a', 'b']}}" |
| 1033 | + ] |
| 1034 | + }, |
| 1035 | + "execution_count": null, |
| 1036 | + "metadata": {}, |
| 1037 | + "output_type": "execute_result" |
| 1038 | + } |
| 1039 | + ], |
| 1040 | + "source": [ |
| 1041 | + "def path_test2(\n", |
| 1042 | + " a: Path, # a type hint\n", |
| 1043 | + " b: Path # b type hint\n", |
| 1044 | + "):\n", |
| 1045 | + " \"Mandatory docstring\"\n", |
| 1046 | + " return a/b\n", |
| 1047 | + "\n", |
| 1048 | + "get_schema(path_test2)" |
| 1049 | + ] |
| 1050 | + }, |
919 | 1051 | {
|
920 | 1052 | "cell_type": "code",
|
921 | 1053 | "execution_count": null,
|
|
0 commit comments