diff --git a/lib/python/.gitignore b/lib/python/.gitignore index 1f4bb524a1c7dfe8ec62be60b755993e13f7dedc..b11bfe061cb8fd2c97c9195211a8ba08ed1ae0ee 100644 --- a/lib/python/.gitignore +++ b/lib/python/.gitignore @@ -7,6 +7,7 @@ dbrepo.egg-info/ build/ htmlcov/ tmp-* +report.xml # debug debug.py @@ -15,9 +16,8 @@ debug.py .pypirc # coverage -coverage.txt +coverage.* .coverage -report.xml # environment .env diff --git a/lib/python/README.md b/lib/python/README.md index 443787cbb4cdcb13d0e3ec522d0d9762262000e8..11506a7bf059630b65ed703d4674cde8cf3642e9 100644 --- a/lib/python/README.md +++ b/lib/python/README.md @@ -2,7 +2,7 @@ Official client library for [DBRepo](https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/1.4.3/), a database repository to support research based -on [requests](https://pypi.org/project/requests/), [pydantic](https://pypi.org/project/pydantic/), [tuspy](https://pypi.org/project/tuspy/) +on [requests](https://pypi.org/project/requests/), [pydantic](https://pypi.org/project/pydantic/) and [pika](https://pypi.org/project/pika/). ## Installing @@ -20,9 +20,11 @@ Get public data from a table as pandas `DataFrame`: ```python from dbrepo.RestClient import RestClient -client = RestClient(endpoint="https://dbrepo1.ec.tuwien.ac.at") +client = RestClient(endpoint="https://test.dbrepo.tuwien.ac.at") # Get a small data slice of just three rows -df = client.get_table_data(database_id=7, table_id=13, page=0, size=3, df=True) +df = client.get_table_data(database_id="e0d82287-9099-4077-8f69-3c19fc3bc145", + table_id="71f8c746-ea26-4651-b3f2-ce46830f1af4", + page=0, size=3) print(df) # x_coord component unit ... value stationid meantype # 0 16.52617 Feinstaub (PM10) µg/m³ ... 21.0 01:0001 HMW @@ -32,19 +34,23 @@ print(df) # [3 rows x 12 columns] ``` -Import data into a table: +Create table and import `DataFrame` into a table: ```python import pandas as pd from dbrepo.RestClient import RestClient -client = RestClient(endpoint="https://dbrepo1.ec.tuwien.ac.at", username="foo", +client = RestClient(endpoint="https://test.dbrepo.tuwien.ac.at", username="foo", password="bar") df = pd.DataFrame(data={'x_coord': 16.52617, 'component': 'Feinstaub (PM10)', 'unit': 'µg/m³', ...}) -client.import_table_data(database_id=7, table_id=13, file_name_or_data_frame=df) +client.create_table(database_id="e0d82287-9099-4077-8f69-3c19fc3bc145", + name="Sensor", is_public=True, is_schema_public=True, + dataframe=df) ``` +... or just create the table schema by setting `create_table(..., withData=False)`. + ## Supported Features & Best-Practices - Manage user @@ -76,7 +82,6 @@ AMQP_API_PORT="5672" AMQP_API_USERNAME="foo" AMQP_API_PASSWORD="bar" AMQP_API_VIRTUAL_HOST="dbrepo" -REST_UPLOAD_ENDPOINT="https://dbrepo1.ec.tuwien.ac.at/api/upload/files" ``` You can disable logging by setting the log level to e.g. `INFO`: diff --git a/lib/python/coverage.xml b/lib/python/coverage.xml deleted file mode 100644 index ac21b0bc1ed6b9f659ba578333c89e481c34ca8f..0000000000000000000000000000000000000000 --- a/lib/python/coverage.xml +++ /dev/null @@ -1,1866 +0,0 @@ -<?xml version="1.0" ?> -<coverage version="7.6.10" timestamp="1740478405603" lines-valid="1820" lines-covered="1743" line-rate="0.9577" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0"> - <!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.6.10 --> - <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> - <sources> - <source>/home/mweise/Projects/fda-services/lib/python</source> - </sources> - <packages> - <package name="dbrepo" line-rate="0.9134" branch-rate="0" complexity="0"> - <classes> - <class name="RestClient.py" filename="dbrepo/RestClient.py" complexity="0" line-rate="0.9248" branch-rate="0"> - <methods/> - <lines> - <line number="1" hits="1"/> - <line number="2" hits="1"/> - <line number="3" hits="1"/> - <line number="5" hits="1"/> - <line number="6" hits="1"/> - <line number="7" hits="1"/> - <line number="9" hits="1"/> - <line number="10" hits="1"/> - <line number="11" hits="1"/> - <line number="15" hits="1"/> - <line number="19" hits="1"/> - <line number="31" hits="1"/> - <line number="32" hits="1"/> - <line number="33" hits="1"/> - <line number="34" hits="1"/> - <line number="36" hits="1"/> - <line number="41" hits="1"/> - <line number="42" hits="1"/> - <line number="43" hits="1"/> - <line number="44" hits="1"/> - <line number="45" hits="1"/> - <line number="47" hits="1"/> - <line number="48" hits="1"/> - <line number="51" hits="1"/> - <line number="53" hits="1"/> - <line number="54" hits="1"/> - <line number="55" hits="1"/> - <line number="56" hits="1"/> - <line number="57" hits="1"/> - <line number="58" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="1"/> - <line number="61" hits="1"/> - <line number="62" hits="1"/> - <line number="63" hits="1"/> - <line number="64" hits="1"/> - <line number="66" hits="1"/> - <line number="67" hits="1"/> - <line number="68" hits="1"/> - <line number="69" hits="1"/> - <line number="70" hits="1"/> - <line number="71" hits="1"/> - <line number="72" hits="1"/> - <line number="73" hits="1"/> - <line number="74" hits="1"/> - <line number="75" hits="1"/> - <line number="76" hits="1"/> - <line number="77" hits="1"/> - <line number="80" hits="1"/> - <line number="86" hits="1"/> - <line number="87" hits="1"/> - <line number="88" hits="1"/> - <line number="89" hits="1"/> - <line number="90" hits="1"/> - <line number="92" hits="1"/> - <line number="100" hits="1"/> - <line number="101" hits="1"/> - <line number="102" hits="1"/> - <line number="103" hits="1"/> - <line number="104" hits="1"/> - <line number="105" hits="1"/> - <line number="108" hits="1"/> - <line number="116" hits="1"/> - <line number="117" hits="1"/> - <line number="118" hits="1"/> - <line number="119" hits="1"/> - <line number="120" hits="1"/> - <line number="121" hits="1"/> - <line number="124" hits="1"/> - <line number="134" hits="1"/> - <line number="135" hits="1"/> - <line number="136" hits="1"/> - <line number="137" hits="1"/> - <line number="138" hits="1"/> - <line number="139" hits="1"/> - <line number="140" hits="1"/> - <line number="141" hits="1"/> - <line number="142" hits="1"/> - <line number="143" hits="1"/> - <line number="146" hits="1"/> - <line number="166" hits="1"/> - <line number="167" hits="1"/> - <line number="170" hits="1"/> - <line number="171" hits="1"/> - <line number="172" hits="1"/> - <line number="173" hits="1"/> - <line number="174" hits="1"/> - <line number="175" hits="1"/> - <line number="176" hits="1"/> - <line number="177" hits="1"/> - <line number="178" hits="1"/> - <line number="179" hits="1"/> - <line number="182" hits="1"/> - <line number="190" hits="1"/> - <line number="191" hits="1"/> - <line number="192" hits="1"/> - <line number="193" hits="1"/> - <line number="194" hits="1"/> - <line number="195" hits="1"/> - <line number="198" hits="1"/> - <line number="207" hits="1"/> - <line number="208" hits="1"/> - <line number="209" hits="1"/> - <line number="210" hits="1"/> - <line number="211" hits="1"/> - <line number="212" hits="1"/> - <line number="213" hits="1"/> - <line number="214" hits="1"/> - <line number="217" hits="1"/> - <line number="225" hits="1"/> - <line number="226" hits="1"/> - <line number="227" hits="1"/> - <line number="228" hits="1"/> - <line number="229" hits="1"/> - <line number="230" hits="1"/> - <line number="233" hits="1"/> - <line number="240" hits="1"/> - <line number="241" hits="1"/> - <line number="242" hits="1"/> - <line number="243" hits="1"/> - <line number="244" hits="1"/> - <line number="247" hits="1"/> - <line number="258" hits="1"/> - <line number="259" hits="1"/> - <line number="260" hits="1"/> - <line number="261" hits="1"/> - <line number="262" hits="1"/> - <line number="263" hits="1"/> - <line number="264" hits="1"/> - <line number="265" hits="1"/> - <line number="266" hits="1"/> - <line number="267" hits="1"/> - <line number="270" hits="1"/> - <line number="290" hits="1"/> - <line number="291" hits="1"/> - <line number="294" hits="1"/> - <line number="295" hits="1"/> - <line number="296" hits="1"/> - <line number="297" hits="1"/> - <line number="298" hits="1"/> - <line number="299" hits="1"/> - <line number="300" hits="1"/> - <line number="301" hits="1"/> - <line number="302" hits="1"/> - <line number="303" hits="1"/> - <line number="304" hits="1"/> - <line number="305" hits="1"/> - <line number="306" hits="1"/> - <line number="307" hits="1"/> - <line number="308" hits="1"/> - <line number="309" hits="1"/> - <line number="312" hits="1"/> - <line number="336" hits="1"/> - <line number="337" hits="1"/> - <line number="342" hits="1"/> - <line number="343" hits="1"/> - <line number="344" hits="1"/> - <line number="345" hits="1"/> - <line number="346" hits="1"/> - <line number="347" hits="1"/> - <line number="348" hits="1"/> - <line number="349" hits="1"/> - <line number="350" hits="1"/> - <line number="351" hits="1"/> - <line number="352" hits="1"/> - <line number="353" hits="1"/> - <line number="356" hits="1"/> - <line number="373" hits="1"/> - <line number="374" hits="1"/> - <line number="376" hits="1"/> - <line number="377" hits="1"/> - <line number="378" hits="1"/> - <line number="379" hits="1"/> - <line number="380" hits="1"/> - <line number="381" hits="1"/> - <line number="382" hits="1"/> - <line number="383" hits="1"/> - <line number="384" hits="1"/> - <line number="385" hits="1"/> - <line number="386" hits="1"/> - <line number="388" hits="1"/> - <line number="389" hits="1"/> - <line number="390" hits="1"/> - <line number="393" hits="1"/> - <line number="409" hits="1"/> - <line number="410" hits="1"/> - <line number="411" hits="1"/> - <line number="412" hits="1"/> - <line number="413" hits="1"/> - <line number="414" hits="1"/> - <line number="415" hits="1"/> - <line number="416" hits="1"/> - <line number="417" hits="1"/> - <line number="418" hits="1"/> - <line number="419" hits="1"/> - <line number="420" hits="1"/> - <line number="421" hits="1"/> - <line number="423" hits="1"/> - <line number="424" hits="1"/> - <line number="426" hits="1"/> - <line number="429" hits="1"/> - <line number="444" hits="1"/> - <line number="445" hits="1"/> - <line number="446" hits="1"/> - <line number="447" hits="1"/> - <line number="448" hits="1"/> - <line number="449" hits="1"/> - <line number="450" hits="1"/> - <line number="451" hits="1"/> - <line number="452" hits="1"/> - <line number="453" hits="1"/> - <line number="454" hits="1"/> - <line number="455" hits="1"/> - <line number="456" hits="1"/> - <line number="457" hits="1"/> - <line number="458" hits="1"/> - <line number="459" hits="1"/> - <line number="460" hits="1"/> - <line number="462" hits="1"/> - <line number="463" hits="1"/> - <line number="464" hits="1"/> - <line number="467" hits="1"/> - <line number="491" hits="1"/> - <line number="492" hits="1"/> - <line number="495" hits="1"/> - <line number="496" hits="1"/> - <line number="497" hits="1"/> - <line number="498" hits="1"/> - <line number="499" hits="1"/> - <line number="500" hits="1"/> - <line number="501" hits="1"/> - <line number="502" hits="1"/> - <line number="503" hits="1"/> - <line number="504" hits="1"/> - <line number="505" hits="1"/> - <line number="506" hits="1"/> - <line number="507" hits="1"/> - <line number="508" hits="1"/> - <line number="509" hits="1"/> - <line number="510" hits="1"/> - <line number="513" hits="1"/> - <line number="525" hits="1"/> - <line number="526" hits="1"/> - <line number="527" hits="1"/> - <line number="528" hits="1"/> - <line number="529" hits="1"/> - <line number="530" hits="1"/> - <line number="531" hits="1"/> - <line number="532" hits="1"/> - <line number="533" hits="1"/> - <line number="534" hits="1"/> - <line number="537" hits="1"/> - <line number="550" hits="1"/> - <line number="551" hits="1"/> - <line number="552" hits="1"/> - <line number="553" hits="1"/> - <line number="554" hits="1"/> - <line number="555" hits="1"/> - <line number="556" hits="1"/> - <line number="557" hits="1"/> - <line number="558" hits="1"/> - <line number="559" hits="1"/> - <line number="562" hits="1"/> - <line number="576" hits="1"/> - <line number="577" hits="1"/> - <line number="578" hits="1"/> - <line number="579" hits="1"/> - <line number="580" hits="1"/> - <line number="581" hits="1"/> - <line number="582" hits="1"/> - <line number="583" hits="1"/> - <line number="584" hits="1"/> - <line number="585" hits="1"/> - <line number="586" hits="1"/> - <line number="587" hits="1"/> - <line number="588" hits="1"/> - <line number="589" hits="1"/> - <line number="590" hits="1"/> - <line number="593" hits="1"/> - <line number="606" hits="1"/> - <line number="607" hits="1"/> - <line number="608" hits="1"/> - <line number="609" hits="1"/> - <line number="610" hits="1"/> - <line number="611" hits="1"/> - <line number="612" hits="1"/> - <line number="613" hits="1"/> - <line number="614" hits="1"/> - <line number="615" hits="1"/> - <line number="616" hits="1"/> - <line number="619" hits="1"/> - <line number="633" hits="1"/> - <line number="634" hits="1"/> - <line number="635" hits="1"/> - <line number="636" hits="1"/> - <line number="637" hits="1"/> - <line number="638" hits="1"/> - <line number="639" hits="1"/> - <line number="640" hits="1"/> - <line number="641" hits="1"/> - <line number="642" hits="1"/> - <line number="643" hits="1"/> - <line number="644" hits="1"/> - <line number="645" hits="1"/> - <line number="646" hits="1"/> - <line number="649" hits="1"/> - <line number="660" hits="1"/> - <line number="661" hits="1"/> - <line number="662" hits="1"/> - <line number="663" hits="1"/> - <line number="664" hits="1"/> - <line number="665" hits="1"/> - <line number="666" hits="1"/> - <line number="667" hits="1"/> - <line number="670" hits="1"/> - <line number="683" hits="1"/> - <line number="684" hits="1"/> - <line number="685" hits="1"/> - <line number="686" hits="1"/> - <line number="687" hits="1"/> - <line number="688" hits="1"/> - <line number="689" hits="1"/> - <line number="690" hits="1"/> - <line number="691" hits="1"/> - <line number="692" hits="1"/> - <line number="695" hits="1"/> - <line number="710" hits="1"/> - <line number="711" hits="1"/> - <line number="713" hits="1"/> - <line number="714" hits="1"/> - <line number="715" hits="1"/> - <line number="716" hits="1"/> - <line number="717" hits="1"/> - <line number="718" hits="1"/> - <line number="719" hits="1"/> - <line number="720" hits="1"/> - <line number="723" hits="1"/> - <line number="743" hits="1"/> - <line number="744" hits="1"/> - <line number="747" hits="1"/> - <line number="748" hits="1"/> - <line number="749" hits="1"/> - <line number="750" hits="1"/> - <line number="751" hits="1"/> - <line number="752" hits="1"/> - <line number="753" hits="1"/> - <line number="754" hits="1"/> - <line number="755" hits="1"/> - <line number="756" hits="1"/> - <line number="757" hits="1"/> - <line number="758" hits="1"/> - <line number="759" hits="1"/> - <line number="760" hits="1"/> - <line number="761" hits="1"/> - <line number="762" hits="1"/> - <line number="765" hits="1"/> - <line number="780" hits="1"/> - <line number="781" hits="1"/> - <line number="782" hits="1"/> - <line number="783" hits="1"/> - <line number="784" hits="1"/> - <line number="785" hits="1"/> - <line number="786" hits="1"/> - <line number="787" hits="1"/> - <line number="788" hits="1"/> - <line number="789" hits="1"/> - <line number="790" hits="1"/> - <line number="791" hits="1"/> - <line number="792" hits="1"/> - <line number="793" hits="1"/> - <line number="794" hits="1"/> - <line number="795" hits="1"/> - <line number="796" hits="1"/> - <line number="799" hits="1"/> - <line number="817" hits="1"/> - <line number="818" hits="1"/> - <line number="819" hits="1"/> - <line number="820" hits="1"/> - <line number="821" hits="1"/> - <line number="822" hits="1"/> - <line number="823" hits="1"/> - <line number="824" hits="1"/> - <line number="825" hits="1"/> - <line number="826" hits="1"/> - <line number="827" hits="1"/> - <line number="828" hits="1"/> - <line number="829" hits="1"/> - <line number="830" hits="1"/> - <line number="831" hits="1"/> - <line number="832" hits="1"/> - <line number="833" hits="1"/> - <line number="834" hits="1"/> - <line number="836" hits="1"/> - <line number="839" hits="1"/> - <line number="858" hits="1"/> - <line number="859" hits="1"/> - <line number="860" hits="1"/> - <line number="861" hits="1"/> - <line number="862" hits="1"/> - <line number="863" hits="1"/> - <line number="864" hits="1"/> - <line number="865" hits="1"/> - <line number="866" hits="1"/> - <line number="867" hits="1"/> - <line number="868" hits="1"/> - <line number="869" hits="1"/> - <line number="870" hits="1"/> - <line number="871" hits="1"/> - <line number="872" hits="1"/> - <line number="873" hits="1"/> - <line number="874" hits="1"/> - <line number="875" hits="1"/> - <line number="877" hits="1"/> - <line number="880" hits="1"/> - <line number="894" hits="1"/> - <line number="895" hits="1"/> - <line number="896" hits="1"/> - <line number="897" hits="1"/> - <line number="898" hits="1"/> - <line number="899" hits="1"/> - <line number="900" hits="1"/> - <line number="901" hits="1"/> - <line number="902" hits="1"/> - <line number="903" hits="1"/> - <line number="904" hits="1"/> - <line number="905" hits="1"/> - <line number="907" hits="1"/> - <line number="910" hits="1"/> - <line number="926" hits="0"/> - <line number="927" hits="0"/> - <line number="928" hits="0"/> - <line number="929" hits="0"/> - <line number="932" hits="0"/> - <line number="933" hits="0"/> - <line number="934" hits="0"/> - <line number="935" hits="0"/> - <line number="936" hits="0"/> - <line number="937" hits="0"/> - <line number="938" hits="0"/> - <line number="939" hits="0"/> - <line number="940" hits="0"/> - <line number="941" hits="0"/> - <line number="943" hits="0"/> - <line number="946" hits="1"/> - <line number="960" hits="0"/> - <line number="961" hits="0"/> - <line number="962" hits="0"/> - <line number="968" hits="0"/> - <line number="969" hits="0"/> - <line number="970" hits="0"/> - <line number="971" hits="0"/> - <line number="972" hits="0"/> - <line number="973" hits="0"/> - <line number="974" hits="0"/> - <line number="975" hits="0"/> - <line number="976" hits="0"/> - <line number="977" hits="0"/> - <line number="980" hits="1"/> - <line number="992" hits="0"/> - <line number="993" hits="0"/> - <line number="994" hits="0"/> - <line number="998" hits="0"/> - <line number="999" hits="0"/> - <line number="1000" hits="0"/> - <line number="1001" hits="0"/> - <line number="1002" hits="0"/> - <line number="1003" hits="0"/> - <line number="1004" hits="0"/> - <line number="1005" hits="0"/> - <line number="1006" hits="0"/> - <line number="1007" hits="0"/> - <line number="1010" hits="1"/> - <line number="1025" hits="1"/> - <line number="1026" hits="1"/> - <line number="1027" hits="1"/> - <line number="1028" hits="1"/> - <line number="1029" hits="1"/> - <line number="1030" hits="1"/> - <line number="1031" hits="1"/> - <line number="1032" hits="1"/> - <line number="1033" hits="1"/> - <line number="1034" hits="1"/> - <line number="1035" hits="1"/> - <line number="1037" hits="1"/> - <line number="1038" hits="1"/> - <line number="1039" hits="1"/> - <line number="1042" hits="1"/> - <line number="1057" hits="1"/> - <line number="1058" hits="1"/> - <line number="1059" hits="1"/> - <line number="1060" hits="1"/> - <line number="1061" hits="1"/> - <line number="1062" hits="1"/> - <line number="1063" hits="1"/> - <line number="1064" hits="1"/> - <line number="1065" hits="1"/> - <line number="1066" hits="1"/> - <line number="1067" hits="1"/> - <line number="1068" hits="1"/> - <line number="1070" hits="1"/> - <line number="1073" hits="1"/> - <line number="1087" hits="1"/> - <line number="1088" hits="1"/> - <line number="1089" hits="1"/> - <line number="1090" hits="1"/> - <line number="1091" hits="1"/> - <line number="1092" hits="1"/> - <line number="1093" hits="1"/> - <line number="1094" hits="1"/> - <line number="1095" hits="1"/> - <line number="1096" hits="1"/> - <line number="1097" hits="1"/> - <line number="1098" hits="1"/> - <line number="1100" hits="1"/> - <line number="1103" hits="1"/> - <line number="1120" hits="1"/> - <line number="1121" hits="1"/> - <line number="1122" hits="1"/> - <line number="1123" hits="1"/> - <line number="1124" hits="1"/> - <line number="1125" hits="1"/> - <line number="1126" hits="1"/> - <line number="1127" hits="1"/> - <line number="1128" hits="1"/> - <line number="1129" hits="1"/> - <line number="1130" hits="1"/> - <line number="1131" hits="1"/> - <line number="1132" hits="1"/> - <line number="1133" hits="1"/> - <line number="1134" hits="1"/> - <line number="1135" hits="1"/> - <line number="1136" hits="1"/> - <line number="1138" hits="1"/> - <line number="1141" hits="1"/> - <line number="1157" hits="1"/> - <line number="1158" hits="1"/> - <line number="1159" hits="1"/> - <line number="1160" hits="1"/> - <line number="1161" hits="1"/> - <line number="1162" hits="1"/> - <line number="1163" hits="1"/> - <line number="1164" hits="1"/> - <line number="1165" hits="1"/> - <line number="1166" hits="1"/> - <line number="1167" hits="1"/> - <line number="1168" hits="1"/> - <line number="1169" hits="1"/> - <line number="1170" hits="1"/> - <line number="1172" hits="1"/> - <line number="1175" hits="1"/> - <line number="1187" hits="1"/> - <line number="1188" hits="1"/> - <line number="1189" hits="1"/> - <line number="1190" hits="1"/> - <line number="1191" hits="1"/> - <line number="1192" hits="1"/> - <line number="1193" hits="1"/> - <line number="1194" hits="1"/> - <line number="1195" hits="1"/> - <line number="1196" hits="1"/> - <line number="1199" hits="1"/> - <line number="1216" hits="1"/> - <line number="1217" hits="1"/> - <line number="1218" hits="1"/> - <line number="1219" hits="1"/> - <line number="1220" hits="1"/> - <line number="1221" hits="1"/> - <line number="1222" hits="1"/> - <line number="1223" hits="1"/> - <line number="1224" hits="1"/> - <line number="1225" hits="1"/> - <line number="1226" hits="1"/> - <line number="1227" hits="1"/> - <line number="1228" hits="1"/> - <line number="1230" hits="1"/> - <line number="1231" hits="1"/> - <line number="1232" hits="1"/> - <line number="1235" hits="1"/> - <line number="1252" hits="1"/> - <line number="1253" hits="1"/> - <line number="1254" hits="1"/> - <line number="1255" hits="1"/> - <line number="1256" hits="1"/> - <line number="1257" hits="1"/> - <line number="1258" hits="1"/> - <line number="1259" hits="1"/> - <line number="1260" hits="1"/> - <line number="1261" hits="1"/> - <line number="1262" hits="1"/> - <line number="1263" hits="1"/> - <line number="1264" hits="1"/> - <line number="1266" hits="1"/> - <line number="1267" hits="1"/> - <line number="1268" hits="1"/> - <line number="1271" hits="1"/> - <line number="1285" hits="1"/> - <line number="1286" hits="1"/> - <line number="1287" hits="1"/> - <line number="1288" hits="1"/> - <line number="1289" hits="1"/> - <line number="1290" hits="1"/> - <line number="1291" hits="1"/> - <line number="1292" hits="1"/> - <line number="1293" hits="1"/> - <line number="1294" hits="1"/> - <line number="1295" hits="1"/> - <line number="1296" hits="1"/> - <line number="1298" hits="1"/> - <line number="1299" hits="1"/> - <line number="1300" hits="1"/> - <line number="1303" hits="1"/> - <line number="1326" hits="1"/> - <line number="1327" hits="1"/> - <line number="1328" hits="1"/> - <line number="1329" hits="1"/> - <line number="1330" hits="1"/> - <line number="1331" hits="1"/> - <line number="1332" hits="1"/> - <line number="1333" hits="1"/> - <line number="1335" hits="1"/> - <line number="1336" hits="1"/> - <line number="1337" hits="1"/> - <line number="1338" hits="1"/> - <line number="1339" hits="1"/> - <line number="1340" hits="1"/> - <line number="1341" hits="1"/> - <line number="1342" hits="1"/> - <line number="1343" hits="1"/> - <line number="1344" hits="1"/> - <line number="1345" hits="1"/> - <line number="1346" hits="1"/> - <line number="1347" hits="1"/> - <line number="1348" hits="1"/> - <line number="1349" hits="1"/> - <line number="1350" hits="1"/> - <line number="1353" hits="1"/> - <line number="1371" hits="1"/> - <line number="1372" hits="1"/> - <line number="1373" hits="1"/> - <line number="1374" hits="1"/> - <line number="1375" hits="1"/> - <line number="1376" hits="1"/> - <line number="1377" hits="1"/> - <line number="1378" hits="1"/> - <line number="1379" hits="1"/> - <line number="1380" hits="1"/> - <line number="1381" hits="1"/> - <line number="1382" hits="1"/> - <line number="1383" hits="1"/> - <line number="1384" hits="1"/> - <line number="1385" hits="1"/> - <line number="1386" hits="1"/> - <line number="1389" hits="1"/> - <line number="1404" hits="1"/> - <line number="1405" hits="1"/> - <line number="1406" hits="1"/> - <line number="1407" hits="1"/> - <line number="1408" hits="1"/> - <line number="1409" hits="1"/> - <line number="1410" hits="1"/> - <line number="1411" hits="1"/> - <line number="1412" hits="1"/> - <line number="1413" hits="1"/> - <line number="1414" hits="1"/> - <line number="1415" hits="1"/> - <line number="1416" hits="1"/> - <line number="1419" hits="1"/> - <line number="1434" hits="1"/> - <line number="1435" hits="1"/> - <line number="1436" hits="1"/> - <line number="1437" hits="1"/> - <line number="1438" hits="1"/> - <line number="1439" hits="1"/> - <line number="1440" hits="1"/> - <line number="1441" hits="1"/> - <line number="1442" hits="1"/> - <line number="1443" hits="1"/> - <line number="1444" hits="1"/> - <line number="1445" hits="1"/> - <line number="1446" hits="1"/> - <line number="1447" hits="1"/> - <line number="1450" hits="1"/> - <line number="1463" hits="1"/> - <line number="1464" hits="1"/> - <line number="1465" hits="1"/> - <line number="1466" hits="1"/> - <line number="1467" hits="1"/> - <line number="1468" hits="1"/> - <line number="1469" hits="1"/> - <line number="1470" hits="1"/> - <line number="1471" hits="1"/> - <line number="1472" hits="1"/> - <line number="1473" hits="1"/> - <line number="1474" hits="1"/> - <line number="1477" hits="1"/> - <line number="1495" hits="1"/> - <line number="1496" hits="1"/> - <line number="1497" hits="1"/> - <line number="1498" hits="1"/> - <line number="1499" hits="1"/> - <line number="1500" hits="1"/> - <line number="1501" hits="1"/> - <line number="1502" hits="1"/> - <line number="1503" hits="1"/> - <line number="1504" hits="1"/> - <line number="1505" hits="1"/> - <line number="1506" hits="1"/> - <line number="1507" hits="1"/> - <line number="1508" hits="1"/> - <line number="1509" hits="1"/> - <line number="1510" hits="1"/> - <line number="1513" hits="1"/> - <line number="1549" hits="1"/> - <line number="1550" hits="1"/> - <line number="1555" hits="1"/> - <line number="1556" hits="1"/> - <line number="1557" hits="1"/> - <line number="1558" hits="1"/> - <line number="1559" hits="1"/> - <line number="1560" hits="1"/> - <line number="1561" hits="1"/> - <line number="1562" hits="1"/> - <line number="1563" hits="1"/> - <line number="1564" hits="1"/> - <line number="1565" hits="1"/> - <line number="1566" hits="1"/> - <line number="1568" hits="1"/> - <line number="1569" hits="1"/> - <line number="1570" hits="1"/> - <line number="1573" hits="1"/> - <line number="1610" hits="1"/> - <line number="1611" hits="1"/> - <line number="1617" hits="1"/> - <line number="1618" hits="1"/> - <line number="1619" hits="1"/> - <line number="1620" hits="1"/> - <line number="1621" hits="1"/> - <line number="1622" hits="1"/> - <line number="1623" hits="1"/> - <line number="1624" hits="1"/> - <line number="1625" hits="1"/> - <line number="1626" hits="1"/> - <line number="1627" hits="1"/> - <line number="1628" hits="1"/> - <line number="1630" hits="1"/> - <line number="1631" hits="1"/> - <line number="1632" hits="1"/> - <line number="1635" hits="1"/> - <line number="1650" hits="1"/> - <line number="1651" hits="1"/> - <line number="1652" hits="1"/> - <line number="1653" hits="1"/> - <line number="1654" hits="1"/> - <line number="1655" hits="1"/> - <line number="1656" hits="1"/> - <line number="1657" hits="1"/> - <line number="1658" hits="1"/> - <line number="1659" hits="1"/> - <line number="1660" hits="1"/> - <line number="1661" hits="1"/> - <line number="1662" hits="1"/> - <line number="1664" hits="1"/> - <line number="1665" hits="1"/> - <line number="1666" hits="1"/> - <line number="1669" hits="1"/> - <line number="1675" hits="1"/> - <line number="1676" hits="1"/> - <line number="1677" hits="1"/> - <line number="1678" hits="1"/> - <line number="1679" hits="1"/> - <line number="1680" hits="1"/> - <line number="1683" hits="1"/> - <line number="1689" hits="0"/> - <line number="1690" hits="0"/> - <line number="1691" hits="0"/> - <line number="1692" hits="0"/> - <line number="1693" hits="0"/> - <line number="1694" hits="0"/> - <line number="1697" hits="1"/> - <line number="1703" hits="1"/> - <line number="1704" hits="1"/> - <line number="1705" hits="1"/> - <line number="1706" hits="1"/> - <line number="1707" hits="1"/> - <line number="1708" hits="1"/> - <line number="1711" hits="1"/> - <line number="1730" hits="1"/> - <line number="1731" hits="1"/> - <line number="1732" hits="1"/> - <line number="1733" hits="1"/> - <line number="1734" hits="1"/> - <line number="1735" hits="1"/> - <line number="1736" hits="1"/> - <line number="1737" hits="1"/> - <line number="1738" hits="1"/> - <line number="1739" hits="1"/> - <line number="1740" hits="1"/> - <line number="1741" hits="1"/> - <line number="1742" hits="1"/> - <line number="1743" hits="1"/> - <line number="1744" hits="1"/> - <line number="1745" hits="1"/> - <line number="1746" hits="1"/> - <line number="1747" hits="1"/> - <line number="1748" hits="1"/> - <line number="1749" hits="1"/> - <line number="1750" hits="1"/> - <line number="1751" hits="1"/> - <line number="1752" hits="1"/> - <line number="1753" hits="1"/> - <line number="1754" hits="1"/> - <line number="1755" hits="1"/> - <line number="1756" hits="1"/> - <line number="1757" hits="1"/> - <line number="1759" hits="1"/> - <line number="1762" hits="1"/> - <line number="1773" hits="0"/> - <line number="1774" hits="0"/> - <line number="1775" hits="0"/> - <line number="1776" hits="0"/> - <line number="1777" hits="0"/> - <line number="1778" hits="0"/> - <line number="1779" hits="0"/> - <line number="1780" hits="0"/> - <line number="1783" hits="1"/> - <line number="1794" hits="0"/> - <line number="1795" hits="0"/> - <line number="1796" hits="0"/> - <line number="1797" hits="0"/> - <line number="1798" hits="0"/> - <line number="1799" hits="0"/> - <line number="1800" hits="0"/> - <line number="1801" hits="0"/> - <line number="1804" hits="1"/> - <line number="1810" hits="1"/> - <line number="1811" hits="1"/> - <line number="1812" hits="1"/> - <line number="1813" hits="1"/> - <line number="1814" hits="1"/> - <line number="1815" hits="0"/> - <line number="1818" hits="1"/> - <line number="1824" hits="1"/> - <line number="1825" hits="1"/> - <line number="1826" hits="1"/> - <line number="1827" hits="1"/> - <line number="1828" hits="1"/> - <line number="1829" hits="0"/> - <line number="1833" hits="1"/> - <line number="1853" hits="1"/> - <line number="1854" hits="1"/> - <line number="1856" hits="1"/> - <line number="1857" hits="1"/> - <line number="1858" hits="1"/> - <line number="1859" hits="1"/> - <line number="1860" hits="1"/> - <line number="1861" hits="1"/> - <line number="1862" hits="1"/> - <line number="1863" hits="1"/> - <line number="1864" hits="1"/> - <line number="1865" hits="1"/> - <line number="1866" hits="1"/> - <line number="1867" hits="1"/> - <line number="1868" hits="1"/> - <line number="1869" hits="1"/> - </lines> - </class> - <class name="UploadClient.py" filename="dbrepo/UploadClient.py" complexity="0" line-rate="0.52" branch-rate="0"> - <methods/> - <lines> - <line number="1" hits="1"/> - <line number="2" hits="1"/> - <line number="3" hits="1"/> - <line number="4" hits="1"/> - <line number="5" hits="1"/> - <line number="7" hits="1"/> - <line number="8" hits="1"/> - <line number="10" hits="1"/> - <line number="12" hits="1"/> - <line number="16" hits="1"/> - <line number="24" hits="1"/> - <line number="26" hits="1"/> - <line number="27" hits="0"/> - <line number="29" hits="1"/> - <line number="30" hits="0"/> - <line number="31" hits="0"/> - <line number="32" hits="0"/> - <line number="33" hits="0"/> - <line number="34" hits="0"/> - <line number="35" hits="0"/> - <line number="36" hits="0"/> - <line number="37" hits="0"/> - <line number="38" hits="0"/> - <line number="39" hits="0"/> - <line number="40" hits="0"/> - </lines> - </class> - <class name="__init__.py" filename="dbrepo/__init__.py" complexity="0" line-rate="1" branch-rate="0"> - <methods/> - <lines/> - </class> - </classes> - </package> - <package name="dbrepo.api" line-rate="1" branch-rate="0" complexity="0"> - <classes> - <class name="__init__.py" filename="dbrepo/api/__init__.py" complexity="0" line-rate="1" branch-rate="0"> - <methods/> - <lines/> - </class> - <class name="dto.py" filename="dbrepo/api/dto.py" complexity="0" line-rate="1" branch-rate="0"> - <methods/> - <lines> - <line number="1" hits="1"/> - <line number="3" hits="1"/> - <line number="4" hits="1"/> - <line number="5" hits="1"/> - <line number="6" hits="1"/> - <line number="8" hits="1"/> - <line number="10" hits="1"/> - <line number="15" hits="1"/> - <line number="16" hits="1"/> - <line number="17" hits="1"/> - <line number="18" hits="1"/> - <line number="19" hits="1"/> - <line number="22" hits="1"/> - <line number="23" hits="1"/> - <line number="24" hits="1"/> - <line number="25" hits="1"/> - <line number="26" hits="1"/> - <line number="27" hits="1"/> - <line number="28" hits="1"/> - <line number="29" hits="1"/> - <line number="30" hits="1"/> - <line number="31" hits="1"/> - <line number="32" hits="1"/> - <line number="33" hits="1"/> - <line number="36" hits="1"/> - <line number="37" hits="1"/> - <line number="38" hits="1"/> - <line number="39" hits="1"/> - <line number="40" hits="1"/> - <line number="43" hits="1"/> - <line number="44" hits="1"/> - <line number="45" hits="1"/> - <line number="46" hits="1"/> - <line number="47" hits="1"/> - <line number="50" hits="1"/> - <line number="51" hits="1"/> - <line number="52" hits="1"/> - <line number="55" hits="1"/> - <line number="56" hits="1"/> - <line number="57" hits="1"/> - <line number="58" hits="1"/> - <line number="59" hits="1"/> - <line number="60" hits="1"/> - <line number="61" hits="1"/> - <line number="62" hits="1"/> - <line number="63" hits="1"/> - <line number="66" hits="1"/> - <line number="67" hits="1"/> - <line number="68" hits="1"/> - <line number="69" hits="1"/> - <line number="72" hits="1"/> - <line number="73" hits="1"/> - <line number="74" hits="1"/> - <line number="75" hits="1"/> - <line number="76" hits="1"/> - <line number="77" hits="1"/> - <line number="78" hits="1"/> - <line number="81" hits="1"/> - <line number="82" hits="1"/> - <line number="83" hits="1"/> - <line number="84" hits="1"/> - <line number="85" hits="1"/> - <line number="86" hits="1"/> - <line number="87" hits="1"/> - <line number="88" hits="1"/> - <line number="91" hits="1"/> - <line number="92" hits="1"/> - <line number="93" hits="1"/> - <line number="94" hits="1"/> - <line number="95" hits="1"/> - <line number="96" hits="1"/> - <line number="97" hits="1"/> - <line number="98" hits="1"/> - <line number="99" hits="1"/> - <line number="102" hits="1"/> - <line number="103" hits="1"/> - <line number="104" hits="1"/> - <line number="105" hits="1"/> - <line number="106" hits="1"/> - <line number="107" hits="1"/> - <line number="108" hits="1"/> - <line number="111" hits="1"/> - <line number="112" hits="1"/> - <line number="113" hits="1"/> - <line number="114" hits="1"/> - <line number="115" hits="1"/> - <line number="116" hits="1"/> - <line number="117" hits="1"/> - <line number="118" hits="1"/> - <line number="121" hits="1"/> - <line number="122" hits="1"/> - <line number="123" hits="1"/> - <line number="124" hits="1"/> - <line number="125" hits="1"/> - <line number="126" hits="1"/> - <line number="127" hits="1"/> - <line number="128" hits="1"/> - <line number="129" hits="1"/> - <line number="130" hits="1"/> - <line number="133" hits="1"/> - <line number="134" hits="1"/> - <line number="135" hits="1"/> - <line number="136" hits="1"/> - <line number="137" hits="1"/> - <line number="140" hits="1"/> - <line number="141" hits="1"/> - <line number="142" hits="1"/> - <line number="143" hits="1"/> - <line number="144" hits="1"/> - <line number="145" hits="1"/> - <line number="146" hits="1"/> - <line number="147" hits="1"/> - <line number="150" hits="1"/> - <line number="151" hits="1"/> - <line number="154" hits="1"/> - <line number="155" hits="1"/> - <line number="158" hits="1"/> - <line number="162" hits="1"/> - <line number="163" hits="1"/> - <line number="165" hits="1"/> - <line number="166" hits="1"/> - <line number="168" hits="1"/> - <line number="169" hits="1"/> - <line number="172" hits="1"/> - <line number="176" hits="1"/> - <line number="177" hits="1"/> - <line number="178" hits="1"/> - <line number="179" hits="1"/> - <line number="180" hits="1"/> - <line number="181" hits="1"/> - <line number="182" hits="1"/> - <line number="183" hits="1"/> - <line number="184" hits="1"/> - <line number="185" hits="1"/> - <line number="186" hits="1"/> - <line number="187" hits="1"/> - <line number="188" hits="1"/> - <line number="189" hits="1"/> - <line number="190" hits="1"/> - <line number="191" hits="1"/> - <line number="192" hits="1"/> - <line number="193" hits="1"/> - <line number="194" hits="1"/> - <line number="195" hits="1"/> - <line number="196" hits="1"/> - <line number="197" hits="1"/> - <line number="198" hits="1"/> - <line number="199" hits="1"/> - <line number="200" hits="1"/> - <line number="201" hits="1"/> - <line number="202" hits="1"/> - <line number="203" hits="1"/> - <line number="204" hits="1"/> - <line number="205" hits="1"/> - <line number="208" hits="1"/> - <line number="212" hits="1"/> - <line number="213" hits="1"/> - <line number="214" hits="1"/> - <line number="215" hits="1"/> - <line number="216" hits="1"/> - <line number="217" hits="1"/> - <line number="218" hits="1"/> - <line number="219" hits="1"/> - <line number="220" hits="1"/> - <line number="221" hits="1"/> - <line number="222" hits="1"/> - <line number="223" hits="1"/> - <line number="224" hits="1"/> - <line number="225" hits="1"/> - <line number="226" hits="1"/> - <line number="227" hits="1"/> - <line number="228" hits="1"/> - <line number="229" hits="1"/> - <line number="230" hits="1"/> - <line number="231" hits="1"/> - <line number="232" hits="1"/> - <line number="233" hits="1"/> - <line number="234" hits="1"/> - <line number="235" hits="1"/> - <line number="236" hits="1"/> - <line number="237" hits="1"/> - <line number="238" hits="1"/> - <line number="239" hits="1"/> - <line number="240" hits="1"/> - <line number="241" hits="1"/> - <line number="242" hits="1"/> - <line number="243" hits="1"/> - <line number="244" hits="1"/> - <line number="245" hits="1"/> - <line number="246" hits="1"/> - <line number="247" hits="1"/> - <line number="248" hits="1"/> - <line number="249" hits="1"/> - <line number="250" hits="1"/> - <line number="251" hits="1"/> - <line number="252" hits="1"/> - <line number="253" hits="1"/> - <line number="254" hits="1"/> - <line number="255" hits="1"/> - <line number="256" hits="1"/> - <line number="257" hits="1"/> - <line number="258" hits="1"/> - <line number="259" hits="1"/> - <line number="260" hits="1"/> - <line number="261" hits="1"/> - <line number="262" hits="1"/> - <line number="263" hits="1"/> - <line number="264" hits="1"/> - <line number="265" hits="1"/> - <line number="266" hits="1"/> - <line number="267" hits="1"/> - <line number="268" hits="1"/> - <line number="269" hits="1"/> - <line number="270" hits="1"/> - <line number="271" hits="1"/> - <line number="272" hits="1"/> - <line number="273" hits="1"/> - <line number="274" hits="1"/> - <line number="275" hits="1"/> - <line number="276" hits="1"/> - <line number="277" hits="1"/> - <line number="278" hits="1"/> - <line number="279" hits="1"/> - <line number="280" hits="1"/> - <line number="281" hits="1"/> - <line number="282" hits="1"/> - <line number="283" hits="1"/> - <line number="284" hits="1"/> - <line number="285" hits="1"/> - <line number="286" hits="1"/> - <line number="287" hits="1"/> - <line number="288" hits="1"/> - <line number="289" hits="1"/> - <line number="290" hits="1"/> - <line number="291" hits="1"/> - <line number="292" hits="1"/> - <line number="293" hits="1"/> - <line number="294" hits="1"/> - <line number="295" hits="1"/> - <line number="296" hits="1"/> - <line number="297" hits="1"/> - <line number="298" hits="1"/> - <line number="299" hits="1"/> - <line number="300" hits="1"/> - <line number="301" hits="1"/> - <line number="302" hits="1"/> - <line number="303" hits="1"/> - <line number="304" hits="1"/> - <line number="305" hits="1"/> - <line number="306" hits="1"/> - <line number="307" hits="1"/> - <line number="308" hits="1"/> - <line number="309" hits="1"/> - <line number="310" hits="1"/> - <line number="311" hits="1"/> - <line number="312" hits="1"/> - <line number="313" hits="1"/> - <line number="314" hits="1"/> - <line number="315" hits="1"/> - <line number="316" hits="1"/> - <line number="317" hits="1"/> - <line number="318" hits="1"/> - <line number="319" hits="1"/> - <line number="320" hits="1"/> - <line number="321" hits="1"/> - <line number="322" hits="1"/> - <line number="323" hits="1"/> - <line number="324" hits="1"/> - <line number="325" hits="1"/> - <line number="326" hits="1"/> - <line number="327" hits="1"/> - <line number="328" hits="1"/> - <line number="329" hits="1"/> - <line number="330" hits="1"/> - <line number="331" hits="1"/> - <line number="332" hits="1"/> - <line number="333" hits="1"/> - <line number="334" hits="1"/> - <line number="335" hits="1"/> - <line number="336" hits="1"/> - <line number="337" hits="1"/> - <line number="338" hits="1"/> - <line number="339" hits="1"/> - <line number="340" hits="1"/> - <line number="341" hits="1"/> - <line number="342" hits="1"/> - <line number="343" hits="1"/> - <line number="344" hits="1"/> - <line number="345" hits="1"/> - <line number="346" hits="1"/> - <line number="347" hits="1"/> - <line number="348" hits="1"/> - <line number="349" hits="1"/> - <line number="350" hits="1"/> - <line number="351" hits="1"/> - <line number="352" hits="1"/> - <line number="353" hits="1"/> - <line number="354" hits="1"/> - <line number="355" hits="1"/> - <line number="356" hits="1"/> - <line number="357" hits="1"/> - <line number="358" hits="1"/> - <line number="359" hits="1"/> - <line number="360" hits="1"/> - <line number="361" hits="1"/> - <line number="362" hits="1"/> - <line number="363" hits="1"/> - <line number="364" hits="1"/> - <line number="365" hits="1"/> - <line number="366" hits="1"/> - <line number="367" hits="1"/> - <line number="368" hits="1"/> - <line number="369" hits="1"/> - <line number="370" hits="1"/> - <line number="371" hits="1"/> - <line number="372" hits="1"/> - <line number="373" hits="1"/> - <line number="374" hits="1"/> - <line number="375" hits="1"/> - <line number="376" hits="1"/> - <line number="377" hits="1"/> - <line number="378" hits="1"/> - <line number="379" hits="1"/> - <line number="380" hits="1"/> - <line number="381" hits="1"/> - <line number="382" hits="1"/> - <line number="383" hits="1"/> - <line number="384" hits="1"/> - <line number="385" hits="1"/> - <line number="386" hits="1"/> - <line number="387" hits="1"/> - <line number="388" hits="1"/> - <line number="389" hits="1"/> - <line number="390" hits="1"/> - <line number="391" hits="1"/> - <line number="392" hits="1"/> - <line number="393" hits="1"/> - <line number="394" hits="1"/> - <line number="395" hits="1"/> - <line number="398" hits="1"/> - <line number="399" hits="1"/> - <line number="400" hits="1"/> - <line number="403" hits="1"/> - <line number="404" hits="1"/> - <line number="407" hits="1"/> - <line number="408" hits="1"/> - <line number="411" hits="1"/> - <line number="415" hits="1"/> - <line number="416" hits="1"/> - <line number="417" hits="1"/> - <line number="418" hits="1"/> - <line number="421" hits="1"/> - <line number="422" hits="1"/> - <line number="423" hits="1"/> - <line number="424" hits="1"/> - <line number="427" hits="1"/> - <line number="428" hits="1"/> - <line number="431" hits="1"/> - <line number="432" hits="1"/> - <line number="433" hits="1"/> - <line number="434" hits="1"/> - <line number="435" hits="1"/> - <line number="438" hits="1"/> - <line number="439" hits="1"/> - <line number="440" hits="1"/> - <line number="441" hits="1"/> - <line number="444" hits="1"/> - <line number="445" hits="1"/> - <line number="448" hits="1"/> - <line number="449" hits="1"/> - <line number="450" hits="1"/> - <line number="451" hits="1"/> - <line number="452" hits="1"/> - <line number="453" hits="1"/> - <line number="454" hits="1"/> - <line number="455" hits="1"/> - <line number="458" hits="1"/> - <line number="459" hits="1"/> - <line number="460" hits="1"/> - <line number="461" hits="1"/> - <line number="462" hits="1"/> - <line number="463" hits="1"/> - <line number="464" hits="1"/> - <line number="467" hits="1"/> - <line number="468" hits="1"/> - <line number="471" hits="1"/> - <line number="472" hits="1"/> - <line number="473" hits="1"/> - <line number="474" hits="1"/> - <line number="477" hits="1"/> - <line number="478" hits="1"/> - <line number="479" hits="1"/> - <line number="480" hits="1"/> - <line number="481" hits="1"/> - <line number="482" hits="1"/> - <line number="483" hits="1"/> - <line number="486" hits="1"/> - <line number="487" hits="1"/> - <line number="490" hits="1"/> - <line number="491" hits="1"/> - <line number="492" hits="1"/> - <line number="495" hits="1"/> - <line number="496" hits="1"/> - <line number="499" hits="1"/> - <line number="500" hits="1"/> - <line number="501" hits="1"/> - <line number="502" hits="1"/> - <line number="503" hits="1"/> - <line number="504" hits="1"/> - <line number="507" hits="1"/> - <line number="508" hits="1"/> - <line number="509" hits="1"/> - <line number="512" hits="1"/> - <line number="513" hits="1"/> - <line number="514" hits="1"/> - <line number="517" hits="1"/> - <line number="518" hits="1"/> - <line number="521" hits="1"/> - <line number="522" hits="1"/> - <line number="523" hits="1"/> - <line number="524" hits="1"/> - <line number="525" hits="1"/> - <line number="526" hits="1"/> - <line number="527" hits="1"/> - <line number="530" hits="1"/> - <line number="531" hits="1"/> - <line number="532" hits="1"/> - <line number="533" hits="1"/> - <line number="534" hits="1"/> - <line number="535" hits="1"/> - <line number="536" hits="1"/> - <line number="537" hits="1"/> - <line number="538" hits="1"/> - <line number="539" hits="1"/> - <line number="540" hits="1"/> - <line number="541" hits="1"/> - <line number="544" hits="1"/> - <line number="545" hits="1"/> - <line number="546" hits="1"/> - <line number="547" hits="1"/> - <line number="548" hits="1"/> - <line number="551" hits="1"/> - <line number="555" hits="1"/> - <line number="556" hits="1"/> - <line number="557" hits="1"/> - <line number="558" hits="1"/> - <line number="561" hits="1"/> - <line number="565" hits="1"/> - <line number="566" hits="1"/> - <line number="567" hits="1"/> - <line number="570" hits="1"/> - <line number="571" hits="1"/> - <line number="572" hits="1"/> - <line number="573" hits="1"/> - <line number="574" hits="1"/> - <line number="575" hits="1"/> - <line number="576" hits="1"/> - <line number="577" hits="1"/> - <line number="578" hits="1"/> - <line number="579" hits="1"/> - <line number="580" hits="1"/> - <line number="581" hits="1"/> - <line number="582" hits="1"/> - <line number="585" hits="1"/> - <line number="586" hits="1"/> - <line number="587" hits="1"/> - <line number="588" hits="1"/> - <line number="589" hits="1"/> - <line number="590" hits="1"/> - <line number="591" hits="1"/> - <line number="592" hits="1"/> - <line number="593" hits="1"/> - <line number="596" hits="1"/> - <line number="597" hits="1"/> - <line number="598" hits="1"/> - <line number="599" hits="1"/> - <line number="600" hits="1"/> - <line number="601" hits="1"/> - <line number="602" hits="1"/> - <line number="603" hits="1"/> - <line number="604" hits="1"/> - <line number="605" hits="1"/> - <line number="606" hits="1"/> - <line number="607" hits="1"/> - <line number="610" hits="1"/> - <line number="611" hits="1"/> - <line number="614" hits="1"/> - <line number="615" hits="1"/> - <line number="616" hits="1"/> - <line number="617" hits="1"/> - <line number="618" hits="1"/> - <line number="621" hits="1"/> - <line number="622" hits="1"/> - <line number="623" hits="1"/> - <line number="624" hits="1"/> - <line number="627" hits="1"/> - <line number="628" hits="1"/> - <line number="631" hits="1"/> - <line number="632" hits="1"/> - <line number="633" hits="1"/> - <line number="634" hits="1"/> - <line number="635" hits="1"/> - <line number="636" hits="1"/> - <line number="637" hits="1"/> - <line number="638" hits="1"/> - <line number="639" hits="1"/> - <line number="640" hits="1"/> - <line number="641" hits="1"/> - <line number="642" hits="1"/> - <line number="643" hits="1"/> - <line number="644" hits="1"/> - <line number="645" hits="1"/> - <line number="646" hits="1"/> - <line number="647" hits="1"/> - <line number="648" hits="1"/> - <line number="649" hits="1"/> - <line number="650" hits="1"/> - <line number="651" hits="1"/> - <line number="652" hits="1"/> - <line number="653" hits="1"/> - <line number="656" hits="1"/> - <line number="657" hits="1"/> - <line number="660" hits="1"/> - <line number="661" hits="1"/> - <line number="662" hits="1"/> - <line number="663" hits="1"/> - <line number="664" hits="1"/> - <line number="665" hits="1"/> - <line number="666" hits="1"/> - <line number="667" hits="1"/> - <line number="668" hits="1"/> - <line number="669" hits="1"/> - <line number="670" hits="1"/> - <line number="671" hits="1"/> - <line number="672" hits="1"/> - <line number="673" hits="1"/> - <line number="674" hits="1"/> - <line number="675" hits="1"/> - <line number="676" hits="1"/> - <line number="677" hits="1"/> - <line number="678" hits="1"/> - <line number="679" hits="1"/> - <line number="680" hits="1"/> - <line number="681" hits="1"/> - <line number="682" hits="1"/> - <line number="683" hits="1"/> - <line number="684" hits="1"/> - <line number="685" hits="1"/> - <line number="688" hits="1"/> - <line number="689" hits="1"/> - <line number="690" hits="1"/> - <line number="691" hits="1"/> - <line number="692" hits="1"/> - <line number="693" hits="1"/> - <line number="694" hits="1"/> - <line number="697" hits="1"/> - <line number="698" hits="1"/> - <line number="699" hits="1"/> - <line number="700" hits="1"/> - <line number="701" hits="1"/> - <line number="702" hits="1"/> - <line number="703" hits="1"/> - <line number="704" hits="1"/> - <line number="705" hits="1"/> - <line number="706" hits="1"/> - <line number="707" hits="1"/> - <line number="708" hits="1"/> - <line number="709" hits="1"/> - <line number="712" hits="1"/> - <line number="713" hits="1"/> - <line number="714" hits="1"/> - <line number="715" hits="1"/> - <line number="716" hits="1"/> - <line number="717" hits="1"/> - <line number="718" hits="1"/> - <line number="719" hits="1"/> - <line number="720" hits="1"/> - <line number="721" hits="1"/> - <line number="722" hits="1"/> - <line number="723" hits="1"/> - <line number="724" hits="1"/> - <line number="727" hits="1"/> - <line number="728" hits="1"/> - <line number="729" hits="1"/> - <line number="730" hits="1"/> - <line number="731" hits="1"/> - <line number="734" hits="1"/> - <line number="735" hits="1"/> - <line number="736" hits="1"/> - <line number="737" hits="1"/> - <line number="740" hits="1"/> - <line number="741" hits="1"/> - <line number="742" hits="1"/> - <line number="743" hits="1"/> - <line number="744" hits="1"/> - <line number="745" hits="1"/> - <line number="746" hits="1"/> - <line number="747" hits="1"/> - <line number="748" hits="1"/> - <line number="749" hits="1"/> - <line number="750" hits="1"/> - <line number="753" hits="1"/> - <line number="754" hits="1"/> - <line number="755" hits="1"/> - <line number="756" hits="1"/> - <line number="757" hits="1"/> - <line number="760" hits="1"/> - <line number="761" hits="1"/> - <line number="762" hits="1"/> - <line number="763" hits="1"/> - <line number="766" hits="1"/> - <line number="767" hits="1"/> - <line number="770" hits="1"/> - <line number="771" hits="1"/> - <line number="772" hits="1"/> - <line number="773" hits="1"/> - <line number="774" hits="1"/> - <line number="775" hits="1"/> - <line number="778" hits="1"/> - <line number="779" hits="1"/> - <line number="780" hits="1"/> - <line number="781" hits="1"/> - <line number="784" hits="1"/> - <line number="785" hits="1"/> - <line number="788" hits="1"/> - <line number="789" hits="1"/> - <line number="790" hits="1"/> - <line number="791" hits="1"/> - <line number="792" hits="1"/> - <line number="795" hits="1"/> - <line number="796" hits="1"/> - <line number="799" hits="1"/> - <line number="803" hits="1"/> - <line number="804" hits="1"/> - <line number="805" hits="1"/> - <line number="806" hits="1"/> - <line number="809" hits="1"/> - <line number="813" hits="1"/> - <line number="814" hits="1"/> - <line number="817" hits="1"/> - <line number="821" hits="1"/> - <line number="822" hits="1"/> - <line number="823" hits="1"/> - <line number="824" hits="1"/> - <line number="825" hits="1"/> - <line number="826" hits="1"/> - <line number="827" hits="1"/> - <line number="828" hits="1"/> - <line number="829" hits="1"/> - <line number="830" hits="1"/> - <line number="831" hits="1"/> - <line number="832" hits="1"/> - <line number="833" hits="1"/> - <line number="834" hits="1"/> - <line number="835" hits="1"/> - <line number="836" hits="1"/> - <line number="837" hits="1"/> - <line number="838" hits="1"/> - <line number="841" hits="1"/> - <line number="845" hits="1"/> - <line number="846" hits="1"/> - <line number="847" hits="1"/> - <line number="848" hits="1"/> - <line number="849" hits="1"/> - <line number="850" hits="1"/> - <line number="851" hits="1"/> - <line number="852" hits="1"/> - <line number="853" hits="1"/> - <line number="854" hits="1"/> - <line number="855" hits="1"/> - <line number="856" hits="1"/> - <line number="857" hits="1"/> - <line number="858" hits="1"/> - <line number="859" hits="1"/> - <line number="860" hits="1"/> - <line number="861" hits="1"/> - <line number="862" hits="1"/> - <line number="863" hits="1"/> - <line number="864" hits="1"/> - <line number="865" hits="1"/> - <line number="866" hits="1"/> - <line number="867" hits="1"/> - <line number="868" hits="1"/> - <line number="869" hits="1"/> - <line number="870" hits="1"/> - <line number="871" hits="1"/> - <line number="872" hits="1"/> - <line number="873" hits="1"/> - <line number="874" hits="1"/> - <line number="875" hits="1"/> - <line number="876" hits="1"/> - <line number="877" hits="1"/> - <line number="878" hits="1"/> - <line number="881" hits="1"/> - <line number="885" hits="1"/> - <line number="886" hits="1"/> - <line number="887" hits="1"/> - <line number="888" hits="1"/> - <line number="889" hits="1"/> - <line number="890" hits="1"/> - <line number="893" hits="1"/> - <line number="897" hits="1"/> - <line number="898" hits="1"/> - <line number="900" hits="1"/> - <line number="901" hits="1"/> - <line number="904" hits="1"/> - <line number="908" hits="1"/> - <line number="909" hits="1"/> - <line number="911" hits="1"/> - <line number="912" hits="1"/> - <line number="914" hits="1"/> - <line number="915" hits="1"/> - <line number="917" hits="1"/> - <line number="918" hits="1"/> - <line number="921" hits="1"/> - <line number="925" hits="1"/> - <line number="926" hits="1"/> - <line number="928" hits="1"/> - <line number="929" hits="1"/> - <line number="932" hits="1"/> - <line number="936" hits="1"/> - <line number="937" hits="1"/> - <line number="939" hits="1"/> - <line number="940" hits="1"/> - <line number="942" hits="1"/> - <line number="943" hits="1"/> - <line number="945" hits="1"/> - <line number="946" hits="1"/> - <line number="949" hits="1"/> - <line number="950" hits="1"/> - <line number="951" hits="1"/> - <line number="952" hits="1"/> - <line number="953" hits="1"/> - <line number="954" hits="1"/> - <line number="955" hits="1"/> - <line number="956" hits="1"/> - <line number="957" hits="1"/> - <line number="958" hits="1"/> - <line number="959" hits="1"/> - <line number="960" hits="1"/> - <line number="961" hits="1"/> - <line number="964" hits="1"/> - <line number="965" hits="1"/> - <line number="968" hits="1"/> - <line number="969" hits="1"/> - <line number="970" hits="1"/> - <line number="973" hits="1"/> - <line number="974" hits="1"/> - <line number="975" hits="1"/> - <line number="978" hits="1"/> - <line number="979" hits="1"/> - <line number="980" hits="1"/> - <line number="981" hits="1"/> - <line number="982" hits="1"/> - <line number="983" hits="1"/> - <line number="984" hits="1"/> - <line number="985" hits="1"/> - <line number="986" hits="1"/> - <line number="987" hits="1"/> - <line number="988" hits="1"/> - <line number="989" hits="1"/> - <line number="990" hits="1"/> - <line number="991" hits="1"/> - <line number="992" hits="1"/> - <line number="993" hits="1"/> - <line number="994" hits="1"/> - <line number="997" hits="1"/> - <line number="998" hits="1"/> - <line number="999" hits="1"/> - <line number="1000" hits="1"/> - <line number="1001" hits="1"/> - <line number="1002" hits="1"/> - <line number="1003" hits="1"/> - <line number="1004" hits="1"/> - <line number="1005" hits="1"/> - <line number="1006" hits="1"/> - <line number="1007" hits="1"/> - <line number="1008" hits="1"/> - <line number="1009" hits="1"/> - <line number="1010" hits="1"/> - <line number="1011" hits="1"/> - <line number="1012" hits="1"/> - <line number="1013" hits="1"/> - <line number="1014" hits="1"/> - <line number="1015" hits="1"/> - <line number="1016" hits="1"/> - <line number="1017" hits="1"/> - <line number="1018" hits="1"/> - <line number="1019" hits="1"/> - <line number="1020" hits="1"/> - <line number="1021" hits="1"/> - <line number="1022" hits="1"/> - <line number="1023" hits="1"/> - <line number="1026" hits="1"/> - <line number="1027" hits="1"/> - <line number="1028" hits="1"/> - <line number="1029" hits="1"/> - <line number="1030" hits="1"/> - <line number="1031" hits="1"/> - <line number="1032" hits="1"/> - <line number="1033" hits="1"/> - <line number="1034" hits="1"/> - <line number="1035" hits="1"/> - <line number="1036" hits="1"/> - <line number="1037" hits="1"/> - <line number="1038" hits="1"/> - <line number="1039" hits="1"/> - <line number="1040" hits="1"/> - <line number="1041" hits="1"/> - <line number="1042" hits="1"/> - <line number="1045" hits="1"/> - <line number="1046" hits="1"/> - <line number="1047" hits="1"/> - <line number="1048" hits="1"/> - <line number="1049" hits="1"/> - <line number="1050" hits="1"/> - <line number="1051" hits="1"/> - <line number="1052" hits="1"/> - <line number="1053" hits="1"/> - <line number="1054" hits="1"/> - <line number="1055" hits="1"/> - <line number="1056" hits="1"/> - <line number="1057" hits="1"/> - <line number="1058" hits="1"/> - <line number="1059" hits="1"/> - <line number="1060" hits="1"/> - <line number="1061" hits="1"/> - <line number="1062" hits="1"/> - <line number="1063" hits="1"/> - <line number="1064" hits="1"/> - <line number="1067" hits="1"/> - <line number="1068" hits="1"/> - <line number="1069" hits="1"/> - <line number="1070" hits="1"/> - <line number="1071" hits="1"/> - <line number="1072" hits="1"/> - <line number="1073" hits="1"/> - <line number="1074" hits="1"/> - <line number="1075" hits="1"/> - <line number="1076" hits="1"/> - <line number="1077" hits="1"/> - <line number="1080" hits="1"/> - <line number="1081" hits="1"/> - <line number="1082" hits="1"/> - <line number="1083" hits="1"/> - <line number="1084" hits="1"/> - <line number="1085" hits="1"/> - <line number="1086" hits="1"/> - <line number="1087" hits="1"/> - <line number="1088" hits="1"/> - <line number="1089" hits="1"/> - <line number="1090" hits="1"/> - <line number="1091" hits="1"/> - <line number="1092" hits="1"/> - <line number="1093" hits="1"/> - <line number="1094" hits="1"/> - <line number="1095" hits="1"/> - <line number="1096" hits="1"/> - <line number="1097" hits="1"/> - <line number="1100" hits="1"/> - <line number="1101" hits="1"/> - <line number="1102" hits="1"/> - <line number="1103" hits="1"/> - <line number="1106" hits="1"/> - <line number="1107" hits="1"/> - <line number="1108" hits="1"/> - <line number="1109" hits="1"/> - <line number="1110" hits="1"/> - <line number="1113" hits="1"/> - <line number="1117" hits="1"/> - <line number="1118" hits="1"/> - <line number="1119" hits="1"/> - <line number="1120" hits="1"/> - <line number="1121" hits="1"/> - <line number="1124" hits="1"/> - <line number="1125" hits="1"/> - <line number="1128" hits="1"/> - <line number="1129" hits="1"/> - <line number="1130" hits="1"/> - <line number="1131" hits="1"/> - <line number="1132" hits="1"/> - <line number="1133" hits="1"/> - <line number="1134" hits="1"/> - <line number="1135" hits="1"/> - <line number="1138" hits="1"/> - <line number="1139" hits="1"/> - <line number="1140" hits="1"/> - <line number="1141" hits="1"/> - <line number="1142" hits="1"/> - <line number="1143" hits="1"/> - <line number="1146" hits="1"/> - <line number="1147" hits="1"/> - <line number="1148" hits="1"/> - <line number="1149" hits="1"/> - <line number="1152" hits="1"/> - <line number="1153" hits="1"/> - <line number="1154" hits="1"/> - <line number="1155" hits="1"/> - <line number="1156" hits="1"/> - </lines> - </class> - <class name="exceptions.py" filename="dbrepo/api/exceptions.py" complexity="0" line-rate="1" branch-rate="0"> - <methods/> - <lines> - <line number="1" hits="1"/> - <line number="5" hits="1"/> - <line number="8" hits="1"/> - <line number="12" hits="1"/> - <line number="15" hits="1"/> - <line number="19" hits="1"/> - <line number="22" hits="1"/> - <line number="26" hits="1"/> - <line number="29" hits="1"/> - <line number="33" hits="1"/> - <line number="36" hits="1"/> - <line number="40" hits="1"/> - <line number="43" hits="1"/> - <line number="47" hits="1"/> - <line number="50" hits="1"/> - <line number="54" hits="1"/> - <line number="57" hits="1"/> - <line number="61" hits="1"/> - <line number="64" hits="1"/> - <line number="68" hits="1"/> - <line number="71" hits="1"/> - <line number="75" hits="1"/> - <line number="78" hits="1"/> - <line number="82" hits="1"/> - <line number="85" hits="1"/> - <line number="89" hits="1"/> - <line number="92" hits="1"/> - <line number="96" hits="1"/> - <line number="99" hits="1"/> - <line number="103" hits="1"/> - <line number="106" hits="1"/> - <line number="110" hits="1"/> - </lines> - </class> - </classes> - </package> - </packages> -</coverage> diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py index 9b043bd32faa64783d02406a78d4a81b57716711..f2a93151ecff15ece92618ddf30d9d7bfa0f1dcd 100644 --- a/lib/python/dbrepo/RestClient.py +++ b/lib/python/dbrepo/RestClient.py @@ -11,7 +11,7 @@ from dbrepo.api.dto import * from dbrepo.api.exceptions import ResponseCodeError, NotExistsError, \ ForbiddenError, MalformedError, NameExistsError, QueryStoreError, ExternalSystemError, \ AuthenticationError, FormatNotAvailable, RequestError, ServiceError, ServiceConnectionError -from dbrepo.api.mapper import query_to_subset +from dbrepo.api.mapper import query_to_subset, dataframe_to_table_definition logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)-6s %(message)s', level=logging.INFO, stream=sys.stdout) @@ -463,9 +463,8 @@ class RestClient: raise ResponseCodeError( f'Failed to update database schema: response code: {response.status_code} is not 200 (OK)') - def create_table(self, database_id: str, name: str, is_public: bool, is_schema_public: bool, - columns: List[CreateTableColumn], constraints: CreateTableConstraints, - description: str = None) -> TableBrief: + def create_table(self, database_id: str, name: str, is_public: bool, is_schema_public: bool, dataframe: DataFrame, + description: str = None, with_data: bool = True) -> TableBrief: """ Updates the database owner of a database with given database id. @@ -473,9 +472,9 @@ class RestClient: :param name: The name of the created table. :param is_public: The visibility of the data. If set to true the data will be publicly visible. :param is_schema_public: The visibility of the schema metadata. If set to true the schema metadata will be publicly visible. - :param constraints: The constraints of the created table. - :param columns: The columns of the created table. + :param dataframe: The `pandas` dataframe. :param description: The description of the created table. Optional. + :param with_data: If set to `True`, the data will be included in the new table. Optional. Default: `True`. :returns: The table, if successful. @@ -488,12 +487,18 @@ class RestClient: :raises ResponseCodeError: If something went wrong with the creation. """ url = f'/api/database/{database_id}/table' + columns, constraints = dataframe_to_table_definition(dataframe) response = self._wrapper(method="post", url=url, force_auth=True, payload=CreateTable(name=name, is_public=is_public, is_schema_public=is_schema_public, description=description, columns=columns, constraints=constraints)) if response.status_code == 201: body = response.json() - return TableBrief.model_validate(body) + table = TableBrief.model_validate(body) + if with_data: + self.import_table_data(database_id=database_id, + table_id=table.id, + dataframe=dataframe.reset_index()) + return table if response.status_code == 400: raise MalformedError(f'Failed to create table: {response.text}') if response.status_code == 403: @@ -919,9 +924,9 @@ class RestClient: :raises ResponseCodeError: If something went wrong with the insert. """ - url = f'/api/upload' buffer = BytesIO() - dataframe.to_csv(path_or_buf=buffer, header=False, index=False) + dataframe.to_csv(path_or_buf=buffer, header=True, index=False) + url = f'/api/upload' response = self._wrapper(method="post", url=url, force_auth=True, files={'file': ('dataframe.csv', buffer.getvalue())}) if response.status_code == 201: @@ -949,8 +954,8 @@ class RestClient: url = f'/api/database/{database_id}/table/{table_id}/data/import' response = self._wrapper(method="post", url=url, force_auth=True, - payload=Import(location=self._upload(dataframe), separator=',', quote='"', - header=True, line_termination='\n')) + payload=Import(location=self._upload(dataframe), separator=',', quote='"', header=True, + line_termination='\n')) if response.status_code == 202: return if response.status_code == 400: @@ -1354,7 +1359,7 @@ class RestClient: payload=subset) if response.status_code == 201: logging.info(f'Created subset with id: {response.headers["X-Id"]}') - return DataFrame.from_records(response.json()) + return DataFrame.from_records(response.json(), columns=query.columns) if response.status_code == 400: raise MalformedError(f'Failed to create subset: {response.text}') if response.status_code == 403: diff --git a/lib/python/dbrepo/api/mapper.py b/lib/python/dbrepo/api/mapper.py index c062b29923f17f18f8a9d21f5c1913df2b3bb3d4..bede7b38384dae549fed119c9794b96c6aa0c921 100644 --- a/lib/python/dbrepo/api/mapper.py +++ b/lib/python/dbrepo/api/mapper.py @@ -1,4 +1,11 @@ -from dbrepo.api.dto import Subset, QueryDefinition, Database, Table, Image, Filter, Order +import logging + +import pandas +from numpy import dtype +from pandas import DataFrame, Series + +from dbrepo.api.dto import Subset, QueryDefinition, Database, Table, Image, Filter, Order, CreateTableColumn, \ + CreateTableConstraints, ColumnType from dbrepo.api.exceptions import MalformedError @@ -28,7 +35,7 @@ def query_to_subset(database: Database, image: Image, query: QueryDefinition) -> column_id=filter_column_ids[0], operator_id=filter_ops_ids[0], value=filter.value)) - order = None + orders = [] if query.order is not None: for order in query.order: # column_id @@ -36,5 +43,80 @@ def query_to_subset(database: Database, image: Image, query: QueryDefinition) -> column.internal_name == order.column] if len(order_column_ids) != 1: raise MalformedError(f'Failed to create view: order column name not found in database') - order.append(Order(column_id=order_column_ids[0].id, direction=order.direction)) - return Subset(table_id=tables[0].id, columns=filtered_column_ids, filter=filters, order=order) + orders.append(Order(column_id=order_column_ids[0], direction=order.direction)) + return Subset(table_id=tables[0].id, columns=filtered_column_ids, filter=filters, order=orders) + + +def dataframe_to_table_definition(dataframe: DataFrame) -> ([CreateTableColumn], CreateTableConstraints): + if dataframe.index.name is None: + raise MalformedError(f'Failed to map dataframe: index not set') + constraints = CreateTableConstraints(uniques=[], + checks=[], + foreign_keys=[], + primary_key=dataframe.index.names) + dataframe = dataframe.reset_index() + columns = [] + for name, series in dataframe.items(): + column = CreateTableColumn(name=str(name), + type=ColumnType.TEXT, + null_allowed=contains_null(dataframe[name])) + if series.dtype == dtype('float64'): + if pandas.to_numeric(dataframe[name], errors='coerce').notnull().all(): + logging.debug(f"mapped column {name} from float64 to decimal") + column.type = ColumnType.DECIMAL + column.size = 40 + column.d = 20 + else: + logging.debug(f"mapped column {name} from float64 to text") + column.type = ColumnType.TEXT + elif series.dtype == dtype('int64'): + min_val = min(dataframe[name]) + max_val = max(dataframe[name]) + if 0 <= min_val <= 1 and 0 <= max_val <= 1 and 'id' not in name: + logging.debug(f"mapped column {name} from int64 to bool") + column.type = ColumnType.BOOL + columns.append(column) + continue + logging.debug(f"mapped column {name} from int64 to bigint") + column.type = ColumnType.BIGINT + elif series.dtype == dtype('O'): + try: + pandas.to_datetime(dataframe[name], format='mixed') + if dataframe[name].str.contains(':').any(): + logging.debug(f"mapped column {name} from O to timestamp") + column.type = ColumnType.TIMESTAMP + columns.append(column) + continue + logging.debug(f"mapped column {name} from O to date") + column.type = ColumnType.DATE + columns.append(column) + continue + except ValueError: + pass + max_size = max(dataframe[name].astype(str).map(len)) + if max_size <= 1: + logging.debug(f"mapped column {name} from O to char") + column.type = ColumnType.CHAR + column.size = 1 + if 0 <= max_size <= 255: + logging.debug(f"mapped column {name} from O to varchar") + column.type = ColumnType.VARCHAR + column.size = 255 + else: + logging.debug(f"mapped column {name} from O to text") + column.type = ColumnType.TEXT + elif series.dtype == dtype('bool'): + logging.debug(f"mapped column {name} from bool to bool") + column.type = ColumnType.BOOL + elif series.dtype == dtype('datetime64'): + logging.debug(f"mapped column {name} from datetime64 to datetime") + column.type = ColumnType.DATETIME + else: + logging.warning(f'default to \'text\' for column {name} and type {dtype}') + columns.append(column) + return columns, constraints + +def contains_null(dataframe: DataFrame) -> bool: + if '\\N' in dataframe.values: + return True + return dataframe.isnull().values.any() diff --git a/lib/python/tests/test_unit_query.py b/lib/python/tests/test_unit_query.py index 44f165b9b0ba36ab2375ddcd78c6c50cd363c7d9..528d6775a7e3b84a3afdceb68344518d234ba21d 100644 --- a/lib/python/tests/test_unit_query.py +++ b/lib/python/tests/test_unit_query.py @@ -93,14 +93,14 @@ class QueryUnitTest(unittest.TestCase): def test_create_subset_succeeds(self): with requests_mock.Mocker() as mock: exp = [{'id': 1, 'username': 'foo'}, {'id': 2, 'username': 'bar'}] - df = DataFrame.from_records(json.dumps(exp)) + df = DataFrame.from_records(exp) # mock mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), status_code=200) mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), status_code=200) - mock.post(f'/api/database/{self.database.id}/subset', json=json.dumps(exp), - headers={'X-Id': '1'}, status_code=201) + mock.post(f'/api/database/{self.database.id}/subset', json=exp, + headers={'X-Id': '85bc1217-29ab-4c09-9f98-8c019238a9c8'}, status_code=201) # test client = RestClient(username="a", password="b") response = client.create_subset(database_id="6bd39359-b154-456d-b9c2-caa516a45732", page=0, size=10, @@ -263,14 +263,14 @@ class QueryUnitTest(unittest.TestCase): def test_create_subset_anonymous_succeeds(self): with requests_mock.Mocker() as mock: exp = [{'id': 1, 'username': 'foo'}, {'id': 2, 'username': 'bar'}] - df = DataFrame.from_records(json.dumps(exp)) + df = DataFrame.from_records(exp) # mock mock.get(f'/api/image/{self.image.id}', json=self.image.model_dump(), status_code=200) mock.get(f'/api/database/{self.database.id}', json=self.database.model_dump(), status_code=200) - mock.post(f'/api/database/{self.database.id}/subset', json=json.dumps(exp), - headers={'X-Id': '1'}, status_code=201) + mock.post(f'/api/database/{self.database.id}/subset', json=exp, + headers={'X-Id': '85bc1217-29ab-4c09-9f98-8c019238a9c8'}, status_code=201) # test client = RestClient() diff --git a/lib/python/tests/test_unit_table.py b/lib/python/tests/test_unit_table.py index a5632f4237f2ab9a34b111e5168cebe7fc084ef6..c67b54c6144016df23a85fc6bb8fe8c46b9a0565 100644 --- a/lib/python/tests/test_unit_table.py +++ b/lib/python/tests/test_unit_table.py @@ -6,7 +6,7 @@ import requests_mock from pandas import DataFrame from dbrepo.RestClient import RestClient -from dbrepo.api.dto import Table, CreateTableConstraints, Column, Constraints, ColumnType, ConceptBrief, UnitBrief, \ +from dbrepo.api.dto import Table, Column, Constraints, ColumnType, ConceptBrief, UnitBrief, \ TableStatistics, ColumnStatistic, PrimaryKey, ColumnBrief, TableBrief, UserBrief, History, HistoryEventType from dbrepo.api.exceptions import MalformedError, ForbiddenError, NotExistsError, NameExistsError, \ AuthenticationError, ExternalSystemError, ServiceError, ServiceConnectionError, ResponseCodeError @@ -25,125 +25,137 @@ class TableUnitTest(unittest.TestCase): is_public=True, is_schema_public=True) with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', json=exp.model_dump(), status_code=201) # test client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, with_data=False, + is_public=True, is_schema_public=True) self.assertEqual(exp, response) + def test_create_table_index_missing_fails(self): + with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}]) + # test + client = RestClient(username="a", password="b") + try: + client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", + description="Test Table", dataframe=dataframe, with_data=False, + is_public=True, is_schema_public=True) + except MalformedError: + pass + def test_create_table_400_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=400) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except MalformedError: pass def test_create_table_403_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=403) # test try: RestClient(username="a", password="b").create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except ForbiddenError: pass def test_create_table_404_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=404) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except NotExistsError: pass def test_create_table_409_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=409) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except NameExistsError: pass def test_create_table_502_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=502) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except ServiceConnectionError: pass def test_create_table_503_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=503) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except ServiceError: pass def test_create_table_unknown_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=200) # test try: client = RestClient(username="a", password="b") response = client.create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except ResponseCodeError: pass def test_create_table_anonymous_fails(self): with requests_mock.Mocker() as mock: + dataframe = DataFrame.from_records([{'id': 1, 'name': 'foobar'}], index=['id']) # mock mock.post('/api/database/6bd39359-b154-456d-b9c2-caa516a45732/table', status_code=409) # test try: response = RestClient().create_table(database_id="6bd39359-b154-456d-b9c2-caa516a45732", name="Test", - description="Test Table", columns=[], - is_public=True, is_schema_public=True, - constraints=CreateTableConstraints()) + description="Test Table", dataframe=dataframe, + is_public=True, is_schema_public=True) except AuthenticationError: pass