diff --git a/Test Notebook.ipynb b/Test Notebook.ipynb index dc27277049..9f70607095 100644 --- a/Test Notebook.ipynb +++ b/Test Notebook.ipynb @@ -29,15 +29,8 @@ "outputs": [], "source": [ "inp = gradio.inputs.ImageUpload(image_width=299, image_height=299)\n", - "out = gradio.outputs.Label(label_names='imagenet1000', max_label_length=8)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ + "out = gradio.outputs.Label(label_names='imagenet1000', max_label_length=8, num_top_classes=5)\n", + "\n", "iface = gradio.Interface(inputs=inp, \n", " outputs=out,\n", " model=model, \n", @@ -54,8 +47,8 @@ "output_type": "stream", "text": [ "NOTE: Gradio is in beta stage, please report all bugs to: a12d@stanford.edu\n", - "Model is running locally at: http://localhost:7860/interface.html\n", - "Model available publicly for 8 hours at: https://efb97fa5.ngrok.io/interface.html\n" + "Model is running locally at: http://localhost:7861/interface.html\n", + "Model available publicly for 8 hours at: http://4d315e61.ngrok.io/interface.html\n" ] }, { @@ -65,50 +58,63 @@ " \n", " " ], "text/plain": [ - "" + "" ] }, "metadata": {}, "output_type": "display_data" }, - { - "data": { - "text/plain": [ - "('http://localhost:7860/interface.html', 'https://efb97fa5.ngrok.io')" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, { "name": "stderr", "output_type": "stream", "text": [ - "127.0.0.1 - - [06/Mar/2019 11:24:00] \"GET /interface.html HTTP/1.1\" 200 -\n", - "127.0.0.1 - - [06/Mar/2019 11:24:00] \"GET /interface.html HTTP/1.1\" 200 -\n", - "127.0.0.1 - - [06/Mar/2019 11:24:00] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", - "127.0.0.1 - - [06/Mar/2019 11:24:00] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dddddddddddddddddddd cleaver,\n", - "dddddddddddddddddddd cleaver,\n" + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /static/css/gradio.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /static/js/image-upload-input.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:01] \"GET /static/js/class-output.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:02] code 404, message File not found\n", + "127.0.0.1 - - [06/Mar/2019 11:55:02] \"GET /favicon.ico HTTP/1.1\" 404 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:08] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/css/style.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/css/gradio.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/js/utils.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/img/logo_inline.png HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/js/image-upload-input.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:09] \"GET /static/js/class-output.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:55:10] code 404, message File not found\n", + "127.0.0.1 - - [06/Mar/2019 11:55:10] \"GET /favicon.ico HTTP/1.1\" 404 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:07] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:07] \"GET /static/css/gradio.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:07] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:07] \"GET /static/js/image-upload-input.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:07] \"GET /static/js/class-output.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:31] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:43] \"GET /interface.html HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/js/utils.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/css/gradio.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/js/all-io.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/css/style.css HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/js/image-upload-input.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/js/class-output.js HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:44] \"GET /static/img/logo_inline.png HTTP/1.1\" 200 -\n", + "127.0.0.1 - - [06/Mar/2019 11:58:45] code 404, message File not found\n", + "127.0.0.1 - - [06/Mar/2019 11:58:45] \"GET /favicon.ico HTTP/1.1\" 404 -\n" ] } ], "source": [ - "iface.launch(inline=True, browser=True, share=True)" + "iface.launch(inline=True, browser=True, share=True);" ] } ], diff --git a/build/lib/gradio/__init__.py b/build/lib/gradio/__init__.py index ee12ab164f..4b898437e3 100644 --- a/build/lib/gradio/__init__.py +++ b/build/lib/gradio/__init__.py @@ -1 +1 @@ -from gradio.interface import Interface # This makes Interface importable as gradio.Interface. +from gradio.interface import Interface # This makes it possible to import `Interface` as `gradio.Interface`. diff --git a/build/lib/gradio/imagenet_class_labels.py b/build/lib/gradio/imagenet_class_labels.py new file mode 100644 index 0000000000..b8ed7a7682 --- /dev/null +++ b/build/lib/gradio/imagenet_class_labels.py @@ -0,0 +1,1000 @@ +NAMES1000 = {0: 'tench, Tinca tinca', + 1: 'goldfish, Carassius auratus', + 2: 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias', + 3: 'tiger shark, Galeocerdo cuvieri', + 4: 'hammerhead, hammerhead shark', + 5: 'electric ray, crampfish, numbfish, torpedo', + 6: 'stingray', + 7: 'cock', + 8: 'hen', + 9: 'ostrich, Struthio camelus', + 10: 'brambling, Fringilla montifringilla', + 11: 'goldfinch, Carduelis carduelis', + 12: 'house finch, linnet, Carpodacus mexicanus', + 13: 'junco, snowbird', + 14: 'indigo bunting, indigo finch, indigo bird, Passerina cyanea', + 15: 'robin, American robin, Turdus migratorius', + 16: 'bulbul', + 17: 'jay', + 18: 'magpie', + 19: 'chickadee', + 20: 'water ouzel, dipper', + 21: 'kite', + 22: 'bald eagle, American eagle, Haliaeetus leucocephalus', + 23: 'vulture', + 24: 'great grey owl, great gray owl, Strix nebulosa', + 25: 'European fire salamander, Salamandra salamandra', + 26: 'common newt, Triturus vulgaris', + 27: 'eft', + 28: 'spotted salamander, Ambystoma maculatum', + 29: 'axolotl, mud puppy, Ambystoma mexicanum', + 30: 'bullfrog, Rana catesbeiana', + 31: 'tree frog, tree-frog', + 32: 'tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui', + 33: 'loggerhead, loggerhead turtle, Caretta caretta', + 34: 'leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea', + 35: 'mud turtle', + 36: 'terrapin', + 37: 'box turtle, box tortoise', + 38: 'banded gecko', + 39: 'common iguana, iguana, Iguana iguana', + 40: 'American chameleon, anole, Anolis carolinensis', + 41: 'whiptail, whiptail lizard', + 42: 'agama', + 43: 'frilled lizard, Chlamydosaurus kingi', + 44: 'alligator lizard', + 45: 'Gila monster, Heloderma suspectum', + 46: 'green lizard, Lacerta viridis', + 47: 'African chameleon, Chamaeleo chamaeleon', + 48: 'Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis', + 49: 'African crocodile, Nile crocodile, Crocodylus niloticus', + 50: 'American alligator, Alligator mississipiensis', + 51: 'triceratops', + 52: 'thunder snake, worm snake, Carphophis amoenus', + 53: 'ringneck snake, ring-necked snake, ring snake', + 54: 'hognose snake, puff adder, sand viper', + 55: 'green snake, grass snake', + 56: 'king snake, kingsnake', + 57: 'garter snake, grass snake', + 58: 'water snake', + 59: 'vine snake', + 60: 'night snake, Hypsiglena torquata', + 61: 'boa constrictor, Constrictor constrictor', + 62: 'rock python, rock snake, Python sebae', + 63: 'Indian cobra, Naja naja', + 64: 'green mamba', + 65: 'sea snake', + 66: 'horned viper, cerastes, sand viper, horned asp, Cerastes cornutus', + 67: 'diamondback, diamondback rattlesnake, Crotalus adamanteus', + 68: 'sidewinder, horned rattlesnake, Crotalus cerastes', + 69: 'trilobite', + 70: 'harvestman, daddy longlegs, Phalangium opilio', + 71: 'scorpion', + 72: 'black and gold garden spider, Argiope aurantia', + 73: 'barn spider, Araneus cavaticus', + 74: 'garden spider, Aranea diademata', + 75: 'black widow, Latrodectus mactans', + 76: 'tarantula', + 77: 'wolf spider, hunting spider', + 78: 'tick', + 79: 'centipede', + 80: 'black grouse', + 81: 'ptarmigan', + 82: 'ruffed grouse, partridge, Bonasa umbellus', + 83: 'prairie chicken, prairie grouse, prairie fowl', + 84: 'peacock', + 85: 'quail', + 86: 'partridge', + 87: 'African grey, African gray, Psittacus erithacus', + 88: 'macaw', + 89: 'sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita', + 90: 'lorikeet', + 91: 'coucal', + 92: 'bee eater', + 93: 'hornbill', + 94: 'hummingbird', + 95: 'jacamar', + 96: 'toucan', + 97: 'drake', + 98: 'red-breasted merganser, Mergus serrator', + 99: 'goose', + 100: 'black swan, Cygnus atratus', + 101: 'tusker', + 102: 'echidna, spiny anteater, anteater', + 103: 'platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus', + 104: 'wallaby, brush kangaroo', + 105: 'koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus', + 106: 'wombat', + 107: 'jellyfish', + 108: 'sea anemone, anemone', + 109: 'brain coral', + 110: 'flatworm, platyhelminth', + 111: 'nematode, nematode worm, roundworm', + 112: 'conch', + 113: 'snail', + 114: 'slug', + 115: 'sea slug, nudibranch', + 116: 'chiton, coat-of-mail shell, sea cradle, polyplacophore', + 117: 'chambered nautilus, pearly nautilus, nautilus', + 118: 'Dungeness crab, Cancer magister', + 119: 'rock crab, Cancer irroratus', + 120: 'fiddler crab', + 121: 'king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica', + 122: 'American lobster, Northern lobster, Maine lobster, Homarus americanus', + 123: 'spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish', + 124: 'crayfish, crawfish, crawdad, crawdaddy', + 125: 'hermit crab', + 126: 'isopod', + 127: 'white stork, Ciconia ciconia', + 128: 'black stork, Ciconia nigra', + 129: 'spoonbill', + 130: 'flamingo', + 131: 'little blue heron, Egretta caerulea', + 132: 'American egret, great white heron, Egretta albus', + 133: 'bittern', + 134: 'crane', + 135: 'limpkin, Aramus pictus', + 136: 'European gallinule, Porphyrio porphyrio', + 137: 'American coot, marsh hen, mud hen, water hen, Fulica americana', + 138: 'bustard', + 139: 'ruddy turnstone, Arenaria interpres', + 140: 'red-backed sandpiper, dunlin, Erolia alpina', + 141: 'redshank, Tringa totanus', + 142: 'dowitcher', + 143: 'oystercatcher, oyster catcher', + 144: 'pelican', + 145: 'king penguin, Aptenodytes patagonica', + 146: 'albatross, mollymawk', + 147: 'grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus', + 148: 'killer whale, killer, orca, grampus, sea wolf, Orcinus orca', + 149: 'dugong, Dugong dugon', + 150: 'sea lion', + 151: 'Chihuahua', + 152: 'Japanese spaniel', + 153: 'Maltese dog, Maltese terrier, Maltese', + 154: 'Pekinese, Pekingese, Peke', + 155: 'Shih-Tzu', + 156: 'Blenheim spaniel', + 157: 'papillon', + 158: 'toy terrier', + 159: 'Rhodesian ridgeback', + 160: 'Afghan hound, Afghan', + 161: 'basset, basset hound', + 162: 'beagle', + 163: 'bloodhound, sleuthhound', + 164: 'bluetick', + 165: 'black-and-tan coonhound', + 166: 'Walker hound, Walker foxhound', + 167: 'English foxhound', + 168: 'redbone', + 169: 'borzoi, Russian wolfhound', + 170: 'Irish wolfhound', + 171: 'Italian greyhound', + 172: 'whippet', + 173: 'Ibizan hound, Ibizan Podenco', + 174: 'Norwegian elkhound, elkhound', + 175: 'otterhound, otter hound', + 176: 'Saluki, gazelle hound', + 177: 'Scottish deerhound, deerhound', + 178: 'Weimaraner', + 179: 'Staffordshire bullterrier, Staffordshire bull terrier', + 180: 'American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier', + 181: 'Bedlington terrier', + 182: 'Border terrier', + 183: 'Kerry blue terrier', + 184: 'Irish terrier', + 185: 'Norfolk terrier', + 186: 'Norwich terrier', + 187: 'Yorkshire terrier', + 188: 'wire-haired fox terrier', + 189: 'Lakeland terrier', + 190: 'Sealyham terrier, Sealyham', + 191: 'Airedale, Airedale terrier', + 192: 'cairn, cairn terrier', + 193: 'Australian terrier', + 194: 'Dandie Dinmont, Dandie Dinmont terrier', + 195: 'Boston bull, Boston terrier', + 196: 'miniature schnauzer', + 197: 'giant schnauzer', + 198: 'standard schnauzer', + 199: 'Scotch terrier, Scottish terrier, Scottie', + 200: 'Tibetan terrier, chrysanthemum dog', + 201: 'silky terrier, Sydney silky', + 202: 'soft-coated wheaten terrier', + 203: 'West Highland white terrier', + 204: 'Lhasa, Lhasa apso', + 205: 'flat-coated retriever', + 206: 'curly-coated retriever', + 207: 'golden retriever', + 208: 'Labrador retriever', + 209: 'Chesapeake Bay retriever', + 210: 'German short-haired pointer', + 211: 'vizsla, Hungarian pointer', + 212: 'English setter', + 213: 'Irish setter, red setter', + 214: 'Gordon setter', + 215: 'Brittany spaniel', + 216: 'clumber, clumber spaniel', + 217: 'English springer, English springer spaniel', + 218: 'Welsh springer spaniel', + 219: 'cocker spaniel, English cocker spaniel, cocker', + 220: 'Sussex spaniel', + 221: 'Irish water spaniel', + 222: 'kuvasz', + 223: 'schipperke', + 224: 'groenendael', + 225: 'malinois', + 226: 'briard', + 227: 'kelpie', + 228: 'komondor', + 229: 'Old English sheepdog, bobtail', + 230: 'Shetland sheepdog, Shetland sheep dog, Shetland', + 231: 'collie', + 232: 'Border collie', + 233: 'Bouvier des Flandres, Bouviers des Flandres', + 234: 'Rottweiler', + 235: 'German shepherd, German shepherd dog, German police dog, alsatian', + 236: 'Doberman, Doberman pinscher', + 237: 'miniature pinscher', + 238: 'Greater Swiss Mountain dog', + 239: 'Bernese mountain dog', + 240: 'Appenzeller', + 241: 'EntleBucher', + 242: 'boxer', + 243: 'bull mastiff', + 244: 'Tibetan mastiff', + 245: 'French bulldog', + 246: 'Great Dane', + 247: 'Saint Bernard, St Bernard', + 248: 'Eskimo dog, husky', + 249: 'malamute, malemute, Alaskan malamute', + 250: 'Siberian husky', + 251: 'dalmatian, coach dog, carriage dog', + 252: 'affenpinscher, monkey pinscher, monkey dog', + 253: 'basenji', + 254: 'pug, pug-dog', + 255: 'Leonberg', + 256: 'Newfoundland, Newfoundland dog', + 257: 'Great Pyrenees', + 258: 'Samoyed, Samoyede', + 259: 'Pomeranian', + 260: 'chow, chow chow', + 261: 'keeshond', + 262: 'Brabancon griffon', + 263: 'Pembroke, Pembroke Welsh corgi', + 264: 'Cardigan, Cardigan Welsh corgi', + 265: 'toy poodle', + 266: 'miniature poodle', + 267: 'standard poodle', + 268: 'Mexican hairless', + 269: 'timber wolf, grey wolf, gray wolf, Canis lupus', + 270: 'white wolf, Arctic wolf, Canis lupus tundrarum', + 271: 'red wolf, maned wolf, Canis rufus, Canis niger', + 272: 'coyote, prairie wolf, brush wolf, Canis latrans', + 273: 'dingo, warrigal, warragal, Canis dingo', + 274: 'dhole, Cuon alpinus', + 275: 'African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus', + 276: 'hyena, hyaena', + 277: 'red fox, Vulpes vulpes', + 278: 'kit fox, Vulpes macrotis', + 279: 'Arctic fox, white fox, Alopex lagopus', + 280: 'grey fox, gray fox, Urocyon cinereoargenteus', + 281: 'tabby, tabby cat', + 282: 'tiger cat', + 283: 'Persian cat', + 284: 'Siamese cat, Siamese', + 285: 'Egyptian cat', + 286: 'cougar, puma, catamount, mountain lion, painter, panther, Felis concolor', + 287: 'lynx, catamount', + 288: 'leopard, Panthera pardus', + 289: 'snow leopard, ounce, Panthera uncia', + 290: 'jaguar, panther, Panthera onca, Felis onca', + 291: 'lion, king of beasts, Panthera leo', + 292: 'tiger, Panthera tigris', + 293: 'cheetah, chetah, Acinonyx jubatus', + 294: 'brown bear, bruin, Ursus arctos', + 295: 'American black bear, black bear, Ursus americanus, Euarctos americanus', + 296: 'ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus', + 297: 'sloth bear, Melursus ursinus, Ursus ursinus', + 298: 'mongoose', + 299: 'meerkat, mierkat', + 300: 'tiger beetle', + 301: 'ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle', + 302: 'ground beetle, carabid beetle', + 303: 'long-horned beetle, longicorn, longicorn beetle', + 304: 'leaf beetle, chrysomelid', + 305: 'dung beetle', + 306: 'rhinoceros beetle', + 307: 'weevil', + 308: 'fly', + 309: 'bee', + 310: 'ant, emmet, pismire', + 311: 'grasshopper, hopper', + 312: 'cricket', + 313: 'walking stick, walkingstick, stick insect', + 314: 'cockroach, roach', + 315: 'mantis, mantid', + 316: 'cicada, cicala', + 317: 'leafhopper', + 318: 'lacewing, lacewing fly', + 319: "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", + 320: 'damselfly', + 321: 'admiral', + 322: 'ringlet, ringlet butterfly', + 323: 'monarch, monarch butterfly, milkweed butterfly, Danaus plexippus', + 324: 'cabbage butterfly', + 325: 'sulphur butterfly, sulfur butterfly', + 326: 'lycaenid, lycaenid butterfly', + 327: 'starfish, sea star', + 328: 'sea urchin', + 329: 'sea cucumber, holothurian', + 330: 'wood rabbit, cottontail, cottontail rabbit', + 331: 'hare', + 332: 'Angora, Angora rabbit', + 333: 'hamster', + 334: 'porcupine, hedgehog', + 335: 'fox squirrel, eastern fox squirrel, Sciurus niger', + 336: 'marmot', + 337: 'beaver', + 338: 'guinea pig, Cavia cobaya', + 339: 'sorrel', + 340: 'zebra', + 341: 'hog, pig, grunter, squealer, Sus scrofa', + 342: 'wild boar, boar, Sus scrofa', + 343: 'warthog', + 344: 'hippopotamus, hippo, river horse, Hippopotamus amphibius', + 345: 'ox', + 346: 'water buffalo, water ox, Asiatic buffalo, Bubalus bubalis', + 347: 'bison', + 348: 'ram, tup', + 349: 'bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis', + 350: 'ibex, Capra ibex', + 351: 'hartebeest', + 352: 'impala, Aepyceros melampus', + 353: 'gazelle', + 354: 'Arabian camel, dromedary, Camelus dromedarius', + 355: 'llama', + 356: 'weasel', + 357: 'mink', + 358: 'polecat, fitch, foulmart, foumart, Mustela putorius', + 359: 'black-footed ferret, ferret, Mustela nigripes', + 360: 'otter', + 361: 'skunk, polecat, wood pussy', + 362: 'badger', + 363: 'armadillo', + 364: 'three-toed sloth, ai, Bradypus tridactylus', + 365: 'orangutan, orang, orangutang, Pongo pygmaeus', + 366: 'gorilla, Gorilla gorilla', + 367: 'chimpanzee, chimp, Pan troglodytes', + 368: 'gibbon, Hylobates lar', + 369: 'siamang, Hylobates syndactylus, Symphalangus syndactylus', + 370: 'guenon, guenon monkey', + 371: 'patas, hussar monkey, Erythrocebus patas', + 372: 'baboon', + 373: 'macaque', + 374: 'langur', + 375: 'colobus, colobus monkey', + 376: 'proboscis monkey, Nasalis larvatus', + 377: 'marmoset', + 378: 'capuchin, ringtail, Cebus capucinus', + 379: 'howler monkey, howler', + 380: 'titi, titi monkey', + 381: 'spider monkey, Ateles geoffroyi', + 382: 'squirrel monkey, Saimiri sciureus', + 383: 'Madagascar cat, ring-tailed lemur, Lemur catta', + 384: 'indri, indris, Indri indri, Indri brevicaudatus', + 385: 'Indian elephant, Elephas maximus', + 386: 'African elephant, Loxodonta africana', + 387: 'lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens', + 388: 'giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca', + 389: 'barracouta, snoek', + 390: 'eel', + 391: 'coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch', + 392: 'rock beauty, Holocanthus tricolor', + 393: 'anemone fish', + 394: 'sturgeon', + 395: 'gar, garfish, garpike, billfish, Lepisosteus osseus', + 396: 'lionfish', + 397: 'puffer, pufferfish, blowfish, globefish', + 398: 'abacus', + 399: 'abaya', + 400: "academic gown, academic robe, judge's robe", + 401: 'accordion, piano accordion, squeeze box', + 402: 'acoustic guitar', + 403: 'aircraft carrier, carrier, flattop, attack aircraft carrier', + 404: 'airliner', + 405: 'airship, dirigible', + 406: 'altar', + 407: 'ambulance', + 408: 'amphibian, amphibious vehicle', + 409: 'analog clock', + 410: 'apiary, bee house', + 411: 'apron', + 412: 'ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin', + 413: 'assault rifle, assault gun', + 414: 'backpack, back pack, knapsack, packsack, rucksack, haversack', + 415: 'bakery, bakeshop, bakehouse', + 416: 'balance beam, beam', + 417: 'balloon', + 418: 'ballpoint, ballpoint pen, ballpen, Biro', + 419: 'Band Aid', + 420: 'banjo', + 421: 'bannister, banister, balustrade, balusters, handrail', + 422: 'barbell', + 423: 'barber chair', + 424: 'barbershop', + 425: 'barn', + 426: 'barometer', + 427: 'barrel, cask', + 428: 'barrow, garden cart, lawn cart, wheelbarrow', + 429: 'baseball', + 430: 'basketball', + 431: 'bassinet', + 432: 'bassoon', + 433: 'bathing cap, swimming cap', + 434: 'bath towel', + 435: 'bathtub, bathing tub, bath, tub', + 436: 'beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon', + 437: 'beacon, lighthouse, beacon light, pharos', + 438: 'beaker', + 439: 'bearskin, busby, shako', + 440: 'beer bottle', + 441: 'beer glass', + 442: 'bell cote, bell cot', + 443: 'bib', + 444: 'bicycle-built-for-two, tandem bicycle, tandem', + 445: 'bikini, two-piece', + 446: 'binder, ring-binder', + 447: 'binoculars, field glasses, opera glasses', + 448: 'birdhouse', + 449: 'boathouse', + 450: 'bobsled, bobsleigh, bob', + 451: 'bolo tie, bolo, bola tie, bola', + 452: 'bonnet, poke bonnet', + 453: 'bookcase', + 454: 'bookshop, bookstore, bookstall', + 455: 'bottlecap', + 456: 'bow', + 457: 'bow tie, bow-tie, bowtie', + 458: 'brass, memorial tablet, plaque', + 459: 'brassiere, bra, bandeau', + 460: 'breakwater, groin, groyne, mole, bulwark, seawall, jetty', + 461: 'breastplate, aegis, egis', + 462: 'broom', + 463: 'bucket, pail', + 464: 'buckle', + 465: 'bulletproof vest', + 466: 'bullet train, bullet', + 467: 'butcher shop, meat market', + 468: 'cab, hack, taxi, taxicab', + 469: 'caldron, cauldron', + 470: 'candle, taper, wax light', + 471: 'cannon', + 472: 'canoe', + 473: 'can opener, tin opener', + 474: 'cardigan', + 475: 'car mirror', + 476: 'carousel, carrousel, merry-go-round, roundabout, whirligig', + 477: "carpenter's kit, tool kit", + 478: 'carton', + 479: 'car wheel', + 480: 'cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM', + 481: 'cassette', + 482: 'cassette player', + 483: 'castle', + 484: 'catamaran', + 485: 'CD player', + 486: 'cello, violoncello', + 487: 'cellular telephone, cellular phone, cellphone, cell, mobile phone', + 488: 'chain', + 489: 'chainlink fence', + 490: 'chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour', + 491: 'chain saw, chainsaw', + 492: 'chest', + 493: 'chiffonier, commode', + 494: 'chime, bell, gong', + 495: 'china cabinet, china closet', + 496: 'Christmas stocking', + 497: 'church, church building', + 498: 'cinema, movie theater, movie theatre, movie house, picture palace', + 499: 'cleaver, meat cleaver, chopper', + 500: 'cliff dwelling', + 501: 'cloak', + 502: 'clog, geta, patten, sabot', + 503: 'cocktail shaker', + 504: 'coffee mug', + 505: 'coffeepot', + 506: 'coil, spiral, volute, whorl, helix', + 507: 'combination lock', + 508: 'computer keyboard, keypad', + 509: 'confectionery, confectionary, candy store', + 510: 'container ship, containership, container vessel', + 511: 'convertible', + 512: 'corkscrew, bottle screw', + 513: 'cornet, horn, trumpet, trump', + 514: 'cowboy boot', + 515: 'cowboy hat, ten-gallon hat', + 516: 'cradle', + 517: 'crane', + 518: 'crash helmet', + 519: 'crate', + 520: 'crib, cot', + 521: 'Crock Pot', + 522: 'croquet ball', + 523: 'crutch', + 524: 'cuirass', + 525: 'dam, dike, dyke', + 526: 'desk', + 527: 'desktop computer', + 528: 'dial telephone, dial phone', + 529: 'diaper, nappy, napkin', + 530: 'digital clock', + 531: 'digital watch', + 532: 'dining table, board', + 533: 'dishrag, dishcloth', + 534: 'dishwasher, dish washer, dishwashing machine', + 535: 'disk brake, disc brake', + 536: 'dock, dockage, docking facility', + 537: 'dogsled, dog sled, dog sleigh', + 538: 'dome', + 539: 'doormat, welcome mat', + 540: 'drilling platform, offshore rig', + 541: 'drum, membranophone, tympan', + 542: 'drumstick', + 543: 'dumbbell', + 544: 'Dutch oven', + 545: 'electric fan, blower', + 546: 'electric guitar', + 547: 'electric locomotive', + 548: 'entertainment center', + 549: 'envelope', + 550: 'espresso maker', + 551: 'face powder', + 552: 'feather boa, boa', + 553: 'file, file cabinet, filing cabinet', + 554: 'fireboat', + 555: 'fire engine, fire truck', + 556: 'fire screen, fireguard', + 557: 'flagpole, flagstaff', + 558: 'flute, transverse flute', + 559: 'folding chair', + 560: 'football helmet', + 561: 'forklift', + 562: 'fountain', + 563: 'fountain pen', + 564: 'four-poster', + 565: 'freight car', + 566: 'French horn, horn', + 567: 'frying pan, frypan, skillet', + 568: 'fur coat', + 569: 'garbage truck, dustcart', + 570: 'gasmask, respirator, gas helmet', + 571: 'gas pump, gasoline pump, petrol pump, island dispenser', + 572: 'goblet', + 573: 'go-kart', + 574: 'golf ball', + 575: 'golfcart, golf cart', + 576: 'gondola', + 577: 'gong, tam-tam', + 578: 'gown', + 579: 'grand piano, grand', + 580: 'greenhouse, nursery, glasshouse', + 581: 'grille, radiator grille', + 582: 'grocery store, grocery, food market, market', + 583: 'guillotine', + 584: 'hair slide', + 585: 'hair spray', + 586: 'half track', + 587: 'hammer', + 588: 'hamper', + 589: 'hand blower, blow dryer, blow drier, hair dryer, hair drier', + 590: 'hand-held computer, hand-held microcomputer', + 591: 'handkerchief, hankie, hanky, hankey', + 592: 'hard disc, hard disk, fixed disk', + 593: 'harmonica, mouth organ, harp, mouth harp', + 594: 'harp', + 595: 'harvester, reaper', + 596: 'hatchet', + 597: 'holster', + 598: 'home theater, home theatre', + 599: 'honeycomb', + 600: 'hook, claw', + 601: 'hoopskirt, crinoline', + 602: 'horizontal bar, high bar', + 603: 'horse cart, horse-cart', + 604: 'hourglass', + 605: 'iPod', + 606: 'iron, smoothing iron', + 607: "jack-o'-lantern", + 608: 'jean, blue jean, denim', + 609: 'jeep, landrover', + 610: 'jersey, T-shirt, tee shirt', + 611: 'jigsaw puzzle', + 612: 'jinrikisha, ricksha, rickshaw', + 613: 'joystick', + 614: 'kimono', + 615: 'knee pad', + 616: 'knot', + 617: 'lab coat, laboratory coat', + 618: 'ladle', + 619: 'lampshade, lamp shade', + 620: 'laptop, laptop computer', + 621: 'lawn mower, mower', + 622: 'lens cap, lens cover', + 623: 'letter opener, paper knife, paperknife', + 624: 'library', + 625: 'lifeboat', + 626: 'lighter, light, igniter, ignitor', + 627: 'limousine, limo', + 628: 'liner, ocean liner', + 629: 'lipstick, lip rouge', + 630: 'Loafer', + 631: 'lotion', + 632: 'loudspeaker, speaker, speaker unit, loudspeaker system, speaker system', + 633: "loupe, jeweler's loupe", + 634: 'lumbermill, sawmill', + 635: 'magnetic compass', + 636: 'mailbag, postbag', + 637: 'mailbox, letter box', + 638: 'maillot', + 639: 'maillot, tank suit', + 640: 'manhole cover', + 641: 'maraca', + 642: 'marimba, xylophone', + 643: 'mask', + 644: 'matchstick', + 645: 'maypole', + 646: 'maze, labyrinth', + 647: 'measuring cup', + 648: 'medicine chest, medicine cabinet', + 649: 'megalith, megalithic structure', + 650: 'microphone, mike', + 651: 'microwave, microwave oven', + 652: 'military uniform', + 653: 'milk can', + 654: 'minibus', + 655: 'miniskirt, mini', + 656: 'minivan', + 657: 'missile', + 658: 'mitten', + 659: 'mixing bowl', + 660: 'mobile home, manufactured home', + 661: 'Model T', + 662: 'modem', + 663: 'monastery', + 664: 'monitor', + 665: 'moped', + 666: 'mortar', + 667: 'mortarboard', + 668: 'mosque', + 669: 'mosquito net', + 670: 'motor scooter, scooter', + 671: 'mountain bike, all-terrain bike, off-roader', + 672: 'mountain tent', + 673: 'mouse, computer mouse', + 674: 'mousetrap', + 675: 'moving van', + 676: 'muzzle', + 677: 'nail', + 678: 'neck brace', + 679: 'necklace', + 680: 'nipple', + 681: 'notebook, notebook computer', + 682: 'obelisk', + 683: 'oboe, hautboy, hautbois', + 684: 'ocarina, sweet potato', + 685: 'odometer, hodometer, mileometer, milometer', + 686: 'oil filter', + 687: 'organ, pipe organ', + 688: 'oscilloscope, scope, cathode-ray oscilloscope, CRO', + 689: 'overskirt', + 690: 'oxcart', + 691: 'oxygen mask', + 692: 'packet', + 693: 'paddle, boat paddle', + 694: 'paddlewheel, paddle wheel', + 695: 'padlock', + 696: 'paintbrush', + 697: "pajama, pyjama, pj's, jammies", + 698: 'palace', + 699: 'panpipe, pandean pipe, syrinx', + 700: 'paper towel', + 701: 'parachute, chute', + 702: 'parallel bars, bars', + 703: 'park bench', + 704: 'parking meter', + 705: 'passenger car, coach, carriage', + 706: 'patio, terrace', + 707: 'pay-phone, pay-station', + 708: 'pedestal, plinth, footstall', + 709: 'pencil box, pencil case', + 710: 'pencil sharpener', + 711: 'perfume, essence', + 712: 'Petri dish', + 713: 'photocopier', + 714: 'pick, plectrum, plectron', + 715: 'pickelhaube', + 716: 'picket fence, paling', + 717: 'pickup, pickup truck', + 718: 'pier', + 719: 'piggy bank, penny bank', + 720: 'pill bottle', + 721: 'pillow', + 722: 'ping-pong ball', + 723: 'pinwheel', + 724: 'pirate, pirate ship', + 725: 'pitcher, ewer', + 726: "plane, carpenter's plane, woodworking plane", + 727: 'planetarium', + 728: 'plastic bag', + 729: 'plate rack', + 730: 'plow, plough', + 731: "plunger, plumber's helper", + 732: 'Polaroid camera, Polaroid Land camera', + 733: 'pole', + 734: 'police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria', + 735: 'poncho', + 736: 'pool table, billiard table, snooker table', + 737: 'pop bottle, soda bottle', + 738: 'pot, flowerpot', + 739: "potter's wheel", + 740: 'power drill', + 741: 'prayer rug, prayer mat', + 742: 'printer', + 743: 'prison, prison house', + 744: 'projectile, missile', + 745: 'projector', + 746: 'puck, hockey puck', + 747: 'punching bag, punch bag, punching ball, punchball', + 748: 'purse', + 749: 'quill, quill pen', + 750: 'quilt, comforter, comfort, puff', + 751: 'racer, race car, racing car', + 752: 'racket, racquet', + 753: 'radiator', + 754: 'radio, wireless', + 755: 'radio telescope, radio reflector', + 756: 'rain barrel', + 757: 'recreational vehicle, RV, R.V.', + 758: 'reel', + 759: 'reflex camera', + 760: 'refrigerator, icebox', + 761: 'remote control, remote', + 762: 'restaurant, eating house, eating place, eatery', + 763: 'revolver, six-gun, six-shooter', + 764: 'rifle', + 765: 'rocking chair, rocker', + 766: 'rotisserie', + 767: 'rubber eraser, rubber, pencil eraser', + 768: 'rugby ball', + 769: 'rule, ruler', + 770: 'running shoe', + 771: 'safe', + 772: 'safety pin', + 773: 'saltshaker, salt shaker', + 774: 'sandal', + 775: 'sarong', + 776: 'sax, saxophone', + 777: 'scabbard', + 778: 'scale, weighing machine', + 779: 'school bus', + 780: 'schooner', + 781: 'scoreboard', + 782: 'screen, CRT screen', + 783: 'screw', + 784: 'screwdriver', + 785: 'seat belt, seatbelt', + 786: 'sewing machine', + 787: 'shield, buckler', + 788: 'shoe shop, shoe-shop, shoe store', + 789: 'shoji', + 790: 'shopping basket', + 791: 'shopping cart', + 792: 'shovel', + 793: 'shower cap', + 794: 'shower curtain', + 795: 'ski', + 796: 'ski mask', + 797: 'sleeping bag', + 798: 'slide rule, slipstick', + 799: 'sliding door', + 800: 'slot, one-armed bandit', + 801: 'snorkel', + 802: 'snowmobile', + 803: 'snowplow, snowplough', + 804: 'soap dispenser', + 805: 'soccer ball', + 806: 'sock', + 807: 'solar dish, solar collector, solar furnace', + 808: 'sombrero', + 809: 'soup bowl', + 810: 'space bar', + 811: 'space heater', + 812: 'space shuttle', + 813: 'spatula', + 814: 'speedboat', + 815: "spider web, spider's web", + 816: 'spindle', + 817: 'sports car, sport car', + 818: 'spotlight, spot', + 819: 'stage', + 820: 'steam locomotive', + 821: 'steel arch bridge', + 822: 'steel drum', + 823: 'stethoscope', + 824: 'stole', + 825: 'stone wall', + 826: 'stopwatch, stop watch', + 827: 'stove', + 828: 'strainer', + 829: 'streetcar, tram, tramcar, trolley, trolley car', + 830: 'stretcher', + 831: 'studio couch, day bed', + 832: 'stupa, tope', + 833: 'submarine, pigboat, sub, U-boat', + 834: 'suit, suit of clothes', + 835: 'sundial', + 836: 'sunglass', + 837: 'sunglasses, dark glasses, shades', + 838: 'sunscreen, sunblock, sun blocker', + 839: 'suspension bridge', + 840: 'swab, swob, mop', + 841: 'sweatshirt', + 842: 'swimming trunks, bathing trunks', + 843: 'swing', + 844: 'switch, electric switch, electrical switch', + 845: 'syringe', + 846: 'table lamp', + 847: 'tank, army tank, armored combat vehicle, armoured combat vehicle', + 848: 'tape player', + 849: 'teapot', + 850: 'teddy, teddy bear', + 851: 'television, television system', + 852: 'tennis ball', + 853: 'thatch, thatched roof', + 854: 'theater curtain, theatre curtain', + 855: 'thimble', + 856: 'thresher, thrasher, threshing machine', + 857: 'throne', + 858: 'tile roof', + 859: 'toaster', + 860: 'tobacco shop, tobacconist shop, tobacconist', + 861: 'toilet seat', + 862: 'torch', + 863: 'totem pole', + 864: 'tow truck, tow car, wrecker', + 865: 'toyshop', + 866: 'tractor', + 867: 'trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi', + 868: 'tray', + 869: 'trench coat', + 870: 'tricycle, trike, velocipede', + 871: 'trimaran', + 872: 'tripod', + 873: 'triumphal arch', + 874: 'trolleybus, trolley coach, trackless trolley', + 875: 'trombone', + 876: 'tub, vat', + 877: 'turnstile', + 878: 'typewriter keyboard', + 879: 'umbrella', + 880: 'unicycle, monocycle', + 881: 'upright, upright piano', + 882: 'vacuum, vacuum cleaner', + 883: 'vase', + 884: 'vault', + 885: 'velvet', + 886: 'vending machine', + 887: 'vestment', + 888: 'viaduct', + 889: 'violin, fiddle', + 890: 'volleyball', + 891: 'waffle iron', + 892: 'wall clock', + 893: 'wallet, billfold, notecase, pocketbook', + 894: 'wardrobe, closet, press', + 895: 'warplane, military plane', + 896: 'washbasin, handbasin, washbowl, lavabo, wash-hand basin', + 897: 'washer, automatic washer, washing machine', + 898: 'water bottle', + 899: 'water jug', + 900: 'water tower', + 901: 'whiskey jug', + 902: 'whistle', + 903: 'wig', + 904: 'window screen', + 905: 'window shade', + 906: 'Windsor tie', + 907: 'wine bottle', + 908: 'wing', + 909: 'wok', + 910: 'wooden spoon', + 911: 'wool, woolen, woollen', + 912: 'worm fence, snake fence, snake-rail fence, Virginia fence', + 913: 'wreck', + 914: 'yawl', + 915: 'yurt', + 916: 'web site, website, internet site, site', + 917: 'comic book', + 918: 'crossword puzzle, crossword', + 919: 'street sign', + 920: 'traffic light, traffic signal, stoplight', + 921: 'book jacket, dust cover, dust jacket, dust wrapper', + 922: 'menu', + 923: 'plate', + 924: 'guacamole', + 925: 'consomme', + 926: 'hot pot, hotpot', + 927: 'trifle', + 928: 'ice cream, icecream', + 929: 'ice lolly, lolly, lollipop, popsicle', + 930: 'French loaf', + 931: 'bagel, beigel', + 932: 'pretzel', + 933: 'cheeseburger', + 934: 'hotdog, hot dog, red hot', + 935: 'mashed potato', + 936: 'head cabbage', + 937: 'broccoli', + 938: 'cauliflower', + 939: 'zucchini, courgette', + 940: 'spaghetti squash', + 941: 'acorn squash', + 942: 'butternut squash', + 943: 'cucumber, cuke', + 944: 'artichoke, globe artichoke', + 945: 'bell pepper', + 946: 'cardoon', + 947: 'mushroom', + 948: 'Granny Smith', + 949: 'strawberry', + 950: 'orange', + 951: 'lemon', + 952: 'fig', + 953: 'pineapple, ananas', + 954: 'banana', + 955: 'jackfruit, jak, jack', + 956: 'custard apple', + 957: 'pomegranate', + 958: 'hay', + 959: 'carbonara', + 960: 'chocolate sauce, chocolate syrup', + 961: 'dough', + 962: 'meat loaf, meatloaf', + 963: 'pizza, pizza pie', + 964: 'potpie', + 965: 'burrito', + 966: 'red wine', + 967: 'espresso', + 968: 'cup', + 969: 'eggnog', + 970: 'alp', + 971: 'bubble', + 972: 'cliff, drop, drop-off', + 973: 'coral reef', + 974: 'geyser', + 975: 'lakeside, lakeshore', + 976: 'promontory, headland, head, foreland', + 977: 'sandbar, sand bar', + 978: 'seashore, coast, seacoast, sea-coast', + 979: 'valley, vale', + 980: 'volcano', + 981: 'ballplayer, baseball player', + 982: 'groom, bridegroom', + 983: 'scuba diver', + 984: 'rapeseed', + 985: 'daisy', + 986: "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", + 987: 'corn', + 988: 'acorn', + 989: 'hip, rose hip, rosehip', + 990: 'buckeye, horse chestnut, conker', + 991: 'coral fungus', + 992: 'agaric', + 993: 'gyromitra', + 994: 'stinkhorn, carrion fungus', + 995: 'earthstar', + 996: 'hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa', + 997: 'bolete', + 998: 'ear, spike, capitulum', + 999: 'toilet tissue, toilet paper, bathroom tissue'} \ No newline at end of file diff --git a/build/lib/gradio/inputs.py b/build/lib/gradio/inputs.py index 02a3e7c6eb..415f720bd4 100644 --- a/build/lib/gradio/inputs.py +++ b/build/lib/gradio/inputs.py @@ -1,9 +1,15 @@ +""" +This module defines various classes that can serve as the `input` to an interface. Each class must inherit from +`AbstractInput`, and each class must define a path to its template. All of the subclasses of `AbstractInput` are +automatically added to a registry, which allows them to be easily referenced in other parts of the code. +""" + from abc import ABC, abstractmethod import base64 -from PIL import Image +from gradio import preprocessing_utils from io import BytesIO import numpy as np -from gradio import preprocessing_utils +from PIL import Image class AbstractInput(ABC): """ @@ -12,84 +18,115 @@ class AbstractInput(ABC): """ def __init__(self, preprocessing_fn=None): + """ + :param preprocessing_fn: an optional preprocessing function that overrides the default + """ if preprocessing_fn is not None: - self._pre_process = preprocessing_fn + if not callable(preprocessing_fn): + raise ValueError('`preprocessing_fn` must be a callable function') + self.preprocess = preprocessing_fn super().__init__() @abstractmethod - def _get_template_path(self): + def get_template_path(self): """ All interfaces should define a method that returns the path to its template. """ pass @abstractmethod - def _pre_process(self): + def preprocess(self, inp): """ - All interfaces should define a method that returns the path to its template. + All interfaces should define a default preprocessing method """ pass class Sketchpad(AbstractInput): + def __init__(self, preprocessing_fn=None, image_width=28, image_height=28): + self.image_width = image_width + self.image_height = image_height + super().__init__(preprocessing_fn=preprocessing_fn) - def _get_template_path(self): + def get_template_path(self): return 'templates/sketchpad_input.html' - def _pre_process(self, imgstring): + def preprocess(self, inp): """ + Default preprocessing method for the SketchPad is to convert the sketch to black and white and resize 28x28 """ - content = imgstring.split(';')[1] + content = inp.split(';')[1] image_encoded = content.split(',')[1] - body = base64.decodebytes(image_encoded.encode('utf-8')) im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') - im = preprocessing_utils.resize_and_crop(im, (28, 28)) - array = np.array(im).flatten().reshape(1, 28, 28, 1) + im = preprocessing_utils.resize_and_crop(im, (self.image_width, self.image_height)) + array = np.array(im).flatten().reshape(1, self.image_width, self.image_height, 1) return array class Webcam(AbstractInput): + def __init__(self, preprocessing_fn=None, image_width=224, image_height=224, num_channels=3): + self.image_width = image_width + self.image_height = image_height + self.num_channels = num_channels + super().__init__(preprocessing_fn=preprocessing_fn) - def _get_template_path(self): + def get_template_path(self): return 'templates/webcam_input.html' - def _pre_process(self, imgstring): + def preprocess(self, inp): """ + Default preprocessing method for is to convert the picture to black and white and resize to be 48x48 """ - content = imgstring.split(';')[1] + content = inp.split(';')[1] image_encoded = content.split(',')[1] - body = base64.decodebytes(image_encoded.encode('utf-8')) - im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') - im = preprocessing_utils.resize_and_crop(im, (48, 48)) - array = np.array(im).flatten().reshape(1, 48, 48, 1) + im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('RGB') + im = preprocessing_utils.resize_and_crop(im, (self.image_width, self.image_height)) + array = np.array(im).flatten().reshape(1, self.image_width, self.image_height, self.num_channels) return array class Textbox(AbstractInput): - def _get_template_path(self): + def get_template_path(self): return 'templates/textbox_input.html' - def _pre_process(self, text): + def preprocess(self, inp): """ + By default, no pre-processing is applied to text. """ - return text + return inp + class ImageUpload(AbstractInput): + def __init__(self, preprocessing_fn=None, image_width=224, image_height=224, num_channels=3, image_mode='RGB', + scale = 1/127.5, shift = -1): + self.image_width = image_width + self.image_height = image_height + self.num_channels = num_channels + self.image_mode = image_mode + self.scale = scale + self.shift = shift + super().__init__(preprocessing_fn=preprocessing_fn) - def _get_template_path(self): + def get_template_path(self): return 'templates/image_upload_input.html' - def _pre_process(self, imgstring): + def preprocess(self, inp): """ + Default preprocessing method for is to convert the picture to black and white and resize to be 48x48 """ - content = imgstring.split(';')[1] + content = inp.split(';')[1] image_encoded = content.split(',')[1] - body = base64.decodebytes(image_encoded.encode('utf-8')) - im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert('L') - im = preprocessing_utils.resize_and_crop(im, (48, 48)) - array = np.array(im).flatten().reshape(1, 48, 48, 1) + im = Image.open(BytesIO(base64.b64decode(image_encoded))).convert(self.image_mode) + im = preprocessing_utils.resize_and_crop(im, (self.image_width, self.image_height)) + im = np.array(im).flatten() + im = im * self.scale + self.shift + if self.num_channels is None: + array = im.reshape(1, self.image_width, self.image_height) + else: + array = im.reshape(1, self.image_width, self.image_height, self.num_channels) return array +# Automatically adds all subclasses of AbstractInput into a dictionary (keyed by class name) for easy referencing. registry = {cls.__name__.lower(): cls for cls in AbstractInput.__subclasses__()} diff --git a/build/lib/gradio/interface.py b/build/lib/gradio/interface.py index 91360dcc24..366cfb83b1 100644 --- a/build/lib/gradio/interface.py +++ b/build/lib/gradio/interface.py @@ -1,14 +1,15 @@ +''' +This is the core file in the `gradio` package, and defines the Interface class, including methods for constructing the +interface using the input and output types. +''' + import asyncio import websockets import nest_asyncio import webbrowser -import pkg_resources -from bs4 import BeautifulSoup -from gradio import inputs -from gradio import outputs +import gradio.inputs +import gradio.outputs from gradio import networking -import os -import shutil import tempfile nest_asyncio.apply() @@ -17,46 +18,53 @@ LOCALHOST_IP = '127.0.0.1' INITIAL_WEBSOCKET_PORT = 9200 TRY_NUM_PORTS = 100 -BASE_TEMPLATE = pkg_resources.resource_filename('gradio', 'templates/base_template.html') -JS_PATH_LIB = pkg_resources.resource_filename('gradio', 'js/') -CSS_PATH_LIB = pkg_resources.resource_filename('gradio', 'css/') -JS_PATH_TEMP = 'js/' -CSS_PATH_TEMP = 'css/' -TEMPLATE_TEMP = 'interface.html' -BASE_JS_FILE = 'js/all-io.js' - -class Interface(): +class Interface: """ + The Interface class represents a general input/output interface for a machine learning model. During construction, + the appropriate inputs and outputs """ # Dictionary in which each key is a valid `model_type` argument to constructor, and the value being the description. VALID_MODEL_TYPES = {'sklearn': 'sklearn model', 'keras': 'keras model', 'function': 'python function'} - def __init__(self, input, output, model, model_type=None, preprocessing_fn=None, postprocessing_fn=None): + def __init__(self, inputs, outputs, model, model_type=None, preprocessing_fns=None, postprocessing_fns=None, + verbose=True): """ - :param model_type: what kind of trained model, can be 'keras' or 'sklearn'. + :param inputs: a string or `AbstractInput` representing the input interface. + :param outputs: a string or `AbstractOutput` representing the output interface. :param model_obj: the model object, such as a sklearn classifier or keras model. - :param model_params: additional model parameters. + :param model_type: what kind of trained model, can be 'keras' or 'sklearn' or 'function'. Inferred if not + provided. + :param preprocessing_fns: an optional function that overrides the preprocessing function of the input interface. + :param postprocessing_fns: an optional function that overrides the postprocessing fn of the output interface. """ - self.input_interface = inputs.registry[input](preprocessing_fn) - self.output_interface = outputs.registry[output](postprocessing_fn) + if isinstance(inputs, str): + self.input_interface = gradio.inputs.registry[inputs.lower()](preprocessing_fns) + elif isinstance(inputs, gradio.inputs.AbstractInput): + self.input_interface = inputs + else: + raise ValueError('Input interface must be of type `str` or `AbstractInput`') + if isinstance(outputs, str): + self.output_interface = gradio.outputs.registry[outputs.lower()](postprocessing_fns) + elif isinstance(outputs, gradio.outputs.AbstractOutput): + self.output_interface = outputs + else: + raise ValueError('Output interface must be of type `str` or `AbstractOutput`') self.model_obj = model if model_type is None: model_type = self._infer_model_type(model) - if model_type is None: - raise ValueError("model_type could not be inferred, please specify parameter `model_type`") - else: + if verbose: print("Model type not explicitly identified, inferred to be: {}".format( - self.VALID_MODEL_TYPES[model_type])) + self.VALID_MODEL_TYPES[model_type])) elif not(model_type.lower() in self.VALID_MODEL_TYPES): ValueError('model_type must be one of: {}'.format(self.VALID_MODEL_TYPES)) self.model_type = model_type + self.verbose = verbose - def _infer_model_type(self, model): - if callable(model): - return 'function' - + @staticmethod + def _infer_model_type(model): + """ Helper method that attempts to identify the type of trained ML model.""" try: import sklearn if isinstance(model, sklearn.base.BaseEstimator): @@ -78,124 +86,100 @@ class Interface(): except ImportError: pass - return None + if callable(model): + return 'function' - def _build_template(self, temp_dir): - input_template_path = pkg_resources.resource_filename( - 'gradio', self.input_interface._get_template_path()) - output_template_path = pkg_resources.resource_filename( - 'gradio', self.output_interface._get_template_path()) - input_page = open(input_template_path) - output_page = open(output_template_path) - input_soup = BeautifulSoup(input_page.read(), features="html.parser") - output_soup = BeautifulSoup(output_page.read(), features="html.parser") - - all_io_page = open(BASE_TEMPLATE) - all_io_soup = BeautifulSoup(all_io_page.read(), features="html.parser") - input_tag = all_io_soup.find("div", {"id": "input"}) - output_tag = all_io_soup.find("div", {"id": "output"}) - - input_tag.replace_with(input_soup) - output_tag.replace_with(output_soup) - - f = open(os.path.join(temp_dir, TEMPLATE_TEMP), "w") - f.write(str(all_io_soup.prettify)) - - self._copy_files(JS_PATH_LIB, os.path.join(temp_dir, JS_PATH_TEMP)) - self._copy_files(CSS_PATH_LIB, os.path.join(temp_dir, CSS_PATH_TEMP)) - return - - def _copy_files(self, src_dir, dest_dir): - if not os.path.exists(dest_dir): - os.makedirs(dest_dir) - src_files = os.listdir(src_dir) - for file_name in src_files: - full_file_name = os.path.join(src_dir, file_name) - if os.path.isfile(full_file_name): - shutil.copy(full_file_name, dest_dir) - - def _set_socket_url_in_js(self, temp_dir, socket_url): - with open(os.path.join(temp_dir, BASE_JS_FILE)) as fin: - lines = fin.readlines() - lines[0] = 'var NGROK_URL = "{}"\n'.format(socket_url.replace('http', 'ws')) - - with open(os.path.join(temp_dir, BASE_JS_FILE), 'w') as fout: - for line in lines: - fout.write(line) - - def _set_socket_port_in_js(self, temp_dir, socket_port): - with open(os.path.join(temp_dir, BASE_JS_FILE)) as fin: - lines = fin.readlines() - lines[1] = 'var SOCKET_PORT = {}\n'.format(socket_port) - - with open(os.path.join(temp_dir, BASE_JS_FILE), 'w') as fout: - for line in lines: - fout.write(line) - - def predict(self, array): - if self.model_type=='sklearn': - return self.model_obj.predict(array) - elif self.model_type=='keras': - return self.model_obj.predict(array) - elif self.model_type=='function': - return self.model_obj(array) - else: - ValueError('model_type must be one of: {}'.format(self.VALID_MODEL_TYPES)) + raise ValueError("model_type could not be inferred, please specify parameter `model_type`") async def communicate(self, websocket, path): """ - Method that defines how this interface communicates with the websocket. - :param websocket: a Websocket object used to communicate with the interface frontend - :param path: ignored + Method that defines how this interface should communicates with the websocket. (1) When an input is received by + the websocket, it is passed into the input interface and preprocssed. (2) Then the model is called to make a + prediction. (3) Finally, the prediction is postprocessed to get something to be displayed by the output. + :param websocket: a Websocket server used to communicate with the interface frontend + :param path: not used, but required for compliance with websocket library """ while True: try: msg = await websocket.recv() - processed_input = self.input_interface._pre_process(msg) + processed_input = self.input_interface.preprocess(msg) prediction = self.predict(processed_input) - processed_output = self.output_interface._post_process(prediction) + processed_output = self.output_interface.postprocess(prediction) await websocket.send(str(processed_output)) except websockets.exceptions.ConnectionClosed: pass + # except Exception as e: + # print(e) - def launch(self, share_link=False, verbose=True): + def predict(self, preprocessed_input): """ - Standard method shared by interfaces that launches a websocket at a specified IP address. + Method that calls the relevant method of the model object to make a prediction. + :param preprocessed_input: the preprocessed input returned by the input interface + """ + if self.model_type=='sklearn': + return self.model_obj.predict(preprocessed_input) + elif self.model_type=='keras': + return self.model_obj.predict(preprocessed_input) + elif self.model_type=='function': + return self.model_obj(preprocessed_input) + else: + ValueError('model_type must be one of: {}'.format(self.VALID_MODEL_TYPES)) + + def launch(self, inline=None, browser=None, share=False): + """ + Standard method shared by interfaces that creates the interface and sets up a websocket to communicate with it. + :param share: boolean. If True, then a share link is generated using ngrok is displayed to the user. """ output_directory = tempfile.mkdtemp() + + # Set up a port to serve the directory containing the static files with interface. server_port = networking.start_simple_server(output_directory) path_to_server = 'http://localhost:{}/'.format(server_port) - self._build_template(output_directory) + networking.build_template(output_directory, self.input_interface, self.output_interface) - ports_in_use = networking.get_ports_in_use(INITIAL_WEBSOCKET_PORT, INITIAL_WEBSOCKET_PORT + TRY_NUM_PORTS) - for i in range(TRY_NUM_PORTS): - if not ((INITIAL_WEBSOCKET_PORT + i) in ports_in_use): - break - else: - raise OSError("All ports from {} to {} are in use. Please close a port.".format( - INITIAL_WEBSOCKET_PORT, INITIAL_WEBSOCKET_PORT + TRY_NUM_PORTS)) - - start_server = websockets.serve(self.communicate, LOCALHOST_IP, INITIAL_WEBSOCKET_PORT + i) - self._set_socket_port_in_js(output_directory, INITIAL_WEBSOCKET_PORT + i) - if verbose: + # Set up a port to serve a websocket that sets up the communication between the front-end and model. + websocket_port = networking.get_first_available_port( + INITIAL_WEBSOCKET_PORT, INITIAL_WEBSOCKET_PORT + TRY_NUM_PORTS) + start_server = websockets.serve(self.communicate, LOCALHOST_IP, websocket_port) + networking.set_socket_port_in_js(output_directory, websocket_port) # sets the websocket port in the JS file. + if self.verbose: print("NOTE: Gradio is in beta stage, please report all bugs to: a12d@stanford.edu") - print("Model available locally at: {}".format(path_to_server + TEMPLATE_TEMP)) + print("Model is running locally at: {}".format(path_to_server + networking.TEMPLATE_TEMP)) - if share_link: - networking.kill_processes([4040, 4041]) - site_ngrok_url = networking.setup_ngrok(server_port) - socket_ngrok_url = networking.setup_ngrok(INITIAL_WEBSOCKET_PORT, api_url=networking.NGROK_TUNNELS_API_URL2) - self._set_socket_url_in_js(output_directory, socket_ngrok_url) - if verbose: - print("Model available publicly for 8 hours at: {}".format(site_ngrok_url + '/' + TEMPLATE_TEMP)) + if share: + site_ngrok_url = networking.setup_ngrok(server_port, websocket_port, output_directory) + if self.verbose: + print("Model available publicly for 8 hours at: {}".format( + site_ngrok_url + '/' + networking.TEMPLATE_TEMP)) else: - if verbose: - print("To create a public link, set `share_link=True` in the argument to `launch()`") + if self.verbose: + print("To create a public link, set `share=True` in the argument to `launch()`") + site_ngrok_url = None + # Keep the server running in the background. asyncio.get_event_loop().run_until_complete(start_server) try: asyncio.get_event_loop().run_forever() except RuntimeError: # Runtime errors are thrown in jupyter notebooks because of async. pass - webbrowser.open(path_to_server + TEMPLATE_TEMP) + if inline is None: + try: # Check if running interactively using ipython. + _ = get_ipython() + inline = True + if browser is None: + browser = False + except NameError: + inline = False + if browser is None: + browser = True + else: + if browser is None: + browser = False + if browser: + webbrowser.open(path_to_server + networking.TEMPLATE_TEMP) # Open a browser tab with the interface. + if inline: + from IPython.display import IFrame + display(IFrame(path_to_server + networking.TEMPLATE_TEMP, width=1000, height=500)) + + return path_to_server + networking.TEMPLATE_TEMP, site_ngrok_url \ No newline at end of file diff --git a/build/lib/gradio/networking.py b/build/lib/gradio/networking.py index 2ace36072b..7183b57510 100644 --- a/build/lib/gradio/networking.py +++ b/build/lib/gradio/networking.py @@ -1,3 +1,7 @@ +''' +Defines helper methods useful for setting up ports, launching servers, and handling `ngrok` +''' + import subprocess import requests import zipfile @@ -5,21 +9,31 @@ import io import sys import os import socket -from psutil import process_iter, AccessDenied +from psutil import process_iter, AccessDenied, NoSuchProcess from signal import SIGTERM # or SIGKILL import threading from http.server import HTTPServer as BaseHTTPServer, SimpleHTTPRequestHandler import stat from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry +import pkg_resources +from bs4 import BeautifulSoup +from distutils import dir_util -INITIAL_PORT_VALUE = 7860 -TRY_NUM_PORTS = 100 +INITIAL_PORT_VALUE = 7860 # The http server will try to open on port 7860. If not available, 7861, 7862, etc. +TRY_NUM_PORTS = 100 # Number of ports to try before giving up and throwing an exception. LOCALHOST_NAME = 'localhost' -LOCALHOST_PREFIX = 'localhost:' NGROK_TUNNELS_API_URL = "http://localhost:4040/api/tunnels" # TODO(this should be captured from output) NGROK_TUNNELS_API_URL2 = "http://localhost:4041/api/tunnels" # TODO(this should be captured from output) + +BASE_TEMPLATE = pkg_resources.resource_filename('gradio', 'templates/base_template.html') +STATIC_PATH_LIB = pkg_resources.resource_filename('gradio', 'static/') +STATIC_PATH_TEMP = 'static/' +TEMPLATE_TEMP = 'interface.html' +BASE_JS_FILE = 'static/js/all-io.js' + + NGROK_ZIP_URLS = { "linux": "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip", "darwin": "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip", @@ -27,48 +41,83 @@ NGROK_ZIP_URLS = { } -def get_ports_in_use(start, stop): - ports_in_use = [] - for port in range(start, stop): +def build_template(temp_dir, input_interface, output_interface): + """ + Builds a complete HTML template with supporting JS and CSS files in a given directory. + :param temp_dir: string with path to temp directory in which the template should be built + :param input_interface: an AbstractInput object which includes is used to get the input template + :param output_interface: an AbstractInput object which includes is used to get the input template + """ + input_template_path = pkg_resources.resource_filename('gradio', input_interface.get_template_path()) + output_template_path = pkg_resources.resource_filename('gradio', output_interface.get_template_path()) + input_page = open(input_template_path) + output_page = open(output_template_path) + input_soup = BeautifulSoup(input_page.read(), features="html.parser") + output_soup = BeautifulSoup(output_page.read(), features="html.parser") + + all_io_page = open(BASE_TEMPLATE) + all_io_soup = BeautifulSoup(all_io_page.read(), features="html.parser") + input_tag = all_io_soup.find("div", {"id": "input"}) + output_tag = all_io_soup.find("div", {"id": "output"}) + + input_tag.replace_with(input_soup) + output_tag.replace_with(output_soup) + + f = open(os.path.join(temp_dir, TEMPLATE_TEMP), "w") + f.write(str(all_io_soup)) + + copy_files(STATIC_PATH_LIB, os.path.join(temp_dir, STATIC_PATH_TEMP)) + + +def copy_files(src_dir, dest_dir): + """ + Copies all the files from one directory to another + :param src_dir: string path to source directory + :param dest_dir: string path to destination directory + """ + dir_util.copy_tree(src_dir, dest_dir) + + +#TODO(abidlabs): Handle the http vs. https issue that sometimes happens (a ws cannot be loaded from an https page) +def set_socket_url_in_js(temp_dir, socket_url): + with open(os.path.join(temp_dir, BASE_JS_FILE)) as fin: + lines = fin.readlines() + lines[0] = 'var NGROK_URL = "{}"\n'.format(socket_url.replace('http', 'ws')) + + with open(os.path.join(temp_dir, BASE_JS_FILE), 'w') as fout: + for line in lines: + fout.write(line) + + +def set_socket_port_in_js(temp_dir, socket_port): + with open(os.path.join(temp_dir, BASE_JS_FILE)) as fin: + lines = fin.readlines() + lines[1] = 'var SOCKET_PORT = {}\n'.format(socket_port) + + with open(os.path.join(temp_dir, BASE_JS_FILE), 'w') as fout: + for line in lines: + fout.write(line) + + +def get_first_available_port(initial, final): + """ + Gets the first open port in a specified range of port numbers + :param initial: the initial value in the range of port numbers + :param final: final (exclusive) value in the range of port numbers, should be greater than `initial` + :return: + """ + for port in range(initial, final): try: s = socket.socket() # create a socket object s.bind((LOCALHOST_NAME, port)) # Bind to the port s.close() + return port except OSError: - ports_in_use.append(port) - return ports_in_use - # ports_in_use = [] - # try: - # for proc in process_iter(): - # for conns in proc.connections(kind='inet'): - # ports_in_use.append(conns.laddr.port) - # except AccessDenied: - # pass # TODO(abidlabs): somehow find a way to handle this issue? - # return ports_in_use + pass + raise OSError("All ports from {} to {} are in use. Please close a port.".format(initial, final)) def serve_files_in_background(port, directory_to_serve=None): - # class Handler(http.server.SimpleHTTPRequestHandler): - # def __init__(self, *args, **kwargs): - # super().__init__(*args, directory=directory_to_serve, **kwargs) - # - # server = socketserver.ThreadingTCPServer(('localhost', port), Handler) - # # Ensures that Ctrl-C cleanly kills all spawned threads - # server.daemon_threads = True - # # Quicker rebinding - # server.allow_reuse_address = True - # - # # A custom signal handle to allow us to Ctrl-C out of the process - # def signal_handler(signal, frame): - # print('Exiting http server (Ctrl+C pressed)') - # try: - # if (server): - # server.server_close() - # finally: - # sys.exit(0) - # - # # Install the keyboard interrupt handler - # signal.signal(signal.SIGINT, signal_handler) class HTTPHandler(SimpleHTTPRequestHandler): """This handler uses server.base_path instead of always using os.getcwd()""" @@ -101,21 +150,9 @@ def serve_files_in_background(port, directory_to_serve=None): def start_simple_server(directory_to_serve=None): - # TODO(abidlabs): increment port number until free port is found - ports_in_use = get_ports_in_use(start=INITIAL_PORT_VALUE, stop=INITIAL_PORT_VALUE + TRY_NUM_PORTS) - for i in range(TRY_NUM_PORTS): - if not((INITIAL_PORT_VALUE + i) in ports_in_use): - break - else: - raise OSError("All ports from {} to {} are in use. Please close a port.".format( - INITIAL_PORT_VALUE, INITIAL_PORT_VALUE + TRY_NUM_PORTS)) - serve_files_in_background(INITIAL_PORT_VALUE + i, directory_to_serve) - # if directory_to_serve is None: - # subprocess.Popen(['python', '-m', 'http.server', str(INITIAL_PORT_VALUE + i)]) - # else: - # cmd = ' '.join(['python', '-m', 'http.server', '-d', directory_to_serve, str(INITIAL_PORT_VALUE + i)]) - # subprocess.Popen(cmd, shell=True) # Doesn't seem to work if list is passed for some reason. - return INITIAL_PORT_VALUE + i + port = get_first_available_port(INITIAL_PORT_VALUE, INITIAL_PORT_VALUE + TRY_NUM_PORTS) + serve_files_in_background(port, directory_to_serve) + return port def download_ngrok(): @@ -133,7 +170,7 @@ def download_ngrok(): os.chmod('ngrok', st.st_mode | stat.S_IEXEC) -def setup_ngrok(local_port, api_url=NGROK_TUNNELS_API_URL): +def create_ngrok_tunnel(local_port, api_url): if not(os.path.isfile('ngrok.exe') or os.path.isfile('ngrok')): download_ngrok() if sys.platform == 'win32': @@ -147,18 +184,26 @@ def setup_ngrok(local_port, api_url=NGROK_TUNNELS_API_URL): session.mount('https://', adapter) r = session.get(api_url) for tunnel in r.json()['tunnels']: - if LOCALHOST_PREFIX + str(local_port) in tunnel['config']['addr']: + if '{}:'.format(LOCALHOST_NAME) + str(local_port) in tunnel['config']['addr']: return tunnel['public_url'] raise RuntimeError("Not able to retrieve ngrok public URL") -def kill_processes(process_ids): +def setup_ngrok(server_port, websocket_port, output_directory): + kill_processes([4040, 4041]) #TODO(abidlabs): better way to do this + site_ngrok_url = create_ngrok_tunnel(server_port, NGROK_TUNNELS_API_URL) + socket_ngrok_url = create_ngrok_tunnel(websocket_port, NGROK_TUNNELS_API_URL2) + set_socket_url_in_js(output_directory, socket_ngrok_url) + return site_ngrok_url + + +def kill_processes(process_ids): #TODO(abidlabs): remove this, we shouldn't need to kill for proc in process_iter(): try: for conns in proc.connections(kind='inet'): if conns.laddr.port in process_ids: proc.send_signal(SIGTERM) # or SIGKILL - except AccessDenied: + except (AccessDenied, NoSuchProcess): pass diff --git a/build/lib/gradio/outputs.py b/build/lib/gradio/outputs.py index 9a0e5b6fc0..3223ffb1a5 100644 --- a/build/lib/gradio/outputs.py +++ b/build/lib/gradio/outputs.py @@ -1,5 +1,13 @@ +""" +This module defines various classes that can serve as the `output` to an interface. Each class must inherit from +`AbstractOutput`, and each class must define a path to its template. All of the subclasses of `AbstractOutput` are +automatically added to a registry, which allows them to be easily referenced in other parts of the code. +""" + from abc import ABC, abstractmethod import numpy as np +import json +from gradio import imagenet_class_labels class AbstractOutput(ABC): """ @@ -9,52 +17,86 @@ class AbstractOutput(ABC): def __init__(self, postprocessing_fn=None): """ + :param postprocessing_fn: an optional postprocessing function that overrides the default """ if postprocessing_fn is not None: - self._post_process = postprocessing_fn + self.postprocess = postprocessing_fn super().__init__() @abstractmethod - def _get_template_path(self): + def get_template_path(self): """ All interfaces should define a method that returns the path to its template. """ pass @abstractmethod - def _post_process(self): + def postprocess(self, prediction): """ - All interfaces should define a method that returns the path to its template. + All interfaces should define a default postprocessing method """ pass -class Class(AbstractOutput): +class Label(AbstractOutput): + LABEL_KEY = 'label' + CONFIDENCES_KEY = 'confidences' + CONFIDENCE_KEY = 'confidence' - def _get_template_path(self): - return 'templates/class_output.html' + def __init__(self, postprocessing_fn=None, num_top_classes=3, show_confidences=True, label_names=None, + max_label_length=None): + self.num_top_classes = num_top_classes + self.show_confidences = show_confidences + self.label_names = label_names + self.max_label_length = max_label_length + super().__init__(postprocessing_fn=postprocessing_fn) - def _post_process(self, prediction): + def get_label_name(self, label): + if self.label_names is None: + name = label + elif self.label_names == 'imagenet1000': + name = imagenet_class_labels.NAMES1000[label] + else: # if list or dictionary + name = self.label_names[label] + if self.max_label_length is not None: + name = name[:self.max_label_length] + return name + + def get_template_path(self): + return 'templates/label_output.html' + + def postprocess(self, prediction): """ """ + response = dict() + # TODO(abidlabs): check if list, if so convert to numpy array if isinstance(prediction, np.ndarray): prediction = prediction.squeeze() - if prediction.size == 1: - return prediction - else: - return prediction.argmax() + if prediction.size == 1: # if it's single value + response[Label.LABEL_KEY] = self.get_label_name(np.asscalar(prediction)) + elif len(prediction.shape) == 1: # if a 1D + response[Label.LABEL_KEY] = self.get_label_name(int(prediction.argmax())) + if self.show_confidences: + response[Label.CONFIDENCES_KEY] = [] + for i in range(self.num_top_classes): + response[Label.CONFIDENCES_KEY].append({ + Label.LABEL_KEY: self.get_label_name(int(prediction.argmax())), + Label.CONFIDENCE_KEY: float(prediction.max()), + }) + prediction[prediction.argmax()] = 0 elif isinstance(prediction, str): - return prediction + response[Label.LABEL_KEY] = prediction else: raise ValueError("Unable to post-process model prediction.") + return json.dumps(response) class Textbox(AbstractOutput): - def _get_template_path(self): + def get_template_path(self): return 'templates/textbox_output.html' - def _post_process(self, prediction): + def postprocess(self, prediction): """ """ return prediction diff --git a/build/lib/gradio/templates/base_template.html b/build/lib/gradio/templates/base_template.html new file mode 100644 index 0000000000..a8e29e925f --- /dev/null +++ b/build/lib/gradio/templates/base_template.html @@ -0,0 +1,28 @@ + + + + Gradio + + + + + + + + + + +
+
+
+ +
+
+
+
+
+ + diff --git a/build/lib/gradio/templates/image_upload_input.html b/build/lib/gradio/templates/image_upload_input.html index f6a2f33b97..ee02413ecb 100644 --- a/build/lib/gradio/templates/image_upload_input.html +++ b/build/lib/gradio/templates/image_upload_input.html @@ -1,31 +1,11 @@ - -
-
Image Upload Input:
- -
-
Click here
or
drag and drop
an image - - -
-
- - -
- - -
- + + + diff --git a/build/lib/gradio/templates/label_output.html b/build/lib/gradio/templates/label_output.html new file mode 100644 index 0000000000..f9303439eb --- /dev/null +++ b/build/lib/gradio/templates/label_output.html @@ -0,0 +1,7 @@ +
+
Output
+
+
+
+
+ diff --git a/dist/gradio-0.2.1-py3-none-any.whl b/dist/gradio-0.3.1-py3-none-any.whl similarity index 95% rename from dist/gradio-0.2.1-py3-none-any.whl rename to dist/gradio-0.3.1-py3-none-any.whl index 1bf896e798..fcd096178e 100644 Binary files a/dist/gradio-0.2.1-py3-none-any.whl and b/dist/gradio-0.3.1-py3-none-any.whl differ diff --git a/dist/gradio-0.3.1.tar.gz b/dist/gradio-0.3.1.tar.gz new file mode 100644 index 0000000000..2d5ea3c796 Binary files /dev/null and b/dist/gradio-0.3.1.tar.gz differ diff --git a/gradio.egg-info/PKG-INFO b/gradio.egg-info/PKG-INFO index 67b60844b1..b51346b024 100644 --- a/gradio.egg-info/PKG-INFO +++ b/gradio.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: gradio -Version: 0.2.1 +Version: 0.3.1 Summary: Python library for easily interacting with trained machine learning models Home-page: https://github.com/abidlabs/gradio Author: Abubakar Abid diff --git a/gradio.egg-info/SOURCES.txt b/gradio.egg-info/SOURCES.txt index a9a72989e6..f1b286bf3b 100644 --- a/gradio.egg-info/SOURCES.txt +++ b/gradio.egg-info/SOURCES.txt @@ -2,6 +2,7 @@ MANIFEST.in README.md setup.py gradio/__init__.py +gradio/imagenet_class_labels.py gradio/inputs.py gradio/interface.py gradio/networking.py @@ -12,50 +13,10 @@ gradio.egg-info/SOURCES.txt gradio.egg-info/dependency_links.txt gradio.egg-info/requires.txt gradio.egg-info/top_level.txt -gradio/css/.DS_Store -gradio/css/bootstrap-grid.css -gradio/css/bootstrap-grid.css.map -gradio/css/bootstrap-grid.min.css -gradio/css/bootstrap-grid.min.css.map -gradio/css/bootstrap-reboot.css -gradio/css/bootstrap-reboot.css.map -gradio/css/bootstrap-reboot.min.css -gradio/css/bootstrap-reboot.min.css.map -gradio/css/bootstrap.css -gradio/css/bootstrap.css.map -gradio/css/bootstrap.min.css -gradio/css/bootstrap.min.css.map -gradio/css/draw-a-digit.css -gradio/css/dropzone.css -gradio/css/index.css -gradio/js/all-io.js -gradio/js/audio-input.js -gradio/js/bootstrap-notify.min.js -gradio/js/bootstrap.bundle.js -gradio/js/bootstrap.bundle.js.map -gradio/js/bootstrap.bundle.min.js -gradio/js/bootstrap.bundle.min.js.map -gradio/js/bootstrap.js -gradio/js/bootstrap.js.map -gradio/js/bootstrap.min.js -gradio/js/bootstrap.min.js.map -gradio/js/class-output.js -gradio/js/draw-a-digit.js -gradio/js/dropzone.js -gradio/js/emotion-detector.js -gradio/js/image-upload-input.js -gradio/js/jquery-3.3.1.min.js -gradio/js/sketchpad-input.js -gradio/js/textbox-input.js -gradio/js/textbox-output.js -gradio/js/webcam-input.js -gradio/templates/all_io.html -gradio/templates/audio_input.html -gradio/templates/class_output.html -gradio/templates/draw_a_digit.html -gradio/templates/emotion_detector.html +gradio/templates/base_template.html gradio/templates/image_upload_input.html -gradio/templates/sketchpad_input.html -gradio/templates/textbox_input.html -gradio/templates/textbox_output.html -gradio/templates/webcam_input.html \ No newline at end of file +gradio/templates/label_output.html +test/test_inputs.py +test/test_interface.py +test/test_networking.py +test/test_outputs.py \ No newline at end of file diff --git a/gradio/outputs.py b/gradio/outputs.py index 281cdb3662..3223ffb1a5 100644 --- a/gradio/outputs.py +++ b/gradio/outputs.py @@ -69,7 +69,6 @@ class Label(AbstractOutput): """ """ response = dict() - print('dddddddddddddddddddd', self.get_label_name(499)) # TODO(abidlabs): check if list, if so convert to numpy array if isinstance(prediction, np.ndarray): prediction = prediction.squeeze() diff --git a/gradio/static/js/class-output.js b/gradio/static/js/class-output.js index 22babf9ba3..5daba2d036 100644 --- a/gradio/static/js/class-output.js +++ b/gradio/static/js/class-output.js @@ -27,19 +27,19 @@ try { sleep(300).then(() => { // $(".output_class").text(event.data); var data = JSON.parse(event.data) - data = { - label: "happy", - confidences : [ - { - label : "happy", - confidence: 0.7 - }, - { - label : "sad", - confidence: 0.3 - }, - ] - } + // data = { + // label: "happy", + // confidences : [ + // { + // label : "happy", + // confidence: 0.7 + // }, + // { + // label : "sad", + // confidence: 0.3 + // }, + // ] + // } $(".output_class").text(data["label"]) $(".confidence_intervals").empty() if ("confidences" in data) { diff --git a/gradio/static/js/image-upload-input.js b/gradio/static/js/image-upload-input.js index 6dec0cdc98..cf9986f015 100644 --- a/gradio/static/js/image-upload-input.js +++ b/gradio/static/js/image-upload-input.js @@ -1,4 +1,4 @@ -var cropper; +// var cropper; $('body').on('click', ".input_image.drop_mode", function (e) { $(this).parent().find(".hidden_upload").click(); @@ -17,10 +17,10 @@ function loadPreviewFromFiles(files) { $(".input_image").removeClass("drop_mode") var image = $(".input_image img") image.attr("src", this.result) - image.cropper({aspectRatio : 1.0}); - if (!cropper) { - cropper = image.data('cropper'); - } + // image.cropper({aspectRatio : 1.0}); + // if (!cropper) { + // cropper = image.data('cropper'); + // } } } @@ -50,10 +50,10 @@ $('body').on('click', '.submit', function(e) { }) $('body').on('click', '.clear', function(e) { - if (cropper) { - cropper.destroy(); - cropper = null - } + // if (cropper) { + // cropper.destroy(); + // cropper = null + // } $(".input_caption").show() $(".input_image img").removeAttr("src"); $(".input_image").addClass("drop_mode") diff --git a/setup.py b/setup.py index 9b55184831..c9ef587a2a 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: setup( name='gradio', - version='0.2.1', + version='0.3.1', include_package_data=True, description='Python library for easily interacting with trained machine learning models', author='Abubakar Abid',