Unverified Commit 66677498 authored by liuzhe-lz's avatar liuzhe-lz Committed by GitHub
Browse files

Merge v1.1 back to master

Merge v1.1 back to master
parents d6b61e2f 5557a2e4
...@@ -8,89 +8,48 @@ import MonacoHTML from '../public-child/MonacoEditor'; ...@@ -8,89 +8,48 @@ import MonacoHTML from '../public-child/MonacoEditor';
import '../../static/style/logDrawer.scss'; import '../../static/style/logDrawer.scss';
interface LogDrawerProps { interface LogDrawerProps {
isVisble: boolean;
closeDrawer: () => void; closeDrawer: () => void;
activeTab?: string; activeTab?: string;
} }
interface LogDrawerState { interface LogDrawerState {
nniManagerLogStr: string; nniManagerLogStr: string | null;
dispatcherLogStr: string; dispatcherLogStr: string | null;
isLoading: boolean; isLoading: boolean;
isLoadispatcher: boolean; logDrawerHeight: number;
} }
class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
private timerId: number | undefined;
public _isLogDrawer: boolean;
constructor(props: LogDrawerProps) { constructor(props: LogDrawerProps) {
super(props); super(props);
this.state = { this.state = {
nniManagerLogStr: 'nnimanager', nniManagerLogStr: null,
dispatcherLogStr: 'dispatcher', dispatcherLogStr: null,
isLoading: false, isLoading: true,
isLoadispatcher: false logDrawerHeight: window.innerHeight - 48
}; };
} }
getNNImanagerLogmessage = () => {
if (this._isLogDrawer === true) {
this.setState({ isLoading: true }, () => {
axios(`${DOWNLOAD_IP}/nnimanager.log`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
setTimeout(() => { this.setNNImanager(res.data); }, 300);
}
});
});
}
}
setDispatcher = (value: string) => {
if (this._isLogDrawer === true) {
this.setState({ isLoadispatcher: false, dispatcherLogStr: value });
}
}
setNNImanager = (val: string) => {
if (this._isLogDrawer === true) {
this.setState({ isLoading: false, nniManagerLogStr: val });
}
}
getdispatcherLogmessage = () => {
if (this._isLogDrawer === true) {
this.setState({ isLoadispatcher: true }, () => {
axios(`${DOWNLOAD_IP}/dispatcher.log`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
setTimeout(() => { this.setDispatcher(res.data); }, 300);
}
});
});
}
}
downloadNNImanager = () => { downloadNNImanager = () => {
const { nniManagerLogStr } = this.state; if (this.state.nniManagerLogStr !== null) {
downFile(nniManagerLogStr, 'nnimanager.log'); downFile(this.state.nniManagerLogStr, 'nnimanager.log');
}
} }
downloadDispatcher = () => { downloadDispatcher = () => {
const { dispatcherLogStr } = this.state; if (this.state.dispatcherLogStr !== null) {
downFile(dispatcherLogStr, 'dispatcher.log'); downFile(this.state.dispatcherLogStr, 'dispatcher.log');
}
} }
dispatcherHTML = () => { dispatcherHTML = () => {
return ( return (
<div> <div>
<span>Dispatcher Log</span> <span>Dispatcher Log</span>
<span className="refresh" onClick={this.getdispatcherLogmessage}> <span className="refresh" onClick={this.manualRefresh}>
<Icon type="sync" /> <Icon type="sync" />
</span> </span>
</div> </div>
...@@ -101,37 +60,28 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -101,37 +60,28 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
return ( return (
<div> <div>
<span>NNImanager Log</span> <span>NNImanager Log</span>
<span className="refresh" onClick={this.getNNImanagerLogmessage}><Icon type="sync" /></span> <span className="refresh" onClick={this.manualRefresh}><Icon type="sync" /></span>
</div> </div>
); );
} }
componentDidMount() { setLogDrawerHeight = () => {
this._isLogDrawer = true; this.setState(() => ({ logDrawerHeight: window.innerHeight - 48 }));
this.getNNImanagerLogmessage();
this.getdispatcherLogmessage();
} }
componentWillReceiveProps(nextProps: LogDrawerProps) { async componentDidMount() {
const { isVisble, activeTab } = nextProps; this.refresh();
if (isVisble === true) { window.addEventListener('resize', this.setLogDrawerHeight);
if (activeTab === 'nnimanager') {
this.getNNImanagerLogmessage();
}
if (activeTab === 'dispatcher') {
this.getdispatcherLogmessage();
}
}
} }
componentWillUnmount() { componentWillUnmount() {
this._isLogDrawer = false; window.clearTimeout(this.timerId);
window.removeEventListener('resize', this.setLogDrawerHeight);
} }
render() { render() {
const { isVisble, closeDrawer, activeTab } = this.props; const { closeDrawer, activeTab } = this.props;
const { nniManagerLogStr, dispatcherLogStr, isLoadispatcher, isLoading } = this.state; const { nniManagerLogStr, dispatcherLogStr, isLoading, logDrawerHeight } = this.state;
const heights: number = window.innerHeight - 48; // padding top and bottom
return ( return (
<Row> <Row>
<Drawer <Drawer
...@@ -139,18 +89,26 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -139,18 +89,26 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
closable={false} closable={false}
destroyOnClose={true} destroyOnClose={true}
onClose={closeDrawer} onClose={closeDrawer}
visible={isVisble} visible={true}
width="76%" width="76%"
height={heights} height={logDrawerHeight}
// className="logDrawer" // className="logDrawer"
> >
<div className="card-container log-tab-body" style={{ height: heights }}> <div className="card-container log-tab-body">
<Tabs type="card" defaultActiveKey={activeTab} style={{ height: heights + 19 }}> <Tabs
type="card"
defaultActiveKey={activeTab}
style={{ height: logDrawerHeight, minHeight: 190 }}
>
{/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */} {/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */}
{/* <TabPane tab="Dispatcher Log" key="dispatcher"> */} {/* <TabPane tab="Dispatcher Log" key="dispatcher"> */}
<TabPane tab={this.dispatcherHTML()} key="dispatcher"> <TabPane tab={this.dispatcherHTML()} key="dispatcher">
<div> <div>
<MonacoHTML content={dispatcherLogStr} loading={isLoadispatcher} /> <MonacoHTML
content={dispatcherLogStr || 'Loading...'}
loading={isLoading}
height={logDrawerHeight - 104}
/>
</div> </div>
<Row className="buttons"> <Row className="buttons">
<Col span={12} className="download"> <Col span={12} className="download">
...@@ -174,7 +132,11 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -174,7 +132,11 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
<TabPane tab={this.nnimanagerHTML()} key="nnimanager"> <TabPane tab={this.nnimanagerHTML()} key="nnimanager">
{/* <TabPane tab="NNImanager Log" key="nnimanager"> */} {/* <TabPane tab="NNImanager Log" key="nnimanager"> */}
<div> <div>
<MonacoHTML content={nniManagerLogStr} loading={isLoading} /> <MonacoHTML
content={nniManagerLogStr || 'Loading...'}
loading={isLoading}
height={logDrawerHeight - 104}
/>
</div> </div>
<Row className="buttons"> <Row className="buttons">
<Col span={12} className="download"> <Col span={12} className="download">
...@@ -201,6 +163,31 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -201,6 +163,31 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
</Row> </Row>
); );
} }
private refresh = () => {
window.clearTimeout(this.timerId);
const dispatcherPromise = axios.get(`${DOWNLOAD_IP}/dispatcher.log`);
const nniManagerPromise = axios.get(`${DOWNLOAD_IP}/nnimanager.log`);
dispatcherPromise.then(res => {
if (res.status === 200) {
this.setState({ dispatcherLogStr: res.data });
}
});
nniManagerPromise.then(res => {
if (res.status === 200) {
this.setState({ nniManagerLogStr: res.data });
}
});
Promise.all([dispatcherPromise, nniManagerPromise]).then(() => {
this.setState({ isLoading: false });
this.timerId = window.setTimeout(this.refresh, 300);
});
}
private manualRefresh = () => {
this.setState({ isLoading: true });
this.refresh();
}
} }
export default LogDrawer; export default LogDrawer;
...@@ -214,7 +214,12 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -214,7 +214,12 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
type="ghost" type="ghost"
> >
<a target="_blank" href="https://nni.readthedocs.io/en/latest/Tutorial/WebUI.html"> <a target="_blank" href="https://nni.readthedocs.io/en/latest/Tutorial/WebUI.html">
<Icon type="question" /><span>Help</span> <img
src={require('../static/img/icon/ques.png')}
alt="question"
className="question"
/>
<span>Help</span>
</a> </a>
</Button> </Button>
</span> </span>
...@@ -329,8 +334,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -329,8 +334,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
render() { render() {
const mobile = (<MediaQuery maxWidth={884}>{this.mobileHTML()}</MediaQuery>); const mobile = (<MediaQuery maxWidth={884}>{this.mobileHTML()}</MediaQuery>);
const tablet = (<MediaQuery minWidth={885} maxWidth={1241}>{this.tabeltHTML()}</MediaQuery>); const tablet = (<MediaQuery minWidth={885} maxWidth={1281}>{this.tabeltHTML()}</MediaQuery>);
const desktop = (<MediaQuery minWidth={1242}>{this.desktopHTML()}</MediaQuery>); const desktop = (<MediaQuery minWidth={1282}>{this.desktopHTML()}</MediaQuery>);
const { isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state; const { isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state;
return ( return (
<div> <div>
...@@ -338,11 +343,12 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -338,11 +343,12 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
{tablet} {tablet}
{desktop} {desktop}
{/* the drawer for dispatcher & nnimanager log message */} {/* the drawer for dispatcher & nnimanager log message */}
<LogDrawer {isvisibleLogDrawer ? (
isVisble={isvisibleLogDrawer} <LogDrawer
closeDrawer={this.closeLogDrawer} closeDrawer={this.closeLogDrawer}
activeTab={activeKey} activeTab={activeKey}
/> />
) : null}
<ExperimentDrawer <ExperimentDrawer
isVisble={isvisibleExperimentDrawer} isVisble={isvisibleExperimentDrawer}
closeExpDrawer={this.closeExpDrawer} closeExpDrawer={this.closeExpDrawer}
......
...@@ -100,10 +100,6 @@ class TrialsDetail extends React.Component<TrialsDetailProps, TrialDetailState> ...@@ -100,10 +100,6 @@ class TrialsDetail extends React.Component<TrialsDetailProps, TrialDetailState>
this.setState({ whichGraph: activeKey }); this.setState({ whichGraph: activeKey });
} }
test = () => {
alert('TableList component was not properly initialized.');
}
updateSearchFilterType = (value: string) => { updateSearchFilterType = (value: string) => {
// clear input value and re-render table // clear input value and re-render table
if (this.searchInput !== null) { if (this.searchInput !== null) {
...@@ -167,14 +163,14 @@ class TrialsDetail extends React.Component<TrialsDetailProps, TrialDetailState> ...@@ -167,14 +163,14 @@ class TrialsDetail extends React.Component<TrialsDetailProps, TrialDetailState>
<Col span={14} className="right"> <Col span={14} className="right">
<Button <Button
className="common" className="common"
onClick={this.tableList ? this.tableList.addColumn : this.test} onClick={() => { if (this.tableList) { this.tableList.addColumn(); }}}
> >
Add column Add column
</Button> </Button>
<Button <Button
className="mediateBtn common" className="mediateBtn common"
// use child-component tableList's function, the function is in child-component. // use child-component tableList's function, the function is in child-component.
onClick={this.tableList ? this.tableList.compareBtn : this.test} onClick={() => { if (this.tableList) { this.tableList.compareBtn(); }}}
> >
Compare Compare
</Button> </Button>
......
...@@ -184,11 +184,12 @@ class Progressed extends React.Component<ProgressProps, ProgressState> { ...@@ -184,11 +184,12 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
</Col> </Col>
</Row> </Row>
{/* learn about click -> default active key is dispatcher. */} {/* learn about click -> default active key is dispatcher. */}
<LogDrawer {isShowLogDrawer ? (
isVisble={isShowLogDrawer} <LogDrawer
closeDrawer={this.closeDrawer} closeDrawer={this.closeDrawer}
activeTab="dispatcher" activeTab="dispatcher"
/> />
) : null}
</Row> </Row>
); );
} }
......
...@@ -6,6 +6,7 @@ import MonacoEditor from 'react-monaco-editor'; ...@@ -6,6 +6,7 @@ import MonacoEditor from 'react-monaco-editor';
interface MonacoEditorProps { interface MonacoEditorProps {
content: string; content: string;
loading: boolean; loading: boolean;
height: number;
} }
class MonacoHTML extends React.Component<MonacoEditorProps, {}> { class MonacoHTML extends React.Component<MonacoEditorProps, {}> {
...@@ -25,18 +26,17 @@ class MonacoHTML extends React.Component<MonacoEditorProps, {}> { ...@@ -25,18 +26,17 @@ class MonacoHTML extends React.Component<MonacoEditorProps, {}> {
} }
render() { render() {
const { content, loading } = this.props; const { content, loading, height } = this.props;
const heights: number = window.innerHeight - 48;
return ( return (
<div className="just-for-log"> <div className="just-for-log">
<Spin <Spin
// tip="Loading..." // tip="Loading..."
style={{ width: '100%', height: heights * 0.9 }} style={{ width: '100%', height: height }}
spinning={loading} spinning={loading}
> >
<MonacoEditor <MonacoEditor
width="100%" width="100%"
height={heights * 0.9} height={height}
language="json" language="json"
value={content} value={content}
options={DRAWEROPTION} options={DRAWEROPTION}
......
...@@ -135,17 +135,17 @@ function generateScatterSeries(trials: Trial[]) { ...@@ -135,17 +135,17 @@ function generateScatterSeries(trials: Trial[]) {
function generateBestCurveSeries(trials: Trial[]) { function generateBestCurveSeries(trials: Trial[]) {
let best = trials[0]; let best = trials[0];
const data = [[ best.sequenceId, best.accuracy, best.info.hyperParameters ]]; const data = [[ best.sequenceId, best.accuracy, best.description.parameters ]];
for (let i = 1; i < trials.length; i++) { for (let i = 1; i < trials.length; i++) {
const trial = trials[i]; const trial = trials[i];
const delta = trial.accuracy! - best.accuracy!; const delta = trial.accuracy! - best.accuracy!;
const better = (EXPERIMENT.optimizeMode === 'minimize') ? (delta < 0) : (delta > 0); const better = (EXPERIMENT.optimizeMode === 'minimize') ? (delta < 0) : (delta > 0);
if (better) { if (better) {
data.push([ trial.sequenceId, trial.accuracy, trial.info.hyperParameters ]); data.push([ trial.sequenceId, trial.accuracy, trial.description.parameters ]);
best = trial; best = trial;
} else { } else {
data.push([ trial.sequenceId, best.accuracy, trial.info.hyperParameters ]); data.push([ trial.sequenceId, best.accuracy, trial.description.parameters ]);
} }
} }
......
...@@ -262,16 +262,10 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -262,16 +262,10 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
<div> <div>
{/* style in para.scss */} {/* style in para.scss */}
<Row className="meline intermediate"> <Row className="meline intermediate">
{/* filter message */}
<span>Filter</span>
<Switch
defaultChecked={false}
onChange={this.switchTurn}
/>
{ {
isFilter isFilter
? ?
<span> <span style={{marginRight: 15}}>
<span className="filter-x"># Intermediate result</span> <span className="filter-x"># Intermediate result</span>
<input <input
// placeholder="point" // placeholder="point"
...@@ -300,6 +294,12 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState> ...@@ -300,6 +294,12 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
: :
null null
} }
{/* filter message */}
<span>Filter</span>
<Switch
defaultChecked={false}
onChange={this.switchTurn}
/>
</Row> </Row>
<Row className="intermediate-graph"> <Row className="intermediate-graph">
<ReactEcharts <ReactEcharts
......
...@@ -251,13 +251,15 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -251,13 +251,15 @@ class TableList extends React.Component<TableListProps, TableListState> {
const showColumn: Array<object> = []; const showColumn: Array<object> = [];
// parameter as table column // parameter as table column
const trialMess = TRIALS.getTrial(tableSource[0].id);
const trial = trialMess.description.parameters;
const parameterColumn: Array<string> = Object.keys(trial);
const parameterStr: Array<string> = []; const parameterStr: Array<string> = [];
parameterColumn.forEach(value => { if (tableSource.length > 0) {
parameterStr.push(`${value} (search space)`); const trialMess = TRIALS.getTrial(tableSource[0].id);
}); const trial = trialMess.description.parameters;
const parameterColumn: Array<string> = Object.keys(trial);
parameterColumn.forEach(value => {
parameterStr.push(`${value} (search space)`);
});
}
showTitle = COLUMNPro.concat(parameterStr); showTitle = COLUMNPro.concat(parameterStr);
// only succeed trials have final keys // only succeed trials have final keys
...@@ -330,20 +332,35 @@ class TableList extends React.Component<TableListProps, TableListState> { ...@@ -330,20 +332,35 @@ class TableList extends React.Component<TableListProps, TableListState> {
<Icon type="line-chart" /> <Icon type="line-chart" />
</Button> </Button>
{/* kill job */} {/* kill job */}
<Popconfirm {
title="Are you sure to cancel this trial?" flag
onConfirm={killJob. ?
bind(this, record.key, record.id, record.status)} <Button
> type="default"
<Button disabled={true}
type="default" className="margin-mediate special"
disabled={flag} title="kill"
className="margin-mediate special" >
title="kill" <Icon type="stop" />
> </Button>
<Icon type="stop" /> :
</Button> <Popconfirm
</Popconfirm> title="Are you sure to cancel this trial?"
okText="Yes"
cancelText="No"
onConfirm={killJob.
bind(this, record.key, record.id, record.status)}
>
<Button
type="default"
disabled={false}
className="margin-mediate special"
title="kill"
>
<Icon type="stop" />
</Button>
</Popconfirm>
}
</Row> </Row>
); );
}, },
......
...@@ -43,7 +43,7 @@ class Trial implements TableObj { ...@@ -43,7 +43,7 @@ class Trial implements TableObj {
} }
get sortable(): boolean { get sortable(): boolean {
return this.finalAcc !== undefined && !isNaN(this.finalAcc); return this.metricsInitialized && this.finalAcc !== undefined && !isNaN(this.finalAcc);
} }
/* table obj start */ /* table obj start */
...@@ -132,7 +132,7 @@ class Trial implements TableObj { ...@@ -132,7 +132,7 @@ class Trial implements TableObj {
/* table obj end */ /* table obj end */
public initialized(): boolean { public initialized(): boolean {
return !!(this.infoField && this.metricsInitialized); return Boolean(this.infoField);
} }
public updateMetrics(metrics: MetricDataRecord[]): boolean { public updateMetrics(metrics: MetricDataRecord[]): boolean {
......
...@@ -6,7 +6,7 @@ Button.tableButton{ ...@@ -6,7 +6,7 @@ Button.tableButton{
border-color: $btnBgcolor; border-color: $btnBgcolor;
height: 26px; height: 26px;
font-size: 14px; font-size: 14px;
margin-top: 2px; margin-top: 4px;
border-radius: 0; border-radius: 0;
} }
......
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
height: 100%; height: 100%;
} }
/* log drawer download & close button's row */
.buttons{ .buttons{
margin-top: 11px; margin-top: 16px;
.close{ .close{
text-align: right; text-align: right;
} }
......
...@@ -21,7 +21,7 @@ $drowHoverBgColor: #e2e2e2; ...@@ -21,7 +21,7 @@ $drowHoverBgColor: #e2e2e2;
padding-bottom: 14px; padding-bottom: 14px;
.down-icon{ .down-icon{
font-size: 20px !important; font-size: 20px !important;
padding-right: 2px; padding-right: 6px;
} }
} }
...@@ -186,6 +186,11 @@ $drowHoverBgColor: #e2e2e2; ...@@ -186,6 +186,11 @@ $drowHoverBgColor: #e2e2e2;
width: 20px; width: 20px;
margin-right: 8px; margin-right: 8px;
} }
/* ? icon style */
.question{
width: 14px;
margin-right: 4px;
}
.feedback{ .feedback{
font-size: 16px; font-size: 16px;
margin: 0 20px; margin: 0 20px;
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
.ant-tabs-tab-active{ .ant-tabs-tab-active{
.panelTitle{ .panelTitle{
background-color: #999; background-color: #999;
/*
span{ span{
color: #fff; color: #fff;
font-weight: normal; font-weight: normal;
} }
*/
} }
} }
.panelTitle{ .panelTitle{
......
...@@ -3,10 +3,11 @@ import sys ...@@ -3,10 +3,11 @@ import sys
import os import os
import signal import signal
import psutil import psutil
from .common_utils import print_error, print_normal, print_warning from .common_utils import print_error, print_normal, print_warning
def check_output_command(file_path, head=None, tail=None): def check_output_command(file_path, head=None, tail=None):
'''call check_output command to read content from a file''' """call check_output command to read content from a file"""
if os.path.exists(file_path): if os.path.exists(file_path):
if sys.platform == 'win32': if sys.platform == 'win32':
cmds = ['powershell.exe', 'type', file_path] cmds = ['powershell.exe', 'type', file_path]
...@@ -26,8 +27,9 @@ def check_output_command(file_path, head=None, tail=None): ...@@ -26,8 +27,9 @@ def check_output_command(file_path, head=None, tail=None):
print_error('{0} does not exist!'.format(file_path)) print_error('{0} does not exist!'.format(file_path))
exit(1) exit(1)
def kill_command(pid): def kill_command(pid):
'''kill command''' """kill command"""
if sys.platform == 'win32': if sys.platform == 'win32':
process = psutil.Process(pid=pid) process = psutil.Process(pid=pid)
process.send_signal(signal.CTRL_BREAK_EVENT) process.send_signal(signal.CTRL_BREAK_EVENT)
...@@ -35,21 +37,35 @@ def kill_command(pid): ...@@ -35,21 +37,35 @@ def kill_command(pid):
cmds = ['kill', str(pid)] cmds = ['kill', str(pid)]
call(cmds) call(cmds)
def install_package_command(package_name): def install_package_command(package_name):
'''install python package from pip''' """
#TODO refactor python logic Install python package from pip.
if sys.platform == "win32":
cmds = 'python -m pip install --user {0}'.format(package_name) Parameters
else: ----------
cmds = 'python3 -m pip install --user {0}'.format(package_name) package_name: str
call(cmds, shell=True) The name of package to be installed.
"""
call(_get_pip_install() + [package_name], shell=False)
def install_requirements_command(requirements_path): def install_requirements_command(requirements_path):
'''install requirements.txt''' """
cmds = 'cd ' + requirements_path + ' && {0} -m pip install --user -r requirements.txt' Install packages from `requirements.txt` in `requirements_path`.
#TODO refactor python logic
if sys.platform == "win32": Parameters
cmds = cmds.format('python') ----------
else: requirements_path: str
cmds = cmds.format('python3') Path to the directory that contains `requirements.txt`.
call(cmds, shell=True) """
call(_get_pip_install() + ["-r", os.path.join(requirements_path, "requirements.txt")], shell=False)
def _get_pip_install():
python = "python" if sys.platform == "win32" else "python3"
ret = [python, "-m", "pip", "install"]
if "CONDA_DEFAULT_ENV" not in os.environ and "VIRTUAL_ENV" not in os.environ and \
(sys.platform != "win32" and os.getuid() != 0): # on unix and not running in root
ret.append("--user") # not in virtualenv or conda
return ret
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment