├── 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 | [](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
--------------------------------------------------------------------------------