Skip to content

Commit

Permalink
python generator: alfa
Browse files Browse the repository at this point in the history
  • Loading branch information
GenaRazmakhnin committed Oct 8, 2023
1 parent 755e292 commit d50b050
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 80 deletions.
79 changes: 79 additions & 0 deletions src/python-generator/base.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
(ns python-generator.base
(:require
[python-generator.extractor :as extractors]
[python-generator.helpers :as helpers]
[cheshire.core]
[clojure.string :as str])
(:gen-class))

(defn save-to [directory, filename]
(fn [text] (helpers/write-to-file directory, filename, text)))

(defn push-to-end [string1, string2] (str string2, string1))

(defn combine-base-file [definition, data]
(-> (str "\nclass " (helpers/get-resource-name (:type definition)) "(BaseModel)" ":\n")
(str (clojure.string/join "\n" (:elements data)) "\n")))

(defn combine-file [definition, data]
(-> #_(str (helpers/add-element-import (filter boolean (:imports-element data))))
#_(str (helpers/add-backbone-element-import (filter boolean (:imports-backbone-element data))))
#_(push-to-end (str "if TYPE_CHECKING:\n\t\"import typings\"\n"))
#_(str "else:\n\t\"import typings\"\n")
#_((typechecking-ignore-runtime (ignore (filter boolean (:imports data)))))
#_((if (= (helpers/get-resource-name (:base definition)) "DomainResource") (fn [string] (str string "from resource.index import DomainResource\n\n")) str))
#_((if (= (helpers/get-resource-name (:base definition)) "Resource") (fn [string] (str string "from base.resource import Resource\n\n")) str))
#_((if (= (helpers/get-resource-name (:base definition)) "BackboneElement") (fn [string] (str string "from element.index import BackboneElement\nfrom base.index import Element\n\n")) str))
#_((if (= (helpers/get-resource-name (:base definition)) "Element") (fn [string] (str string "from base.index import Element\n\n")) str))
(str "\nclass " (helpers/get-resource-name (:type definition)) (helpers/get-parent (:base definition)) ":\n")
(str (clojure.string/join "\n" (:elements data)) "\n")))

(defn compile-single-class []
(fn [definition]
(->> (helpers/elements-to-vector definition)
(helpers/get-typings-and-imports (or (:required definition) []))
(combine-file definition))))

(defn compile-single-base-class []
(fn [definition]
(->> (helpers/elements-to-vector definition)
(helpers/get-typings-and-imports (or (:required definition) []))
(combine-base-file definition))))

(defn compile-bases []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-base)
(map (compile-single-base-class))
(str/join)))

(defn compile-elements []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-element)
(map (compile-single-class))
(str/join)))

(defn compile-backbone-elements []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-backbone-element)
(map (compile-single-class))
(str/join)))

(defn compile-resources []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-resource)
(map (compile-single-class))
(str/join)))


(defn root-compiler []
(->> (str (compile-resources))
(str (compile-backbone-elements))
(str (compile-elements))
(str (compile-bases))
(str "from pydantic import BaseModel\n\n")
(str "from typing import Optional\n")
(str "from __future__ import annotations\n")
((save-to "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/base" "__init__"))))

(root-compiler)

13 changes: 6 additions & 7 deletions src/python-generator/exporter.clj
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@
(helpers/write-to-file "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/backbone", "index")))

(defn domain-index []
(helpers/write-to-file "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/domain", "__init__", "")
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-domain-resource)
(map (fn [definition] (str "from domain." (clojure.string/lower-case (helpers/get-resource-name (:type definition))) " import " (helpers/get-resource-name (:type definition)) "\n")))
(map (fn [definition] (str "from resources." (clojure.string/lower-case (helpers/get-resource-name (:type definition))) " import " (helpers/get-resource-name (:type definition)) "\n")))
(clojure.string/join)
(helpers/write-to-file "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/domain", "index")))
(helpers/write-to-file "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/resources", "__init__")))

(base-index)
(element-index)
(resource-index)
(backbone-index)
;; (base-index)
;; (element-index)
;; (resource-index)
;; (backbone-index)
(domain-index)
40 changes: 14 additions & 26 deletions src/python-generator/helpers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
(def backbone-elements #{"Population" "Timing" "MarketingStatus" "SubstanceAmount" "ProductShelfLife" "ProdCharacteristic" "Dosage" "ElementDefinition"})
(def primitives-string #{"dateTime" "xhtml" "Distance" "time" "date" "string" "uuid" "oid" "id" "Dosage" "Duration" "instant" "Count" "decimal" "code" "base64Binary" "unsignedInt" "url" "markdown" "uri" "positiveInt" "canonical" "Age" "Timing"})

(defn uppercase-first-letter [string]
(str (str/upper-case (first string)) (subs string 1)))

(defn escape-keyword [word]
(if (.contains #{"class", "global", "for", "import"} word) (str word "_") word))

Expand All @@ -26,23 +29,23 @@
(defn get-resource-name [reference]
(last (str/split (str reference) #"/")))

(defn get-type [type]
(defn get-type [name type]
(cond
(= type "BackboneElement") (uppercase-first-letter name)
(= type "boolean") "bool"
(= type "integer") "int"
(= type "") "str"
(.contains primitives-string type) "str"
:else (or type "str")))

(defn derive-basic-type [type]
(-> (get-resource-name type)
(get-type)))
(defn derive-basic-type [name element]
(get-type name (get-resource-name (:type element))))

(defn append-default-none [string] (str string " = None"))
(defn append-default-vector [string] (str string " = []"))

(defn transform-element [element required]
(->> (derive-basic-type (:type element))
(defn transform-element [name element required]
(->> (derive-basic-type name element)
((if (:array element) wrap-vector str))
((if (and (not required) (not (:array element))) wrap-optional str))
((if (and (not required) (not (:array element))) append-default-none str))
Expand All @@ -52,36 +55,21 @@
(->> (seq (:elements definition))
(filter (fn [[_, v]] (not (contains? v :choices))))))

(defn transform-element-to-type [definition]
(fn [[k, v]] (str "\t" (escape-keyword (name k)) ": " (transform-element v (.contains (or (:required definition) []) (name k))))))

(defn get-parent [base-reference]
(->> (get-resource-name base-reference)
(string-interpolation "(" ")")))

(defn collect-types [required, [k, v]]
(str "\t" (escape-keyword (name k)) ": " (transform-element v (.contains required (name k)))))

(defn collect-imports [[_, v]]
(let [type (derive-basic-type (:type v))]
(if (.contains elements type) type nil)))

(defn collect-backbone-imports [[_, v]]
(let [type (derive-basic-type (:type v))]
(if (.contains backbone-elements type) type nil)))

(defn add-element-import [data]
(clojure.string/join (map (fn [item] (str "from element.index import " item "\n")), data)))
(str "\t" (escape-keyword (name k)) ": " (transform-element (name k) v (.contains required (name k)))))

(defn add-backbone-element-import [data]
(clojure.string/join (map (fn [item] (str "from backbone.index import " item "\n")), data)))
(defn resolve-backbone-elements [[k, v]]
(if (= (get-resource-name (:type v)) "BackboneElement") (vector k, v) (vector)))

(defn get-typings-and-imports [required, data]
(reduce (fn [acc, item]
(hash-map :elements (conj (:elements acc) (collect-types required item))
:imports-element (conj (:imports-element acc) (collect-imports item))
:imports-backbone-element (conj (:imports-backbone-element acc) (collect-backbone-imports item))))
(hash-map :elements [] :imports-element [] :imports-backbone-element []) data))
:backbone-elements (conj (:backbone-elements acc) (resolve-backbone-elements item))))
(hash-map :elements [] :backbone-elements []) data))

(defn parse-ndjson-gz [path]
(with-open [rdr (-> path
Expand Down
70 changes: 23 additions & 47 deletions src/python-generator/index.clj
Original file line number Diff line number Diff line change
@@ -1,73 +1,49 @@
(ns python-generator.index
(:require
[python-generator.extractor :as extractors]
[python-generator.helpers :as helpers]
[cheshire.core]
[clojure.string :as str])
[clojure.string :as str]
[python-generator.extractor :as extractors]
[python-generator.helpers :as helpers])
(:gen-class))

(defn save-to [directory, filename]
(fn [text] (helpers/write-to-file directory, filename, text)))

(defn push-to-end [string1, string2] (str string2, string1))
(defn compile-single-backbone [definition, data]
(->> #_(str "class " (helpers/get-resource-name (:type definition)) (helpers/get-parent (:base definition)) ":\n")
(str (clojure.string/join "\n" (:elements data)) "\n\n")))

(defn ignore [data]
(clojure.string/join (map (fn [item] (str "\t" item " = Any\n")), data)))
(defn compile-backbone [definition]
(->> (helpers/elements-to-vector definition)
(helpers/get-typings-and-imports (or (:required definition) []))
(compile-single-backbone definition)))

(defn typechecking-ignore-runtime [string]
(fn [inner_string] (str inner_string string "\n")))
(defn test [data]
(->> (filter (fn [item] (> (count item) 0)) (:backbone-elements data))
(map (fn [[k, v]]
(->> (str (compile-backbone v))
(str "class " (helpers/uppercase-first-letter (name k)) "(BackboneElement):\n"))))
(str/join)))

(defn combine-file [definition, data]
(-> (str (helpers/add-element-import (filter boolean (:imports-element data))))
(str (helpers/add-backbone-element-import (filter boolean (:imports-backbone-element data))))
#_(push-to-end (str "if TYPE_CHECKING:\n\t\"import typings\"\n"))
(push-to-end (str "from typing import TYPE_CHECKING, Optional, Any\n\n"))
#_(push-to-end (str "from __future__ import annotations\n"))
#_(str "else:\n\t\"import typings\"\n")
#_((typechecking-ignore-runtime (ignore (filter boolean (:imports data)))))
((if (= (helpers/get-resource-name (:base definition)) "DomainResource") (fn [string] (str string "from resource.index import DomainResource\n\n")) str))
((if (= (helpers/get-resource-name (:base definition)) "Resource") (fn [string] (str string "from base.resource import Resource\n\n")) str))
((if (= (helpers/get-resource-name (:base definition)) "BackboneElement") (fn [string] (str string "from element.index import BackboneElement\nfrom base.index import Element\n\n")) str))
((if (= (helpers/get-resource-name (:base definition)) "Element") (fn [string] (str string "from base.index import Element\n\n")) str))
(str "\nclass " (helpers/get-resource-name (:type definition)) "Origin" (helpers/get-parent (:base definition)) ":\n")
(str (clojure.string/join "\n" (:elements data)) "\n\n")))
(->> (str (clojure.string/join "\n" (:elements data)) "\n\n")
(str "class " (helpers/get-resource-name (:type definition)) (helpers/get-parent (:base definition)) ":\n")
(str (test data))
(str "from base import *\n\n")
(str "from typing import Optional\n")))

(defn compile-single-class [directory]
(fn [definition]
(->> (helpers/elements-to-vector definition)
(helpers/get-typings-and-imports (or (:required definition) []))
(combine-file definition)
(push-to-end (str "class " (helpers/get-resource-name (:type definition)) "(" (helpers/get-resource-name (:type definition)) "Origin)" ": pass\n"))
(str/join)
((save-to directory (str/lower-case (helpers/get-resource-name (:type definition))))))))

(defn compile-bases []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-base)
(map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/base"))))

(defn compile-elements []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-element)
(map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/element"))))

(defn compile-backbone-elements []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-backbone-element)
(map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/backbone"))))

(defn compile-resources []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-resource)
(map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/resource"))))

(defn compile-domains []
(->> (helpers/parse-ndjson-gz "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/fhir-schema/hl7.fhir.r4.core#4.0.1/package.ndjson.gz")
(extractors/filter-domain-resource)
(helpers/side-effect-map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/domain"))))
(helpers/side-effect-map (compile-single-class "/Users/gena.razmakhnin/Documents/aidbox-sdk-js/test_dir/resources"))))

(compile-bases)
(compile-elements)
(compile-backbone-elements)
(compile-resources)
(compile-domains)

0 comments on commit d50b050

Please sign in to comment.