From 4dc07fc332392042e8299735666028cc53c55b2c Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sat, 21 Nov 2020 19:27:37 +0100 Subject: [PATCH] :recycle: Change the structure completely --- .gitignore | 12 +- .travis.yml | 9 - docs/{ => docs}/index.md | 0 docs/{ => docs}/managing_apps/startapp.md | 0 .../managing_projects/startproject.md | 0 docs/{ => docs}/release-notes.md | 0 .../docs_assets}/startproject.png | Bin mkdocs.yml => docs/mkdocs.yml | 0 manage_fastapi/__init__.py | 1 - manage_fastapi/__main__.py | 3 - manage_fastapi/config.py | 10 + manage_fastapi/constants.py | 21 + manage_fastapi/generator.py | 20 + manage_fastapi/main.py | 58 ++- manage_fastapi/project_utils.py | 166 ------- manage_fastapi/schemas.py | 33 ++ manage_fastapi/templates.py | 335 ------------- manage_fastapi/templates/__init__.py | 0 manage_fastapi/templates/project/__init__.py | 0 .../templates/project/cookiecutter.json | 8 + .../project/hooks/post_gen_project.py | 21 + .../{{ cookiecutter.name }}/app/__init__.py | 0 .../{{ cookiecutter.name }}/app/main.py | 3 + .../{{ cookiecutter.name }}/pyproject.toml | 15 + .../{{ cookiecutter.name }}/requirements.txt | 2 + .../{{ cookiecutter.name }}/tests/__init__.py | 0 poetry.lock | 443 +++++++++++++++++- pyproject.toml | 13 +- 28 files changed, 622 insertions(+), 551 deletions(-) delete mode 100644 .travis.yml rename docs/{ => docs}/index.md (100%) rename docs/{ => docs}/managing_apps/startapp.md (100%) rename docs/{ => docs}/managing_projects/startproject.md (100%) rename docs/{ => docs}/release-notes.md (100%) rename {docs_assets => docs/docs_assets}/startproject.png (100%) rename mkdocs.yml => docs/mkdocs.yml (100%) delete mode 100644 manage_fastapi/__main__.py create mode 100644 manage_fastapi/config.py create mode 100644 manage_fastapi/constants.py create mode 100644 manage_fastapi/generator.py delete mode 100644 manage_fastapi/project_utils.py create mode 100644 manage_fastapi/schemas.py delete mode 100644 manage_fastapi/templates.py create mode 100644 manage_fastapi/templates/__init__.py create mode 100644 manage_fastapi/templates/project/__init__.py create mode 100644 manage_fastapi/templates/project/cookiecutter.json create mode 100644 manage_fastapi/templates/project/hooks/post_gen_project.py create mode 100644 manage_fastapi/templates/project/{{ cookiecutter.name }}/app/__init__.py create mode 100644 manage_fastapi/templates/project/{{ cookiecutter.name }}/app/main.py create mode 100644 manage_fastapi/templates/project/{{ cookiecutter.name }}/pyproject.toml create mode 100644 manage_fastapi/templates/project/{{ cookiecutter.name }}/requirements.txt create mode 100644 manage_fastapi/templates/project/{{ cookiecutter.name }}/tests/__init__.py diff --git a/.gitignore b/.gitignore index 552fd3e..bb9de92 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ __pycache__/ *.py[cod] *$py.class - site # Distribution / packaging @@ -62,11 +61,6 @@ coverage.xml .hypothesis/ .pytest_cache/ - - - - - # PyBuilder target/ @@ -88,13 +82,13 @@ ENV/ env.bak/ venv.bak/ - # Rope project settings .ropeproject - - # mypy .mypy_cache/ .dmypy.json dmypy.json + +# Temporary Files +tmp diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 146c4e5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: python -python: - - "3.6" - - "3.7" - - "3.8" -install: - - pip install typer pytest -script: - - pytest diff --git a/docs/index.md b/docs/docs/index.md similarity index 100% rename from docs/index.md rename to docs/docs/index.md diff --git a/docs/managing_apps/startapp.md b/docs/docs/managing_apps/startapp.md similarity index 100% rename from docs/managing_apps/startapp.md rename to docs/docs/managing_apps/startapp.md diff --git a/docs/managing_projects/startproject.md b/docs/docs/managing_projects/startproject.md similarity index 100% rename from docs/managing_projects/startproject.md rename to docs/docs/managing_projects/startproject.md diff --git a/docs/release-notes.md b/docs/docs/release-notes.md similarity index 100% rename from docs/release-notes.md rename to docs/docs/release-notes.md diff --git a/docs_assets/startproject.png b/docs/docs_assets/startproject.png similarity index 100% rename from docs_assets/startproject.png rename to docs/docs_assets/startproject.png diff --git a/mkdocs.yml b/docs/mkdocs.yml similarity index 100% rename from mkdocs.yml rename to docs/mkdocs.yml diff --git a/manage_fastapi/__init__.py b/manage_fastapi/__init__.py index aa5efd5..e69de29 100644 --- a/manage_fastapi/__init__.py +++ b/manage_fastapi/__init__.py @@ -1 +0,0 @@ -__version__ = "0.1.60" diff --git a/manage_fastapi/__main__.py b/manage_fastapi/__main__.py deleted file mode 100644 index daa32d7..0000000 --- a/manage_fastapi/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .main import app - -app(prog_name="manage-fastapi") diff --git a/manage_fastapi/config.py b/manage_fastapi/config.py new file mode 100644 index 0000000..7276b19 --- /dev/null +++ b/manage_fastapi/config.py @@ -0,0 +1,10 @@ +import os + +TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "templates") + +try: + import fastapi + + FASTAPI_VERSION = fastapi.__version__ +except ModuleNotFoundError: + FASTAPI_VERSION = "0.61.2" diff --git a/manage_fastapi/constants.py b/manage_fastapi/constants.py new file mode 100644 index 0000000..fb0bb4c --- /dev/null +++ b/manage_fastapi/constants.py @@ -0,0 +1,21 @@ +from enum import Enum, EnumMeta + + +class BaseMetadataEnum(EnumMeta): + def __getitem__(self, key): + return getattr(self, key.upper()) + + def __iter__(self): + return (member[1].value for member in self.__members__.items()) + + +class BaseEnum(Enum, metaclass=BaseMetadataEnum): + """Base enum class.""" + + +class Packaging(BaseEnum): + PIP = "๐Ÿ“ƒ pip" + POETRY = "๐Ÿงพ poetry" + + +PYTHON_VERSIONS = ("3.6", "3.7", "3.8", "3.9") diff --git a/manage_fastapi/generator.py b/manage_fastapi/generator.py new file mode 100644 index 0000000..c36dafe --- /dev/null +++ b/manage_fastapi/generator.py @@ -0,0 +1,20 @@ +import os + +import typer +from cookiecutter.exceptions import OutputDirExistsException +from cookiecutter.main import cookiecutter + +from manage_fastapi.config import TEMPLATES_DIR +from manage_fastapi.schemas import Context + + +def generate_project(context: Context): + try: + cookiecutter( + os.path.join(TEMPLATES_DIR, "project"), + extra_context=context.dict(), + no_input=True, + ) + typer.echo(f'"{context.name}" created successfully! ๐ŸŽ‰') + except OutputDirExistsException: + typer.echo(f'"{context.name}" already exists. ๐Ÿ˜ž') diff --git a/manage_fastapi/main.py b/manage_fastapi/main.py index c443064..1465454 100644 --- a/manage_fastapi/main.py +++ b/manage_fastapi/main.py @@ -1,22 +1,46 @@ -import pkg_resources import typer +from bullet import Bullet, Input, SlidePrompt, colors + +from manage_fastapi.constants import PYTHON_VERSIONS, Packaging +from manage_fastapi.generator import generate_project +from manage_fastapi.schemas import Context + +app = typer.Typer(help="Managing FastAPI projects made easy!", name="Manage FastAPI") -from .project_utils import select_database, start_app, start_project - -app = typer.Typer( - add_completion=False, - help="Managing FastAPI projects made easy!", - name="Manage FastAPI", -) +@app.command(help="Creates a FastAPI project.") +def startproject(default: bool = typer.Option(False)): + if default: + context = Context(name="fastapi-project", packaging=Packaging.PIP, python="3.8") + else: + cli = SlidePrompt( + [ + Input("Insert the project's name: "), + Bullet( + prompt="Choose the package manager:", + choices=list(Packaging), + bullet=" >", + margin=2, + word_color=colors.foreground["white"], + word_on_switch=colors.foreground["white"], + ), + Bullet( + prompt="Select Python version:", + choices=PYTHON_VERSIONS, + bullet=" >", + margin=2, + word_color=colors.foreground["white"], + word_on_switch=colors.foreground["white"], + ), + ], + ) + result = cli.launch() + context = Context( + name=result[0][1], packaging=result[1][1], python=result[2][1] + ) + generate_project(context) -@app.command(help="Creates a project with the given name.") -def startproject(projectname: str = typer.Argument(...)): - database_option = select_database() - start_project(projectname, database_option=database_option) - - -@app.command(help="Creates a app with the given name.") -def startapp(appname: str = typer.Argument(...)): - start_app(appname) +@app.command(help="Creates a FastAPI component.") +def startapp(): + ... diff --git a/manage_fastapi/project_utils.py b/manage_fastapi/project_utils.py deleted file mode 100644 index c407c16..0000000 --- a/manage_fastapi/project_utils.py +++ /dev/null @@ -1,166 +0,0 @@ -from pathlib import Path - -from .templates import ( - api_template, - async_sql_database_template, - async_sql_main_template, - database_options_template, - empty_main_template, - endpoint_template, - mongo_database_template, - mongo_main_template, - mongo_utils_template, - requirements_template, - schema_template, - settings_template, - test_template, - tortoise_database_template, - tortoise_main_template, - settings_without_database, -) - - -def start_project( - project_name: str, current_path: str = Path.cwd(), database_option: str = None -) -> str: - try: - Path(f"{current_path}/{project_name}").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/{project_name}/tests").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/{project_name}/core").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/{project_name}/core/schemas").mkdir( - parents=True, exist_ok=False - ) - Path(f"{current_path}/{project_name}/__init__.py").touch() - Path(f"{current_path}/{project_name}/core/__init__.py").touch() - Path(f"{current_path}/{project_name}/tests/__init__.py").touch() - Path(f"{current_path}/{project_name}/core/schemas/__init__.py").touch() - - with open( - f"{current_path}/{project_name}/core/schemas/schema.py", "a+" - ) as schema, open( - f"{current_path}/{project_name}/core/settings.py", "a+" - ) as settings, open( - f"{current_path}/requirements.txt", "a+" - ) as requirements: - schema.write(schema_template.replace("{project_name}", project_name)) - settings.write(settings_template.replace("{project_name}", project_name)) - requirements.write(requirements_template) - - if database_option == "0": - - Path(f"{current_path}/{project_name}/core/models").mkdir( - parents=True, exist_ok=False - ) - Path(f"{current_path}/{project_name}/core/models/__init__.py").touch() - - with open( - f"{current_path}/{project_name}/core/models/database.py", "a+" - ) as database, open( - f"{current_path}/{project_name}/main.py", "a+" - ) as main, open( - f"{current_path}/requirements.txt", "a+" - ) as requirements: - database.write( - async_sql_database_template.replace("{project_name}", project_name) - ) - main.write( - async_sql_main_template.replace("{project_name}", project_name) - ) - requirements.write("databases[postgresql,sqlite,mysql]==0.3.2\n") - - # Tortoise ORM = 1 - elif database_option == "1": - Path(f"{current_path}/{project_name}/core/models").mkdir( - parents=True, exist_ok=False - ) - Path(f"{current_path}/{project_name}/core/models/__init__.py").touch() - - with open( - f"{current_path}/{project_name}/core/models/database.py", "a+" - ) as database, open( - f"{current_path}/{project_name}/main.py", "a+" - ) as main, open( - f"{current_path}/requirements.txt", "a+" - ) as requirements: - database.write(tortoise_database_template) - main.write( - tortoise_main_template.replace("{project_name}", project_name) - ) - requirements.write("tortoise-orm==0.16.14\n") - - # MongoDB - elif database_option == "2": - Path(f"{current_path}/{project_name}/core/models").mkdir( - parents=True, exist_ok=False - ) - Path(f"{current_path}/{project_name}/core/models/__init__.py").touch() - - with open( - f"{current_path}/{project_name}/core/models/database.py", "a+" - ) as database, open( - f"{current_path}/{project_name}/main.py", "a+" - ) as main, open( - f"{current_path}/{project_name}/core/models/utils.py", "a+" - ) as utils, open( - f"{current_path}/requirements.txt", "a+" - ) as requirements: - database.write( - mongo_database_template.replace("{project_name}", project_name) - ) - main.write(mongo_main_template.replace("{project_name}", project_name)) - utils.write( - mongo_utils_template.replace("{project_name}", project_name) - ) - requirements.write("motor==2.1.0\n") - - else: - with open(f"{current_path}/{project_name}/main.py", "a+") as main: - main.write(empty_main_template.replace("{project_name}", project_name)) - - # Delete settings - settings = Path(f"{current_path}/{project_name}/core/settings.py") - settings.unlink() - - with open( - f"{current_path}/{project_name}/core/settings.py", "a+" - ) as settings: - settings.write( - settings_without_database.replace("{project_name}", project_name) - ) - - except FileExistsError: - print(f"Project {project_name} already exists!") - - else: - print(f"Project {project_name} created successfully!") - print("We created requirements file for your project needs.") - - -def start_app(app_name: str, current_path: str = Path.cwd()) -> str: - try: - Path(f"{current_path}/{app_name}").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/{app_name}/endpoints").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/{app_name}/__init__.py").touch() - Path(f"{current_path}/{app_name}/endpoints/__init__.py").touch() - Path(f"{current_path}/tests/{app_name}").mkdir(parents=True, exist_ok=False) - Path(f"{current_path}/tests/{app_name}/__init__.py").touch() - - with open( - f"{current_path}/{app_name}/endpoints/endpoint.py", "a+" - ) as endpoint, open(f"{current_path}/{app_name}/api.py", "a+") as api, open( - f"{current_path}/tests/{app_name}/test_{app_name}.py", "a+" - ) as test: - endpoint.write(endpoint_template.replace("{app_name}", app_name)) - api.write(api_template.replace("{app_name}", app_name)) - test.write(test_template.replace("{app_name}", app_name)) - - except FileExistsError: - print(f"Application {app_name} already exists!") - - else: - print(f"Application {app_name} created successfully!") - - -def select_database() -> int: - option = input(database_options_template + "Select a database: ") - return option diff --git a/manage_fastapi/schemas.py b/manage_fastapi/schemas.py new file mode 100644 index 0000000..641eee2 --- /dev/null +++ b/manage_fastapi/schemas.py @@ -0,0 +1,33 @@ +import subprocess + +from pydantic import BaseModel, EmailStr, root_validator, validator + +from manage_fastapi.config import FASTAPI_VERSION +from manage_fastapi.constants import PYTHON_VERSIONS, Packaging + + +class Context(BaseModel): + name: str + packaging: Packaging + + username: str + email: EmailStr + + python: str + fastapi: str = FASTAPI_VERSION + + @root_validator(pre=True) + def git_info(cls, values: dict): + values["username"] = subprocess.check_output( + ["git", "config", "--get", "user.name"] + ) + values["email"] = subprocess.check_output( + ["git", "config", "--get", "user.email"] + ) + return values + + @validator("python") + def validate_python_version(cls, value): + if value not in PYTHON_VERSIONS: + raise ValueError(f"Invalid Python version: {value}.") + return value diff --git a/manage_fastapi/templates.py b/manage_fastapi/templates.py deleted file mode 100644 index 2ea0d2f..0000000 --- a/manage_fastapi/templates.py +++ /dev/null @@ -1,335 +0,0 @@ -database_options_template = """[0] PostgreSQL - SQLite - MySQL -[1] Tortoise -[2] MongoDB -[9] Create without Database - -""" - -schema_template = """# For more information check Pydantic documentation = https://pydantic-docs.helpmanual.io/usage/models/ -# -# Creating your custom classes -# -# class ClassName(BaseModel): -# name: str -# value: int -# - -from pydantic import BaseModel, Field - - -class Model(BaseModel): - pass -""" - - -settings_template = """from typing import Any, Dict, List, Optional, Union - -from pydantic import BaseSettings, AnyHttpUrl, HttpUrl, validator - - -class Settings(BaseSettings): - PROJECT_NAME: str = "{project_name}" - - BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [ - "http://localhost", - "http://localhost:80", - "http://localhost:8000", - ] - - @validator("BACKEND_CORS_ORIGINS", pre=True) - def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]: - if isinstance(v, str) and not v.startswith("["): - return [i.strip() for i in v.split(",")] - elif isinstance(v, (list, str)): - return v - raise ValueError(v) - - # Database Settings - DB_SERVER: Optional[str] = "" - DB_USER: Optional[str] = "" - DB_PASSWORD: Optional[str] = "" - DB_PORT: Optional[str] = "" - DB_NAME: Optional[str] = "" - DB_PORT: Optional[str] = "" - - # DATABASE_URL: str = f"{DB_SERVER}://{DB_USER}:{DB_PASSWORD}@{DB_PORT}:{DB_PORT}/{DB_NAME}" - - DATABASE_URL = "sqlite:///./test.db" - - - - class Config: - case_sensitive = True - - -settings = Settings() -""" - - -settings_without_database = """from typing import Any, Dict, List, Optional, Union - -from pydantic import BaseSettings, AnyHttpUrl, HttpUrl, validator - - -class Settings(BaseSettings): - PROJECT_NAME: str = "{project_name}" - - BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [ - "http://localhost", - "http://localhost:80", - "http://localhost:8000", - ] - - @validator("BACKEND_CORS_ORIGINS", pre=True) - def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]: - if isinstance(v, str) and not v.startswith("["): - return [i.strip() for i in v.split(",")] - elif isinstance(v, (list, str)): - return v - raise ValueError(v) - - - class Config: - case_sensitive = True - - -settings = Settings() -""" - -endpoint_template = """from fastapi import APIRouter, Body, Depends - - -router = APIRouter() - - -@router.get("/") -async def hello_fastapi(): - return {"Hello":"FastAPI"} -""" - - -api_template = """# This is an example of how you can route and you are free to change -# if you want to include this router to your app -# go to your main.py then add this -# from {app_name}.api import api_router as {app_name}_router - - - - -from fastapi import APIRouter - -from {app_name}.endpoints import endpoint - -api_router = APIRouter() -api_router.include_router(endpoint.router, prefix="/{app_name}", tags=["{app_name}"]) -""" - -test_template = """from fastapi.testclient import TestClient -from {app_name}.api import api_router as app - -items = {} - -client = TestClient(app) - -@app.get("/hello") -async def get_hello(): - response = client.get("/hello") - assert response.status_code == 200 - assert response.json() == {"Hello": "FastAPI"} - -@app.on_event("startup") -async def startup_event(): - items["foo"] = {"name": "Fighters"} - items["bar"] = {"name": "Tenders"} - - -@app.get("/items/{item_id}") -async def read_items(item_id: str): - return items[item_id] - - -def test_read_items(): - response = client.get("/items/foo") - assert response.status_code == 200 - assert response.json() == {"name": "Fighters"} -""" - -requirements_template = """fastapi==0.61.0 -uvicorn==0.11.8 -""" - - -# TORTOISE Main | Database template - -tortoise_main_template = """from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from core.models.database import Example -from tortoise.contrib.fastapi import HTTPNotFoundError, register_tortoise - - -from core.settings import settings - -app = FastAPI(title=settings.PROJECT_NAME) - - -if settings.BACKEND_CORS_ORIGINS: - app.add_middleware( - CORSMiddleware, - allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], - allow_methods=["*"], - allow_headers=["*"], - ) - - - -register_tortoise( - app, - db_url=settings.DATABASE_URL, - modules={"models": ["{project_name}.core.models"]}, - generate_schemas=True, - add_exception_handlers=True, -) -""" - -tortoise_database_template = """from tortoise import fields, models -from tortoise.contrib.pydantic import pydantic_model_creator - - -class Example(models.Model): - - id = fields.IntField(pk=True) - created_at = fields.DatetimeField(auto_now_add=True) - modified_at = fields.DatetimeField(auto_now=True) - - class PydanticMeta: - pass - - -Example = pydantic_model_creator(Example, name="Example") -""" - - -# Postgresql, SQLite, MySQL Main | Database - -empty_main_template = """from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from core.settings import settings - -if settings.BACKEND_CORS_ORIGINS: - app.add_middleware( - CORSMiddleware, - allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], - allow_methods=["*"], - allow_headers=["*"], - ) - - -""" - - -async_sql_main_template = """from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from core.settings import settings -from core.models.database import database - -app = FastAPI(title=settings.PROJECT_NAME) - -if settings.BACKEND_CORS_ORIGINS: - app.add_middleware( - CORSMiddleware, - allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], - allow_methods=["*"], - allow_headers=["*"], - ) - - -@app.on_event("startup") -async def connect_database(): - await database.connect() - - -@app.on_event("shutdown") -async def disconnect_database(): - await database.disconnect() -""" - -async_sql_database_template = """import sqlalchemy -from core.settings import settings -import databases - -database = databases.Database(settings.DATABASE_URL) -metadata = sqlalchemy.MetaData() - -# Put your database models here | Below - -# FastAPI documentation for databases: https://fastapi.tiangolo.com/advanced/async-sql-databases/ - -# Put your database models here | Above - - -engine = sqlalchemy.create_engine(settings.DATABASE_URL) -metadata.create_all(engine) -""" - - -### MONGODB -mongo_main_template = """from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from core.settings import settings -from core.models.utils import connect_to_mongo, close_mongo_connection - -app = FastAPI() - -if settings.BACKEND_CORS_ORIGINS: - app.add_middleware( - CORSMiddleware, - allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], - allow_methods=["*"], - allow_headers=["*"], - ) - -app.add_event_handler("startup", connect_to_mongo) -app.add_event_handler("shutdown", close_mongo_connection) - - -""" - - -mongo_database_template = """from motor.motor_asyncio import AsyncIOMotorClient - - -class DataBase: - client: AsyncIOMotorClient = None - - -db = DataBase() - - -async def get_database() -> AsyncIOMotorClient: - return db.client -""" - -mongo_utils_template = """import logging - -from motor.motor_asyncio import AsyncIOMotorClient -from core.models.database import db - -logger = logging.getLogger(__name__) - - -async def connect_to_mongo(): - db.client = AsyncIOMotorClient(str("localhost:27017"), - maxPoolSize=10, - minPoolSize=10) - - logger.info(f"Connecting to mongoDB") - - -async def close_mongo_connection(): - db.client.close() - logger.info(f"Closing to mongoDB") -""" diff --git a/manage_fastapi/templates/__init__.py b/manage_fastapi/templates/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manage_fastapi/templates/project/__init__.py b/manage_fastapi/templates/project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manage_fastapi/templates/project/cookiecutter.json b/manage_fastapi/templates/project/cookiecutter.json new file mode 100644 index 0000000..9fbd9b2 --- /dev/null +++ b/manage_fastapi/templates/project/cookiecutter.json @@ -0,0 +1,8 @@ +{ + "name": "{{ cookiecutter.name }}", + "packaging": "{{ cookiecutter.packaging }}", + "username": "{{ cookiecutter.username }}", + "email": "{{ cookiecutter.email }}", + "python": "{{ cookiecutter.python }}", + "fastapi": "{{ cookiecutter.fastapi }}" +} diff --git a/manage_fastapi/templates/project/hooks/post_gen_project.py b/manage_fastapi/templates/project/hooks/post_gen_project.py new file mode 100644 index 0000000..e5ed6fb --- /dev/null +++ b/manage_fastapi/templates/project/hooks/post_gen_project.py @@ -0,0 +1,21 @@ +import os + +from manage_fastapi.constants import Packaging + +packaging = "{{ cookiecutter.packaging }}" +base_dir = os.getcwd() + +remove_paths = [] +if packaging == str(Packaging.PIP): + remove_paths = ["poetry.lock", "pyproject.toml"] +elif packaging == str(Packaging.POETRY): + remove_paths = ["requirements.txt"] + + +for path in remove_paths: + path = os.path.join(base_dir, path) + if path and os.path.exists(path): + if os.path.isdir(path): + os.rmdir(path) + else: + os.unlink(path) diff --git a/manage_fastapi/templates/project/{{ cookiecutter.name }}/app/__init__.py b/manage_fastapi/templates/project/{{ cookiecutter.name }}/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manage_fastapi/templates/project/{{ cookiecutter.name }}/app/main.py b/manage_fastapi/templates/project/{{ cookiecutter.name }}/app/main.py new file mode 100644 index 0000000..9bb71ec --- /dev/null +++ b/manage_fastapi/templates/project/{{ cookiecutter.name }}/app/main.py @@ -0,0 +1,3 @@ +from fastapi import FastAPI + +app = FastAPI() diff --git a/manage_fastapi/templates/project/{{ cookiecutter.name }}/pyproject.toml b/manage_fastapi/templates/project/{{ cookiecutter.name }}/pyproject.toml new file mode 100644 index 0000000..c431045 --- /dev/null +++ b/manage_fastapi/templates/project/{{ cookiecutter.name }}/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "{{ cookiecutter.name }}" +version = "0.1.0" +description = "" +authors = ["{{ cookiecutter.username }} <{{ cookiecutter.email }}>"] + +[tool.poetry.dependencies] +python = "^{{ cookiecutter.python }}" +fastapi = "^{{ cookiecutter.fastapi }}" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/manage_fastapi/templates/project/{{ cookiecutter.name }}/requirements.txt b/manage_fastapi/templates/project/{{ cookiecutter.name }}/requirements.txt new file mode 100644 index 0000000..59db9ea --- /dev/null +++ b/manage_fastapi/templates/project/{{ cookiecutter.name }}/requirements.txt @@ -0,0 +1,2 @@ +fastapi==0.61.2 +uvicorn==0.12.2 diff --git a/manage_fastapi/templates/project/{{ cookiecutter.name }}/tests/__init__.py b/manage_fastapi/templates/project/{{ cookiecutter.name }}/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/poetry.lock b/poetry.lock index 6405ae5..bd1936e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "atomicwrites" version = "1.4.0" @@ -8,15 +16,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "20.2.0" +version = "20.3.0" description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] @@ -31,6 +39,37 @@ python-versions = "*" [package.dependencies] pyflakes = ">=1.1.0" +[[package]] +name = "black" +version = "20.8b1" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +appdirs = "*" +click = ">=7.1.2" +dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} +mypy-extensions = ">=0.4.3" +pathspec = ">=0.6,<1" +regex = ">=2020.1.8" +toml = ">=0.10.1" +typed-ast = ">=1.4.0" +typing-extensions = ">=3.7.4" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +name = "cfgv" +version = "3.2.0" +description = "Validate configuration and produce human readable error messages." +category = "dev" +optional = false +python-versions = ">=3.6.1" + [[package]] name = "click" version = "7.1.2" @@ -47,6 +86,55 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "dataclasses" +version = "0.8" +description = "A backport of the dataclasses module for Python 3.6" +category = "dev" +optional = false +python-versions = ">=3.6, <3.7" + +[[package]] +name = "distlib" +version = "0.3.1" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "filelock" +version = "3.0.12" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "flake8" +version = "3.8.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[[package]] +name = "identify" +version = "1.5.9" +description = "File identification library for Python" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.extras] +license = ["editdistance"] + [[package]] name = "importlib-metadata" version = "2.0.0" @@ -62,6 +150,41 @@ zipp = ">=0.5" docs = ["sphinx", "rst.linker"] testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] +[[package]] +name = "importlib-resources" +version = "3.3.0" +description = "Read resources from Python packages" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" + +[package.dependencies] +zipp = {version = ">=0.4", markers = "python_version < \"3.8\""} + +[package.extras] +docs = ["sphinx", "rst.linker", "jaraco.packaging"] + +[[package]] +name = "isort" +version = "5.6.4" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.extras] +pipfile_deprecated_finder = ["pipreqs", "requirementslib"] +requirements_deprecated_finder = ["pipreqs", "pip-api"] +colors = ["colorama (>=0.4.3,<0.5.0)"] + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "more-itertools" version = "8.6.0" @@ -70,6 +193,38 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "mypy" +version = "0.790" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +mypy-extensions = ">=0.4.3,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" + +[package.extras] +dmypy = ["psutil (>=4.0)"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "nodeenv" +version = "1.5.0" +description = "Node.js virtual environment builder" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "packaging" version = "20.4" @@ -82,6 +237,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" pyparsing = ">=2.0.2" six = "*" +[[package]] +name = "pathspec" +version = "0.8.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "pluggy" version = "0.13.1" @@ -96,6 +259,24 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +[[package]] +name = "pre-commit" +version = "2.8.2" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-resources = {version = "*", markers = "python_version < \"3.7\""} +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +toml = "*" +virtualenv = ">=20.0.8" + [[package]] name = "py" version = "1.9.0" @@ -104,6 +285,14 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycodestyle" +version = "2.6.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "pyflakes" version = "2.2.0" @@ -143,6 +332,22 @@ wcwidth = "*" checkqa-mypy = ["mypy (==v0.761)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "pyyaml" +version = "5.3.1" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "regex" +version = "2020.11.13" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "six" version = "1.15.0" @@ -151,6 +356,22 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "typer" version = "0.3.2" @@ -168,6 +389,34 @@ all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"] dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"] doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown-include (>=0.5.1,<0.6.0)"] +[[package]] +name = "typing-extensions" +version = "3.7.4.3" +description = "Backported and Experimental Type Hints for Python 3.5+" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "virtualenv" +version = "20.1.0" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +appdirs = ">=1.4.3,<2" +distlib = ">=0.3.1,<1" +filelock = ">=3.0.0,<4" +importlib-metadata = {version = ">=0.12,<3", markers = "python_version < \"3.8\""} +importlib-resources = {version = ">=1.0", markers = "python_version < \"3.7\""} +six = ">=1.9.0,<2" + +[package.extras] +docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] + [[package]] name = "wcwidth" version = "0.2.5" @@ -190,21 +439,32 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake [metadata] lock-version = "1.1" -python-versions = "^3.6" -content-hash = "d3d05bfa4a97145632016a04e8b3213e62b39f6eb6da2e22dc6ba7ca9d2a24d8" +python-versions = "^3.6.1" +content-hash = "8dfbea18350cb2507859b4450dfa9dbdfd59e62d4937f1ef93ff4d594cef0c79" [metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ - {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, - {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] autoflake = [ {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"}, ] +black = [ + {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, +] +cfgv = [ + {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"}, + {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"}, +] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, @@ -213,26 +473,94 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +dataclasses = [ + {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, + {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, +] +distlib = [ + {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, + {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, +] +filelock = [ + {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, + {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, +] +flake8 = [ + {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, + {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, +] +identify = [ + {file = "identify-1.5.9-py2.py3-none-any.whl", hash = "sha256:5dd84ac64a9a115b8e0b27d1756b244b882ad264c3c423f42af8235a6e71ca12"}, + {file = "identify-1.5.9.tar.gz", hash = "sha256:c9504ba6a043ee2db0a9d69e43246bc138034895f6338d5aed1b41e4a73b1513"}, +] importlib-metadata = [ {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, ] +importlib-resources = [ + {file = "importlib_resources-3.3.0-py2.py3-none-any.whl", hash = "sha256:a3d34a8464ce1d5d7c92b0ea4e921e696d86f2aa212e684451cb1482c8d84ed5"}, + {file = "importlib_resources-3.3.0.tar.gz", hash = "sha256:7b51f0106c8ec564b1bef3d9c588bc694ce2b92125bbb6278f4f2f5b54ec3592"}, +] +isort = [ + {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, + {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] more-itertools = [ {file = "more-itertools-8.6.0.tar.gz", hash = "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf"}, {file = "more_itertools-8.6.0-py3-none-any.whl", hash = "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330"}, ] +mypy = [ + {file = "mypy-0.790-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669"}, + {file = "mypy-0.790-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802"}, + {file = "mypy-0.790-cp35-cp35m-win_amd64.whl", hash = "sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de"}, + {file = "mypy-0.790-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1"}, + {file = "mypy-0.790-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc"}, + {file = "mypy-0.790-cp36-cp36m-win_amd64.whl", hash = "sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7"}, + {file = "mypy-0.790-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"}, + {file = "mypy-0.790-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178"}, + {file = "mypy-0.790-cp37-cp37m-win_amd64.whl", hash = "sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324"}, + {file = "mypy-0.790-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01"}, + {file = "mypy-0.790-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666"}, + {file = "mypy-0.790-cp38-cp38-win_amd64.whl", hash = "sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea"}, + {file = "mypy-0.790-py3-none-any.whl", hash = "sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122"}, + {file = "mypy-0.790.tar.gz", hash = "sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +nodeenv = [ + {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"}, + {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"}, +] packaging = [ {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, ] +pathspec = [ + {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, + {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] +pre-commit = [ + {file = "pre_commit-2.8.2-py2.py3-none-any.whl", hash = "sha256:22e6aa3bd571debb01eb7d34483f11c01b65237be4eebbf30c3d4fb65762d315"}, + {file = "pre_commit-2.8.2.tar.gz", hash = "sha256:905ebc9b534b991baec87e934431f2d0606ba27f2b90f7f652985f5a5b8b6ae6"}, +] py = [ {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, ] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] pyflakes = [ {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, @@ -245,14 +573,115 @@ pytest = [ {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] +pyyaml = [ + {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, + {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, + {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, + {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, + {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, + {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, + {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, + {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, +] +regex = [ + {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"}, + {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"}, + {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"}, + {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"}, + {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"}, + {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"}, + {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"}, + {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"}, + {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"}, + {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"}, + {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"}, + {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"}, + {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, +] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, + {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, + {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] typer = [ {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, ] +typing-extensions = [ + {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, + {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, + {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, +] +virtualenv = [ + {file = "virtualenv-20.1.0-py2.py3-none-any.whl", hash = "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2"}, + {file = "virtualenv-20.1.0.tar.gz", hash = "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380"}, +] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, diff --git a/pyproject.toml b/pyproject.toml index a39edf2..b46d39d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,11 @@ [tool.poetry] name = "manage-fastapi" -version = "0.1.60" +version = "1.0.0" description = "Managing FastAPI projects made easy." -authors = ["ycd "] +authors = [ + "ycd ", + "Marcelo Trylesinski ", +] readme = "README.md" license = "MIT" repository = "https://github.com/ycd/manage-fastapi" @@ -20,20 +23,22 @@ classifiers = [ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", ] [tool.poetry.dependencies] -python = "^3.6" +python = "^3.6.1" typer = "^0.3.2" [tool.poetry.dev-dependencies] pytest = "^5.2" autoflake = "1.4" -pre-commit = "^2.8" flake8 = "3.8.4" mypy = "0.790" isort = "^5.0" +pre-commit = "^2.8.2" +black = "^20.8b1" [tool.poetry.scripts] manage-fastapi = 'manage_fastapi.main:app'