11import ejs from "ejs" ;
2- import { getContext , helpers , Property } from "@dylibso/xtp-bindgen" ;
2+ import {
3+ helpers ,
4+ getContext ,
5+ ObjectType ,
6+ EnumType ,
7+ ArrayType ,
8+ XtpNormalizedType ,
9+ XtpTyped
10+ } from "@dylibso/xtp-bindgen"
311
4- function toPythonType ( property : Property ) : string {
5- let tp
12+ function pythonTypeName ( s : string ) : string {
13+ return helpers . snakeToPascalCase ( s ) ;
14+ }
15+
16+ function pythonFunctionName ( s : string ) : string {
17+ return helpers . camelToSnakeCase ( s ) ;
18+ }
19+
20+ function isOptional ( type : String ) : boolean {
21+ return type . startsWith ( 'Optional[' )
22+ }
623
7- if ( property . $ref ) {
8- tp = property . $ref . name
9- } else {
10- switch ( property . type ) {
11- case "string" :
12- if ( property . format === "date-time" ) {
13- tp = "datetime"
14- } else {
15- tp = "str"
16- }
17- break
18- case "number" :
19- // @ts -ignore
20- if ( property . contentType === "application/json" ) {
21- tp = "str"
22- } else if ( property . format === "float" || property . format === "double" ) {
23- tp = "float"
24- } else {
25- tp = "int"
26- }
27- break
28- case "integer" :
29- // @ts -ignore
30- if ( property . contentType === "application/json" ) {
31- tp = "str"
32- } else {
33- tp = "int"
34- }
35- break
36- case "boolean" :
37- tp = "bool"
38- break
39- case "object" :
40- tp = "dict"
41- break
42- case "array" :
43- if ( ! property . items ) {
44- tp = "list"
45- } else {
46- tp = `List[${ toPythonType ( property . items as Property ) } ]`
47- }
48- break
49- case "buffer" :
50- tp = "bytes"
51- break
52- default :
53- throw new Error ( "Can't convert property to Python type: " + property . type ) ;
54- }
24+ function toPythonTypeX ( type : XtpNormalizedType ) : string {
25+ const opt = ( t : string ) => {
26+ return type . nullable ? `Optional[${ t } ]` : t
5527 }
28+ switch ( type . kind ) {
29+ case 'string' :
30+ return opt ( 'str' ) ;
31+ case 'int32' :
32+ return opt ( 'int' ) ;
33+ case 'float' :
34+ return opt ( 'float' ) ;
35+ case 'double' :
36+ return opt ( 'float' )
37+ case 'byte' :
38+ return opt ( 'byte' ) ;
39+ case 'date-time' :
40+ return opt ( "datetime" ) ;
41+ case 'boolean' :
42+ return opt ( 'bool' ) ;
43+ case 'array' :
44+ const arrayType = type as ArrayType
45+ return opt ( `List[${ toPythonTypeX ( arrayType . elementType ) } ]` ) ;
46+ case 'buffer' :
47+ return opt ( 'bytes' ) ;
48+ case 'map' :
49+ // TODO: improve typing of dicts
50+ return opt ( 'dict' ) ;
51+ case 'object' :
52+ return opt ( pythonTypeName ( ( type as ObjectType ) . name ) ) ;
53+ case 'enum' :
54+ return opt ( pythonTypeName ( ( type as EnumType ) . name ) ) ;
55+ default :
56+ throw new Error ( "Can't convert XTP type to Python type: " + type )
57+ }
58+ }
59+
60+
61+ function toPythonType ( property : XtpTyped ) : string {
62+ let t = toPythonTypeX ( property . xtpType ) ;
63+ if ( isOptional ( t ) ) return t ;
64+ return `Optional[${ t } ]` ;
65+ }
5666
57- if ( ! tp ) throw new Error ( "Cant convert property to Python type: " + property . type )
58- if ( ! property . nullable && ! property . required ) return tp
59- return `Optional[${ tp } ]`
67+ function toPythonParamType ( property : XtpTyped ) : string {
68+ let t = toPythonTypeX ( property . xtpType ) ;
69+ // We need to represent bare int/float as a str in Python for now,
70+ // there may be some updates to the encoder we can make to handle
71+ // this case at some point
72+ t = t . replace ( 'int' , 'str' ) ;
73+ t = t . replace ( 'float' , 'str' ) ;
74+ return t ;
6075}
6176
6277export function render ( ) {
@@ -65,6 +80,9 @@ export function render() {
6580 ...helpers ,
6681 ...getContext ( ) ,
6782 toPythonType,
83+ toPythonParamType,
84+ pythonTypeName,
85+ pythonFunctionName
6886 } ;
6987
7088 const output = ejs . render ( tmpl , ctx ) ;
0 commit comments