warp-server 0.1.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 (226) hide show
  1. warp_server-0.1.0/.github/workflows/ci.yml +39 -0
  2. warp_server-0.1.0/.gitignore +43 -0
  3. warp_server-0.1.0/.gitmodules +3 -0
  4. warp_server-0.1.0/.pre-commit-config.yaml +16 -0
  5. warp_server-0.1.0/DpNC5NEDJL42WlYjCyyNIGhdNHmLEtJ5h73TqVBYdM8 +1 -0
  6. warp_server-0.1.0/PKG-INFO +104 -0
  7. warp_server-0.1.0/README.md +88 -0
  8. warp_server-0.1.0/err.txt +0 -0
  9. warp_server-0.1.0/pyproject.toml +46 -0
  10. warp_server-0.1.0/src/warp_server/__init__.py +0 -0
  11. warp_server-0.1.0/src/warp_server/auth.py +66 -0
  12. warp_server-0.1.0/src/warp_server/cli.py +278 -0
  13. warp_server-0.1.0/src/warp_server/config.py +11 -0
  14. warp_server-0.1.0/src/warp_server/database.py +13 -0
  15. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/BasicBlock.py +54 -0
  16. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/BasicBlockGUID.py +46 -0
  17. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/Constraint.py +67 -0
  18. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/ConstraintGUID.py +46 -0
  19. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/Function.py +199 -0
  20. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/FunctionComment.py +63 -0
  21. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/FunctionGUID.py +46 -0
  22. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/FunctionVariable.py +109 -0
  23. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/SignatureChunk.py +74 -0
  24. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SigBin/__init__.py +0 -0
  25. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SymbolBin/Symbol.py +76 -0
  26. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SymbolBin/SymbolClass.py +8 -0
  27. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SymbolBin/SymbolModifiers.py +7 -0
  28. warp_server-0.1.0/src/warp_server/gen_flatbuffers/SymbolBin/__init__.py +0 -0
  29. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TargetBin/Target.py +63 -0
  30. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TargetBin/__init__.py +0 -0
  31. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Array.py +80 -0
  32. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/ArrayModifiers.py +6 -0
  33. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/BitOffset.py +26 -0
  34. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/BitShift.py +26 -0
  35. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/BitSize.py +26 -0
  36. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/BitWidth.py +26 -0
  37. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Boolean.py +54 -0
  38. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/CallingConvention.py +50 -0
  39. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Character.py +54 -0
  40. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/ComputedType.py +71 -0
  41. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Enumeration.py +91 -0
  42. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/EnumerationMember.py +63 -0
  43. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Float.py +54 -0
  44. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Function.py +128 -0
  45. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/FunctionMember.py +96 -0
  46. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Integer.py +67 -0
  47. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/LocationClass.py +8 -0
  48. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/MetadataValueType.py +7 -0
  49. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Pointer.py +118 -0
  50. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/PointerAddressing.py +8 -0
  51. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Referrer.py +67 -0
  52. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/RegisterLocation.py +50 -0
  53. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/StackLocation.py +54 -0
  54. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Structure.py +74 -0
  55. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/StructureMember.py +97 -0
  56. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/StructureMemberModifiers.py +7 -0
  57. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Type.py +191 -0
  58. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/TypeChunk.py +74 -0
  59. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/TypeClass.py +18 -0
  60. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/TypeGUID.py +46 -0
  61. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/TypeMetadata.py +102 -0
  62. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/TypeModifiers.py +7 -0
  63. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Union.py +74 -0
  64. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/UnionMember.py +67 -0
  65. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/UnsignedBitOffset.py +26 -0
  66. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/Void.py +37 -0
  67. warp_server-0.1.0/src/warp_server/gen_flatbuffers/TypeBin/__init__.py +0 -0
  68. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/Chunk.py +97 -0
  69. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/ChunkHeader.py +110 -0
  70. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/ChunkType.py +7 -0
  71. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/CompressionType.py +7 -0
  72. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/File.py +95 -0
  73. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/FileHeader.py +54 -0
  74. warp_server-0.1.0/src/warp_server/gen_flatbuffers/Warp/__init__.py +0 -0
  75. warp_server-0.1.0/src/warp_server/gen_flatbuffers/__init__.py +2 -0
  76. warp_server-0.1.0/src/warp_server/main.py +51 -0
  77. warp_server-0.1.0/src/warp_server/models.py +237 -0
  78. warp_server-0.1.0/src/warp_server/routers/__init__.py +0 -0
  79. warp_server-0.1.0/src/warp_server/routers/auth.py +26 -0
  80. warp_server-0.1.0/src/warp_server/routers/commits.py +80 -0
  81. warp_server-0.1.0/src/warp_server/routers/files.py +225 -0
  82. warp_server-0.1.0/src/warp_server/routers/functions.py +201 -0
  83. warp_server-0.1.0/src/warp_server/routers/search.py +122 -0
  84. warp_server-0.1.0/src/warp_server/routers/sources.py +166 -0
  85. warp_server-0.1.0/src/warp_server/routers/status.py +10 -0
  86. warp_server-0.1.0/src/warp_server/routers/symbols.py +52 -0
  87. warp_server-0.1.0/src/warp_server/routers/targets.py +40 -0
  88. warp_server-0.1.0/src/warp_server/routers/types.py +86 -0
  89. warp_server-0.1.0/src/warp_server/routers/users.py +241 -0
  90. warp_server-0.1.0/src/warp_server/schemas.py +280 -0
  91. warp_server-0.1.0/src/warp_server/warp_parser.py +1129 -0
  92. warp_server-0.1.0/tests/__init__.py +0 -0
  93. warp_server-0.1.0/tests/conftest.py +74 -0
  94. warp_server-0.1.0/tests/test_commits.py +83 -0
  95. warp_server-0.1.0/tests/test_files.py +77 -0
  96. warp_server-0.1.0/tests/test_functions.py +147 -0
  97. warp_server-0.1.0/tests/test_search.py +77 -0
  98. warp_server-0.1.0/tests/test_sources.py +151 -0
  99. warp_server-0.1.0/tests/test_status.py +9 -0
  100. warp_server-0.1.0/tests/test_targets.py +41 -0
  101. warp_server-0.1.0/tests/test_users.py +148 -0
  102. warp_server-0.1.0/tests/test_warp_parser.py +647 -0
  103. warp_server-0.1.0/uv.lock +843 -0
  104. warp_server-0.1.0/warp/.git +1 -0
  105. warp_server-0.1.0/warp/.github/workflows/CI.yaml +60 -0
  106. warp_server-0.1.0/warp/.gitignore +66 -0
  107. warp_server-0.1.0/warp/Cargo.toml +18 -0
  108. warp_server-0.1.0/warp/LICENSE +13 -0
  109. warp_server-0.1.0/warp/README.md +182 -0
  110. warp_server-0.1.0/warp/about.hbs +72 -0
  111. warp_server-0.1.0/warp/about.toml +17 -0
  112. warp_server-0.1.0/warp/rust/Cargo.toml +32 -0
  113. warp_server-0.1.0/warp/rust/benches/chunk.rs +64 -0
  114. warp_server-0.1.0/warp/rust/benches/type.rs +45 -0
  115. warp_server-0.1.0/warp/rust/build.rs +22 -0
  116. warp_server-0.1.0/warp/rust/examples/dumper.rs +43 -0
  117. warp_server-0.1.0/warp/rust/examples/random.rs +44 -0
  118. warp_server-0.1.0/warp/rust/examples/type_builder.rs +132 -0
  119. warp_server-0.1.0/warp/rust/fixtures/random.warp +0 -0
  120. warp_server-0.1.0/warp/rust/fuzz/.gitignore +4 -0
  121. warp_server-0.1.0/warp/rust/fuzz/Cargo.toml +36 -0
  122. warp_server-0.1.0/warp/rust/fuzz/fuzz_targets/file.rs +13 -0
  123. warp_server-0.1.0/warp/rust/fuzz/fuzz_targets/function.rs +11 -0
  124. warp_server-0.1.0/warp/rust/fuzz/fuzz_targets/type.rs +10 -0
  125. warp_server-0.1.0/warp/rust/src/cached_builder.rs +51 -0
  126. warp_server-0.1.0/warp/rust/src/chunk.rs +317 -0
  127. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/mod.rs +127 -0
  128. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/basic_block_generated.rs +109 -0
  129. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/basic_block_guid_generated.rs +92 -0
  130. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/constraint_generated.rs +126 -0
  131. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/constraint_guid_generated.rs +92 -0
  132. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/function_comment_generated.rs +126 -0
  133. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/function_generated.rs +194 -0
  134. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/function_guid_generated.rs +92 -0
  135. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/function_variable_generated.rs +229 -0
  136. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/sig_bin/signature_chunk_generated.rs +180 -0
  137. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/symbol_bin/symbol_class_generated.rs +100 -0
  138. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/symbol_bin/symbol_generated.rs +142 -0
  139. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/symbol_bin/symbol_modifiers_generated.rs +65 -0
  140. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/target_bin/target_generated.rs +125 -0
  141. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/array_generated.rs +143 -0
  142. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/array_modifiers_generated.rs +64 -0
  143. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/bit_offset_generated.rs +107 -0
  144. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/bit_shift_generated.rs +107 -0
  145. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/bit_size_generated.rs +107 -0
  146. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/bit_width_generated.rs +107 -0
  147. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/boolean_generated.rs +108 -0
  148. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/calling_convention_generated.rs +108 -0
  149. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/character_generated.rs +108 -0
  150. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/computed_type_generated.rs +126 -0
  151. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/enumeration_generated.rs +126 -0
  152. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/enumeration_member_generated.rs +125 -0
  153. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/float_generated.rs +108 -0
  154. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/function_generated.rs +142 -0
  155. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/function_member_generated.rs +214 -0
  156. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/function_member_location_generated.rs +179 -0
  157. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/integer_generated.rs +125 -0
  158. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/location_class_generated.rs +102 -0
  159. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/metadata_value_type_generated.rs +96 -0
  160. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/pointer_addressing_generated.rs +100 -0
  161. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/pointer_generated.rs +176 -0
  162. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/referrer_generated.rs +125 -0
  163. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/register_location_generated.rs +108 -0
  164. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/stack_location_generated.rs +109 -0
  165. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/structure_generated.rs +108 -0
  166. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/structure_member_generated.rs +161 -0
  167. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/structure_member_modifiers_generated.rs +65 -0
  168. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_chunk_generated.rs +180 -0
  169. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_class_generated.rs +142 -0
  170. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_generated.rs +500 -0
  171. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_guid_generated.rs +92 -0
  172. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_metadata_generated.rs +153 -0
  173. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/type_modifiers_generated.rs +65 -0
  174. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/union_generated.rs +108 -0
  175. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/union_member_generated.rs +126 -0
  176. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/unsigned_bit_offset_generated.rs +107 -0
  177. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/type_bin/void_generated.rs +90 -0
  178. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/chunk_generated.rs +126 -0
  179. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/chunk_header_generated.rs +176 -0
  180. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/chunk_type_generated.rs +96 -0
  181. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/compression_type_generated.rs +96 -0
  182. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/file_generated.rs +211 -0
  183. warp_server-0.1.0/warp/rust/src/gen_flatbuffers/warp/file_header_generated.rs +108 -0
  184. warp_server-0.1.0/warp/rust/src/lib.rs +239 -0
  185. warp_server-0.1.0/warp/rust/src/mock.rs +183 -0
  186. warp_server-0.1.0/warp/rust/src/signature/basic_block.rs +105 -0
  187. warp_server-0.1.0/warp/rust/src/signature/chunk.rs +186 -0
  188. warp_server-0.1.0/warp/rust/src/signature/comment.rs +35 -0
  189. warp_server-0.1.0/warp/rust/src/signature/constraint.rs +145 -0
  190. warp_server-0.1.0/warp/rust/src/signature/function.rs +195 -0
  191. warp_server-0.1.0/warp/rust/src/signature/variable.rs +62 -0
  192. warp_server-0.1.0/warp/rust/src/signature.rs +6 -0
  193. warp_server-0.1.0/warp/rust/src/symbol.rs +97 -0
  194. warp_server-0.1.0/warp/rust/src/target.rs +36 -0
  195. warp_server-0.1.0/warp/rust/src/type/chunk.rs +155 -0
  196. warp_server-0.1.0/warp/rust/src/type/class/array.rs +80 -0
  197. warp_server-0.1.0/warp/rust/src/type/class/boolean.rs +37 -0
  198. warp_server-0.1.0/warp/rust/src/type/class/character.rs +38 -0
  199. warp_server-0.1.0/warp/rust/src/type/class/enumeration.rs +97 -0
  200. warp_server-0.1.0/warp/rust/src/type/class/float.rs +37 -0
  201. warp_server-0.1.0/warp/rust/src/type/class/function.rs +257 -0
  202. warp_server-0.1.0/warp/rust/src/type/class/integer.rs +83 -0
  203. warp_server-0.1.0/warp/rust/src/type/class/pointer.rs +101 -0
  204. warp_server-0.1.0/warp/rust/src/type/class/referrer.rs +44 -0
  205. warp_server-0.1.0/warp/rust/src/type/class/structure.rs +139 -0
  206. warp_server-0.1.0/warp/rust/src/type/class/union.rs +200 -0
  207. warp_server-0.1.0/warp/rust/src/type/class/void.rs +59 -0
  208. warp_server-0.1.0/warp/rust/src/type/class.rs +165 -0
  209. warp_server-0.1.0/warp/rust/src/type/guid.rs +68 -0
  210. warp_server-0.1.0/warp/rust/src/type.rs +415 -0
  211. warp_server-0.1.0/warp/rust/tests/chunk.rs +237 -0
  212. warp_server-0.1.0/warp/rust/tests/file.rs +61 -0
  213. warp_server-0.1.0/warp/rust/tests/signature.rs +16 -0
  214. warp_server-0.1.0/warp/rust/tests/snapshots/file__file_format_regression.snap +6047 -0
  215. warp_server-0.1.0/warp/rust/tests/types.rs +142 -0
  216. warp_server-0.1.0/warp/signature.fbs +60 -0
  217. warp_server-0.1.0/warp/symbol.fbs +21 -0
  218. warp_server-0.1.0/warp/target.fbs +10 -0
  219. warp_server-0.1.0/warp/type.fbs +249 -0
  220. warp_server-0.1.0/warp/warp.fbs +51 -0
  221. warp_server-0.1.0/warp/warp_cli/Cargo.toml +10 -0
  222. warp_server-0.1.0/warp/warp_cli/src/main.rs +24 -0
  223. warp_server-0.1.0/warp/warp_cli/src/operation/find.rs +81 -0
  224. warp_server-0.1.0/warp/warp_cli/src/operation/merge.rs +29 -0
  225. warp_server-0.1.0/warp/warp_cli/src/operation.rs +24 -0
  226. warp_server-0.1.0/warp/warp_cli/src/utility.rs +9 -0
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ submodules: true
16
+ - uses: astral-sh/setup-uv@v5
17
+ with:
18
+ python-version: "3.12"
19
+ enable-cache: false
20
+ - uses: astral-sh/ruff-action@v3
21
+
22
+ test:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ submodules: true
28
+ - uses: astral-sh/setup-uv@v5
29
+ with:
30
+ python-version: "3.12"
31
+ - name: Install flatbuffers compiler
32
+ run: |
33
+ curl -Lo flatc.zip "https://github.com/google/flatbuffers/releases/download/v25.12.19/Linux.flatc.binary.clang%2B%2B-18.zip"
34
+ sudo unzip -o flatc.zip flatc -d /usr/local/bin
35
+ sudo chmod +x /usr/local/bin/flatc
36
+ - name: Generate FlatBuffer bindings
37
+ run: flatc --python -o src/warp_server/gen_flatbuffers warp/*.fbs
38
+ - run: uv sync
39
+ - run: uv run pytest -v
@@ -0,0 +1,43 @@
1
+ # macOS
2
+ .DS_Store
3
+ .AppleDouble
4
+ .LSOverride
5
+ ._*
6
+
7
+ # Python
8
+ __pycache__/
9
+ *.py[cod]
10
+ *.pyo
11
+ *.pyd
12
+ *.so
13
+ *.egg
14
+ *.egg-info/
15
+ dist/
16
+ build/
17
+ .eggs/
18
+ .mypy_cache/
19
+ .ruff_cache/
20
+ .pytest_cache/
21
+ .coverage
22
+ htmlcov/
23
+
24
+ # uv / virtualenvs
25
+ .venv/
26
+ venv/
27
+ .python-version
28
+
29
+ # Editors
30
+ .vscode/
31
+ .idea/
32
+ *.swp
33
+ *.swo
34
+ *~
35
+
36
+ # Xcode
37
+ *.xcuserstate
38
+ xcuserdata/
39
+ *.xcworkspace/xcuserdata/
40
+ DerivedData/
41
+
42
+ warp-plugin-binja
43
+ warp.db
@@ -0,0 +1,3 @@
1
+ [submodule "warp"]
2
+ path = warp
3
+ url = https://github.com/vector35/warp
@@ -0,0 +1,16 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-toml
9
+ - id: check-added-large-files
10
+
11
+ - repo: https://github.com/astral-sh/ruff-pre-commit
12
+ rev: v0.11.4
13
+ hooks:
14
+ - id: ruff
15
+ args: [--fix]
16
+ - id: ruff-format
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.4
2
+ Name: warp-server
3
+ Version: 0.1.0
4
+ Summary: WARP signature server API
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: aiosqlite>=0.20
7
+ Requires-Dist: click>=8.1
8
+ Requires-Dist: fastapi>=0.115
9
+ Requires-Dist: flatbuffers>=25.12.19
10
+ Requires-Dist: pydantic-settings>=2.0
11
+ Requires-Dist: pydantic>=2.0
12
+ Requires-Dist: python-multipart>=0.0.9
13
+ Requires-Dist: sqlalchemy[asyncio]>=2.0
14
+ Requires-Dist: uvicorn[standard]>=0.30
15
+ Description-Content-Type: text/markdown
16
+
17
+ # warp-server
18
+
19
+ FastAPI implementation of the WARP signature server API.
20
+
21
+ ## Development
22
+
23
+ ```bash
24
+ git submodule update --init # fetch warp/ schemas
25
+ uv sync
26
+ uv run warp-server # start dev server on :8000
27
+ uv run pytest # run tests
28
+ ```
29
+
30
+ ### Regenerating FlatBuffer bindings
31
+
32
+ The Python FlatBuffer bindings are generated from the `.fbs` schemas in `warp/`. To regenerate:
33
+
34
+ ```bash
35
+ brew install flatbuffers # if not already installed
36
+ flatc --python -o src/warp_server/gen_flatbuffers warp/*.fbs
37
+ ```
38
+
39
+ ## Bootstrap: Create a User with an API Key
40
+
41
+ The server uses Bearer token auth via API keys. Use the `warp-ctl` CLI to manage users and keys.
42
+
43
+ ### Quick bootstrap (admin + key in one step)
44
+
45
+ ```bash
46
+ uv run warp-ctl bootstrap
47
+ # Created admin user id=1 username=admin
48
+ # API key: <key>
49
+ ```
50
+
51
+ Options: `--email`, `--username` to customize the admin account.
52
+
53
+ ### Managing users
54
+
55
+ ```bash
56
+ # create a regular user
57
+ uv run warp-ctl user create --email alice@example.com --username alice
58
+
59
+ # create an admin
60
+ uv run warp-ctl user create --email ops@example.com --username ops --role Admin
61
+
62
+ # list all users
63
+ uv run warp-ctl user list
64
+
65
+ # delete a user
66
+ uv run warp-ctl user delete 2
67
+ ```
68
+
69
+ ### Managing API keys
70
+
71
+ ```bash
72
+ # create a key for user id 1
73
+ uv run warp-ctl key create --user-id 1 --name dev-key
74
+
75
+ # list all keys (or filter by --user-id)
76
+ uv run warp-ctl key list
77
+ uv run warp-ctl key list --user-id 1
78
+
79
+ # revoke a key
80
+ uv run warp-ctl key revoke 3
81
+ ```
82
+
83
+ ### Managing sources
84
+
85
+ ```bash
86
+ # create a source owned by user 1
87
+ uv run warp-ctl source create --name my-signatures --user-id 1
88
+
89
+ # list sources
90
+ uv run warp-ctl source list
91
+ ```
92
+
93
+ ### Using the API key
94
+
95
+ ```bash
96
+ # verify auth
97
+ curl -H "Authorization: Bearer <key>" http://localhost:8000/api/v1/users/me
98
+
99
+ # create a source via the API
100
+ curl -X POST http://localhost:8000/api/v1/sources \
101
+ -H "Authorization: Bearer <key>" \
102
+ -H "Content-Type: application/json" \
103
+ -d '{"name": "my-source", "user_ids": []}'
104
+ ```
@@ -0,0 +1,88 @@
1
+ # warp-server
2
+
3
+ FastAPI implementation of the WARP signature server API.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ git submodule update --init # fetch warp/ schemas
9
+ uv sync
10
+ uv run warp-server # start dev server on :8000
11
+ uv run pytest # run tests
12
+ ```
13
+
14
+ ### Regenerating FlatBuffer bindings
15
+
16
+ The Python FlatBuffer bindings are generated from the `.fbs` schemas in `warp/`. To regenerate:
17
+
18
+ ```bash
19
+ brew install flatbuffers # if not already installed
20
+ flatc --python -o src/warp_server/gen_flatbuffers warp/*.fbs
21
+ ```
22
+
23
+ ## Bootstrap: Create a User with an API Key
24
+
25
+ The server uses Bearer token auth via API keys. Use the `warp-ctl` CLI to manage users and keys.
26
+
27
+ ### Quick bootstrap (admin + key in one step)
28
+
29
+ ```bash
30
+ uv run warp-ctl bootstrap
31
+ # Created admin user id=1 username=admin
32
+ # API key: <key>
33
+ ```
34
+
35
+ Options: `--email`, `--username` to customize the admin account.
36
+
37
+ ### Managing users
38
+
39
+ ```bash
40
+ # create a regular user
41
+ uv run warp-ctl user create --email alice@example.com --username alice
42
+
43
+ # create an admin
44
+ uv run warp-ctl user create --email ops@example.com --username ops --role Admin
45
+
46
+ # list all users
47
+ uv run warp-ctl user list
48
+
49
+ # delete a user
50
+ uv run warp-ctl user delete 2
51
+ ```
52
+
53
+ ### Managing API keys
54
+
55
+ ```bash
56
+ # create a key for user id 1
57
+ uv run warp-ctl key create --user-id 1 --name dev-key
58
+
59
+ # list all keys (or filter by --user-id)
60
+ uv run warp-ctl key list
61
+ uv run warp-ctl key list --user-id 1
62
+
63
+ # revoke a key
64
+ uv run warp-ctl key revoke 3
65
+ ```
66
+
67
+ ### Managing sources
68
+
69
+ ```bash
70
+ # create a source owned by user 1
71
+ uv run warp-ctl source create --name my-signatures --user-id 1
72
+
73
+ # list sources
74
+ uv run warp-ctl source list
75
+ ```
76
+
77
+ ### Using the API key
78
+
79
+ ```bash
80
+ # verify auth
81
+ curl -H "Authorization: Bearer <key>" http://localhost:8000/api/v1/users/me
82
+
83
+ # create a source via the API
84
+ curl -X POST http://localhost:8000/api/v1/sources \
85
+ -H "Authorization: Bearer <key>" \
86
+ -H "Content-Type: application/json" \
87
+ -d '{"name": "my-source", "user_ids": []}'
88
+ ```
File without changes
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "warp-server"
3
+ version = "0.1.0"
4
+ description = "WARP signature server API"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "fastapi>=0.115",
9
+ "uvicorn[standard]>=0.30",
10
+ "sqlalchemy[asyncio]>=2.0",
11
+ "aiosqlite>=0.20",
12
+ "pydantic>=2.0",
13
+ "pydantic-settings>=2.0",
14
+ "python-multipart>=0.0.9",
15
+ "click>=8.1",
16
+ "flatbuffers>=25.12.19",
17
+ ]
18
+
19
+ [project.scripts]
20
+ warp-server = "warp_server.main:run"
21
+ warp-ctl = "warp_server.cli:app"
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "pytest>=8.0",
26
+ "pytest-asyncio>=0.24",
27
+ "httpx>=0.27",
28
+ "pre-commit>=4.5.1",
29
+ ]
30
+
31
+ [build-system]
32
+ requires = ["hatchling"]
33
+ build-backend = "hatchling.build"
34
+
35
+ [tool.hatch.build.targets.wheel]
36
+ packages = ["src/warp_server"]
37
+
38
+ [tool.pytest.ini_options]
39
+ asyncio_mode = "auto"
40
+ testpaths = ["tests"]
41
+
42
+ [tool.ruff]
43
+ target-version = "py312"
44
+
45
+ [tool.ruff.lint.per-file-ignores]
46
+ "src/warp_server/warp_parser.py" = ["E402"]
File without changes
@@ -0,0 +1,66 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from fastapi import Depends, HTTPException, Security, status
4
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
5
+ from sqlalchemy import select
6
+ from sqlalchemy.ext.asyncio import AsyncSession
7
+
8
+ from warp_server.database import get_db
9
+ from warp_server.models import ApiKey, User
10
+
11
+ security = HTTPBearer(auto_error=False)
12
+
13
+
14
+ async def get_current_user(
15
+ credentials: HTTPAuthorizationCredentials | None = Security(security),
16
+ db: AsyncSession = Depends(get_db),
17
+ ) -> User:
18
+ if credentials is None:
19
+ raise HTTPException(
20
+ status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authenticated"
21
+ )
22
+
23
+ token = credentials.credentials
24
+ result = await db.execute(select(ApiKey).where(ApiKey.key == token))
25
+ api_key = result.scalar_one_or_none()
26
+ if api_key is None:
27
+ raise HTTPException(
28
+ status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid API key"
29
+ )
30
+
31
+ if api_key.expires_at and api_key.expires_at < datetime.now(timezone.utc):
32
+ raise HTTPException(
33
+ status_code=status.HTTP_401_UNAUTHORIZED, detail="API key expired"
34
+ )
35
+
36
+ # Update last_used_at
37
+ api_key.last_used_at = datetime.now(timezone.utc)
38
+ await db.commit()
39
+
40
+ result = await db.execute(select(User).where(User.id == api_key.user_id))
41
+ user = result.scalar_one_or_none()
42
+ if user is None:
43
+ raise HTTPException(
44
+ status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found"
45
+ )
46
+ return user
47
+
48
+
49
+ async def get_optional_user(
50
+ credentials: HTTPAuthorizationCredentials | None = Security(security),
51
+ db: AsyncSession = Depends(get_db),
52
+ ) -> User | None:
53
+ if credentials is None:
54
+ return None
55
+ try:
56
+ return await get_current_user(credentials, db)
57
+ except HTTPException:
58
+ return None
59
+
60
+
61
+ def require_admin(user: User = Depends(get_current_user)) -> User:
62
+ if user.role != "Admin":
63
+ raise HTTPException(
64
+ status_code=status.HTTP_403_FORBIDDEN, detail="Admin required"
65
+ )
66
+ return user
@@ -0,0 +1,278 @@
1
+ import asyncio
2
+ import secrets
3
+ from datetime import datetime, timezone
4
+
5
+ import click
6
+ from sqlalchemy import select
7
+
8
+ from warp_server.database import async_session, engine
9
+ from warp_server.models import ApiKey, Base, Source, SourceTag, SourceUser, User
10
+
11
+
12
+ @click.group(name="warp-ctl", help="WARP server management CLI.")
13
+ def app():
14
+ pass
15
+
16
+
17
+ @app.group(help="Manage users.")
18
+ def user():
19
+ pass
20
+
21
+
22
+ @app.group(help="Manage API keys.")
23
+ def key():
24
+ pass
25
+
26
+
27
+ @app.group(help="Manage sources.")
28
+ def source():
29
+ pass
30
+
31
+
32
+ def _run(coro):
33
+ return asyncio.run(coro)
34
+
35
+
36
+ async def _ensure_tables():
37
+ async with engine.begin() as conn:
38
+ await conn.run_sync(Base.metadata.create_all)
39
+
40
+
41
+ # ── Users ────────────────────────────────────────────────────────────
42
+
43
+
44
+ @user.command("create")
45
+ @click.option("--email", required=True, help="User email address.")
46
+ @click.option(
47
+ "--username", default=None, help="Username (defaults to email local part)."
48
+ )
49
+ @click.option("--role", default="User", help="Role: User or Admin.")
50
+ def user_create(email, username, role):
51
+ """Create a new user."""
52
+
53
+ async def _create():
54
+ await _ensure_tables()
55
+ async with async_session() as db:
56
+ name = username or email.split("@")[0]
57
+ u = User(email=email, username=name, role=role)
58
+ db.add(u)
59
+ await db.flush()
60
+ raw_key = secrets.token_urlsafe(32)
61
+ db.add(ApiKey(user_id=u.id, key=raw_key, name="default"))
62
+ await db.commit()
63
+ await db.refresh(u)
64
+ click.echo(f"Created user id={u.id} username={u.username} role={u.role}")
65
+ click.echo(f"API key: {raw_key}")
66
+ click.echo("Store this key securely — it cannot be retrieved later.")
67
+
68
+ _run(_create())
69
+
70
+
71
+ @user.command("list")
72
+ def user_list():
73
+ """List all users."""
74
+
75
+ async def _list():
76
+ await _ensure_tables()
77
+ async with async_session() as db:
78
+ result = await db.execute(select(User).order_by(User.id))
79
+ users = result.scalars().all()
80
+ if not users:
81
+ click.echo("No users found.")
82
+ return
83
+ click.echo(
84
+ f"{'ID':<6} {'Username':<20} {'Email':<30} {'Role':<10} {'Created'}"
85
+ )
86
+ click.echo("-" * 80)
87
+ for u in users:
88
+ click.echo(
89
+ f"{u.id:<6} {u.username:<20} {u.email:<30} {u.role:<10} {u.created_at}"
90
+ )
91
+
92
+ _run(_list())
93
+
94
+
95
+ @user.command("delete")
96
+ @click.argument("user_id", type=int)
97
+ def user_delete(user_id):
98
+ """Delete a user by ID."""
99
+
100
+ async def _delete():
101
+ await _ensure_tables()
102
+ async with async_session() as db:
103
+ result = await db.execute(select(User).where(User.id == user_id))
104
+ u = result.scalar_one_or_none()
105
+ if u is None:
106
+ click.echo(f"User {user_id} not found.", err=True)
107
+ raise SystemExit(1)
108
+ await db.delete(u)
109
+ await db.commit()
110
+ click.echo(f"Deleted user id={user_id} username={u.username}")
111
+
112
+ _run(_delete())
113
+
114
+
115
+ # ── API Keys ─────────────────────────────────────────────────────────
116
+
117
+
118
+ @key.command("create")
119
+ @click.option(
120
+ "--user-id", required=True, type=int, help="User ID to create the key for."
121
+ )
122
+ @click.option("--name", default="default", help="Key name/label.")
123
+ def key_create(user_id, name):
124
+ """Create an API key for a user."""
125
+
126
+ async def _create():
127
+ await _ensure_tables()
128
+ async with async_session() as db:
129
+ result = await db.execute(select(User).where(User.id == user_id))
130
+ u = result.scalar_one_or_none()
131
+ if u is None:
132
+ click.echo(f"User {user_id} not found.", err=True)
133
+ raise SystemExit(1)
134
+ raw_key = secrets.token_urlsafe(32)
135
+ api_key = ApiKey(
136
+ user_id=u.id,
137
+ key=raw_key,
138
+ name=name,
139
+ created_at=datetime.now(timezone.utc),
140
+ )
141
+ db.add(api_key)
142
+ await db.commit()
143
+ await db.refresh(api_key)
144
+ click.echo(f"Created API key for user={u.username}")
145
+ click.echo(f"Key: {raw_key}")
146
+ click.echo("Store this key securely — it cannot be retrieved later.")
147
+
148
+ _run(_create())
149
+
150
+
151
+ @key.command("list")
152
+ @click.option("--user-id", default=None, type=int, help="Filter keys by user ID.")
153
+ def key_list(user_id):
154
+ """List API keys."""
155
+
156
+ async def _list():
157
+ await _ensure_tables()
158
+ async with async_session() as db:
159
+ query = select(ApiKey).order_by(ApiKey.id)
160
+ if user_id is not None:
161
+ query = query.where(ApiKey.user_id == user_id)
162
+ result = await db.execute(query)
163
+ keys = result.scalars().all()
164
+ if not keys:
165
+ click.echo("No API keys found.")
166
+ return
167
+ click.echo(
168
+ f"{'ID':<6} {'User ID':<8} {'Name':<16} {'Key (prefix)':<14} {'Created':<26} {'Last Used'}"
169
+ )
170
+ click.echo("-" * 90)
171
+ for k in keys:
172
+ click.echo(
173
+ f"{k.id:<6} {k.user_id:<8} {k.name:<16} {k.key[:12] + '…':<14} {str(k.created_at):<26} {k.last_used_at or '—'}"
174
+ )
175
+
176
+ _run(_list())
177
+
178
+
179
+ @key.command("revoke")
180
+ @click.argument("key_id", type=int)
181
+ def key_revoke(key_id):
182
+ """Revoke (delete) an API key."""
183
+
184
+ async def _revoke():
185
+ await _ensure_tables()
186
+ async with async_session() as db:
187
+ result = await db.execute(select(ApiKey).where(ApiKey.id == key_id))
188
+ api_key = result.scalar_one_or_none()
189
+ if api_key is None:
190
+ click.echo(f"API key {key_id} not found.", err=True)
191
+ raise SystemExit(1)
192
+ await db.delete(api_key)
193
+ await db.commit()
194
+ click.echo(f"Revoked API key id={key_id}")
195
+
196
+ _run(_revoke())
197
+
198
+
199
+ # ── Sources ──────────────────────────────────────────────────────────
200
+
201
+
202
+ @source.command("create")
203
+ @click.option("--name", required=True, help="Source name.")
204
+ @click.option("--user-id", default=None, type=int, help="User ID to add as owner.")
205
+ def source_create(name, user_id):
206
+ """Create a new source."""
207
+
208
+ async def _create():
209
+ await _ensure_tables()
210
+ async with async_session() as db:
211
+ src = Source(name=name)
212
+ db.add(src)
213
+ await db.flush()
214
+ if user_id is not None:
215
+ db.add(SourceUser(source_id=src.id, user_id=user_id))
216
+ db.add(SourceTag(source_id=src.id, tag="trusted"))
217
+ await db.commit()
218
+ await db.refresh(src)
219
+ click.echo(f"Created source id={src.id} name={src.name}")
220
+
221
+ _run(_create())
222
+
223
+
224
+ @source.command("list")
225
+ def source_list():
226
+ """List all sources."""
227
+
228
+ async def _list():
229
+ await _ensure_tables()
230
+ async with async_session() as db:
231
+ result = await db.execute(select(Source).order_by(Source.name))
232
+ sources = result.scalars().all()
233
+ if not sources:
234
+ click.echo("No sources found.")
235
+ return
236
+ click.echo(f"{'ID':<6} {'Name':<30} {'Created'}")
237
+ click.echo("-" * 60)
238
+ for s in sources:
239
+ click.echo(f"{s.id:<6} {s.name:<30} {s.created_at}")
240
+
241
+ _run(_list())
242
+
243
+
244
+ # ── Quick bootstrap ──────────────────────────────────────────────────
245
+
246
+
247
+ @app.command("bootstrap")
248
+ @click.option("--email", default="admin@localhost", help="Admin email.")
249
+ @click.option("--username", default="admin", help="Admin username.")
250
+ def bootstrap(email, username):
251
+ """Create an admin user with an API key in one step."""
252
+
253
+ async def _bootstrap():
254
+ await _ensure_tables()
255
+ async with async_session() as db:
256
+ result = await db.execute(select(User).where(User.username == username))
257
+ existing = result.scalar_one_or_none()
258
+ if existing is not None:
259
+ click.echo(
260
+ f"User '{username}' already exists (id={existing.id}), skipping creation."
261
+ )
262
+ return
263
+ u = User(email=email, username=username, role="Admin")
264
+ db.add(u)
265
+ await db.flush()
266
+ raw_key = secrets.token_urlsafe(32)
267
+ db.add(ApiKey(user_id=u.id, key=raw_key, name="bootstrap"))
268
+ await db.commit()
269
+ await db.refresh(u)
270
+ click.echo(f"Created admin user id={u.id} username={u.username}")
271
+ click.echo(f"API key: {raw_key}")
272
+ click.echo("Store this key securely — it cannot be retrieved later.")
273
+
274
+ _run(_bootstrap())
275
+
276
+
277
+ if __name__ == "__main__":
278
+ app()