mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 23:00:17 +00:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05b46cbe34 | |||
| c045586997 | |||
| 8f0707f697 | |||
| 36929b265c | |||
| 734ba64965 | |||
| 148e6742df | |||
| bcb7e8f4f3 | |||
| f678112099 | |||
| 60b0c5f256 | |||
| c8627939de | |||
| 9144f0158a | |||
| d541aca80f | |||
| c73b2b8d34 | |||
| e2493b489d | |||
| 8dee28ac7c | |||
| cdd3885a0c | |||
| 1a28d528d0 | |||
| 3ba12b8cee | |||
| 5a29ab6917 | |||
| 694144a0c8 | |||
| 8bed8e8741 | |||
| a81a348bce | |||
| fd9e8c5cbc | |||
| 8030b1919d | |||
| 72c789fdd7 | |||
| 1113a9aa0d | |||
| a5532614a2 | |||
| 122023fb70 | |||
| b8fa923ec9 | |||
| ae06b3e01a | |||
| 5599ec2809 | |||
| e795cbddb6 | |||
| 0cb087c37b | |||
| 983cbcc711 | |||
| 6d154b0c78 | |||
| f3f36e28c4 | |||
| fdf4797726 | |||
| 67d8a3be98 | |||
| 4001a60f6c | |||
| d94db41271 | |||
| 8abb78bb58 | |||
| a80db99aa3 | |||
| 69a300f21a | |||
| 1b024b8092 | |||
| a622689597 | |||
| 9943e66c49 | |||
| 7233c08281 | |||
| 0845d92fda | |||
| 1cc02e5a83 | |||
| aa4cd7a144 | |||
| b42ae0dfd7 |
@@ -0,0 +1 @@
|
||||
include LICENSE
|
||||
Generated
+109
-93
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "7bbe1f0addd73250027de73d6fb749aa2be3149af9744b107820c5e10498428e"
|
||||
"sha256": "c0cbfe79ef8c8aa085ee976408a6b934cda63343b8951502b0cc4f0dc3453a3b"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -32,10 +32,10 @@
|
||||
},
|
||||
"apispec": {
|
||||
"hashes": [
|
||||
"sha256:50b1cb8f0dc12db00a53e748b27ae601efdc210f1cb4358729173337b2e47354",
|
||||
"sha256:648934f67aefa386cdde5d1d38ceb1c9fe9157c59824a6fb5499409a70dabab4"
|
||||
"sha256:8072aaba54cb430787c3662512d5c9fe521eae1ec0b6d7d05b129814b6b48f69",
|
||||
"sha256:93a6046bf692e8e4398101d447fffcf148b9dbed66d886073e05b491cd6835fd"
|
||||
],
|
||||
"version": "==1.0.0b5"
|
||||
"version": "==1.0.0b6"
|
||||
},
|
||||
"apistar": {
|
||||
"hashes": [
|
||||
@@ -59,10 +59,10 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
|
||||
"sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
|
||||
],
|
||||
"version": "==2018.10.15"
|
||||
"version": "==2018.11.29"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -117,12 +117,18 @@
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"httptools": {
|
||||
"hashes": [
|
||||
"sha256:04c7703bbef0e8ca28b09811547352b8c7c20549eab70dc24e536bb24fd2b7c5"
|
||||
],
|
||||
"version": "==0.0.11"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
||||
],
|
||||
"version": "==2.7"
|
||||
"version": "==2.8"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
@@ -173,10 +179,10 @@
|
||||
},
|
||||
"marshmallow": {
|
||||
"hashes": [
|
||||
"sha256:0a96d88418c4e7c50a39a734c4ed3d2a991a37e6b7a8970dbbdb8ccb7f08ecb0",
|
||||
"sha256:5a65e5c7e9b4e050c989e09d7353eeb91d313d39dfcfa6540aa27f39bfb00b4e"
|
||||
"sha256:7adba78acbce1a812185ab8139d2c80223387d751f8c558d53eceb8aecf7cae5",
|
||||
"sha256:9aa50624253e654ae97a22854e37287042911c15fb23932be357e56df33c2d51"
|
||||
],
|
||||
"version": "==3.0.0b20"
|
||||
"version": "==3.0.0rc1"
|
||||
},
|
||||
"parse": {
|
||||
"hashes": [
|
||||
@@ -209,10 +215,10 @@
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c",
|
||||
"sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279"
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
],
|
||||
"version": "==2.20.0"
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
@@ -227,10 +233,10 @@
|
||||
},
|
||||
"rfc3986": {
|
||||
"hashes": [
|
||||
"sha256:632b8fcd2ac37f24334316227f909be4f9d0738cbf409404cff6fa5f69a24093",
|
||||
"sha256:8458571c4c57e1cf23593ad860bb601b6a604df6217f829c2bc70dc4b5af941b"
|
||||
"sha256:5ad82677b02b88c8d24f6511b4ee9baa5e7da675599b479fbbc5c9c578b5b737",
|
||||
"sha256:bc3ae4b7cd88a99eff2d3900fcb858d44562fd7f273fc07aeef568b9bb6fc4e1"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"rx": {
|
||||
"hashes": [
|
||||
@@ -241,16 +247,17 @@
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
"version": "==1.12.0"
|
||||
},
|
||||
"starlette": {
|
||||
"hashes": [
|
||||
"sha256:418f1f333529f9b9d5a7bffdaef7df43623b648b5c088ae5be1301c112435641"
|
||||
"sha256:01f04283b49a8cb0c8921baa90dbafe47e953f0a265f6ebb38176038e4bd9bf8"
|
||||
],
|
||||
"version": "==0.7.4"
|
||||
"index": "pypi",
|
||||
"version": "==0.9.9"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
@@ -261,9 +268,24 @@
|
||||
},
|
||||
"uvicorn": {
|
||||
"hashes": [
|
||||
"sha256:38ae2c2d6438438aed08999bb9f7fb0bb12ac99aa9831b30a6045aab88f2cec1"
|
||||
"sha256:9c7b384046305982c658d812de862d31c95e7e1c19dc4f0f432d060d921c968a"
|
||||
],
|
||||
"version": "==0.3.20"
|
||||
"version": "==0.3.23"
|
||||
},
|
||||
"uvloop": {
|
||||
"hashes": [
|
||||
"sha256:0e4ed2bd0e207bc284c3dfe3aafc9e9c96184f78a0f4881f8d5f9ed82eb08ef4",
|
||||
"sha256:145931364fa88c9be5e7960729678677ea8d205ceebff3fbf0751e3463907f10",
|
||||
"sha256:347785a64715f5aa361e01d9414be78c61218fc96fe137d554831c555c3bfe15",
|
||||
"sha256:40b11baef9d36d92a786ab87c59164df8ca49945b0eb6bfcbdd3985c86864d39",
|
||||
"sha256:63b6d876f5b7c1f1e1a31b950bb6eabab9b2490c0ba6df06ecaa86c7dac2dbe6",
|
||||
"sha256:85a63f5b485c756b0390800579b4f22cb3a279795bf52e7698942980fb993793",
|
||||
"sha256:85ce7aed6481f078c4157e7049bc02b13abdaa3f1adc814e234b6262fab3c808",
|
||||
"sha256:975a0b29dfd378493b8be47a0599ea9f284ca9e39b4532ab280beaf7cf50d00f",
|
||||
"sha256:dfe83e6bb90892b0c2440b8e425f83b31c9f23195dd189bd59b2fb3fb12a7080",
|
||||
"sha256:ea97302d8fa9d7b6fb1dd079774edcc581ebd8561e5ea71e1fd95c803904d38a"
|
||||
],
|
||||
"version": "==0.12.0rc1"
|
||||
},
|
||||
"websockets": {
|
||||
"hashes": [
|
||||
@@ -293,10 +315,10 @@
|
||||
},
|
||||
"whitenoise": {
|
||||
"hashes": [
|
||||
"sha256:133a92ff0ab8fb9509f77d4f7d0de493eca19c6fea973f4195d4184f888f2e02",
|
||||
"sha256:32b57d193478908a48acb66bf73e7a3c18679263e3e64bfebcfac1144a430039"
|
||||
"sha256:118ab3e5f815d380171b100b05b76de2a07612f422368a201a9ffdeefb2251c1",
|
||||
"sha256:42133ddd5229eeb6a0c9899496bdbe56c292394bf8666da77deeb27454c0456a"
|
||||
],
|
||||
"version": "==4.1"
|
||||
"version": "==4.1.2"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
@@ -352,10 +374,10 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
|
||||
"sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
|
||||
],
|
||||
"version": "==2018.10.15"
|
||||
"version": "==2018.11.29"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -371,45 +393,39 @@
|
||||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:a3d89af5db9e9806a779a50296b5fdb466e281147c2c235e8225ecc6dbf7bbf3",
|
||||
"sha256:c9b54bebe91a6a803e0772c8561d53f2926bfeb17cd141fbabcb08424086595c"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==0.4.0"
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:043d55226aec1d2baf4b2fcab5c204561ccf184a388096f41e396c1c092aff38",
|
||||
"sha256:10bfd0b80b01d0684f968abbe1186bc19962e07b4b7601bb43b175b617cf689d",
|
||||
"sha256:17e59864f19b3233032edb0566f26c25cc7f599503fb34d2645b5ce1fd6c2c3c",
|
||||
"sha256:2105ee183c51fed27e2b6801029b3903f5c2774c78e3f53bd920ca468d0f5679",
|
||||
"sha256:236505d15af6c7b7bfe2a9485db4b2bdea21d9239351483326184314418c79a8",
|
||||
"sha256:237284425271db4f30d458b355decf388ab20b05278bdf8dc9a65de0973726c6",
|
||||
"sha256:26d8eea4c840b73c61a1081d68bceb57b21a2d4f7afda6cac8ac38cb05226b00",
|
||||
"sha256:39a3740f7721155f4269aedf67b211101c07bd2111b334dfd69b807156ab15d9",
|
||||
"sha256:4bd0c42db8efc8a60965769796d43a5570906a870bc819f7388860aa72779d1b",
|
||||
"sha256:4dcddadea47ac30b696956bd18365cd3a86724821656601151e263b86d34798f",
|
||||
"sha256:51ea341289ac4456db946a25bd644f5635e5ae3793df262813cde875887d25c8",
|
||||
"sha256:5415cafb082dad78935b3045c2e5d8907f436d15ad24c3fdb8e1839e084e4961",
|
||||
"sha256:5631f1983074b33c35dbb84607f337b9d7e9808116d7f0f2cb7b9d6d4381d50e",
|
||||
"sha256:5e9249bc361cd22565fd98590a53fd25a3dd666b74791ed7237fa99de938bbed",
|
||||
"sha256:6a48746154f1331f28ef9e889c625b5b15a36cb86dd8021b4bdd1180a2186aa5",
|
||||
"sha256:71d376dbac64855ed693bc1ca121794570fe603e8783cdfa304ec6825d4e768f",
|
||||
"sha256:749ebd8a615337747592bd1523dfc4af7199b2bf6403b55f96c728668aeff91f",
|
||||
"sha256:8ec528b585b95234e9c0c31dcd0a89152d8ed82b4567aa62dbcb3e9a0600deee",
|
||||
"sha256:a1a9ccd879811437ca0307c914f136d6edb85bd0470e6d4966c6397927bcabd9",
|
||||
"sha256:abd956c334752776230b779537d911a5a12fcb69d8fd3fe332ae63a140301ae6",
|
||||
"sha256:ad18f836017f2e8881145795f483636564807aaed54223459915a0d4735300cf",
|
||||
"sha256:b07ac0b1533298ddbc54c9bf3464664895f22899fec027b8d6c8d3ac59023283",
|
||||
"sha256:d9385f1445e30e8e42b75a36a7899ea1fd0f5784233a626625d70f9b087de404",
|
||||
"sha256:db2d1fcd32dbeeb914b2660af1838e9c178b75173f95fd221b1f9410b5d3ef1d",
|
||||
"sha256:e1dec211147f1fd7cb7a0f9a96aeeca467a5af02d38911307b3b8c2324f9917e",
|
||||
"sha256:e96dffc1fa57bb8c1c238f3d989341a97302492d09cb11f77df031112621c35c",
|
||||
"sha256:ed4d97eb0ecdee29d0748acd84e6380729f78ce5ba0c7fe3401801634c25a1c5"
|
||||
"sha256:029c69deaeeeae1b15bc6c59f0ffa28aa8473721c614a23f2c2976dec245cd12",
|
||||
"sha256:02abbbebc6e9d5abe13cd28b5e963dedb6ffb51c146c916d17b18f141acd9947",
|
||||
"sha256:1bbfe5b82a3921d285e999c6d256c1e16b31c554c29da62d326f86c173d30337",
|
||||
"sha256:210c02f923df33a8d0e461c86fdcbbb17228ff4f6d92609fc06370a98d283c2d",
|
||||
"sha256:2d0807ba935f540d20b49d5bf1c0237b90ce81e133402feda906e540003f2f7a",
|
||||
"sha256:35d7a013874a7c927ce997350d314144ffc5465faf787bb4e46e6c4f381ef562",
|
||||
"sha256:3636f9d0dcb01aed4180ef2e57a4e34bb4cac3ecd203c2a23db8526d86ab2fb4",
|
||||
"sha256:42f4be770af2455a75e4640f033a82c62f3fb0d7a074123266e143269d7010ef",
|
||||
"sha256:48440b25ba6cda72d4c638f3a9efa827b5b87b489c96ab5f4ff597d976413156",
|
||||
"sha256:4dac8dfd1acf6a3ac657475dfdc66c621f291b1b7422a939cc33c13ac5356473",
|
||||
"sha256:4e8474771c69c2991d5eab65764289a7dd450bbea050bc0ebb42b678d8222b42",
|
||||
"sha256:551f10ddfeff56a1325e5a34eff304c5892aa981fd810babb98bfee77ee2fb17",
|
||||
"sha256:5b104982f1809c1577912519eb249f17d9d7e66304ad026666cb60a5ef73309c",
|
||||
"sha256:5c62aef73dfc87bfcca32cee149a1a7a602bc74bac72223236b0023543511c88",
|
||||
"sha256:633151f8d1ad9467b9f7e90854a7f46ed8f2919e8bc7d98d737833e8938fc081",
|
||||
"sha256:772207b9e2d5bf3f9d283b88915723e4e92d9a62c83f44ec92b9bd0cd685541b",
|
||||
"sha256:7d5e02f647cd727afc2659ec14d4d1cc0508c47e6cfb07aea33d7aa9ca94d288",
|
||||
"sha256:a9798a4111abb0f94584000ba2a2c74841f2cfe5f9254709756367aabbae0541",
|
||||
"sha256:b38ea741ab9e35bfa7015c93c93bbd6a1623428f97a67083fc8ebd366238b91f",
|
||||
"sha256:b6a5478c904236543c0347db8a05fac6fc0bd574c870e7970faa88e1d9890044",
|
||||
"sha256:c6248bfc1de36a3844685a2e10ba17c18119ba6252547f921062a323fb31bff1",
|
||||
"sha256:c705ab445936457359b1424ef25ccc0098b0491b26064677c39f1d14a539f056",
|
||||
"sha256:d95a363d663ceee647291131dbd213af258df24f41350246842481ec3709bd33",
|
||||
"sha256:e27265eb80cdc5dab55a40ef6f890e04ecc618649ad3da5265f128b141f93f78",
|
||||
"sha256:ebc276c9cb5d917bd2ae959f84ffc279acafa9c9b50b0fa436ebb70bbe2166ea",
|
||||
"sha256:f4d229866d030863d0fe3bf297d6d11e6133ca15bbb41ed2534a8b9a3d6bd061",
|
||||
"sha256:f95675bd88b51474d4fe5165f3266f419ce754ffadfb97f10323931fa9ac95e5",
|
||||
"sha256:f95bc54fb6d61b9f9ff09c4ae8ff6a3f5edc937cda3ca36fc937302a7c152bf1",
|
||||
"sha256:fd0f6be53de40683584e5331c341e65a679dbe5ec489a0697cec7c2ef1a48cda"
|
||||
],
|
||||
"version": "==5.0a3"
|
||||
"version": "==5.0a4"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
@@ -437,10 +453,10 @@
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
||||
],
|
||||
"version": "==2.7"
|
||||
"version": "==2.8"
|
||||
},
|
||||
"imagesize": {
|
||||
"hashes": [
|
||||
@@ -498,10 +514,10 @@
|
||||
},
|
||||
"marshmallow": {
|
||||
"hashes": [
|
||||
"sha256:0a96d88418c4e7c50a39a734c4ed3d2a991a37e6b7a8970dbbdb8ccb7f08ecb0",
|
||||
"sha256:5a65e5c7e9b4e050c989e09d7353eeb91d313d39dfcfa6540aa27f39bfb00b4e"
|
||||
"sha256:7adba78acbce1a812185ab8139d2c80223387d751f8c558d53eceb8aecf7cae5",
|
||||
"sha256:9aa50624253e654ae97a22854e37287042911c15fb23932be357e56df33c2d51"
|
||||
],
|
||||
"version": "==3.0.0b20"
|
||||
"version": "==3.0.0rc1"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
@@ -512,11 +528,11 @@
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
|
||||
"sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
|
||||
"sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
|
||||
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
|
||||
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
|
||||
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
@@ -562,10 +578,10 @@
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
|
||||
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
|
||||
"sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
|
||||
"sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
@@ -576,11 +592,11 @@
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:630ff1dbe04f469ee78faa5660f712e58b953da7df22ea5d828c9012e134da43",
|
||||
"sha256:a2b5232735dd0b736cbea9c0f09e5070d78fcaba2823a4f6f09d9a81bd19415c"
|
||||
"sha256:f689bf2fc18c4585403348dd56f47d87780bf217c53ed9ae7a3e2d7faa45f8e9",
|
||||
"sha256:f812ea39a0153566be53d88f8de94839db1e8a05352ed8a49525d7d7f37861e9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.10.0"
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"pytest-cov": {
|
||||
"hashes": [
|
||||
@@ -606,10 +622,10 @@
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c",
|
||||
"sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279"
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
],
|
||||
"version": "==2.20.0"
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
@@ -620,10 +636,10 @@
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
"version": "==1.12.0"
|
||||
},
|
||||
"snowballstemmer": {
|
||||
"hashes": [
|
||||
@@ -634,11 +650,11 @@
|
||||
},
|
||||
"sphinx": {
|
||||
"hashes": [
|
||||
"sha256:652eb8c566f18823a022bb4b6dbc868d366df332a11a0226b5bc3a798a479f17",
|
||||
"sha256:d222626d8356de702431e813a05c68a35967e3d66c6cd1c2c89539bb179a7464"
|
||||
"sha256:429e3172466df289f0f742471d7e30ba3ee11f3b5aecd9a840480d03f14bcfe5",
|
||||
"sha256:c4cb17ba44acffae3d3209646b6baec1e215cad3065e852c68cc569d4df1b9f8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.8.1"
|
||||
"version": "==1.8.3"
|
||||
},
|
||||
"sphinxcontrib-websupport": {
|
||||
"hashes": [
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
[](https://pypi.org/project/responder/)
|
||||
[](https://github.com/kennethreitz/responder/graphs/contributors)
|
||||
|
||||
[](http://python-responder.org/)
|
||||
[](https://python-responder.org/)
|
||||
|
||||
|
||||
Powered by [Starlette](https://www.starlette.io/). That `async` declaration is optional. [View documentation](http://python-responder.org).
|
||||
Powered by [Starlette](https://www.starlette.io/). That `async` declaration is optional. [View documentation](https://python-responder.org).
|
||||
|
||||
This gets you a ASGI app, with a production static files server pre-installed, jinja2 templating (without additional imports), and a production webserver based on uvloop, serving up requests with gzip compression automatically.
|
||||
|
||||
@@ -26,7 +26,7 @@ This gets you a ASGI app, with a production static files server pre-installed, j
|
||||
|
||||
## More Examples
|
||||
|
||||
See [the documentation's feature tour](http://python-responder.org/en/latest/tour.html) for more details on features available in Responder.
|
||||
See [the documentation's feature tour](https://python-responder.org/en/latest/tour.html) for more details on features available in Responder.
|
||||
|
||||
|
||||
# Installing Responder
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
.class em,
|
||||
.descname,
|
||||
.method em {
|
||||
font-family: "Operator Mono SSm A", "Operator Mono SSm B" !important;
|
||||
font-family: "Operator Mono SSm A", "Operator Mono SSm B", monospace !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ Features
|
||||
- A pleasant API, with a single import statement.
|
||||
- Class-based views without inheritance.
|
||||
- ASGI framework, the future of Python web services.
|
||||
- WebSocket support!
|
||||
- The ability to mount any ASGI / WSGI app at a subroute.
|
||||
- *f-string syntax* route declaration.
|
||||
- Mutable response object, passed into each view. No need to return anything.
|
||||
@@ -121,13 +122,13 @@ Ideas
|
||||
-----
|
||||
|
||||
- Flask-style route expression, with new capabilities -- all while using Python 3.6+'s new f-string syntax.
|
||||
- I love Falcon's "every request and response is passed into to each view and mutated" methodology, especially ``response.media``, and have used it here. In addition to supporting JSON, I have decided to support YAML as well, as Kubernetes is slowly taking over the world, and it uses YAML for all the things. Content-negotiation and all that.
|
||||
- I love Falcon's "every request and response is passed into each view and mutated" methodology, especially ``response.media``, and have used it here. In addition to supporting JSON, I have decided to support YAML as well, as Kubernetes is slowly taking over the world, and it uses YAML for all the things. Content-negotiation and all that.
|
||||
- **A built in testing client that uses the actual Requests you know and love**.
|
||||
- The ability to mount other WSGI apps easily.
|
||||
- Automatic gzipped-responses.
|
||||
- In addition to Falcon's ``on_get``, ``on_post``, etc methods, Responder features an ``on_request`` method, which gets called on every type of request, much like Requests.
|
||||
- A production static files server is built-in.
|
||||
- Uvicorn built-in as a production web server. I would have chosen Gunicorn, but it doesn't run on Windows. Plus, Uvicorn serves well to protect against slowloris attacks, making nginx unneccessary in production.
|
||||
- Uvicorn built-in as a production web server. I would have chosen Gunicorn, but it doesn't run on Windows. Plus, Uvicorn serves well to protect against slowloris attacks, making nginx unnecessary in production.
|
||||
- GraphQL support, via Graphene. The goal here is to have any GraphQL query exposable at any route, magically.
|
||||
|
||||
|
||||
|
||||
+31
-1
@@ -52,6 +52,8 @@ Serve a GraphQL API::
|
||||
|
||||
Visiting the endpoint will render a *GraphiQL* instance, in the browser.
|
||||
|
||||
You can make use of Responder's Request and Response objects in your GraphQL resolvers through ``info.context['request']`` and ``info.context['response']``.
|
||||
|
||||
|
||||
OpenAPI Schema Support
|
||||
----------------------
|
||||
@@ -81,7 +83,7 @@ Responder comes with built-in support for OpenAPI / marshmallow::
|
||||
schema:
|
||||
$ref = "#/components/schemas/Pet"
|
||||
"""
|
||||
resp.media = PetSchema().dump({"name": "little orange"}).data
|
||||
resp.media = PetSchema().dump({"name": "little orange"})
|
||||
|
||||
|
||||
::
|
||||
@@ -184,6 +186,34 @@ If you'd like a view to be executed before every request, simply do the followin
|
||||
|
||||
Now all requests to your HTTP Service will include an ``X-Pizza`` header.
|
||||
|
||||
WebSocket Support
|
||||
-----------------
|
||||
|
||||
Responder supports WebSockets::
|
||||
|
||||
@api.route('/ws', websocket=True)
|
||||
async def websocket(ws):
|
||||
await ws.accept()
|
||||
while True:
|
||||
name = await ws.receive_text()
|
||||
await ws.send_text(f"Hello {name}!")
|
||||
await ws.close()
|
||||
|
||||
Accepting the connection::
|
||||
|
||||
await websocket.accept()
|
||||
|
||||
Sending and receiving data::
|
||||
|
||||
await websocket.send_{format}(data)
|
||||
await websocket.receive_{format}(data)
|
||||
|
||||
Supported formats: ``text``, ``json``, ``bytes``.
|
||||
|
||||
Closing the connection::
|
||||
|
||||
await websocket.close()
|
||||
|
||||
Using Requests Test Client
|
||||
--------------------------
|
||||
|
||||
|
||||
+54
-20
@@ -13,11 +13,11 @@ import yaml
|
||||
from apispec import APISpec, yaml_utils
|
||||
from apispec.ext.marshmallow import MarshmallowPlugin
|
||||
from asgiref.wsgi import WsgiToAsgi
|
||||
from starlette.exceptions import ExceptionMiddleware
|
||||
from starlette.lifespan import LifespanHandler
|
||||
from starlette.middleware.errors import ServerErrorMiddleware
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from starlette.middleware.gzip import GZipMiddleware
|
||||
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
|
||||
from starlette.middleware.lifespan import LifespanMiddleware
|
||||
from starlette.middleware.trustedhost import TrustedHostMiddleware
|
||||
from starlette.routing import Router
|
||||
from starlette.staticfiles import StaticFiles
|
||||
@@ -90,6 +90,7 @@ class API:
|
||||
self.hsts_enabled = enable_hsts
|
||||
self.cors = cors
|
||||
self.cors_params = cors_params
|
||||
self.debug = debug
|
||||
|
||||
if not allowed_hosts:
|
||||
# if not debug:
|
||||
@@ -135,11 +136,11 @@ class API:
|
||||
|
||||
self.add_middleware(TrustedHostMiddleware, allowed_hosts=self.allowed_hosts)
|
||||
|
||||
self.lifespan_handler = LifespanHandler()
|
||||
self.lifespan_handler = LifespanMiddleware(self.app)
|
||||
|
||||
if self.cors:
|
||||
self.add_middleware(CORSMiddleware, **self.cors_params)
|
||||
self.add_middleware(ExceptionMiddleware, debug=debug)
|
||||
self.add_middleware(ServerErrorMiddleware, debug=debug)
|
||||
|
||||
# Jinja enviroment
|
||||
self.jinja_env = jinja2.Environment(
|
||||
@@ -196,6 +197,7 @@ class API:
|
||||
self.app = middleware_cls(self.app, **middleware_config)
|
||||
|
||||
def __call__(self, scope):
|
||||
|
||||
if scope["type"] == "lifespan":
|
||||
return self.lifespan_handler(scope)
|
||||
|
||||
@@ -220,14 +222,41 @@ class API:
|
||||
async def asgi(receive, send):
|
||||
nonlocal scope, self
|
||||
|
||||
req = models.Request(scope, receive=receive, api=self)
|
||||
resp = await self._dispatch_request(
|
||||
req, scope=scope, send=send, receive=receive
|
||||
)
|
||||
await resp(receive, send)
|
||||
if scope["type"] == "lifespan":
|
||||
return self.lifespan_handler(scope)
|
||||
elif scope["type"] == "websocket":
|
||||
ws = WebSocket(scope=scope, receive=receive, send=send)
|
||||
await self._dispatch_ws(ws)
|
||||
else:
|
||||
req = models.Request(scope, receive=receive, api=self)
|
||||
resp = await self._dispatch_request(
|
||||
req, scope=scope, send=send, receive=receive
|
||||
)
|
||||
await resp(receive, send)
|
||||
|
||||
return asgi
|
||||
|
||||
async def _dispatch_ws(self, ws):
|
||||
route = self.path_matches_route(ws.url.path)
|
||||
route = self.routes.get(route)
|
||||
# await self._dispatch(route, ws=ws)
|
||||
try:
|
||||
try:
|
||||
# Run the view.
|
||||
r = self.background(route.endpoint, ws)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "cr_running"):
|
||||
await r
|
||||
except TypeError as e:
|
||||
cont = True
|
||||
except Exception:
|
||||
self.background(
|
||||
self.default_response,
|
||||
websocket=route.uses_websocket,
|
||||
error=True
|
||||
)
|
||||
raise
|
||||
|
||||
def add_schema(self, name, schema, check_existing=True):
|
||||
"""Adds a mashmallow schema to the API specification."""
|
||||
if check_existing:
|
||||
@@ -292,10 +321,7 @@ class API:
|
||||
route = self.path_matches_route(req.url.path)
|
||||
route = self.routes.get(route)
|
||||
if route:
|
||||
if route.uses_websocket:
|
||||
resp = WebSocket(**options)
|
||||
else:
|
||||
resp = models.Response(req=req, formats=self.formats)
|
||||
resp = models.Response(req=req, formats=self.formats)
|
||||
|
||||
for before_request in self.before_requests:
|
||||
await self._execute_route(route=before_request, req=req, resp=resp)
|
||||
@@ -303,8 +329,8 @@ class API:
|
||||
await self._execute_route(route=route, req=req, resp=resp, **options)
|
||||
else:
|
||||
resp = models.Response(req=req, formats=self.formats)
|
||||
self.default_response(req, resp, notfound=True)
|
||||
self.default_response(req, resp)
|
||||
self.default_response(req=req, resp=resp, notfound=True)
|
||||
self.default_response(req=req, resp=resp)
|
||||
|
||||
self._prepare_session(resp)
|
||||
self._prepare_cookies(resp)
|
||||
@@ -315,11 +341,12 @@ class API:
|
||||
|
||||
params = route.incoming_matches(req.url.path)
|
||||
|
||||
cont = True
|
||||
|
||||
if route.is_function:
|
||||
try:
|
||||
try:
|
||||
# Run the view.
|
||||
|
||||
r = self.background(route.endpoint, req, resp, **params)
|
||||
# If it's async, await it.
|
||||
if hasattr(r, "cr_running"):
|
||||
@@ -414,12 +441,17 @@ class API:
|
||||
sorted(self.routes.items(), key=lambda item: item[1]._weight())
|
||||
)
|
||||
|
||||
def default_response(self, req, resp, notfound=False, error=False):
|
||||
def default_response(
|
||||
self, req=None, resp=None, websocket=False, notfound=False, error=False
|
||||
):
|
||||
if websocket:
|
||||
return
|
||||
|
||||
if resp.status_code is None:
|
||||
resp.status_code = 200
|
||||
|
||||
if self.default_endpoint and notfound:
|
||||
self.default_endpoint(req, resp)
|
||||
self.default_endpoint(req=req, resp=resp)
|
||||
else:
|
||||
if notfound:
|
||||
resp.status_code = status_codes.HTTP_404
|
||||
@@ -433,7 +465,7 @@ class API:
|
||||
|
||||
def static_response(self, req, resp):
|
||||
index = (self.static_dir / "index.html").resolve()
|
||||
resp.content = ""
|
||||
resp.content = None
|
||||
if os.path.exists(index):
|
||||
with open(index, "r") as f:
|
||||
resp.text = f.read()
|
||||
@@ -533,7 +565,7 @@ class API:
|
||||
# TODO: Absolute_url
|
||||
"""Given an endpoint, returns a rendered URL for its route.
|
||||
|
||||
:param view: The route endpoint you're searching for.
|
||||
:param endpoint: The route endpoint you're searching for.
|
||||
:param params: Data to pass into the URL generator (for parameterized URLs).
|
||||
"""
|
||||
route_object = self._route_for(endpoint)
|
||||
@@ -628,4 +660,6 @@ class API:
|
||||
spawn()
|
||||
|
||||
def run(self, **kwargs):
|
||||
if 'debug' not in kwargs:
|
||||
kwargs.update({'debug': self.debug})
|
||||
self.serve(**kwargs)
|
||||
|
||||
@@ -3,6 +3,7 @@ import functools
|
||||
import concurrent.futures
|
||||
import multiprocessing
|
||||
import traceback
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
|
||||
|
||||
class BackgroundQueue:
|
||||
@@ -40,6 +41,4 @@ class BackgroundQueue:
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
return await asyncio.ensure_future(func(*args, **kwargs))
|
||||
else:
|
||||
fn = functools.partial(func, *args, **kwargs)
|
||||
loop = asyncio.get_event_loop()
|
||||
return await loop.run_in_executor(None, fn)
|
||||
return await run_in_threadpool(func, *args, **kwargs)
|
||||
|
||||
@@ -48,8 +48,9 @@ class GraphQLView:
|
||||
return
|
||||
|
||||
query, variables, operation_name = await self._resolve_graphql_query(req)
|
||||
context = {"request": req, "response": resp}
|
||||
result = schema.execute(
|
||||
query, variables=variables, operation_name=operation_name
|
||||
query, variables=variables, operation_name=operation_name, context=context
|
||||
)
|
||||
result, status_code = encode_execution_results(
|
||||
[result],
|
||||
|
||||
+14
-6
@@ -1,11 +1,10 @@
|
||||
from urllib.parse import parse_qs
|
||||
import json
|
||||
|
||||
import yaml
|
||||
import json
|
||||
from parse import findall
|
||||
from .models import QueryDict
|
||||
from requests_toolbelt.multipart import decoder
|
||||
|
||||
from .models import QueryDict
|
||||
|
||||
|
||||
async def format_form(r, encode=False):
|
||||
if encode:
|
||||
@@ -38,6 +37,7 @@ async def format_files(r, encode=False):
|
||||
dump = {}
|
||||
for part in decoded.parts:
|
||||
header = part.headers[b"Content-Disposition"].decode("utf-8")
|
||||
mimetype = part.headers.get(b"Content-Type", None)
|
||||
filename = None
|
||||
|
||||
for section in [h.strip() for h in header.split(";")]:
|
||||
@@ -50,9 +50,17 @@ async def format_files(r, encode=False):
|
||||
|
||||
if key == "filename":
|
||||
filename = value
|
||||
elif key == "name":
|
||||
formname = value
|
||||
|
||||
if filename:
|
||||
dump[filename] = part.content
|
||||
if mimetype is None:
|
||||
dump[formname] = part.content
|
||||
else:
|
||||
dump[formname] = {
|
||||
"filename": filename,
|
||||
"content": part.content,
|
||||
"content-type": mimetype.decode("utf-8"),
|
||||
}
|
||||
return dump
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
import re
|
||||
import functools
|
||||
import inspect
|
||||
from parse import parse
|
||||
|
||||
|
||||
@@ -59,7 +60,7 @@ class Route:
|
||||
|
||||
@property
|
||||
def is_class_based(self):
|
||||
return hasattr(self.endpoint, "__class__")
|
||||
return inspect.isclass(self.endpoint)
|
||||
|
||||
@property
|
||||
def is_function(self):
|
||||
|
||||
@@ -70,7 +70,7 @@ class DebCommand(Command):
|
||||
rmtree(os.path.join(here, "deb_dist"))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
self.status(u"Creating debian mainfest…")
|
||||
self.status(u"Creating debian manifest…")
|
||||
os.system(
|
||||
"python setup.py --command-packages=stdeb.command sdist_dsc -z artful --package3=pipenv --depends3=python3-virtualenv-clone"
|
||||
)
|
||||
|
||||
+17
-24
@@ -334,9 +334,7 @@ def test_schema_generation():
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
api = responder.API(
|
||||
title="Web Service",
|
||||
openapi="3.0",
|
||||
allowed_hosts=["testserver", ";"]
|
||||
title="Web Service", openapi="3.0", allowed_hosts=["testserver", ";"]
|
||||
)
|
||||
|
||||
@api.schema("Pet")
|
||||
@@ -372,7 +370,7 @@ def test_documentation():
|
||||
title="Web Service",
|
||||
openapi="3.0",
|
||||
docs_route="/docs",
|
||||
allowed_hosts=["testserver", ";"]
|
||||
allowed_hosts=["testserver", ";"],
|
||||
)
|
||||
|
||||
@api.schema("Pet")
|
||||
@@ -465,28 +463,27 @@ def test_file_uploads(api):
|
||||
async def upload(req, resp):
|
||||
|
||||
files = await req.media("files")
|
||||
files["hello"] = files["hello"].decode("utf-8")
|
||||
resp.media = {"files": files}
|
||||
result = {}
|
||||
result["hello"] = files["hello"]["content"].decode("utf-8")
|
||||
result["not-a-file"] = files["not-a-file"].decode("utf-8")
|
||||
resp.media = {"files": result}
|
||||
|
||||
world = io.StringIO("world")
|
||||
data = {"hello": world}
|
||||
data = {"hello": ("hello.txt", world, "text/plain"), "not-a-file": b"data only"}
|
||||
r = api.requests.post(api.url_for(upload), files=data)
|
||||
assert r.json() == {"files": {"hello": "world"}}
|
||||
assert r.json() == {"files": {"hello": "world", "not-a-file": "data only"}}
|
||||
|
||||
|
||||
def test_500(api):
|
||||
def catcher(request, exc):
|
||||
return PlainTextResponse("Suppressed error", 500)
|
||||
|
||||
api.app.add_exception_handler(ValueError, catcher)
|
||||
|
||||
@api.route("/")
|
||||
def view(req, resp):
|
||||
raise ValueError
|
||||
|
||||
r = api.requests.get(api.url_for(view))
|
||||
dumb_client = responder.api.TestClient(api, base_url="http://;",
|
||||
raise_server_exceptions=False)
|
||||
r = dumb_client.get(api.url_for(view))
|
||||
assert not r.ok
|
||||
assert r.content == b"Suppressed error"
|
||||
assert r.status_code == responder.status_codes.HTTP_500
|
||||
|
||||
|
||||
def test_404(api):
|
||||
@@ -553,24 +550,22 @@ def test_session_thoroughly(api, session):
|
||||
r = session.get(api.url_for(get))
|
||||
assert r.json() == {"session": {"hello": "world"}}
|
||||
|
||||
def test_before_response(api, session):
|
||||
|
||||
def test_before_response(api, session):
|
||||
@api.route("/get")
|
||||
def get(req, resp):
|
||||
resp.media = req.session
|
||||
|
||||
|
||||
@api.route(before_request=True)
|
||||
def before_request(req, resp):
|
||||
resp.headers["x-pizza"] = "1"
|
||||
|
||||
r = session.get(api.url_for(get))
|
||||
assert 'x-pizza' in r.headers
|
||||
assert "x-pizza" in r.headers
|
||||
|
||||
|
||||
def test_allowed_hosts():
|
||||
api = responder.API(
|
||||
allowed_hosts=[";", "tenant.;"]
|
||||
)
|
||||
api = responder.API(allowed_hosts=[";", "tenant.;"])
|
||||
|
||||
@api.route("/")
|
||||
def get(req, resp):
|
||||
@@ -595,9 +590,7 @@ def test_allowed_hosts():
|
||||
r = api.session(base_url="http://unkown_tenant.;").get(api.url_for(get))
|
||||
assert r.status_code == 400
|
||||
|
||||
api = responder.API(
|
||||
allowed_hosts=["*.;"]
|
||||
)
|
||||
api = responder.API(allowed_hosts=["*.;"])
|
||||
|
||||
@api.route("/")
|
||||
def get(req, resp):
|
||||
|
||||
@@ -8,7 +8,7 @@ from responder import status_codes
|
||||
pytest.param(101, True, id="Normal 101"),
|
||||
pytest.param(199, True, id="Not actual status code but within 100"),
|
||||
pytest.param(0, False, id="Zero case (below 100)"),
|
||||
pytest.param(200, False, id="Above 100")
|
||||
pytest.param(200, False, id="Above 100"),
|
||||
],
|
||||
)
|
||||
def test_is_100(status_code, expected):
|
||||
@@ -21,7 +21,7 @@ def test_is_100(status_code, expected):
|
||||
pytest.param(201, True, id="Normal 201"),
|
||||
pytest.param(299, True, id="Not actual status code but within 200"),
|
||||
pytest.param(0, False, id="Zero case (below 200)"),
|
||||
pytest.param(300, False, id="Above 200")
|
||||
pytest.param(300, False, id="Above 200"),
|
||||
],
|
||||
)
|
||||
def test_is_200(status_code, expected):
|
||||
@@ -34,7 +34,7 @@ def test_is_200(status_code, expected):
|
||||
pytest.param(301, True, id="Normal 301"),
|
||||
pytest.param(399, True, id="Not actual status code but within 300"),
|
||||
pytest.param(0, False, id="Zero case (below 300)"),
|
||||
pytest.param(400, False, id="Above 300")
|
||||
pytest.param(400, False, id="Above 300"),
|
||||
],
|
||||
)
|
||||
def test_is_300(status_code, expected):
|
||||
@@ -47,7 +47,7 @@ def test_is_300(status_code, expected):
|
||||
pytest.param(401, True, id="Normal 401"),
|
||||
pytest.param(499, True, id="Not actual status code but within 400"),
|
||||
pytest.param(0, False, id="Zero case (below 400)"),
|
||||
pytest.param(500, False, id="Above 400")
|
||||
pytest.param(500, False, id="Above 400"),
|
||||
],
|
||||
)
|
||||
def test_is_400(status_code, expected):
|
||||
@@ -57,10 +57,10 @@ def test_is_400(status_code, expected):
|
||||
@pytest.mark.parametrize(
|
||||
"status_code, expected",
|
||||
[
|
||||
pytest.param(501, True, id="Normal 401"),
|
||||
pytest.param(599, True, id="Not actual status code but within 400"),
|
||||
pytest.param(0, False, id="Zero case (below 400)"),
|
||||
pytest.param(600, False, id="Above 500")
|
||||
pytest.param(501, True, id="Normal 501"),
|
||||
pytest.param(599, True, id="Not actual status code but within 500"),
|
||||
pytest.param(0, False, id="Zero case (below 500)"),
|
||||
pytest.param(600, False, id="Above 500"),
|
||||
],
|
||||
)
|
||||
def test_is_500(status_code, expected):
|
||||
|
||||
Reference in New Issue
Block a user