|
1 | 1 | import os |
2 | | -import io |
3 | 2 | import json |
4 | 3 | import platform |
5 | 4 | import ipaddress |
|
19 | 18 | TypeVar, |
20 | 19 | Union, |
21 | 20 | overload, |
| 21 | + Dict, |
| 22 | + List, |
22 | 23 | ) |
23 | 24 |
|
24 | 25 | import sys |
|
62 | 63 | ProgressResponse, |
63 | 64 | PullRequest, |
64 | 65 | PushRequest, |
65 | | - RequestError, |
66 | 66 | ResponseError, |
67 | 67 | ShowRequest, |
68 | 68 | ShowResponse, |
@@ -476,77 +476,77 @@ def push( |
476 | 476 | def create( |
477 | 477 | self, |
478 | 478 | model: str, |
479 | | - path: Optional[Union[str, PathLike]] = None, |
480 | | - modelfile: Optional[str] = None, |
481 | | - *, |
482 | 479 | quantize: Optional[str] = None, |
| 480 | + from_: Optional[str] = None, |
| 481 | + files: Optional[Dict[str, str]] = None, |
| 482 | + adapters: Optional[Dict[str, str]] = None, |
| 483 | + template: Optional[str] = None, |
| 484 | + license: Optional[Union[str, List[str]]] = None, |
| 485 | + system: Optional[str] = None, |
| 486 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 487 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 488 | + *, |
483 | 489 | stream: Literal[False] = False, |
484 | 490 | ) -> ProgressResponse: ... |
485 | 491 |
|
486 | 492 | @overload |
487 | 493 | def create( |
488 | 494 | self, |
489 | 495 | model: str, |
490 | | - path: Optional[Union[str, PathLike]] = None, |
491 | | - modelfile: Optional[str] = None, |
492 | | - *, |
493 | 496 | quantize: Optional[str] = None, |
| 497 | + from_: Optional[str] = None, |
| 498 | + files: Optional[Dict[str, str]] = None, |
| 499 | + adapters: Optional[Dict[str, str]] = None, |
| 500 | + template: Optional[str] = None, |
| 501 | + license: Optional[Union[str, List[str]]] = None, |
| 502 | + system: Optional[str] = None, |
| 503 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 504 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 505 | + *, |
494 | 506 | stream: Literal[True] = True, |
495 | 507 | ) -> Iterator[ProgressResponse]: ... |
496 | 508 |
|
497 | 509 | def create( |
498 | 510 | self, |
499 | 511 | model: str, |
500 | | - path: Optional[Union[str, PathLike]] = None, |
501 | | - modelfile: Optional[str] = None, |
502 | | - *, |
503 | 512 | quantize: Optional[str] = None, |
| 513 | + from_: Optional[str] = None, |
| 514 | + files: Optional[Dict[str, str]] = None, |
| 515 | + adapters: Optional[Dict[str, str]] = None, |
| 516 | + template: Optional[str] = None, |
| 517 | + license: Optional[Union[str, List[str]]] = None, |
| 518 | + system: Optional[str] = None, |
| 519 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 520 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 521 | + *, |
504 | 522 | stream: bool = False, |
505 | 523 | ) -> Union[ProgressResponse, Iterator[ProgressResponse]]: |
506 | 524 | """ |
507 | 525 | Raises `ResponseError` if the request could not be fulfilled. |
508 | 526 |
|
509 | 527 | Returns `ProgressResponse` if `stream` is `False`, otherwise returns a `ProgressResponse` generator. |
510 | 528 | """ |
511 | | - if (realpath := _as_path(path)) and realpath.exists(): |
512 | | - modelfile = self._parse_modelfile(realpath.read_text(), base=realpath.parent) |
513 | | - elif modelfile: |
514 | | - modelfile = self._parse_modelfile(modelfile) |
515 | | - else: |
516 | | - raise RequestError('must provide either path or modelfile') |
517 | | - |
518 | 529 | return self._request( |
519 | 530 | ProgressResponse, |
520 | 531 | 'POST', |
521 | 532 | '/api/create', |
522 | 533 | json=CreateRequest( |
523 | 534 | model=model, |
524 | | - modelfile=modelfile, |
525 | 535 | stream=stream, |
526 | 536 | quantize=quantize, |
| 537 | + from_=from_, |
| 538 | + files=files, |
| 539 | + adapters=adapters, |
| 540 | + license=license, |
| 541 | + template=template, |
| 542 | + system=system, |
| 543 | + parameters=parameters, |
| 544 | + messages=messages, |
527 | 545 | ).model_dump(exclude_none=True), |
528 | 546 | stream=stream, |
529 | 547 | ) |
530 | 548 |
|
531 | | - def _parse_modelfile(self, modelfile: str, base: Optional[Path] = None) -> str: |
532 | | - base = Path.cwd() if base is None else base |
533 | | - |
534 | | - out = io.StringIO() |
535 | | - for line in io.StringIO(modelfile): |
536 | | - command, _, args = line.partition(' ') |
537 | | - if command.upper() not in ['FROM', 'ADAPTER']: |
538 | | - print(line, end='', file=out) |
539 | | - continue |
540 | | - |
541 | | - path = Path(args.strip()).expanduser() |
542 | | - path = path if path.is_absolute() else base / path |
543 | | - if path.exists(): |
544 | | - args = f'@{self._create_blob(path)}\n' |
545 | | - print(command, args, end='', file=out) |
546 | | - |
547 | | - return out.getvalue() |
548 | | - |
549 | | - def _create_blob(self, path: Union[str, Path]) -> str: |
| 549 | + def create_blob(self, path: Union[str, Path]) -> str: |
550 | 550 | sha256sum = sha256() |
551 | 551 | with open(path, 'rb') as r: |
552 | 552 | while True: |
@@ -978,77 +978,78 @@ async def push( |
978 | 978 | async def create( |
979 | 979 | self, |
980 | 980 | model: str, |
981 | | - path: Optional[Union[str, PathLike]] = None, |
982 | | - modelfile: Optional[str] = None, |
983 | | - *, |
984 | 981 | quantize: Optional[str] = None, |
985 | | - stream: Literal[False] = False, |
| 982 | + from_: Optional[str] = None, |
| 983 | + files: Optional[Dict[str, str]] = None, |
| 984 | + adapters: Optional[Dict[str, str]] = None, |
| 985 | + template: Optional[str] = None, |
| 986 | + license: Optional[Union[str, List[str]]] = None, |
| 987 | + system: Optional[str] = None, |
| 988 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 989 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 990 | + *, |
| 991 | + stream: Literal[True] = True, |
986 | 992 | ) -> ProgressResponse: ... |
987 | 993 |
|
988 | 994 | @overload |
989 | 995 | async def create( |
990 | 996 | self, |
991 | 997 | model: str, |
992 | | - path: Optional[Union[str, PathLike]] = None, |
993 | | - modelfile: Optional[str] = None, |
994 | | - *, |
995 | 998 | quantize: Optional[str] = None, |
| 999 | + from_: Optional[str] = None, |
| 1000 | + files: Optional[Dict[str, str]] = None, |
| 1001 | + adapters: Optional[Dict[str, str]] = None, |
| 1002 | + template: Optional[str] = None, |
| 1003 | + license: Optional[Union[str, List[str]]] = None, |
| 1004 | + system: Optional[str] = None, |
| 1005 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 1006 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 1007 | + *, |
996 | 1008 | stream: Literal[True] = True, |
997 | 1009 | ) -> AsyncIterator[ProgressResponse]: ... |
998 | 1010 |
|
999 | 1011 | async def create( |
1000 | 1012 | self, |
1001 | 1013 | model: str, |
1002 | | - path: Optional[Union[str, PathLike]] = None, |
1003 | | - modelfile: Optional[str] = None, |
1004 | | - *, |
1005 | 1014 | quantize: Optional[str] = None, |
| 1015 | + from_: Optional[str] = None, |
| 1016 | + files: Optional[Dict[str, str]] = None, |
| 1017 | + adapters: Optional[Dict[str, str]] = None, |
| 1018 | + template: Optional[str] = None, |
| 1019 | + license: Optional[Union[str, List[str]]] = None, |
| 1020 | + system: Optional[str] = None, |
| 1021 | + parameters: Optional[Union[Mapping[str, Any], Options]] = None, |
| 1022 | + messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None, |
| 1023 | + *, |
1006 | 1024 | stream: bool = False, |
1007 | 1025 | ) -> Union[ProgressResponse, AsyncIterator[ProgressResponse]]: |
1008 | 1026 | """ |
1009 | 1027 | Raises `ResponseError` if the request could not be fulfilled. |
1010 | 1028 |
|
1011 | 1029 | Returns `ProgressResponse` if `stream` is `False`, otherwise returns a `ProgressResponse` generator. |
1012 | 1030 | """ |
1013 | | - if (realpath := _as_path(path)) and realpath.exists(): |
1014 | | - modelfile = await self._parse_modelfile(realpath.read_text(), base=realpath.parent) |
1015 | | - elif modelfile: |
1016 | | - modelfile = await self._parse_modelfile(modelfile) |
1017 | | - else: |
1018 | | - raise RequestError('must provide either path or modelfile') |
1019 | 1031 |
|
1020 | 1032 | return await self._request( |
1021 | 1033 | ProgressResponse, |
1022 | 1034 | 'POST', |
1023 | 1035 | '/api/create', |
1024 | 1036 | json=CreateRequest( |
1025 | 1037 | model=model, |
1026 | | - modelfile=modelfile, |
1027 | 1038 | stream=stream, |
1028 | 1039 | quantize=quantize, |
| 1040 | + from_=from_, |
| 1041 | + files=files, |
| 1042 | + adapters=adapters, |
| 1043 | + license=license, |
| 1044 | + template=template, |
| 1045 | + system=system, |
| 1046 | + parameters=parameters, |
| 1047 | + messages=messages, |
1029 | 1048 | ).model_dump(exclude_none=True), |
1030 | 1049 | stream=stream, |
1031 | 1050 | ) |
1032 | 1051 |
|
1033 | | - async def _parse_modelfile(self, modelfile: str, base: Optional[Path] = None) -> str: |
1034 | | - base = Path.cwd() if base is None else base |
1035 | | - |
1036 | | - out = io.StringIO() |
1037 | | - for line in io.StringIO(modelfile): |
1038 | | - command, _, args = line.partition(' ') |
1039 | | - if command.upper() not in ['FROM', 'ADAPTER']: |
1040 | | - print(line, end='', file=out) |
1041 | | - continue |
1042 | | - |
1043 | | - path = Path(args.strip()).expanduser() |
1044 | | - path = path if path.is_absolute() else base / path |
1045 | | - if path.exists(): |
1046 | | - args = f'@{await self._create_blob(path)}\n' |
1047 | | - print(command, args, end='', file=out) |
1048 | | - |
1049 | | - return out.getvalue() |
1050 | | - |
1051 | | - async def _create_blob(self, path: Union[str, Path]) -> str: |
| 1052 | + async def create_blob(self, path: Union[str, Path]) -> str: |
1052 | 1053 | sha256sum = sha256() |
1053 | 1054 | with open(path, 'rb') as r: |
1054 | 1055 | while True: |
|
0 commit comments