Start working with FastAPI

This commit is contained in:
Alexis Métaireau 2023-10-02 12:15:57 +02:00
commit eea465af5c
15 changed files with 677 additions and 0 deletions

16
Pipfile Normal file
View file

@ -0,0 +1,16 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
fastapi = "*"
sqlalchemy = "*"
sqlalchemy-utils = "*"
uvicorn = "*"
pyyaml = "*"
[dev-packages]
[requires]
python_version = "3.11"

337
Pipfile.lock generated Normal file
View file

@ -0,0 +1,337 @@
{
"_meta": {
"hash": {
"sha256": "b95f0093b5a31fb370823a1219b4cde22ee7b0e07d9c7bc331aad379f05ee7da"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.11"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"annotated-types": {
"hashes": [
"sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802",
"sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"
],
"markers": "python_version >= '3.7'",
"version": "==0.5.0"
},
"anyio": {
"hashes": [
"sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780",
"sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"
],
"markers": "python_version >= '3.7'",
"version": "==3.7.1"
},
"click": {
"hashes": [
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.7"
},
"fastapi": {
"hashes": [
"sha256:345844e6a82062f06a096684196aaf96c1198b25c06b72c1311b882aa2d8a35d",
"sha256:5e5f17e826dbd9e9b5a5145976c5cd90bcaa61f2bf9a69aca423f2bcebe44d83"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==0.103.1"
},
"h11": {
"hashes": [
"sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d",
"sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"
],
"markers": "python_version >= '3.7'",
"version": "==0.14.0"
},
"idna": {
"hashes": [
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
],
"markers": "python_version >= '3.5'",
"version": "==3.4"
},
"pydantic": {
"hashes": [
"sha256:2b2240c8d54bb8f84b88e061fac1bdfa1761c2859c367f9d3afe0ec2966deddc",
"sha256:b172505886028e4356868d617d2d1a776d7af1625d1313450fd51bdd19d9d61f"
],
"markers": "python_version >= '3.7'",
"version": "==2.4.1"
},
"pydantic-core": {
"hashes": [
"sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e",
"sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33",
"sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7",
"sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7",
"sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea",
"sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4",
"sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0",
"sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7",
"sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94",
"sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff",
"sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82",
"sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd",
"sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893",
"sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e",
"sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d",
"sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901",
"sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9",
"sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c",
"sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7",
"sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891",
"sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f",
"sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a",
"sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9",
"sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5",
"sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e",
"sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a",
"sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c",
"sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f",
"sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514",
"sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b",
"sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302",
"sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096",
"sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0",
"sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27",
"sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884",
"sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a",
"sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357",
"sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430",
"sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221",
"sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325",
"sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4",
"sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05",
"sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55",
"sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875",
"sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970",
"sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc",
"sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6",
"sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f",
"sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b",
"sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d",
"sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15",
"sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118",
"sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee",
"sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e",
"sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6",
"sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208",
"sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede",
"sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3",
"sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e",
"sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada",
"sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175",
"sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a",
"sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c",
"sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f",
"sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58",
"sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f",
"sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a",
"sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a",
"sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921",
"sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e",
"sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904",
"sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776",
"sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52",
"sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf",
"sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8",
"sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f",
"sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b",
"sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63",
"sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c",
"sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f",
"sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468",
"sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e",
"sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab",
"sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2",
"sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb",
"sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb",
"sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132",
"sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b",
"sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607",
"sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934",
"sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698",
"sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e",
"sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561",
"sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de",
"sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b",
"sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a",
"sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595",
"sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402",
"sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881",
"sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429",
"sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5",
"sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7",
"sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c",
"sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531",
"sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6",
"sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"
],
"markers": "python_version >= '3.7'",
"version": "==2.10.1"
},
"pyyaml": {
"hashes": [
"sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
"sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
"sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
"sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
"sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
"sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
"sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
"sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
"sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
"sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
"sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
"sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
"sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
"sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
"sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
"sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
"sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
"sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
"sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
"sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
"sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
"sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
"sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
"sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
"sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
"sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
"sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
"sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
"sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
"sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
"sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
"sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
"sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
"sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
"sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
"sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
"sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
"sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
"sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
"sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
"sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
"sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
"sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
"sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
"sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
"sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
"sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
"sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
],
"index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==6.0.1"
},
"sniffio": {
"hashes": [
"sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101",
"sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"
],
"markers": "python_version >= '3.7'",
"version": "==1.3.0"
},
"sqlalchemy": {
"hashes": [
"sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e",
"sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6",
"sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258",
"sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce",
"sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede",
"sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce",
"sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4",
"sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4",
"sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5",
"sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01",
"sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9",
"sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9",
"sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67",
"sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9",
"sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9",
"sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301",
"sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8",
"sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615",
"sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa",
"sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4",
"sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446",
"sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4",
"sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178",
"sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af",
"sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b",
"sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe",
"sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9",
"sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09",
"sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a",
"sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063",
"sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef",
"sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1",
"sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66",
"sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231",
"sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e",
"sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec",
"sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430",
"sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce",
"sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9",
"sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa",
"sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==2.0.21"
},
"sqlalchemy-utils": {
"hashes": [
"sha256:6c96b0768ea3f15c0dc56b363d386138c562752b84f647fb8d31a2223aaab801",
"sha256:a2181bff01eeb84479e38571d2c0718eb52042f9afd8c194d0d02877e84b7d74"
],
"index": "pypi",
"markers": "python_version >= '3.6'",
"version": "==0.41.1"
},
"starlette": {
"hashes": [
"sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75",
"sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"
],
"markers": "python_version >= '3.7'",
"version": "==0.27.0"
},
"typing-extensions": {
"hashes": [
"sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0",
"sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"
],
"markers": "python_version >= '3.8'",
"version": "==4.8.0"
},
"uvicorn": {
"hashes": [
"sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53",
"sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==0.23.2"
}
},
"develop": {}
}

24
README.md Normal file
View file

@ -0,0 +1,24 @@
# On service start.
1. Read the job definitions file and populate the database.
2. From the job definition, create a list of tasks to execute.
3. From time to time (?) clean the db.
# On configuration changes :
- Find and tombstone the JobDefinitions that are not useful anymore.
- Cascade delete the child tasks that are planned. Tombstone them as wel.
# On worker demand :
- Find the tasks for which :
- last_check is not defined
- OR last_check + max_timedelta > datetime.now()
- AND selected_by not defined.
- Mark these tasks as selected by the current worker, on the current date.
# From time to time:
- Check for stalled tasks (datetime.now() - selected_at) > MAX_WORKER_TIME. Remove the lock.
# On the worker side
Hey, I'm XX, give me some work.
<Service answers>
OK, this is done, here are the results for Task<id>: response.

0
argos/__init__.py Normal file
View file

26
argos/checks/__init__.py Normal file
View file

@ -0,0 +1,26 @@
class HTTPStatusCheck:
config = "status-is"
def check(resp):
return True
class HTTPBodyContains:
config = "body-contains"
def check(resp):
return True
class SSLCertificateExpiration:
config = "ssl-certificate-expiration"
def check(resp):
return True
AVAILABLE_CHECKS = (HTTPStatusCheck, HTTPBodyContains, SSLCertificateExpiration)
def get_names(checks=AVAILABLE_CHECKS):
return [c.config for c in checks]

12
argos/database.py Normal file
View file

@ -0,0 +1,12 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:////tmp/argos.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

3
argos/logging.py Normal file
View file

@ -0,0 +1,3 @@
import logging
logger = logging.getLogger(__name__)

35
argos/main.py Normal file
View file

@ -0,0 +1,35 @@
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import queries, models, schemas
from .database import SessionLocal, engine
from .logging import logger
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.on_event("startup")
async def read_config_and_populate_db():
# XXX Get filename from environment.
config = schemas.config.from_yaml("config.yaml")
db = SessionLocal()
try:
queries.update_from_config(db, config)
finally:
db.close()
@app.get("/", response_model=list[schemas.Task])
async def read_tasks(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = queries.list_tasks(db, limit)
return users

39
argos/models.py Normal file
View file

@ -0,0 +1,39 @@
from typing import List
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, JSON, DateTime
from sqlalchemy.orm import relationship, Mapped, mapped_column, DeclarativeBase
from sqlalchemy_utils import ChoiceType
from sqlalchemy.orm import mapped_column
from datetime import datetime
from .schemas import WebsiteCheck
class Base(DeclarativeBase):
type_annotation_map = {
List[WebsiteCheck]: JSON,
dict: JSON
}
class Definition(Base):
__tablename__ = "definitions"
id : Mapped[int]= mapped_column(primary_key=True)
domain : Mapped[str] = mapped_column()
path : Mapped[str] = mapped_column()
# checks : Mapped[List[WebsiteCheck]] = mapped_column()
tasks : Mapped[List["Task"]] = relationship(back_populates="definition")
class Task(Base):
__tablename__ = "tasks"
id : Mapped[int] = mapped_column(primary_key=True)
# XXX enforce "ok" | "nok" | "unknown"
status: Mapped[str] = mapped_column(default="unknown")
max_delta_days: Mapped[int] = mapped_column()
response: Mapped[dict] = mapped_column(default={})
last_check: Mapped[datetime] = mapped_column(nullable=True)
selected_by: Mapped[str] = mapped_column(nullable=True)
selected_at: Mapped[datetime] = mapped_column(nullable=True)
definition_id : Mapped[str] = mapped_column(ForeignKey("definitions.id"))
definition : Mapped["Definition"] = relationship(back_populates="tasks")

30
argos/queries.py Normal file
View file

@ -0,0 +1,30 @@
from sqlalchemy.orm import Session
from . import models, schemas
from .logging import logger
def list_tasks(db: Session, limit: int = 100):
return db.query(models.Task).limit(limit).all()
def update_from_config(db: Session, config: schemas.Config):
for website in config.websites:
domain = website.domain
for p in website.paths:
definition = models.Definition(
domain = str(website.domain),
path = str(p.path),
)
db.add(definition)
for check in p.checks:
for check_key, check_value in check.items():
logger.debug(f"{check_key=}, {check_value=}")
task = models.Task(
definition=definition,
status= "unknown",
max_delta_days = 1, #XXX This should be defined in the config.
)
db.add(task)
db.commit()

View file

@ -0,0 +1,2 @@
from .config import *
from .models import *

72
argos/schemas/config.py Normal file
View file

@ -0,0 +1,72 @@
from pydantic import BaseModel
from enum import StrEnum
from typing import List, Optional, Tuple
import yaml
from pydantic import BaseModel, Field, HttpUrl, validator
from datetime import datetime
from argos.checks import get_names as get_check_names
# This file contains the pydantic schemas. For the database models, check in argos.model.
class Thresholds(BaseModel):
critical: str = Field(alias="critical")
warning: str = Field(alias="warning")
class SSL(BaseModel):
thresholds: Thresholds
WebsiteCheck = dict[StrEnum("Check", get_check_names()), str | int]
class WebsitePath(BaseModel):
path: str
checks: List[WebsiteCheck]
class Website(BaseModel):
domain: HttpUrl
paths: List[WebsitePath]
class Service(BaseModel):
port: int
secrets: List[str]
class Alert(BaseModel):
error: List[str]
warning: List[str]
alert: List[str]
class General(BaseModel):
frequency: str
alerts: Alert
class Config(BaseModel):
general: General
service: Service
ssl: SSL
websites: List[Website]
def validate_config(config: dict):
return Config(**config)
# Method to load YAML file
def from_yaml(file_name):
parsed = load_yaml(file_name)
return validate_config(parsed)
def load_yaml(file_name):
with open(file_name, "r") as stream:
return yaml.safe_load(stream)

15
argos/schemas/models.py Normal file
View file

@ -0,0 +1,15 @@
from pydantic import BaseModel
from datetime import datetime
class Task(BaseModel):
id : int
max_delta_days: int
status: str
response: dict
last_check: datetime | None
selected_by: str | None
selected_at: datetime | None
class Config:
from_attributes = True

32
config.yaml Normal file
View file

@ -0,0 +1,32 @@
general:
frequency: 4h # Run checks every 4 hours.
alerts:
error:
- local
warning:
- local
alert:
- local
service:
port: 8888
# Can be generated using `openssl rand -base64 32`.
secrets:
- "O4kt8Max9/k0EmHaEJ0CGGYbBNFmK8kOZNIoUk3Kjwc"
- "x1T1VZR51pxrv5pQUyzooMG4pMUvHNMhA5y/3cUsYVs="
ssl:
thresholds:
critical: "1d"
warning: "10d"
websites:
- domain: "https://blog.notmyidea.org"
paths:
- path: "/"
checks:
- status-is: 200
- body-contains: "Alexis"
- ssl-certificate-expiration: "on-check"
- path: "/foo"
checks:
- status-is: 400

34
log_conf.yaml Normal file
View file

@ -0,0 +1,34 @@
version: 1
disable_existing_loggers: False
formatters:
default:
# "()": uvicorn.logging.DefaultFormatter
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
access:
# "()": uvicorn.logging.AccessFormatter
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
default:
formatter: default
class: logging.StreamHandler
stream: ext://sys.stderr
access:
formatter: access
class: logging.StreamHandler
stream: ext://sys.stdout
loggers:
uvicorn.error:
level: INFO
handlers:
- default
propagate: no
uvicorn.access:
level: INFO
handlers:
- access
propagate: no
root:
level: DEBUG
handlers:
- default
propagate: no