├── src ├── assets │ └── styles │ │ ├── style.js │ │ └── main.css ├── components │ ├── Subcomponent.jsx │ ├── Home.jsx │ ├── About.jsx │ └── App.jsx ├── tests │ ├── __snapshots__ │ │ └── Home.test.js.snap │ └── Home.test.js ├── reducers │ ├── index.js │ └── itemReducer.js ├── index.html ├── config │ ├── client.js │ └── .eslintrc.js ├── routes.js ├── index.js ├── store.js └── actions │ └── items.js ├── .gitignore ├── requirements.txt ├── .travis.yml ├── server ├── tests │ └── test_api.py └── app.py ├── LICENSE ├── README.md ├── package.json ├── webpack.config.js └── .pylintrc /src/assets/styles/style.js: -------------------------------------------------------------------------------- 1 | import './main.css'; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pem 3 | *.pyc 4 | *.DS_Store 5 | .cache 6 | node_modules 7 | build 8 | __pycache__ -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.12.2 2 | Flask-Cors==3.0.3 3 | gunicorn==19.7.1 4 | pylint==1.8.2 5 | pymongo==3.3.1 6 | pytest==3.0.6 7 | werkzeug==0.16.1 -------------------------------------------------------------------------------- /src/components/Subcomponent.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default (props) => ( 4 |
5 | Subcomponent 6 |
7 | ) -------------------------------------------------------------------------------- /src/components/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Home = (props) => ( 4 |
5 | Home 6 |
7 | ) 8 | 9 | export default Home; -------------------------------------------------------------------------------- /src/tests/__snapshots__/Home.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renders 1`] = ` 4 |
7 | Home 8 |
9 | `; 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - 3.6.1 5 | 6 | install: 7 | - pip install -r requirements.txt 8 | - nvm install 9.2.0 9 | - npm install --no-optional 10 | 11 | script: 12 | - npm run test -------------------------------------------------------------------------------- /src/assets/styles/main.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | height: 100%; 3 | width: 100%; 4 | } 5 | 6 | * { 7 | margin: 0; 8 | padding: 0; 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | font-family: Open Sans; 14 | } -------------------------------------------------------------------------------- /src/tests/Home.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Home from '../components/Home'; 3 | import renderer from 'react-test-renderer'; 4 | 5 | it('renders', () => { 6 | const tree = renderer 7 | .create() 8 | .toJSON(); 9 | expect(tree).toMatchSnapshot(); 10 | }); -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import itemReducer from './itemReducer'; 3 | import { connectRouter } from 'connected-react-router'; 4 | 5 | export const rootReducer = history => combineReducers({ 6 | items: itemReducer, 7 | router: connectRouter(history), 8 | }); -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello! 6 | 7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /src/config/client.js: -------------------------------------------------------------------------------- 1 | let config = { 2 | api: { 3 | protocol: 'http', 4 | host: 'localhost', 5 | port: 7082, 6 | prefix: 'api' 7 | }, 8 | }; 9 | 10 | config.endpoint = config.api.protocol + '://' + 11 | config.api.host + ':' + 12 | config.api.port + '/' + 13 | config.api.prefix + '/'; 14 | 15 | module.exports = config; -------------------------------------------------------------------------------- /src/components/About.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Subcomponent from './Subcomponent'; 3 | import { Route, Switch } from 'react-router-dom'; 4 | 5 | const About = (props) => ( 6 |
7 | About 8 | 9 | 10 | 11 |
12 | ) 13 | 14 | export default About; -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route, Switch } from 'react-router-dom'; 3 | import App from './components/App'; 4 | import Home from './components/Home'; 5 | import About from './components/About'; 6 | 7 | const routes = ( 8 | 9 | 10 | 11 | 12 | 13 | 14 | ) 15 | 16 | export { routes }; -------------------------------------------------------------------------------- /src/components/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | export default class AppWrapper extends React.Component { 5 | render() { 6 | return ( 7 |
8 | Home 9 | About 10 | Subcomponent 11 | {this.props.children} 12 |
13 | ) 14 | } 15 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import 'babel-polyfill'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import { Provider } from 'react-redux'; 5 | import { store, history } from './store'; 6 | import { routes } from './routes'; 7 | import { ConnectedRouter } from 'connected-react-router'; 8 | import './assets/styles/style'; 9 | 10 | // render the main component 11 | ReactDOM.render( 12 | 13 | 14 | {routes} 15 | 16 | , 17 | document.getElementById('app') 18 | ); -------------------------------------------------------------------------------- /server/tests/test_api.py: -------------------------------------------------------------------------------- 1 | '''API test suite''' 2 | import sys, os, json 3 | sys.path.insert(0, 'server') 4 | sys.path.insert(0, '..') 5 | sys.path.insert(0, '.') 6 | 7 | # import the Flask module 8 | from app import app 9 | 10 | # indicate tests are running 11 | app.testing = True 12 | 13 | # generate a test client 14 | app = app.test_client() 15 | 16 | def test_api_data(): 17 | data = app.get('/api/items').get_data(as_text=True) 18 | assert('title' in json.loads(data)[0]) 19 | 20 | def test_index_response(): 21 | response = app.get('/') 22 | assert(response.status_code == 200) -------------------------------------------------------------------------------- /server/app.py: -------------------------------------------------------------------------------- 1 | '''server/app.py - main api app declaration''' 2 | from flask import Flask, jsonify, send_from_directory 3 | from flask_cors import CORS 4 | 5 | '''Main wrapper for app creation''' 6 | app = Flask(__name__, static_folder='../build') 7 | CORS(app) 8 | 9 | ## 10 | # API routes 11 | ## 12 | 13 | @app.route('/api/items') 14 | def items(): 15 | '''Sample API route for data''' 16 | return jsonify([{'title': 'A'}, {'title': 'B'}]) 17 | 18 | ## 19 | # View route 20 | ## 21 | 22 | @app.route('/', defaults={'path': ''}) 23 | @app.route('/') 24 | def index(path): 25 | '''Return index.html for all non-api routes''' 26 | #pylint: disable=unused-argument 27 | return send_from_directory(app.static_folder, 'index.html') -------------------------------------------------------------------------------- /src/config/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "jest": true, 7 | "node": true, 8 | }, 9 | "extends": "eslint:recommended", 10 | "rules": { 11 | "indent": ["error", 2, { "SwitchCase": 1 }], 12 | "linebreak-style": ["error", "unix"], 13 | "no-console": [ 0 ], 14 | "no-empty": [ 0 ], 15 | "no-undef": ["error", { "typeof": false }], 16 | "no-unused-vars": ["error", { "varsIgnorePattern": "React" }], 17 | "quotes": ["error", "single"], 18 | "react/jsx-uses-vars": [ 2 ], 19 | }, 20 | "plugins": [ 21 | "react", 22 | ], 23 | "parser": "babel-eslint", 24 | "parserOptions": { 25 | "ecmaFeatures": { 26 | "jsx": true, 27 | "modules": true, 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /src/reducers/itemReducer.js: -------------------------------------------------------------------------------- 1 | const initialState = { 2 | searches: 0, 3 | isFetching: false, 4 | items: [], 5 | err: null, 6 | } 7 | 8 | const itemReducer = (state = initialState, action) => { 9 | switch (action.type) { 10 | case 'INCREMENT_SEARCHES': 11 | return Object.assign({}, state, { 12 | searches: state.searches + 1, 13 | }) 14 | case 'DECREMENT_SEARCHES': 15 | return Object.assign({}, state, { 16 | searches: state.searches - 1, 17 | }) 18 | case 'REQUEST_ITEMS': 19 | return Object.assign({}, state, { 20 | isFetching: true, 21 | }) 22 | case 'RECEIVE_ITEMS': 23 | return Object.assign({}, state, { 24 | isFetching: false, 25 | items: action.items, 26 | }) 27 | case 'ITEM_REQUEST_FAILED': 28 | return Object.assign({}, state, { 29 | err: action.err, 30 | }) 31 | default: 32 | return state; 33 | } 34 | } 35 | 36 | export default itemReducer; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2020 Yale University 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux'; 2 | import { routerMiddleware } from 'connected-react-router'; 3 | import { rootReducer } from './reducers/index'; 4 | import { createBrowserHistory } from 'history'; 5 | import { fetchItems } from './actions/items'; 6 | import { createLogger } from 'redux-logger'; 7 | import thunkMiddleware from 'redux-thunk'; 8 | import config from './config/client'; 9 | import freeze from 'redux-freeze'; 10 | 11 | const history = createBrowserHistory(); 12 | const loggerMiddleware = createLogger(); 13 | 14 | let middlewares = [ 15 | thunkMiddleware, 16 | routerMiddleware(history) 17 | ]; 18 | 19 | // add the freeze dev middleware 20 | if (process.env.NODE_ENV !== 'production') { 21 | middlewares.push(freeze) 22 | middlewares.push(loggerMiddleware) 23 | } 24 | 25 | // create the store 26 | const store = createStore( 27 | rootReducer(history), 28 | applyMiddleware(...middlewares), 29 | ); 30 | 31 | // initialize app state 32 | store.dispatch(fetchItems(config.endpoint + 'items')); 33 | 34 | export { store, history }; -------------------------------------------------------------------------------- /src/actions/items.js: -------------------------------------------------------------------------------- 1 | import fetch from 'isomorphic-fetch'; 2 | 3 | export const incrementSearches = () => ({ 4 | type: 'INCREMENT_SEARCHES' 5 | }) 6 | 7 | export const decrementSearches = () => ({ 8 | type: 'DECREMENT_SEARCHES' 9 | }) 10 | 11 | export const requestItems = (query) => ({ 12 | type: 'REQUEST_ITEMS', query 13 | }) 14 | 15 | export const receiveItems = (items) => ({ 16 | type: 'RECEIVE_ITEMS', items 17 | }) 18 | 19 | export const itemRequestFailed = (err) => ({ 20 | type: 'ITEM_REQUEST_FAILED', err 21 | }) 22 | 23 | export function fetchItems(query) { 24 | return function(dispatch) { 25 | dispatch(requestItems(query)) 26 | dispatch(incrementSearches()) 27 | return fetch(query) 28 | .then(response => response.json() 29 | .then(json => ({ 30 | status: response.status, 31 | json 32 | }))) 33 | .then(({ status, json }) => { 34 | if (status >= 400) dispatch(itemRequestFailed()) 35 | else dispatch(receiveItems(json)) 36 | }, err => { dispatch(itemRequestFailed(err)) }) 37 | } 38 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note: This repository has been archived 2 | This project was developed under a previous phase of the Yale Digital Humanities Lab. Now a part of Yale Library’s Computational Methods and Data department, the Lab no longer includes this project in its scope of work. As such, it will receive no further updates. 3 | 4 | 5 | # Flask React Boilerplate 6 | 7 | [![Build Status](https://travis-ci.org/YaleDHLab/flask-react-boilerplate.svg?branch=master)](https://travis-ci.org/YaleDHLab/flask-react-boilerplate) 8 | 9 | Simple boilerplate for a Flask backend and React client including: 10 | 11 | * ES6 transpiling via Webpack 12 | * Hot module reloading via Webpack Dev Server 13 | * State management via Redux 14 | * Tests via Pytest and Jest 15 | * Linting via Pylint and Eslint 16 | * Travis CI for automatic testing and linting 17 | 18 | ## Dependencies 19 | 20 | To install the boilerplate dependencies, you can run: 21 | 22 | ```bash 23 | git clone https://github.com/YaleDHLab/flask-react-boilerplate 24 | cd flask-react-boilerplate 25 | npm install --no-optional 26 | pip install -r requirements.txt 27 | ``` 28 | 29 | ## Quickstart 30 | 31 | Once the dependencies are installed, you can start the api with the following command: 32 | 33 | ```bash 34 | npm run production 35 | ``` 36 | 37 | That will start the server on port 7082. To run the development server with hot module reloading, run: 38 | 39 | ```bash 40 | npm run start 41 | ``` 42 | 43 | That will start the webpack dev server on port 7081. 44 | 45 | ## Tests 46 | 47 | To run the Javascript tests (located in `src/tests/`), run: 48 | 49 | ```bash 50 | npm run jest 51 | ``` 52 | 53 | To run the Python tests (located in `server/tests/`), run: 54 | 55 | ```bash 56 | pytest 57 | ``` 58 | 59 | ## Linting 60 | 61 | To lint the Javascript files (located in `src`), run: 62 | 63 | ```bash 64 | npm run lint-js 65 | ``` 66 | 67 | To lint the Python files (located in `server`), run: 68 | 69 | ```bash 70 | npm run lint-py 71 | ``` 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flask-react-boilerplate", 3 | "version": "0.1.0", 4 | "author": "Yale DH Lab", 5 | "license": "MIT", 6 | "description": "Minimal boilerplate for a Flask + React application", 7 | "main": "server/server.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/duhaime/react-boilerplate.git" 11 | }, 12 | "scripts": { 13 | "start": "webpack-dev-server --port 7081 --history-api-fallback --mode=development", 14 | "build": "webpack --config webpack.config.js --mode=production", 15 | "compress": "webpack --config webpack.config.js --mode=production", 16 | "production": "npm run build && npm run serve", 17 | "serve": "FLASK_APP=server/app.py flask run --port=7082", 18 | "lint-js": "eslint -c './src/config/.eslintrc.js' src/", 19 | "lint-py": "pylint server/app.py", 20 | "lint": "npm run lint-js && npm run lint-py", 21 | "jest": "jest", 22 | "test": "npm run build && npm run lint && npm run jest && pytest" 23 | }, 24 | "dependencies": { 25 | "@babel/core": "^7.5.5", 26 | "babel-polyfill": "^6.26.0", 27 | "connected-react-router": "^6.5.2", 28 | "history": "^4.7.2", 29 | "isomorphic-fetch": "^2.2.1", 30 | "jest": "^24.9.0", 31 | "react": "^16.8.6", 32 | "react-dom": "^16.8.6", 33 | "react-redux": "^7.1.0", 34 | "react-router": "^5.0.1", 35 | "react-router-dom": "^5.0.1", 36 | "redux": "^4.0.4", 37 | "redux-freeze": "^0.1.5", 38 | "redux-logger": "^3.0.6", 39 | "redux-thunk": "^2.2.0" 40 | }, 41 | "devDependencies": { 42 | "@babel/preset-env": "^7.5.5", 43 | "@babel/preset-react": "^7.0.0", 44 | "babel-core": "^6.17.0", 45 | "babel-eslint": "^10.0.3", 46 | "babel-loader": "^8.0.6", 47 | "babel-preset-react-hmre": "^1.1.1", 48 | "clean-webpack-plugin": "^3.0.0", 49 | "compression-webpack-plugin": "^3.0.0", 50 | "copy-webpack-plugin": "^5.0.3", 51 | "css-loader": "^3.1.0", 52 | "eslint": "^6.6.0", 53 | "eslint-plugin-react": "^7.16.0", 54 | "file-loader": "^4.1.0", 55 | "html-webpack-plugin": "^3.2.0", 56 | "json-loader": "^0.5.4", 57 | "jsx-loader": "^0.13.2", 58 | "lodash": "^4.17.15", 59 | "mini-css-extract-plugin": "^0.8.0", 60 | "optimize-css-assets-webpack-plugin": "^5.0.3", 61 | "prop-types": "^15.5.10", 62 | "react-test-renderer": "^16.11.0", 63 | "style-loader": "^0.23.1", 64 | "webpack": "^4.36.1", 65 | "webpack-cli": "^3.3.6", 66 | "webpack-dev-server": "^3.7.2", 67 | "webpack-merge": "^4.1.0" 68 | }, 69 | "babel": { 70 | "presets": [ 71 | "@babel/env", 72 | "@babel/react" 73 | ], 74 | "env": { 75 | "start": { 76 | "presets": [ 77 | "@babel/env", 78 | "@babel/react" 79 | ] 80 | } 81 | } 82 | }, 83 | "jest": { 84 | "testEnvironment": "node" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 2 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | const merge = require('webpack-merge'); 7 | const webpack = require('webpack'); 8 | const path = require('path'); 9 | 10 | const paths = { 11 | src: path.resolve(__dirname, 'src'), 12 | build: path.resolve(__dirname, 'build') 13 | } 14 | 15 | const htmlConfig = { 16 | template: path.join(paths.src, 'index.html'), 17 | minify : { 18 | collapseWhitespace: true, 19 | } 20 | } 21 | 22 | const common = { 23 | entry: path.join(paths.src, 'index.js'), 24 | resolve: { 25 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 26 | }, 27 | output: { 28 | path: paths.build, 29 | filename: 'bundle.[hash].js', 30 | publicPath: '/', 31 | }, 32 | performance: { 33 | hints: false, 34 | }, 35 | module: { 36 | rules: [ 37 | { 38 | test: /\.(js|jsx)$/, 39 | exclude: /(node_modules)/, 40 | use: { 41 | loader: 'babel-loader', 42 | options: { 43 | presets: ['@babel/env'] 44 | } 45 | } 46 | }, 47 | { 48 | test: /\.(ts)$/, 49 | exclude: /(node_modules)/, 50 | use: { 51 | loader: 'awesome-typescript-loader', 52 | options: { 53 | useCache: false, 54 | } 55 | } 56 | }, 57 | { 58 | test: /\.(css)$/, 59 | use: [ 60 | { 61 | loader: MiniCssExtractPlugin.loader, 62 | options: { 63 | hmr: process.env.NODE_ENV === 'development', 64 | }, 65 | }, 66 | 'css-loader', 67 | ], 68 | }, 69 | { 70 | test: /\.(png|jpg|gif)$/, 71 | exclude: /(node_modules)/, 72 | use: [ 73 | { 74 | loader: 'file-loader', 75 | options: {} 76 | } 77 | ] 78 | } 79 | ] 80 | }, 81 | plugins: [ 82 | new CleanWebpackPlugin(), 83 | new HtmlWebpackPlugin(htmlConfig), 84 | new MiniCssExtractPlugin({ 85 | filename: '[name].css', 86 | chunkFilename: '[id].css', 87 | ignoreOrder: false, 88 | }), 89 | ] 90 | }; 91 | 92 | const devSettings = { 93 | devtool: 'eval-source-map', 94 | devServer: { 95 | historyApiFallback: true, 96 | quiet: false, 97 | }, 98 | plugins: [ 99 | new webpack.HotModuleReplacementPlugin(), 100 | new CleanWebpackPlugin(), 101 | ] 102 | } 103 | 104 | const prodSettings = { 105 | optimization: { 106 | minimize: true, 107 | }, 108 | devtool: 'source-map', 109 | plugins: [ 110 | new webpack.DefinePlugin({ 'process.env': { 111 | NODE_ENV: JSON.stringify('production') 112 | }}), 113 | new OptimizeCssAssetsPlugin(), 114 | new webpack.optimize.OccurrenceOrderPlugin(), 115 | ] 116 | } 117 | 118 | /** 119 | * Exports 120 | **/ 121 | 122 | const TARGET = process.env.npm_lifecycle_event; 123 | process.env.BABEL_ENV = TARGET; 124 | 125 | if (TARGET === 'start') { 126 | module.exports = merge(common, devSettings) 127 | } 128 | 129 | if (TARGET === 'build' || !TARGET) { 130 | module.exports = merge(common, prodSettings) 131 | } -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | # Pylint output cheatsheet: 2 | # [R]efactor for a “good practice” metric violation 3 | # [C]onvention for coding standard violation 4 | # [W]arning for stylistic problems, or minor programming issues 5 | # [E]rror for important programming issues (i.e. most probably bug) 6 | # [F]atal for errors which prevented further processing 7 | 8 | [MASTER] 9 | 10 | # Use multiple processes to speed up Pylint. 11 | jobs=4 12 | 13 | # Only show warnings with the listed confidence levels. Leave empty to show 14 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED 15 | confidence= 16 | 17 | 18 | [REPORTS] 19 | 20 | # Python expression which should return a note less than 10 (10 is the highest 21 | # note). You have access to the variables errors warning, statement which 22 | # respectively contain the number of errors / warnings messages and the total 23 | # number of statements analyzed. This is used by the global evaluation report 24 | # (RP0004). 25 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 26 | 27 | # Set the output format. Available formats are text, parseable, colorized, json 28 | # and msvs (visual studio).You can also give a reporter class, eg 29 | # mypackage.mymodule.MyReporterClass. 30 | output-format=text 31 | 32 | # Tells whether to display a full report or only the messages 33 | reports=no 34 | 35 | # Activate the evaluation score. 36 | score=yes 37 | 38 | 39 | [REFACTORING] 40 | 41 | # Maximum number of nested blocks for function / method body 42 | max-nested-blocks=5 43 | 44 | 45 | [BASIC] 46 | 47 | # Naming style matching correct argument names 48 | argument-naming-style=snake_case 49 | 50 | # Naming style matching correct attribute names 51 | attr-naming-style=snake_case 52 | 53 | # Bad variable names which should always be refused, separated by a comma 54 | bad-names=foo, 55 | bar, 56 | baz, 57 | cats 58 | 59 | # Naming style matching correct class names 60 | class-naming-style=PascalCase 61 | 62 | # Naming style matching correct constant names 63 | const-naming-style=snake_case 64 | 65 | # Naming style matching correct function names 66 | function-naming-style=snake_case 67 | 68 | # Naming style matching correct module names 69 | module-naming-style=snake_case 70 | 71 | # Naming style matching correct variable names 72 | variable-naming-style=snake_case 73 | 74 | 75 | [FORMAT] 76 | 77 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 78 | expected-line-ending-format=LF 79 | 80 | # Number of spaces of indent required inside a hanging or continued line. 81 | indent-after-paren=2 82 | 83 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 84 | # tab). 85 | indent-string=' ' 86 | 87 | # Maximum number of characters on a single line. 88 | max-line-length=80 89 | 90 | # Maximum number of lines in a module 91 | max-module-lines=1000 92 | 93 | # Allow the body of a class to be on the same line as the declaration if body 94 | # contains single statement. 95 | single-line-class-stmt=yes 96 | 97 | # Allow the body of an if to be on the same line as the test if there is no 98 | # else. 99 | single-line-if-stmt=yes 100 | 101 | 102 | [CLASSES] 103 | 104 | # List of method names used to declare (i.e. assign) instance attributes. 105 | defining-attr-methods=__init__ 106 | 107 | 108 | [DESIGN] 109 | 110 | # Maximum number of arguments for function / method 111 | max-args=5 112 | 113 | # Maximum number of attributes for a class (see R0902). 114 | max-attributes=7 115 | 116 | # Maximum number of boolean expressions in a if statement 117 | max-bool-expr=5 118 | 119 | # Maximum number of branch for function / method body 120 | max-branches=12 121 | 122 | # Maximum number of locals for function / method body 123 | max-locals=15 124 | 125 | # Maximum number of parents for a class (see R0901). 126 | max-parents=7 127 | 128 | # Maximum number of public methods for a class (see R0904). 129 | max-public-methods=20 130 | 131 | # Maximum number of return / yield for function / method body 132 | max-returns=6 133 | 134 | # Maximum number of statements in function / method body 135 | max-statements=50 136 | 137 | # Minimum number of public methods for a class (see R0903). 138 | min-public-methods=2 139 | 140 | 141 | [OVERRIDES] 142 | 143 | # List of pylint default rules to override 144 | disable=missing-final-newline, pointless-string-statement --------------------------------------------------------------------------------