queryapigate 0.35.0__tar.gz → 0.36.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. queryapigate-0.36.0/PKG-INFO +349 -0
  2. queryapigate-0.36.0/README.md +271 -0
  3. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/__init__.py +1 -1
  4. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/apikeys.py +59 -9
  5. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/app.py +5 -2
  6. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/auditstream.py +1 -0
  7. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/configcode.py +17 -6
  8. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/console.py +6 -1
  9. queryapigate-0.35.0/queryapigate/console_dist/assets/AccessMapPage-BVQ6wRwp.js → queryapigate-0.36.0/queryapigate/console_dist/assets/AccessMapPage-h4Txh6_X.js +3 -3
  10. queryapigate-0.35.0/queryapigate/console_dist/assets/AdministratorsPage-BiUGhISO.js → queryapigate-0.36.0/queryapigate/console_dist/assets/AdministratorsPage-DivFXGAk.js +1 -1
  11. queryapigate-0.35.0/queryapigate/console_dist/assets/AgentsPage-CSA-qCUv.js → queryapigate-0.36.0/queryapigate/console_dist/assets/AgentsPage-DgbGG-X6.js +1 -1
  12. queryapigate-0.35.0/queryapigate/console_dist/assets/AlertsPage-MYZoziNZ.js → queryapigate-0.36.0/queryapigate/console_dist/assets/AlertsPage-JvVikVfR.js +1 -1
  13. queryapigate-0.35.0/queryapigate/console_dist/assets/ApiKeysPage-BZISE5oJ.js → queryapigate-0.36.0/queryapigate/console_dist/assets/ApiKeysPage-4l-cQnNJ.js +1 -1
  14. queryapigate-0.35.0/queryapigate/console_dist/assets/ApprovalsPage-CUiEkHq3.js → queryapigate-0.36.0/queryapigate/console_dist/assets/ApprovalsPage-BqQaxTK3.js +1 -1
  15. queryapigate-0.35.0/queryapigate/console_dist/assets/AuditLogPage-D9vrSHU7.js → queryapigate-0.36.0/queryapigate/console_dist/assets/AuditLogPage-DZUuB0af.js +1 -1
  16. queryapigate-0.35.0/queryapigate/console_dist/assets/CachingPage-2hjur6KQ.js → queryapigate-0.36.0/queryapigate/console_dist/assets/CachingPage-BeW1bGwK.js +1 -1
  17. queryapigate-0.35.0/queryapigate/console_dist/assets/CodeBox-BZY9RBv5.js → queryapigate-0.36.0/queryapigate/console_dist/assets/CodeBox-5YJrpfHh.js +1 -1
  18. queryapigate-0.35.0/queryapigate/console_dist/assets/ConnectionsPage-D26k-98S.js → queryapigate-0.36.0/queryapigate/console_dist/assets/ConnectionsPage-onpVbonP.js +1 -1
  19. queryapigate-0.35.0/queryapigate/console_dist/assets/DesignerPage-B_os91xI.js → queryapigate-0.36.0/queryapigate/console_dist/assets/DesignerPage-Zo5YZZhb.js +1 -1
  20. queryapigate-0.35.0/queryapigate/console_dist/assets/DestinationsPage--bjoNE0y.js → queryapigate-0.36.0/queryapigate/console_dist/assets/DestinationsPage-SBwbj6TB.js +1 -1
  21. queryapigate-0.35.0/queryapigate/console_dist/assets/ExportsPage-5ai6Ojbl.js → queryapigate-0.36.0/queryapigate/console_dist/assets/ExportsPage-BIJILblW.js +1 -1
  22. queryapigate-0.35.0/queryapigate/console_dist/assets/HelpPage-DNaGeh-8.js → queryapigate-0.36.0/queryapigate/console_dist/assets/HelpPage-O7S6pfMI.js +1 -1
  23. queryapigate-0.35.0/queryapigate/console_dist/assets/HomePage-DINN_eBD.js → queryapigate-0.36.0/queryapigate/console_dist/assets/HomePage-DY1dpfuK.js +2 -2
  24. queryapigate-0.35.0/queryapigate/console_dist/assets/Managed-CVE0layM.js → queryapigate-0.36.0/queryapigate/console_dist/assets/Managed-DHCfC-9H.js +1 -1
  25. queryapigate-0.35.0/queryapigate/console_dist/assets/MetricsPage-D6UAGhYP.js → queryapigate-0.36.0/queryapigate/console_dist/assets/MetricsPage-D3fhsmN3.js +1 -1
  26. queryapigate-0.35.0/queryapigate/console_dist/assets/RepositoryPage-BvsZyKvp.js → queryapigate-0.36.0/queryapigate/console_dist/assets/RepositoryPage-8se0M13M.js +1 -1
  27. queryapigate-0.35.0/queryapigate/console_dist/assets/Results-D8fDmPdY.js → queryapigate-0.36.0/queryapigate/console_dist/assets/Results-BVRjDSO0.js +1 -1
  28. queryapigate-0.36.0/queryapigate/console_dist/assets/RolesPage-BvYNPktM.js +1 -0
  29. queryapigate-0.35.0/queryapigate/console_dist/assets/SchemaBrowser-Bu0NvoUy.js → queryapigate-0.36.0/queryapigate/console_dist/assets/SchemaBrowser-BBPaiMFY.js +1 -1
  30. queryapigate-0.35.0/queryapigate/console_dist/assets/SettingsPage-BQhT4xlX.js → queryapigate-0.36.0/queryapigate/console_dist/assets/SettingsPage-CxY2Niuc.js +1 -1
  31. queryapigate-0.35.0/queryapigate/console_dist/assets/StatTile-DEmSFOkX.js → queryapigate-0.36.0/queryapigate/console_dist/assets/StatTile-BY-03DUD.js +1 -1
  32. queryapigate-0.35.0/queryapigate/console_dist/assets/Time-MA05YtZP.js → queryapigate-0.36.0/queryapigate/console_dist/assets/Time-yK6sDFr-.js +1 -1
  33. queryapigate-0.35.0/queryapigate/console_dist/assets/forms-C6RLe1F3.js → queryapigate-0.36.0/queryapigate/console_dist/assets/forms-6-RLlXrl.js +1 -1
  34. queryapigate-0.35.0/queryapigate/console_dist/assets/forms-BSqwVHNJ.js → queryapigate-0.36.0/queryapigate/console_dist/assets/forms-uF5aXx1J.js +1 -1
  35. queryapigate-0.35.0/queryapigate/console_dist/assets/icons-DQ8_pv9M.js → queryapigate-0.36.0/queryapigate/console_dist/assets/icons-BPJHnFc_.js +1 -1
  36. queryapigate-0.35.0/queryapigate/console_dist/assets/index-sn5NUET1.js → queryapigate-0.36.0/queryapigate/console_dist/assets/index-DMiPsI_5.js +2 -2
  37. queryapigate-0.35.0/queryapigate/console_dist/assets/maskRules-BGQ7mS0j.js → queryapigate-0.36.0/queryapigate/console_dist/assets/maskRules-BmvHhs_t.js +1 -1
  38. queryapigate-0.35.0/queryapigate/console_dist/assets/reach-2gDU11-l.js → queryapigate-0.36.0/queryapigate/console_dist/assets/reach-Czf5bpIV.js +1 -1
  39. queryapigate-0.35.0/queryapigate/console_dist/assets/shared-D5ownoD-.js → queryapigate-0.36.0/queryapigate/console_dist/assets/shared-CmIynm8l.js +1 -1
  40. queryapigate-0.35.0/queryapigate/console_dist/assets/useMutation-BF7AWw3p.js → queryapigate-0.36.0/queryapigate/console_dist/assets/useMutation-DGd9BCI3.js +1 -1
  41. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/console_dist/index.html +1 -1
  42. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/logging_setup.py +15 -1
  43. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/mcp_server.py +1 -1
  44. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/runners.py +4 -0
  45. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/access.py +14 -4
  46. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/sqltools.py +9 -1
  47. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/store.py +4 -1
  48. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/tableguard.py +44 -8
  49. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/v1_spec.py +10 -2
  50. queryapigate-0.36.0/queryapigate.egg-info/PKG-INFO +349 -0
  51. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate.egg-info/SOURCES.txt +32 -32
  52. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_api_keys.py +6 -1
  53. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_configcode.py +25 -0
  54. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_console.py +7 -0
  55. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_jwt.py +67 -0
  56. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_observability.py +16 -0
  57. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_queryapigate.py +10 -0
  58. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_release_check.py +12 -0
  59. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_sql_guard_fuzz.py +19 -0
  60. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_sql_guard_writes.py +15 -0
  61. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_supply_chain.py +82 -0
  62. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_tableguard.py +30 -0
  63. queryapigate-0.35.0/PKG-INFO +0 -903
  64. queryapigate-0.35.0/README.md +0 -825
  65. queryapigate-0.35.0/queryapigate/console_dist/assets/RolesPage-BdEQdLFD.js +0 -1
  66. queryapigate-0.35.0/queryapigate.egg-info/PKG-INFO +0 -903
  67. {queryapigate-0.35.0 → queryapigate-0.36.0}/LICENSE +0 -0
  68. {queryapigate-0.35.0 → queryapigate-0.36.0}/pyproject.toml +0 -0
  69. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/__main__.py +0 -0
  70. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/accesslog.py +0 -0
  71. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/adminroles.py +0 -0
  72. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/admins.py +0 -0
  73. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/agentwrites.py +0 -0
  74. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/alerts.py +0 -0
  75. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/auditchain.py +0 -0
  76. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/aws.py +0 -0
  77. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/broadcast.py +0 -0
  78. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/bundle.py +0 -0
  79. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/cache.py +0 -0
  80. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/cli.py +0 -0
  81. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/collection_admin.py +0 -0
  82. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/config.py +0 -0
  83. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/console_dist/assets/index-BLd0t6vZ.css +0 -0
  84. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/console_dist/assets/state-O13cl7cO.js +0 -0
  85. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/console_dist/favicon.svg +0 -0
  86. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/cors.py +0 -0
  87. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/databases.py +0 -0
  88. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/db.py +0 -0
  89. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/definitions.py +0 -0
  90. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/deprecations.py +0 -0
  91. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/descriptions.py +0 -0
  92. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/destinations.py +0 -0
  93. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/duckfiles.py +0 -0
  94. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/engine.py +0 -0
  95. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/errors.py +0 -0
  96. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/events.py +0 -0
  97. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/examples.py +0 -0
  98. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/experimental.py +0 -0
  99. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/exporting.py +0 -0
  100. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/exports.py +0 -0
  101. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/formats.py +0 -0
  102. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/governance.py +0 -0
  103. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/gunicorn_conf.py +0 -0
  104. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/history.py +0 -0
  105. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/instances.py +0 -0
  106. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/jwtauth.py +0 -0
  107. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/lib/h2-2.2.224.jar +0 -0
  108. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/limits.py +0 -0
  109. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/masking.py +0 -0
  110. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/metrics.py +0 -0
  111. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/mongotools.py +0 -0
  112. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/oidc.py +0 -0
  113. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/openapi.py +0 -0
  114. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/params.py +0 -0
  115. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/parquet.py +0 -0
  116. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/pool.py +0 -0
  117. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/postman.py +0 -0
  118. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/quotas.py +0 -0
  119. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/ratelimit.py +0 -0
  120. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/rediscache.py +0 -0
  121. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/rekey.py +0 -0
  122. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/schema.py +0 -0
  123. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/secheaders.py +0 -0
  124. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/secretrefs.py +0 -0
  125. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/__init__.py +0 -0
  126. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/administrators.py +0 -0
  127. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/audit.py +0 -0
  128. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/collections.py +0 -0
  129. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/connections.py +0 -0
  130. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/descriptions.py +0 -0
  131. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/destinations.py +0 -0
  132. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/exports.py +0 -0
  133. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/mcp.py +0 -0
  134. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/services/queries.py +0 -0
  135. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/sqlflow.py +0 -0
  136. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/sso.py +0 -0
  137. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/tracing.py +0 -0
  138. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/usage.py +0 -0
  139. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/v1.py +0 -0
  140. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate/vault.py +0 -0
  141. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate.egg-info/dependency_links.txt +0 -0
  142. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate.egg-info/entry_points.txt +0 -0
  143. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate.egg-info/requires.txt +0 -0
  144. {queryapigate-0.35.0 → queryapigate-0.36.0}/queryapigate.egg-info/top_level.txt +0 -0
  145. {queryapigate-0.35.0 → queryapigate-0.36.0}/setup.cfg +0 -0
  146. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_adhoc_history.py +0 -0
  147. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_adminroles.py +0 -0
  148. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_admins.py +0 -0
  149. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_agent_writes.py +0 -0
  150. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_alerts.py +0 -0
  151. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_api_administrators.py +0 -0
  152. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_api_v1.py +0 -0
  153. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_audit_chain.py +0 -0
  154. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_audit_log.py +0 -0
  155. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_audit_siem.py +0 -0
  156. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_audit_stream.py +0 -0
  157. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_aws.py +0 -0
  158. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_backup_restore.py +0 -0
  159. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_broadcast.py +0 -0
  160. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_cli.py +0 -0
  161. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_collection_bundle.py +0 -0
  162. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_collection_postman.py +0 -0
  163. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_collections.py +0 -0
  164. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_connection_encryption.py +0 -0
  165. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_cors_and_rate_limit.py +0 -0
  166. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_data_protection.py +0 -0
  167. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_databases.py +0 -0
  168. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_db.py +0 -0
  169. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_dependency_floors.py +0 -0
  170. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_deprecations.py +0 -0
  171. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_descriptions.py +0 -0
  172. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_destinations.py +0 -0
  173. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_docs_site.py +0 -0
  174. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_duckdb.py +0 -0
  175. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_duckdb_files.py +0 -0
  176. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_errors.py +0 -0
  177. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_events.py +0 -0
  178. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_events_server.py +0 -0
  179. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_examples.py +0 -0
  180. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_experimental.py +0 -0
  181. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_export_security.py +0 -0
  182. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_exporting.py +0 -0
  183. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_exports.py +0 -0
  184. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_fips.py +0 -0
  185. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_helm.py +0 -0
  186. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_history.py +0 -0
  187. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_howto.py +0 -0
  188. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_instances.py +0 -0
  189. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_integration.py +0 -0
  190. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_jdbc.py +0 -0
  191. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_key_rotation.py +0 -0
  192. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_limits.py +0 -0
  193. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_masking.py +0 -0
  194. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_masking_requests.py +0 -0
  195. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_mcp.py +0 -0
  196. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_mcp_keycloak.py +0 -0
  197. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_mcp_oauth.py +0 -0
  198. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_mongotools.py +0 -0
  199. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_multinode.py +0 -0
  200. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_oidc.py +0 -0
  201. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_params.py +0 -0
  202. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_parquet.py +0 -0
  203. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_pool.py +0 -0
  204. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_publishing.py +0 -0
  205. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_query_window.py +0 -0
  206. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_quotas.py +0 -0
  207. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_rekey.py +0 -0
  208. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_response_cache.py +0 -0
  209. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_roles.py +0 -0
  210. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_rolling_upgrade.py +0 -0
  211. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_secretrefs.py +0 -0
  212. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_security_headers.py +0 -0
  213. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_settings.py +0 -0
  214. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_shared_rate_limit.py +0 -0
  215. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_sqlflow.py +0 -0
  216. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_sso.py +0 -0
  217. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_sso_keycloak.py +0 -0
  218. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_tracing.py +0 -0
  219. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_upgrades.py +0 -0
  220. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_usage.py +0 -0
  221. {queryapigate-0.35.0 → queryapigate-0.36.0}/tests/test_vault.py +0 -0
@@ -0,0 +1,349 @@
1
+ Metadata-Version: 2.4
2
+ Name: queryapigate
3
+ Version: 0.36.0
4
+ Summary: Turn SQL into governed REST APIs over MySQL, PostgreSQL, ClickHouse, SQLite, DuckDB, H2, MongoDB, and Parquet/CSV/JSON files - JSON, CSV, Parquet or Excel out, with scoped keys, an admin Console and MCP for AI agents.
5
+ Author-email: Anantha Raju C <arcswdev@gmail.com>
6
+ License-Expression: FSL-1.1-MIT
7
+ Project-URL: Homepage, https://github.com/AnanthaRajuC/QueryAPIGate
8
+ Project-URL: Documentation, https://AnanthaRajuC.github.io/QueryAPIGate/
9
+ Project-URL: Repository, https://github.com/AnanthaRajuC/QueryAPIGate
10
+ Project-URL: Issues, https://github.com/AnanthaRajuC/QueryAPIGate/issues
11
+ Project-URL: Changelog, https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/CHANGELOG.md
12
+ Keywords: sql,api,rest,rest-api,data-api,flask,database,mysql,postgresql,clickhouse,sqlite,duckdb,mongodb,h2,jdbc,parquet,s3,mcp,ai-agents
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Web Environment
15
+ Classifier: Framework :: Flask
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Database
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
25
+ Requires-Python: >=3.11
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: Flask>=3.0
29
+ Requires-Dist: Werkzeug>=3.0
30
+ Requires-Dist: PyYAML>=6.0.1
31
+ Requires-Dist: openpyxl>=3.1
32
+ Provides-Extra: mysql
33
+ Requires-Dist: mysql-connector-python>=8.0; extra == "mysql"
34
+ Provides-Extra: postgres
35
+ Requires-Dist: psycopg2-binary>=2.9.5; extra == "postgres"
36
+ Provides-Extra: clickhouse
37
+ Requires-Dist: clickhouse-driver>=0.2; extra == "clickhouse"
38
+ Provides-Extra: h2
39
+ Requires-Dist: JayDeBeApi>=1.2; extra == "h2"
40
+ Requires-Dist: JPype1>=1.4; extra == "h2"
41
+ Provides-Extra: duckdb
42
+ Requires-Dist: duckdb>=1.2; extra == "duckdb"
43
+ Provides-Extra: mongo
44
+ Requires-Dist: pymongo>=4.0; extra == "mongo"
45
+ Provides-Extra: flow
46
+ Requires-Dist: sqlglot<26,>=25.2; extra == "flow"
47
+ Provides-Extra: encryption
48
+ Requires-Dist: cryptography>=41; extra == "encryption"
49
+ Provides-Extra: redis
50
+ Requires-Dist: redis>=5; extra == "redis"
51
+ Provides-Extra: mcp
52
+ Requires-Dist: mcp<2,>=1.21.1; extra == "mcp"
53
+ Provides-Extra: jwt
54
+ Requires-Dist: PyJWT[crypto]>=2.14; extra == "jwt"
55
+ Provides-Extra: all
56
+ Requires-Dist: queryapigate[clickhouse,duckdb,encryption,flow,h2,jwt,mongo,mysql,postgres]; extra == "all"
57
+ Provides-Extra: otel
58
+ Requires-Dist: opentelemetry-sdk>=1.27; extra == "otel"
59
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27; extra == "otel"
60
+ Provides-Extra: server
61
+ Requires-Dist: gunicorn>=21; extra == "server"
62
+ Provides-Extra: aws
63
+ Requires-Dist: boto3>=1.28; extra == "aws"
64
+ Provides-Extra: docs
65
+ Requires-Dist: mkdocs-material<10,>=9; extra == "docs"
66
+ Provides-Extra: dev
67
+ Requires-Dist: queryapigate[all]; extra == "dev"
68
+ Requires-Dist: queryapigate[redis]; extra == "dev"
69
+ Requires-Dist: queryapigate[otel]; extra == "dev"
70
+ Requires-Dist: queryapigate[aws]; extra == "dev"
71
+ Requires-Dist: queryapigate[mcp]; python_version >= "3.10" and extra == "dev"
72
+ Requires-Dist: ruff>=0.5; extra == "dev"
73
+ Requires-Dist: openapi-spec-validator>=0.7; extra == "dev"
74
+ Requires-Dist: hypothesis>=6.100; extra == "dev"
75
+ Requires-Dist: mypy>=1.10; extra == "dev"
76
+ Requires-Dist: coverage>=7.4; extra == "dev"
77
+ Dynamic: license-file
78
+
79
+ # QueryAPIGate
80
+
81
+ [![CI](https://github.com/AnanthaRajuC/QueryAPIGate/actions/workflows/ci.yml/badge.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/actions/workflows/ci.yml)
82
+ [![codecov](https://codecov.io/gh/AnanthaRajuC/QueryAPIGate/branch/main/graph/badge.svg)](https://codecov.io/gh/AnanthaRajuC/QueryAPIGate)
83
+ [![PyPI](https://img.shields.io/pypi/v/queryapigate.svg)](https://pypi.org/project/queryapigate/)
84
+ [![PyPI downloads](https://img.shields.io/pypi/dm/queryapigate.svg)](https://pypi.org/project/queryapigate/)
85
+ [![License: FSL-1.1-MIT](https://img.shields.io/badge/license-FSL--1.1--MIT-blue.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE)
86
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
87
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/AnanthaRajuC/QueryAPIGate/badge)](https://scorecard.dev/viewer/?uri=github.com/AnanthaRajuC/QueryAPIGate)
88
+ [![SLSA 2](https://slsa.dev/images/gh-badge-level2.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md#slsa-level)
89
+
90
+ ### Turn SQL queries into secure, governed REST APIs.
91
+
92
+ [**Full documentation**](https://AnanthaRajuC.github.io/QueryAPIGate/)
93
+
94
+ <p align="center">
95
+ <a href="https://www.youtube.com/watch?v=WWImFj4m95o">
96
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/demo-thumbnail.png" alt="Watch the demo: saved SQL queries as REST endpoints, scoped API keys, and the Move preview showing which keys gain or lose access" width="640">
97
+ </a>
98
+ <br>
99
+ <sub>Every feature, one by one: <a href="https://youtu.be/cTkv6smFtWA"><b>the full walkthrough</b></a> (6 minutes, in chapters)</sub>
100
+ </p>
101
+
102
+ <p align="center">
103
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/queryapigate-architecture.gif">
104
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/queryapigate-architecture.gif"
105
+ alt="One governed gate between your databases and everything that asks them for data: apps, partners, AI agents, people and pipelines come in through five front doors - REST endpoints, the MCP server, live events, exports and the CLI, the Management API - and every call passes the same governed core (identity, policy, execution) before it reaches PostgreSQL, MySQL, SQLite, DuckDB, ClickHouse, the experimental H2, JDBC and MongoDB, files through DuckDB, or deliveries to object storage" width="820">
106
+ </a>
107
+ <br>
108
+ <sub>Every front door runs the same checks, so an AI agent's call is governed exactly like an app's. Write the SQL once; it's a REST endpoint, an MCP tool, a live event stream and a scheduled export.</sub>
109
+ </p>
110
+
111
+ <p align="center">
112
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/what-happens-to-every-request.gif">
113
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/what-happens-to-every-request.gif"
114
+ alt="What happens to every request, one partner call followed through eight stages: identify the caller, apply its limits, check the grant, validate parameters, guard the SQL, run it, mask and format, record it - a stage that fails stops the call with a typed error code" width="820">
115
+ </a>
116
+ <br>
117
+ <sub>One path for REST, MCP, events and exports. A stage that fails stops the call with a typed error code - except recording, which never blocks the response.</sub>
118
+ </p>
119
+
120
+ **QueryAPIGate** is a self-hosted service that runs SQL against your databases - and against Parquet, CSV and JSON files
121
+ on disk, S3, GCS or the web, through DuckDB - and returns the results as JSON, NDJSON, XML, YAML, CSV, TSV, Excel or
122
+ Parquet. Save a query once and it becomes a versioned endpoint with typed,
123
+ injection-safe parameters and run history - without writing a controller, a repository layer, pagination, auth or
124
+ serialization boilerplate for it.
125
+
126
+ Write SQL. Configure the query. Apply access controls. Get an API.
127
+
128
+ ~~~bash
129
+ $ curl 'http://127.0.0.1:5000/q/example_film_search?text=Harbor&page_size=2' -H 'X-API-Key: demo-key'
130
+ [{"film_id":48,"title":"Broken Harbor","category":"Action","rating":"PG-13"},{"film_id":44,"title":"Electric Harbor","category":"Documentary","rating":"G"}]
131
+
132
+ $ curl 'http://127.0.0.1:5000/q/example_top_films?top_n=2&category=Comedy&format=csv' -H 'X-API-Key: demo-key'
133
+ title,category,rating,rentals,rank
134
+ Electric Signal,Comedy,PG,977,1
135
+ Crimson Garden,Comedy,PG-13,631,2
136
+ ~~~
137
+
138
+ <p align="center">
139
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/run-sql.png">
140
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/run-sql.png"
141
+ alt="The QueryAPIGate Console's API Designer: a joined SQL query with a bound :min_rentals parameter running against the example SQLite connection, the schema browser beside it and paginated results below" width="820">
142
+ </a>
143
+ <br>
144
+ <sub>The built-in Console at <code>/console</code>: write SQL with completion and a schema browser, run it, then save it as an API - no separate tool to install.</sub>
145
+ </p>
146
+
147
+ More of the Console - Home, connections, keys and roles, history, the audit log, metrics, alerts, the access
148
+ map - screen by screen: [**a tour of the Console**](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/SCREENSHOTS.md).
149
+
150
+
151
+ ## Contents
152
+
153
+ - [Why QueryAPIGate](#why-queryapigate)
154
+ - [Features](#features)
155
+ - [Install](#install) · [Quick start](#quick-start) · [Saving a query as an endpoint](#saving-a-query-as-an-endpoint)
156
+ - [Try it with Docker](#try-it-with-docker)
157
+ - [Documentation](#documentation)
158
+ - [Contributing](#contributing) · [Security](#security) · [License](#license) · [Contact](#contact)
159
+
160
+ ---
161
+
162
+ ## Why QueryAPIGate
163
+
164
+ Valuable SQL sits in reports, dashboards, ETL jobs and application code, with no way to a REST endpoint except a
165
+ backend service written around each query. QueryAPIGate makes the query itself the API: write the SQL once, and it is
166
+ a versioned endpoint with typed parameters, governed by who may call it, how often and what they may see - and the same
167
+ query is an MCP tool for AI agents, a live event stream and a scheduled export.
168
+
169
+ It doesn't replace an application backend; it removes the boilerplate when the requirement is "expose this query
170
+ safely". Use cases, how it compares to PostgREST, Hasura and others, and the thinking behind it:
171
+ [why QueryAPIGate](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/WHY.md).
172
+
173
+ ## Features
174
+
175
+ - **[Saved, versioned queries as endpoints](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#save-a-query)** - `GET /q/<name>`, typed and
176
+ injection-safe parameters, drafts and publishing, run history.
177
+ - **[Scoped API keys, roles and collections](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#authentication-and-permissions)** - per
178
+ connection, per query or per collection; expiry, IP allow-lists, rate limits, quotas, table allow-lists.
179
+ - **[Named administrators and SSO](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#administrators-and-admin-roles)** - admin roles and
180
+ tokens, Console sign-in through your identity provider, signed-in users' JWTs.
181
+ - **[Column masking](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#column-masking)** - hash, mask or drop what a caller mustn't see, traced
182
+ through the SQL to the source column.
183
+ - **[An MCP server for AI agents](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/MCP.md)** - saved queries as tools, OAuth sign-in, write tools that
184
+ wait for a person's approval.
185
+ - **[Eight database types, and files](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATABASE_CONNECTION_CONFIGURATION.md#support-matrix)** -
186
+ PostgreSQL, MySQL, SQLite, DuckDB and ClickHouse; H2, JDBC and MongoDB; Parquet, CSV and JSON on S3, GCS, R2 or disk.
187
+ - **[Eight output formats, and streaming](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#streaming-exports)** - JSON, NDJSON, XML, YAML, CSV,
188
+ TSV, Excel and Parquet; whole results streamed from the database cursor.
189
+ - **[Exports to object storage](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#exports-to-object-storage)** - scheduled, incremental, to
190
+ S3, GCS, R2 or a folder.
191
+ - **[Live events](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#live-events-server-sent-events)** - every run as it happens, per key, with
192
+ resume.
193
+ - **[A tamper-evident audit log](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#audit-log)** - a signed hash chain, streamed to your SIEM.
194
+ - **[Observability](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#observability)** - Prometheus metrics, OpenTelemetry tracing, alerts that
195
+ clear themselves, a Grafana dashboard.
196
+ - **[Configuration as code](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#configuration-as-code)** and
197
+ **[secrets from files and Vault](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#secrets-from-files-and-secrets-managers)**.
198
+ - **[OpenAPI and Postman](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#interactive-documentation)** - every saved query a typed endpoint in
199
+ `/openapi.json` and `/docs`.
200
+ - **[Docker, Helm and several instances](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md)** - one PostgreSQL store, Redis for shared
201
+ limits; [signed releases with SLSA provenance](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md#verify-a-release).
202
+
203
+ Every feature in detail: [features](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/FEATURES.md). Every setting:
204
+ [configuration](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/CONFIGURATION.md).
205
+
206
+ ## Install
207
+
208
+ ~~~bash
209
+ pip install "queryapigate[postgres]" # pick the drivers you need: mysql, postgres, clickhouse, h2, duckdb
210
+ # or everything: pip install "queryapigate[all]"
211
+ ~~~
212
+
213
+ SQLite needs no extra driver. H2 and generic JDBC connections (`queryapigate[h2]`) also need a Java runtime; H2's own
214
+ driver jar is bundled, a JDBC connection to another vendor brings its own. DuckDB (`queryapigate[duckdb]`) needs no
215
+ external runtime either - it's a native Python extension, same as SQLite. `queryapigate[encryption]` adds
216
+ [encryption at rest](documentation/API.md#encryption-at-rest-for-connection-passwords) for connection passwords -
217
+ only needed if you set `QUERYAPIGATE_SECRET_KEY`.
218
+ From a clone: `pip install -e ".[dev]"`. Or use Docker - see [below](#try-it-with-docker).
219
+
220
+ ## Quick start
221
+
222
+ Fastest: `queryapigate examples load && queryapigate serve` installs four worked [example APIs](documentation/EXAMPLES.md)
223
+ (reporting, dashboard, export, partner) you can try, and `queryapigate examples unload` removes them again. Loading
224
+ them creates a real API key per scenario, which also means the server now requires a key for every request - set
225
+ `QUERYAPIGATE_API_KEY` yourself first so you have an admin key on hand for ad-hoc SQL too:
226
+
227
+ ~~~bash
228
+ QUERYAPIGATE_API_KEY=demo-key queryapigate examples load # also prints one scoped key per scenario - store them now
229
+ QUERYAPIGATE_API_KEY=demo-key queryapigate serve # http://127.0.0.1:5000
230
+ ~~~
231
+
232
+ The examples come with a small generated `examples` database (films, customers and rentals), so you can also run ad-hoc SQL
233
+ straight away:
234
+
235
+ ~~~bash
236
+ curl -X POST 'http://127.0.0.1:5000/execute_sql?page_size=3' -H 'X-API-Key: demo-key' -H 'Content-Type: application/json' \
237
+ -d '{"sql": "SELECT film_id, title, rating FROM film WHERE film_id > :min", "params": {"min": 10}, "connection_name": "examples"}'
238
+ ~~~
239
+
240
+ Open <http://127.0.0.1:5000/docs> for the interactive API reference, or <http://127.0.0.1:5000/console> for the
241
+ admin UI to manage connections and saved queries and run ad-hoc SQL without leaving the browser.
242
+
243
+ For your own databases, run `queryapigate init` in an empty folder: it creates `queryapigate.db` with an
244
+ inactive template connection for every supported database type. Edit them (admin UI, or `PATCH
245
+ /api/v1/connections/<name>`), set `"active": true`, and start the server there.
246
+
247
+ ## Saving a query as an endpoint
248
+
249
+ This uses the `examples` connection that `queryapigate examples load` sets up:
250
+
251
+ ~~~bash
252
+ curl -X POST http://127.0.0.1:5000/api/v1/queries -H 'X-API-Key: demo-key' -H 'Content-Type: application/json' -d '{
253
+ "name": "film_by_id",
254
+ "sql": "SELECT * FROM film WHERE film_id = :id",
255
+ "parameters": {"id": {"type": "int", "min": 1, "max": 60, "description": "Film id"}},
256
+ "connection_name": "examples",
257
+ "author": "me", "description": "Look up a film",
258
+ "publish": true
259
+ }'
260
+
261
+ curl 'http://127.0.0.1:5000/q/film_by_id?id=7&format=yaml' -H 'X-API-Key: demo-key'
262
+ curl 'http://127.0.0.1:5000/q/film_by_id?id=0' -H 'X-API-Key: demo-key'
263
+ # {"error": "Invalid parameters: id must be at least 1", "errors": {"id": "must be at least 1"}}
264
+ ~~~
265
+
266
+ Rules: `type` (`int`, `float`, `str`, `bool`), `default`, `required`, `enum`, `min`/`max`, `min_length`/`max_length`,
267
+ `pattern` and `description` - see [the API reference](documentation/API.md#parameter-rules).
268
+
269
+ `POST /api/v1/queries/film_by_id/versions` adds version 2 - a draft until published (`"publish": true`, or
270
+ `POST .../publish`); `DELETE /api/v1/queries/film_by_id/versions/1` removes one version.
271
+
272
+ Add `"cache_ttl": 60` to cache a response for that many seconds (`X-Cache: HIT`/`MISS`, `ETag`, `Cache-Control`) -
273
+ opt-in, and never used for a query that writes. See
274
+ [Response caching](documentation/API.md#response-caching).
275
+
276
+ ## Try it with Docker
277
+
278
+ Every release is published for `linux/amd64` and `linux/arm64`, signed:
279
+
280
+ ~~~bash
281
+ docker run -p 5000:5000 -v queryapigate-data:/data -e QUERYAPIGATE_API_KEY=change-me ghcr.io/anantharajuc/queryapigate:latest
282
+ ~~~
283
+
284
+ Or start it in front of a PostgreSQL database seeded with sample films, with
285
+ [`docker-compose.yml`](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/docker-compose.yml):
286
+
287
+ ~~~bash
288
+ docker compose up --build
289
+ curl -H 'X-API-Key: demo-key' 'http://127.0.0.1:5000/q/films_by_rating?rating=PG&max_length=90'
290
+ ~~~
291
+
292
+ Open <http://127.0.0.1:5000/docs>, paste `demo-key` into the box at the top, and both saved queries are there as
293
+ endpoints; `docker compose down -v` cleans up.
294
+
295
+ The image tags, volumes and a real deployment - TLS, secrets, backups, Prometheus and Grafana, several instances,
296
+ Kubernetes: [deployment](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md).
297
+
298
+ ## Documentation
299
+
300
+ The [documentation site](https://AnanthaRajuC.github.io/QueryAPIGate/) has all of it; on GitHub:
301
+
302
+ | | |
303
+ |---|---|
304
+ | **Start** | [Installation and setup](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/INSTALLATION_AND_SETUP.md) · [Configuration](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/CONFIGURATION.md) · [Example APIs](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/EXAMPLES.md) · [How-to guides](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/how-to/how-to.md) |
305
+ | **Reference** | [API](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md) · [MCP server](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/MCP.md) · [Database connections](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATABASE_CONNECTION_CONFIGURATION.md) · [Query metadata](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/QUERY_METADATA_MANAGEMENT.md) · [Features](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/FEATURES.md) |
306
+ | **Run it** | [Deployment](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md) · [Technology stack](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/TECHNOLOGY_STACK.MD) · [A tour of the Console](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/SCREENSHOTS.md) |
307
+ | **Security** | [Security policy](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md) · [Threat model](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/THREAT_MODEL.md) · [Where data goes](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATA_PROTECTION.md) |
308
+ | **Project** | [Why QueryAPIGate](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/WHY.md) · [Changelog](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/CHANGELOG.md) · [Roadmap](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/BACKLOG.md) · [Architecture decisions](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/adr/README.md) |
309
+
310
+ ## Contributing
311
+
312
+ Contributions are welcome - database drivers, security, performance, the Console, documentation, tests. Please read
313
+ [CONTRIBUTING.md](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/CONTRIBUTING.md) first: the development setup, the tests, and how a change gets in.
314
+
315
+ ## Security
316
+
317
+ Report a vulnerability privately - see [SECURITY.md](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md), which also has the hardening checklist for a
318
+ deployment and how to verify a release.
319
+
320
+ ## Third-party components
321
+
322
+ The wheel bundles the [H2 Database](https://h2database.com) JDBC driver (MPL 2.0 / EPL 1.0). The example data is generated
323
+ locally by `queryapigate examples load`; no third-party datasets are included.
324
+
325
+ ## License
326
+
327
+ QueryAPIGate is **source-available**, under the
328
+ [Functional Source License, Version 1.1, MIT Future License](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE)
329
+ (`FSL-1.1-MIT`) © Anantha Raju C. It is not an OSI-approved open source license.
330
+
331
+ In plain terms - the [LICENSE](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE) is the only authoritative text:
332
+
333
+ - **You may** use, copy, modify and redistribute it for any purpose that is not a *Competing Use* - including running it
334
+ inside your own company, non-commercial education and research, and professional services you provide to someone who
335
+ is themselves licensed to use it.
336
+ - **You may not** make it available to others in a commercial product or service that substitutes for QueryAPIGate or
337
+ offers the same or substantially similar functionality (for example, selling it, or hosting it as a paid service).
338
+ - **Each version becomes MIT** on the second anniversary of the date it was released, and can then be used under MIT terms.
339
+ - **Versions up to and including 0.6.1** were released under the MIT license. They are no longer distributed (and the
340
+ repository history was reset in 0.7.0), but a copy you already obtained under MIT remains yours under those terms.
341
+
342
+ Need something the license does not cover, such as offering it as part of a hosted service? Get in touch - commercial
343
+ licensing may be available. This is a summary, not legal advice.
344
+
345
+ ## Contact
346
+
347
+ Anantha Raju C - [@anantharajuc](https://twitter.com/anantharajuc) - arcswdev@gmail.com
348
+
349
+ Project link: <https://github.com/AnanthaRajuC/QueryAPIGate>
@@ -0,0 +1,271 @@
1
+ # QueryAPIGate
2
+
3
+ [![CI](https://github.com/AnanthaRajuC/QueryAPIGate/actions/workflows/ci.yml/badge.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/AnanthaRajuC/QueryAPIGate/branch/main/graph/badge.svg)](https://codecov.io/gh/AnanthaRajuC/QueryAPIGate)
5
+ [![PyPI](https://img.shields.io/pypi/v/queryapigate.svg)](https://pypi.org/project/queryapigate/)
6
+ [![PyPI downloads](https://img.shields.io/pypi/dm/queryapigate.svg)](https://pypi.org/project/queryapigate/)
7
+ [![License: FSL-1.1-MIT](https://img.shields.io/badge/license-FSL--1.1--MIT-blue.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE)
8
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
9
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/AnanthaRajuC/QueryAPIGate/badge)](https://scorecard.dev/viewer/?uri=github.com/AnanthaRajuC/QueryAPIGate)
10
+ [![SLSA 2](https://slsa.dev/images/gh-badge-level2.svg)](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md#slsa-level)
11
+
12
+ ### Turn SQL queries into secure, governed REST APIs.
13
+
14
+ [**Full documentation**](https://AnanthaRajuC.github.io/QueryAPIGate/)
15
+
16
+ <p align="center">
17
+ <a href="https://www.youtube.com/watch?v=WWImFj4m95o">
18
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/demo-thumbnail.png" alt="Watch the demo: saved SQL queries as REST endpoints, scoped API keys, and the Move preview showing which keys gain or lose access" width="640">
19
+ </a>
20
+ <br>
21
+ <sub>Every feature, one by one: <a href="https://youtu.be/cTkv6smFtWA"><b>the full walkthrough</b></a> (6 minutes, in chapters)</sub>
22
+ </p>
23
+
24
+ <p align="center">
25
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/queryapigate-architecture.gif">
26
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/queryapigate-architecture.gif"
27
+ alt="One governed gate between your databases and everything that asks them for data: apps, partners, AI agents, people and pipelines come in through five front doors - REST endpoints, the MCP server, live events, exports and the CLI, the Management API - and every call passes the same governed core (identity, policy, execution) before it reaches PostgreSQL, MySQL, SQLite, DuckDB, ClickHouse, the experimental H2, JDBC and MongoDB, files through DuckDB, or deliveries to object storage" width="820">
28
+ </a>
29
+ <br>
30
+ <sub>Every front door runs the same checks, so an AI agent's call is governed exactly like an app's. Write the SQL once; it's a REST endpoint, an MCP tool, a live event stream and a scheduled export.</sub>
31
+ </p>
32
+
33
+ <p align="center">
34
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/what-happens-to-every-request.gif">
35
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/what-happens-to-every-request.gif"
36
+ alt="What happens to every request, one partner call followed through eight stages: identify the caller, apply its limits, check the grant, validate parameters, guard the SQL, run it, mask and format, record it - a stage that fails stops the call with a typed error code" width="820">
37
+ </a>
38
+ <br>
39
+ <sub>One path for REST, MCP, events and exports. A stage that fails stops the call with a typed error code - except recording, which never blocks the response.</sub>
40
+ </p>
41
+
42
+ **QueryAPIGate** is a self-hosted service that runs SQL against your databases - and against Parquet, CSV and JSON files
43
+ on disk, S3, GCS or the web, through DuckDB - and returns the results as JSON, NDJSON, XML, YAML, CSV, TSV, Excel or
44
+ Parquet. Save a query once and it becomes a versioned endpoint with typed,
45
+ injection-safe parameters and run history - without writing a controller, a repository layer, pagination, auth or
46
+ serialization boilerplate for it.
47
+
48
+ Write SQL. Configure the query. Apply access controls. Get an API.
49
+
50
+ ~~~bash
51
+ $ curl 'http://127.0.0.1:5000/q/example_film_search?text=Harbor&page_size=2' -H 'X-API-Key: demo-key'
52
+ [{"film_id":48,"title":"Broken Harbor","category":"Action","rating":"PG-13"},{"film_id":44,"title":"Electric Harbor","category":"Documentary","rating":"G"}]
53
+
54
+ $ curl 'http://127.0.0.1:5000/q/example_top_films?top_n=2&category=Comedy&format=csv' -H 'X-API-Key: demo-key'
55
+ title,category,rating,rentals,rank
56
+ Electric Signal,Comedy,PG,977,1
57
+ Crimson Garden,Comedy,PG-13,631,2
58
+ ~~~
59
+
60
+ <p align="center">
61
+ <a href="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/run-sql.png">
62
+ <img src="https://raw.githubusercontent.com/AnanthaRajuC/QueryAPIGate/main/documentation/screenshots/run-sql.png"
63
+ alt="The QueryAPIGate Console's API Designer: a joined SQL query with a bound :min_rentals parameter running against the example SQLite connection, the schema browser beside it and paginated results below" width="820">
64
+ </a>
65
+ <br>
66
+ <sub>The built-in Console at <code>/console</code>: write SQL with completion and a schema browser, run it, then save it as an API - no separate tool to install.</sub>
67
+ </p>
68
+
69
+ More of the Console - Home, connections, keys and roles, history, the audit log, metrics, alerts, the access
70
+ map - screen by screen: [**a tour of the Console**](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/SCREENSHOTS.md).
71
+
72
+
73
+ ## Contents
74
+
75
+ - [Why QueryAPIGate](#why-queryapigate)
76
+ - [Features](#features)
77
+ - [Install](#install) · [Quick start](#quick-start) · [Saving a query as an endpoint](#saving-a-query-as-an-endpoint)
78
+ - [Try it with Docker](#try-it-with-docker)
79
+ - [Documentation](#documentation)
80
+ - [Contributing](#contributing) · [Security](#security) · [License](#license) · [Contact](#contact)
81
+
82
+ ---
83
+
84
+ ## Why QueryAPIGate
85
+
86
+ Valuable SQL sits in reports, dashboards, ETL jobs and application code, with no way to a REST endpoint except a
87
+ backend service written around each query. QueryAPIGate makes the query itself the API: write the SQL once, and it is
88
+ a versioned endpoint with typed parameters, governed by who may call it, how often and what they may see - and the same
89
+ query is an MCP tool for AI agents, a live event stream and a scheduled export.
90
+
91
+ It doesn't replace an application backend; it removes the boilerplate when the requirement is "expose this query
92
+ safely". Use cases, how it compares to PostgREST, Hasura and others, and the thinking behind it:
93
+ [why QueryAPIGate](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/WHY.md).
94
+
95
+ ## Features
96
+
97
+ - **[Saved, versioned queries as endpoints](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#save-a-query)** - `GET /q/<name>`, typed and
98
+ injection-safe parameters, drafts and publishing, run history.
99
+ - **[Scoped API keys, roles and collections](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#authentication-and-permissions)** - per
100
+ connection, per query or per collection; expiry, IP allow-lists, rate limits, quotas, table allow-lists.
101
+ - **[Named administrators and SSO](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#administrators-and-admin-roles)** - admin roles and
102
+ tokens, Console sign-in through your identity provider, signed-in users' JWTs.
103
+ - **[Column masking](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#column-masking)** - hash, mask or drop what a caller mustn't see, traced
104
+ through the SQL to the source column.
105
+ - **[An MCP server for AI agents](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/MCP.md)** - saved queries as tools, OAuth sign-in, write tools that
106
+ wait for a person's approval.
107
+ - **[Eight database types, and files](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATABASE_CONNECTION_CONFIGURATION.md#support-matrix)** -
108
+ PostgreSQL, MySQL, SQLite, DuckDB and ClickHouse; H2, JDBC and MongoDB; Parquet, CSV and JSON on S3, GCS, R2 or disk.
109
+ - **[Eight output formats, and streaming](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#streaming-exports)** - JSON, NDJSON, XML, YAML, CSV,
110
+ TSV, Excel and Parquet; whole results streamed from the database cursor.
111
+ - **[Exports to object storage](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#exports-to-object-storage)** - scheduled, incremental, to
112
+ S3, GCS, R2 or a folder.
113
+ - **[Live events](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#live-events-server-sent-events)** - every run as it happens, per key, with
114
+ resume.
115
+ - **[A tamper-evident audit log](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#audit-log)** - a signed hash chain, streamed to your SIEM.
116
+ - **[Observability](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#observability)** - Prometheus metrics, OpenTelemetry tracing, alerts that
117
+ clear themselves, a Grafana dashboard.
118
+ - **[Configuration as code](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#configuration-as-code)** and
119
+ **[secrets from files and Vault](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#secrets-from-files-and-secrets-managers)**.
120
+ - **[OpenAPI and Postman](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md#interactive-documentation)** - every saved query a typed endpoint in
121
+ `/openapi.json` and `/docs`.
122
+ - **[Docker, Helm and several instances](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md)** - one PostgreSQL store, Redis for shared
123
+ limits; [signed releases with SLSA provenance](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md#verify-a-release).
124
+
125
+ Every feature in detail: [features](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/FEATURES.md). Every setting:
126
+ [configuration](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/CONFIGURATION.md).
127
+
128
+ ## Install
129
+
130
+ ~~~bash
131
+ pip install "queryapigate[postgres]" # pick the drivers you need: mysql, postgres, clickhouse, h2, duckdb
132
+ # or everything: pip install "queryapigate[all]"
133
+ ~~~
134
+
135
+ SQLite needs no extra driver. H2 and generic JDBC connections (`queryapigate[h2]`) also need a Java runtime; H2's own
136
+ driver jar is bundled, a JDBC connection to another vendor brings its own. DuckDB (`queryapigate[duckdb]`) needs no
137
+ external runtime either - it's a native Python extension, same as SQLite. `queryapigate[encryption]` adds
138
+ [encryption at rest](documentation/API.md#encryption-at-rest-for-connection-passwords) for connection passwords -
139
+ only needed if you set `QUERYAPIGATE_SECRET_KEY`.
140
+ From a clone: `pip install -e ".[dev]"`. Or use Docker - see [below](#try-it-with-docker).
141
+
142
+ ## Quick start
143
+
144
+ Fastest: `queryapigate examples load && queryapigate serve` installs four worked [example APIs](documentation/EXAMPLES.md)
145
+ (reporting, dashboard, export, partner) you can try, and `queryapigate examples unload` removes them again. Loading
146
+ them creates a real API key per scenario, which also means the server now requires a key for every request - set
147
+ `QUERYAPIGATE_API_KEY` yourself first so you have an admin key on hand for ad-hoc SQL too:
148
+
149
+ ~~~bash
150
+ QUERYAPIGATE_API_KEY=demo-key queryapigate examples load # also prints one scoped key per scenario - store them now
151
+ QUERYAPIGATE_API_KEY=demo-key queryapigate serve # http://127.0.0.1:5000
152
+ ~~~
153
+
154
+ The examples come with a small generated `examples` database (films, customers and rentals), so you can also run ad-hoc SQL
155
+ straight away:
156
+
157
+ ~~~bash
158
+ curl -X POST 'http://127.0.0.1:5000/execute_sql?page_size=3' -H 'X-API-Key: demo-key' -H 'Content-Type: application/json' \
159
+ -d '{"sql": "SELECT film_id, title, rating FROM film WHERE film_id > :min", "params": {"min": 10}, "connection_name": "examples"}'
160
+ ~~~
161
+
162
+ Open <http://127.0.0.1:5000/docs> for the interactive API reference, or <http://127.0.0.1:5000/console> for the
163
+ admin UI to manage connections and saved queries and run ad-hoc SQL without leaving the browser.
164
+
165
+ For your own databases, run `queryapigate init` in an empty folder: it creates `queryapigate.db` with an
166
+ inactive template connection for every supported database type. Edit them (admin UI, or `PATCH
167
+ /api/v1/connections/<name>`), set `"active": true`, and start the server there.
168
+
169
+ ## Saving a query as an endpoint
170
+
171
+ This uses the `examples` connection that `queryapigate examples load` sets up:
172
+
173
+ ~~~bash
174
+ curl -X POST http://127.0.0.1:5000/api/v1/queries -H 'X-API-Key: demo-key' -H 'Content-Type: application/json' -d '{
175
+ "name": "film_by_id",
176
+ "sql": "SELECT * FROM film WHERE film_id = :id",
177
+ "parameters": {"id": {"type": "int", "min": 1, "max": 60, "description": "Film id"}},
178
+ "connection_name": "examples",
179
+ "author": "me", "description": "Look up a film",
180
+ "publish": true
181
+ }'
182
+
183
+ curl 'http://127.0.0.1:5000/q/film_by_id?id=7&format=yaml' -H 'X-API-Key: demo-key'
184
+ curl 'http://127.0.0.1:5000/q/film_by_id?id=0' -H 'X-API-Key: demo-key'
185
+ # {"error": "Invalid parameters: id must be at least 1", "errors": {"id": "must be at least 1"}}
186
+ ~~~
187
+
188
+ Rules: `type` (`int`, `float`, `str`, `bool`), `default`, `required`, `enum`, `min`/`max`, `min_length`/`max_length`,
189
+ `pattern` and `description` - see [the API reference](documentation/API.md#parameter-rules).
190
+
191
+ `POST /api/v1/queries/film_by_id/versions` adds version 2 - a draft until published (`"publish": true`, or
192
+ `POST .../publish`); `DELETE /api/v1/queries/film_by_id/versions/1` removes one version.
193
+
194
+ Add `"cache_ttl": 60` to cache a response for that many seconds (`X-Cache: HIT`/`MISS`, `ETag`, `Cache-Control`) -
195
+ opt-in, and never used for a query that writes. See
196
+ [Response caching](documentation/API.md#response-caching).
197
+
198
+ ## Try it with Docker
199
+
200
+ Every release is published for `linux/amd64` and `linux/arm64`, signed:
201
+
202
+ ~~~bash
203
+ docker run -p 5000:5000 -v queryapigate-data:/data -e QUERYAPIGATE_API_KEY=change-me ghcr.io/anantharajuc/queryapigate:latest
204
+ ~~~
205
+
206
+ Or start it in front of a PostgreSQL database seeded with sample films, with
207
+ [`docker-compose.yml`](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/docker-compose.yml):
208
+
209
+ ~~~bash
210
+ docker compose up --build
211
+ curl -H 'X-API-Key: demo-key' 'http://127.0.0.1:5000/q/films_by_rating?rating=PG&max_length=90'
212
+ ~~~
213
+
214
+ Open <http://127.0.0.1:5000/docs>, paste `demo-key` into the box at the top, and both saved queries are there as
215
+ endpoints; `docker compose down -v` cleans up.
216
+
217
+ The image tags, volumes and a real deployment - TLS, secrets, backups, Prometheus and Grafana, several instances,
218
+ Kubernetes: [deployment](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md).
219
+
220
+ ## Documentation
221
+
222
+ The [documentation site](https://AnanthaRajuC.github.io/QueryAPIGate/) has all of it; on GitHub:
223
+
224
+ | | |
225
+ |---|---|
226
+ | **Start** | [Installation and setup](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/INSTALLATION_AND_SETUP.md) · [Configuration](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/CONFIGURATION.md) · [Example APIs](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/EXAMPLES.md) · [How-to guides](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/how-to/how-to.md) |
227
+ | **Reference** | [API](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/API.md) · [MCP server](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/MCP.md) · [Database connections](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATABASE_CONNECTION_CONFIGURATION.md) · [Query metadata](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/QUERY_METADATA_MANAGEMENT.md) · [Features](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/FEATURES.md) |
228
+ | **Run it** | [Deployment](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DEPLOYMENT.md) · [Technology stack](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/TECHNOLOGY_STACK.MD) · [A tour of the Console](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/SCREENSHOTS.md) |
229
+ | **Security** | [Security policy](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md) · [Threat model](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/THREAT_MODEL.md) · [Where data goes](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/DATA_PROTECTION.md) |
230
+ | **Project** | [Why QueryAPIGate](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/WHY.md) · [Changelog](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/CHANGELOG.md) · [Roadmap](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/BACKLOG.md) · [Architecture decisions](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/documentation/adr/README.md) |
231
+
232
+ ## Contributing
233
+
234
+ Contributions are welcome - database drivers, security, performance, the Console, documentation, tests. Please read
235
+ [CONTRIBUTING.md](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/CONTRIBUTING.md) first: the development setup, the tests, and how a change gets in.
236
+
237
+ ## Security
238
+
239
+ Report a vulnerability privately - see [SECURITY.md](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/SECURITY.md), which also has the hardening checklist for a
240
+ deployment and how to verify a release.
241
+
242
+ ## Third-party components
243
+
244
+ The wheel bundles the [H2 Database](https://h2database.com) JDBC driver (MPL 2.0 / EPL 1.0). The example data is generated
245
+ locally by `queryapigate examples load`; no third-party datasets are included.
246
+
247
+ ## License
248
+
249
+ QueryAPIGate is **source-available**, under the
250
+ [Functional Source License, Version 1.1, MIT Future License](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE)
251
+ (`FSL-1.1-MIT`) © Anantha Raju C. It is not an OSI-approved open source license.
252
+
253
+ In plain terms - the [LICENSE](https://github.com/AnanthaRajuC/QueryAPIGate/blob/main/LICENSE) is the only authoritative text:
254
+
255
+ - **You may** use, copy, modify and redistribute it for any purpose that is not a *Competing Use* - including running it
256
+ inside your own company, non-commercial education and research, and professional services you provide to someone who
257
+ is themselves licensed to use it.
258
+ - **You may not** make it available to others in a commercial product or service that substitutes for QueryAPIGate or
259
+ offers the same or substantially similar functionality (for example, selling it, or hosting it as a paid service).
260
+ - **Each version becomes MIT** on the second anniversary of the date it was released, and can then be used under MIT terms.
261
+ - **Versions up to and including 0.6.1** were released under the MIT license. They are no longer distributed (and the
262
+ repository history was reset in 0.7.0), but a copy you already obtained under MIT remains yours under those terms.
263
+
264
+ Need something the license does not cover, such as offering it as part of a hosted service? Get in touch - commercial
265
+ licensing may be available. This is a summary, not legal advice.
266
+
267
+ ## Contact
268
+
269
+ Anantha Raju C - [@anantharajuc](https://twitter.com/anantharajuc) - arcswdev@gmail.com
270
+
271
+ Project link: <https://github.com/AnanthaRajuC/QueryAPIGate>
@@ -1,5 +1,5 @@
1
1
  """QueryAPIGate - expose SQL databases as a REST API."""
2
- __version__ = "0.35.0"
2
+ __version__ = "0.36.0"
3
3
 
4
4
  from .app import create_app # noqa: E402 (app imports __version__)
5
5