-
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 84c848e
Showing
12 changed files
with
666 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
PYTHONPATH = "./" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
cvpm.egg-info/ | ||
*.pyc | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
default: | ||
@echo "Usage:" | ||
@echo "\tmake test" | ||
@echo "\tmake format" | ||
@echo "\tmake docs" | ||
|
||
test: | ||
|
||
|
||
format: | ||
autoflake -i cvpm/*.py | ||
# autoflake -i cvpm/**/*.py | ||
|
||
isort -i cvpm/*.py | ||
# isort -i cvpm/**/*.py | ||
|
||
yapf -i cvpm/*.py | ||
# yapf -i cvpm/**/*.py | ||
|
||
docs: | ||
cd docs && npm run docs:build | ||
|
||
.PHONY: docs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
[[source]] | ||
|
||
verify_ssl = true | ||
name = "pypi" | ||
url = "https://pypi.python.org/simple" | ||
|
||
|
||
[packages] | ||
|
||
flask = "*" | ||
tqdm = "*" | ||
toml = "*" | ||
requests = "*" | ||
pillow = "*" | ||
numpy = "*" | ||
autoflake = "*" | ||
isort = "*" | ||
yapf = "*" | ||
gevent = "*" | ||
|
||
|
||
[requires] | ||
|
||
python_version = "3.5" | ||
|
||
|
||
[dev-packages] | ||
|
||
pylint = "*" |
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import os | ||
import json | ||
import socket | ||
import traceback | ||
import logging | ||
import gevent.pywsgi | ||
from flask import g | ||
from flask import Flask | ||
from flask import request | ||
from werkzeug.utils import secure_filename | ||
|
||
logger = logging.getLogger() | ||
logger.setLevel("INFO") | ||
server = Flask(__name__) | ||
|
||
ALLOWED_EXTENSIONS_TRAIN = set(['zip']) | ||
ALLOWED_EXTENSIONS_INFER = set(['jpg', 'jpeg', 'png']) | ||
UPLOAD_FOLDER = './temp' | ||
|
||
server.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | ||
|
||
def _isPortOpen(port): | ||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
result = s.connect_ex(('127.0.0.1', port)) | ||
if result == 0: | ||
return True | ||
else: | ||
return False | ||
s.close() | ||
|
||
|
||
def get_available_port(start=8080): | ||
port = start | ||
while True: | ||
if _isPortOpen(port): | ||
port = port + 1 | ||
else: | ||
break | ||
return port | ||
|
||
def allowed_file(filename, phase): | ||
ALLOWED_EXTENSIONS = ALLOWED_EXTENSIONS_TRAIN | ||
if phase == 'infer': | ||
ALLOWED_EXTENSIONS = ALLOWED_EXTENSIONS_INFER | ||
return '.' in filename and \ | ||
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | ||
|
||
|
||
@server.route("/") | ||
def help(): | ||
help_message = server.solver.help_message | ||
return help_message | ||
|
||
|
||
@server.route("/infer", methods=["GET", "POST"]) | ||
def infer(): | ||
if request.method == 'POST': | ||
results = {} | ||
config = request.json | ||
print(request) | ||
if 'file' not in request.files: | ||
return json.dumps({"error": "no file part!", "code": "400"}), 400 | ||
file = request.files['file'] | ||
if file and allowed_file(file.filename, 'infer'): | ||
filename = secure_filename(file.filename) | ||
file_abs_path = os.path.join(server.config['UPLOAD_FOLDER'], filename) | ||
file.save(file_abs_path) | ||
try: | ||
results = server.solver.infer(file_abs_path, config) | ||
return json.dumps(results), 200 | ||
except Exception as e: | ||
traceback.print_exc() | ||
return json.dumps({"error": str(e), "code":"500"}), 500 | ||
else: | ||
return json.dumps({"error": "Forbidden Filename!", "code": "400"}), 400 | ||
|
||
@server.route("/train", methods=["GET", "POST"]) | ||
def train(): | ||
if server.solver.enable_train: | ||
pass | ||
else: | ||
return json.dumps({"error": "not supported!", "code": "404"}), 404 | ||
|
||
|
||
def run_server(solver): | ||
port = get_available_port() | ||
logger.info("Server Running On: " + str(port)) | ||
with server.app_context(): | ||
server.solver = solver | ||
gevent_server = gevent.pywsgi.WSGIServer(('', port), server) | ||
gevent_server.serve_forever() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import json | ||
|
||
import requests | ||
import toml | ||
import tqdm | ||
|
||
from cvpm.Server import run_server | ||
from cvpm.Utility import BundleAnalyzer, Downloader | ||
|
||
|
||
class Solver(object): | ||
def __init__(self, toml_file=None): | ||
self._isReady = False | ||
self.bundle = {} | ||
self._enable_train = False | ||
if toml_file is None: | ||
toml_file = "./pretrained/pretrained.toml" | ||
self._prepare_models(toml_file) | ||
|
||
@property | ||
def enable_train(self): | ||
return self._enable_train | ||
|
||
@property | ||
def is_ready(self): | ||
return self._isReady | ||
|
||
@property | ||
def help_message(self): | ||
ba = BundleAnalyzer(self.bundle) | ||
return json.dumps(ba.load()) | ||
|
||
def _prepare_models(self, toml_file): | ||
parsed_toml = toml.load(toml_file) | ||
downloader = Downloader() | ||
for each in parsed_toml["models"]: | ||
downloader.download(each["url"], "pretrained") | ||
|
||
def set_ready(self): | ||
self._isReady = True | ||
|
||
def infer(self, input, config): | ||
pass | ||
|
||
def train(self, train_x, train_y, **kwargs): | ||
pass | ||
|
||
def start(self): | ||
run_server(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import os | ||
from urllib.request import urlopen | ||
|
||
import numpy as np | ||
import PIL.Image | ||
import requests | ||
from tqdm import tqdm | ||
|
||
|
||
def load_image_file(file, mode='RGB'): | ||
im = PIL.Image.open(file) | ||
if mode: | ||
im = im.convert(mode) | ||
return np.array(im) | ||
|
||
|
||
class Downloader(object): | ||
def __init__(self): | ||
pass | ||
|
||
def download(self, url, target): | ||
filename = url.split('/')[-1] | ||
file_size = int(urlopen(url).info().get('Content-Length', -1)) | ||
chunk_size = 1024 | ||
bars = int(file_size / chunk_size) | ||
dest = os.path.join(target, filename) | ||
if os.path.exists(dest): | ||
first_byte = os.path.getsize(dest) | ||
else: | ||
first_byte = 0 | ||
if first_byte >= file_size: | ||
return file_size | ||
header = {"Range": "bytes=%s-%s" % (first_byte, file_size)} | ||
pbar = tqdm( | ||
total=file_size, | ||
initial=first_byte, | ||
unit='B', | ||
unit_scale=True, | ||
desc=filename) | ||
req = requests.get(url, headers=header, stream=True) | ||
with open(dest, 'ab') as f: | ||
for chunk in req.iter_content(chunk_size=chunk_size): | ||
if chunk: | ||
f.write(chunk) | ||
pbar.update(1024) | ||
pbar.close() | ||
return file_size | ||
|
||
|
||
class BundleAnalyzer(object): | ||
def __init__(self, bundle): | ||
self.bundle = bundle | ||
|
||
def load(self): | ||
result = {} | ||
for name, value in vars(self.bundle).items(): | ||
if name not in [ | ||
"__doc__", "__module__", "__dict__", "__weakref__" | ||
]: | ||
result[name] = value | ||
return result |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import unittest | ||
|
||
from cvpm.Server import get_available_port | ||
|
||
class NetworkTester(unittest.TestCase): | ||
|
||
def test_available_port(self): | ||
print (get_available_port(8080)) | ||
self.assertTrue(True) | ||
|
||
if __name__ == "__main__": | ||
unittest.main() |