Skip to content

Commit

Permalink
init repo
Browse files Browse the repository at this point in the history
  • Loading branch information
xzyaoi committed Sep 8, 2018
0 parents commit 84c848e
Show file tree
Hide file tree
Showing 12 changed files with 666 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PYTHONPATH = "./"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cvpm.egg-info/
*.pyc
.vscode
23 changes: 23 additions & 0 deletions Makefile
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
29 changes: 29 additions & 0 deletions Pipfile
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 = "*"
397 changes: 397 additions & 0 deletions Pipfile.lock

Large diffs are not rendered by default.

Empty file added README.md
Empty file.
91 changes: 91 additions & 0 deletions cvpm/Server.py
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()
49 changes: 49 additions & 0 deletions cvpm/Solver.py
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)
61 changes: 61 additions & 0 deletions cvpm/Utility.py
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 added cvpm/__init__.py
Empty file.
Empty file added setup.py
Empty file.
12 changes: 12 additions & 0 deletions tests/network.py
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()

0 comments on commit 84c848e

Please sign in to comment.