From 18dff2f4b61a7633bc780829473fbaf2bbfcc2e9 Mon Sep 17 00:00:00 2001 From: KristineYW <63246056+KristineYW@users.noreply.github.com> Date: Mon, 15 Jun 2020 18:52:09 -0400 Subject: [PATCH] Lecture notes --- twitoff-kristine/Pipfile | 242 ++++++++++++++++++ twitoff-kristine/README.md | 38 +++ .../__pycache__/hello.cpython-37.pyc | Bin 0 -> 543 bytes twitoff-kristine/migrations/README | 1 + .../migrations/__pycache__/env.cpython-37.pyc | Bin 0 -> 2264 bytes twitoff-kristine/migrations/alembic.ini | 45 ++++ twitoff-kristine/migrations/env.py | 96 +++++++ twitoff-kristine/migrations/script.py.mako | 24 ++ .../migrations/versions/4c94855c06c7_.py | 33 +++ .../__pycache__/4c94855c06c7_.cpython-37.pyc | Bin 0 -> 863 bytes twitoff-kristine/web_app/__init__.py | 26 ++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 818 bytes .../web_app/__pycache__/models.cpython-37.pyc | Bin 0 -> 1433 bytes twitoff-kristine/web_app/models.py | 41 +++ .../__pycache__/book_routes.cpython-37.pyc | Bin 0 -> 1396 bytes .../__pycache__/home_routes.cpython-37.pyc | Bin 0 -> 508 bytes .../web_app/routes/book_routes.py | 45 ++++ .../web_app/routes/home_routes.py | 16 ++ twitoff-kristine/web_app/templates/books.html | 27 ++ .../web_app/templates/new_book.html | 31 +++ .../web_app/twitoff_kristine_development.db | Bin 0 -> 16384 bytes 21 files changed, 665 insertions(+) create mode 100644 twitoff-kristine/Pipfile create mode 100644 twitoff-kristine/README.md create mode 100644 twitoff-kristine/__pycache__/hello.cpython-37.pyc create mode 100644 twitoff-kristine/migrations/README create mode 100644 twitoff-kristine/migrations/__pycache__/env.cpython-37.pyc create mode 100644 twitoff-kristine/migrations/alembic.ini create mode 100644 twitoff-kristine/migrations/env.py create mode 100644 twitoff-kristine/migrations/script.py.mako create mode 100644 twitoff-kristine/migrations/versions/4c94855c06c7_.py create mode 100644 twitoff-kristine/migrations/versions/__pycache__/4c94855c06c7_.cpython-37.pyc create mode 100644 twitoff-kristine/web_app/__init__.py create mode 100644 twitoff-kristine/web_app/__pycache__/__init__.cpython-37.pyc create mode 100644 twitoff-kristine/web_app/__pycache__/models.cpython-37.pyc create mode 100644 twitoff-kristine/web_app/models.py create mode 100644 twitoff-kristine/web_app/routes/__pycache__/book_routes.cpython-37.pyc create mode 100644 twitoff-kristine/web_app/routes/__pycache__/home_routes.cpython-37.pyc create mode 100644 twitoff-kristine/web_app/routes/book_routes.py create mode 100644 twitoff-kristine/web_app/routes/home_routes.py create mode 100644 twitoff-kristine/web_app/templates/books.html create mode 100644 twitoff-kristine/web_app/templates/new_book.html create mode 100644 twitoff-kristine/web_app/twitoff_kristine_development.db diff --git a/twitoff-kristine/Pipfile b/twitoff-kristine/Pipfile new file mode 100644 index 00000000..62b71683 --- /dev/null +++ b/twitoff-kristine/Pipfile @@ -0,0 +1,242 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +flake8 = "*" + +[packages] +alabaster = "==0.7.12" +anaconda-client = "==1.7.2" +anaconda-navigator = "==1.9.12" +anaconda-project = "==0.8.3" +applaunchservices = "==0.2.1" +appnope = "==0.1.0" +appscript = "==1.0.1" +argh = "==0.26.2" +asn1crypto = "==1.3.0" +astroid = "==2.3.3" +astropy = "==4.0" +atomicwrites = "==1.3.0" +attrs = "==19.3.0" +autopep8 = "==1.4.4" +backcall = "==0.1.0" +beautifulsoup4 = "==4.8.2" +bitarray = "==1.2.1" +bkcharts = "==0.2" +bleach = "==3.1.0" +bokeh = "==1.4.0" +boto = "==2.49.0" +certifi = "==2019.11.28" +cffi = "==1.14.0" +chardet = "==3.0.4" +click = "==7.0" +cloudpickle = "==1.3.0" +clyent = "==1.2.2" +colorama = "==0.4.3" +conda = "==4.8.2" +conda-build = "==3.18.11" +conda-package-handling = "==1.6.0" +conda-verify = "==3.4.2" +contextlib2 = "==0.6.0.post1" +cryptography = "==2.8" +cytoolz = "==0.10.1" +dask = "==2.11.0" +decorator = "==4.4.1" +defusedxml = "==0.6.0" +diff-match-patch = "==20181111" +distributed = "==2.11.0" +docutils = "==0.16" +entrypoints = "==0.3" +fastcache = "==1.1.0" +filelock = "==3.0.12" +flake8 = "==3.7.9" +fsspec = "==0.6.2" +future = "==0.18.2" +gevent = "==1.4.0" +glob2 = "==0.7" +gmpy2 = "==2.0.8" +greenlet = "==0.4.15" +h5py = "==2.10.0" +html5lib = "==1.0.1" +hypothesis = "==5.5.4" +idna = "==2.8" +imageio = "==2.6.1" +imagesize = "==1.2.0" +importlib-metadata = "==1.5.0" +intervaltree = "==3.0.2" +ipykernel = "==5.1.4" +ipython = "==7.12.0" +ipywidgets = "==7.5.1" +isort = "==4.3.21" +itsdangerous = "==1.1.0" +jdcal = "==1.4.1" +jedi = "==0.14.1" +joblib = "==0.14.1" +json5 = "==0.9.1" +jsonschema = "==3.2.0" +jupyter = "==1.0.0" +jupyter-client = "==5.3.4" +jupyter-console = "==6.1.0" +jupyter-core = "==4.6.1" +jupyterlab = "==1.2.6" +jupyterlab-server = "==1.0.6" +keyring = "==21.1.0" +kiwisolver = "==1.1.0" +lazy-object-proxy = "==1.4.3" +libarchive-c = "==2.8" +lief = "==0.9.0" +llvmlite = "==0.31.0" +locket = "==0.2.0" +lxml = "==4.5.0" +matplotlib = "==3.1.3" +mccabe = "==0.6.1" +mistune = "==0.8.4" +mkl-fft = "==1.0.15" +mkl-random = "==1.1.0" +mkl-service = "==2.3.0" +mock = "==4.0.1" +more-itertools = "==8.2.0" +mpmath = "==1.1.0" +msgpack = "==0.6.1" +multipledispatch = "==0.6.0" +navigator-updater = "==0.2.1" +nbconvert = "==5.6.1" +nbformat = "==5.0.4" +networkx = "==2.4" +nltk = "==3.4.5" +nose = "==1.3.7" +notebook = "==6.0.3" +numba = "==0.48.0" +numexpr = "==2.7.1" +numpy = "==1.18.1" +numpydoc = "==0.9.2" +olefile = "==0.46" +openpyxl = "==3.0.3" +pandas = "==1.0.1" +pandocfilters = "==1.4.2" +parso = "==0.5.2" +partd = "==1.1.0" +path = "==13.1.0" +pathlib2 = "==2.3.5" +pathtools = "==0.1.2" +patsy = "==0.5.1" +pep8 = "==1.7.1" +pexpect = "==4.8.0" +pickleshare = "==0.7.5" +pkginfo = "==1.5.0.1" +pluggy = "==0.13.1" +ply = "==3.11" +prometheus-client = "==0.7.1" +prompt-toolkit = "==3.0.3" +psutil = "==5.6.7" +ptyprocess = "==0.6.0" +py = "==1.8.1" +pycodestyle = "==2.5.0" +pycosat = "==0.6.3" +pycparser = "==2.19" +pycrypto = "==2.6.1" +pycurl = "==7.43.0.5" +pydocstyle = "==4.0.1" +pyflakes = "==2.1.1" +pylint = "==2.4.4" +pyodbc = "===4.0.0-unsupported" +pyparsing = "==2.4.6" +pyrsistent = "==0.15.7" +pytest = "==5.3.5" +pytest-arraydiff = "==0.3" +pytest-astropy = "==0.8.0" +pytest-astropy-header = "==0.1.2" +pytest-doctestplus = "==0.5.0" +pytest-openfiles = "==0.4.0" +pytest-remotedata = "==0.3.2" +python-dateutil = "==2.8.1" +python-jsonrpc-server = "==0.3.4" +python-language-server = "==0.31.7" +pytz = "==2019.3" +pyzmq = "==18.1.1" +qtconsole = "==4.6.0" +requests = "==2.22.0" +rope = "==0.16.0" +scikit-image = "==0.16.2" +scikit-learn = "==0.22.1" +scipy = "==1.4.1" +seaborn = "==0.10.0" +simplegeneric = "==0.8.1" +singledispatch = "==3.4.0.3" +six = "==1.14.0" +snowballstemmer = "==2.0.0" +sortedcollections = "==1.1.2" +sortedcontainers = "==2.1.0" +soupsieve = "==1.9.5" +sphinxcontrib-applehelp = "==1.0.1" +sphinxcontrib-devhelp = "==1.0.1" +sphinxcontrib-htmlhelp = "==1.0.2" +sphinxcontrib-jsmath = "==1.0.1" +sphinxcontrib-qthelp = "==1.0.2" +sphinxcontrib-serializinghtml = "==1.1.3" +sphinxcontrib-websupport = "==1.2.0" +spyder = "==4.0.1" +spyder-kernels = "==1.8.1" +statsmodels = "==0.11.0" +sympy = "==1.5.1" +tables = "==3.6.1" +tblib = "==1.6.0" +terminado = "==0.8.3" +testpath = "==0.4.4" +toolz = "==0.10.0" +tornado = "==6.0.3" +tqdm = "==4.42.1" +traitlets = "==4.3.3" +ujson = "==1.35" +unicodecsv = "==0.14.1" +urllib3 = "==1.25.8" +watchdog = "==0.10.2" +wcwidth = "==0.1.8" +webencodings = "==0.5.1" +widgetsnbextension = "==3.5.1" +wrapt = "==1.11.2" +wurlitzer = "==2.0.0" +xlrd = "==1.2.0" +xlwings = "==0.17.1" +xlwt = "==1.3.0" +xmltodict = "==0.12.0" +yapf = "==0.28.0" +zict = "==1.0.0" +zipp = "==2.2.0" +Babel = "==2.8.0" +"backports.functools-lru-cache" = "==1.6.1" +"backports.shutil_get_terminal_size" = "==1.0.0" +"backports.tempfile" = "==1.0" +"backports.weakref" = "==1.0.post1" +Bottleneck = "==1.3.2" +Cycler = "==0.10.0" +Cython = "==0.29.15" +et_xmlfile = "==1.0.1" +Flask = "==1.1.1" +HeapDict = "==1.0.1" +ipython_genutils = "==0.2.0" +Jinja2 = "==2.11.1" +MarkupSafe = "==1.1.1" +Pillow = "==7.0.0" +Pygments = "==2.5.2" +pyOpenSSL = "==19.1.0" +PySocks = "==1.7.1" +PyWavelets = "==1.1.1" +PyYAML = "==5.3" +QDarkStyle = "==2.8" +QtAwesome = "==0.6.1" +QtPy = "==1.9.0" +Rtree = "==0.9.3" +"ruamel.yaml" = "==0.15.87" +Send2Trash = "==1.5.0" +Sphinx = "==2.4.0" +SQLAlchemy = "==1.3.13" +Werkzeug = "==1.0.0" +XlsxWriter = "==1.2.7" +flask-sqlalchemy = "*" +flask-migrate = "*" + +[requires] +python_version = "3.7" diff --git a/twitoff-kristine/README.md b/twitoff-kristine/README.md new file mode 100644 index 00000000..3d5cb7fc --- /dev/null +++ b/twitoff-kristine/README.md @@ -0,0 +1,38 @@ +# twitoff-kristine + +## Installation + +```sh +git clone https://github.com/KristineYW/twitoff-kristine.git +cd twitoff-kristine/ +``` + +## Setup + +Setup and activate virtual encvironment: + +```sh +pipenv install +pipenv shell +``` + +Setup the database: + +```sh +# Windows users can omit the "FLASK_APP=web_app" part... + +FLASK_APP=web_app flask db init #> generates app/migrations dir + +# run both when changing the schema: +FLASK_APP=web_app flask db migrate #> creates the db (with "alembic_version" table) +FLASK_APP=web_app flask db upgrade #> creates the specified tables +``` + +## Usage + +Run the web app: + +```sh +FLASK_APP=web_app flask run +``` + diff --git a/twitoff-kristine/__pycache__/hello.cpython-37.pyc b/twitoff-kristine/__pycache__/hello.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7720695e96ecc0360919ac391e996e92626d5de GIT binary patch literal 543 zcmY*WO;5r=5Z&#zv=E4i2fWr}588MqL{J0{f(f7r2T64oY$$EBTLLtC!hc~*^yts< zZ}jTH@E15ayNO?u%w+a;_q}=3dZ|=E5Y_k3>jFmTLms|^KywT!Do`k*I6yNz#27Km zv^5?QMqYHPy<$qJ{)hlE6k-69qozV~)aoH8zX1m1;LJD+JTcv3_f`TjKon_^Cy=5H zB>|x|h*0eTQF4!-(6a^=|<~H{hX~_D_-WnW5BnpcT@voP^7N*Ky3u7|XSCxyQ^JjY4n6Mx%^)ahw?(sF|8r cUH?NXcfu97RhdO}9`1pVFqVk0G-dF$lsx&h~gX-c!aU(JGnD*pmlS%@J61sd3mewN51X1pdX9^+xPRZ zXph<$vGz0?Ma*N-v~vo6m^16rV2(#C;3>>|MSs)>YcyM>ZMMex({&ncpy`F_#p$I} zJiAOgv^#g^4y;+uy*Ii-S7`4A8g0-%U4`~4YtOFDk@$^moFa_4&#s!5I*-v{?Jsx> z8erXfmZ|+jDxz4yxY`9%G|qCiQ}S^(fzdkSlZ>-uEXpED&#YcmmO0D@U{UP3I_i*| z6?<7aWc&c^owODL{3WESj(YO@oaE^~D-MUX$aPR;69EUl#+ygZ=4NWHVm=I|4P^(4 zyakm)GfeRupCIK--D9LY>QMKki(x!#&C#o#?fG-q`VFGqSLhM?7Fu{x@wApICh^yg9@zDS z)0mfF;qjLioljs(Sx@$tmKZ#eG-Z_{dpWba_L*QYk?}K@=fgPOK8)qltg13Tu?IGu z;#4rA;I?+lGZxd5Z>g9aFdlQpDBR-i_7@ND$Eu9?z}*4Ka&yAsB|9X~;r`{>^@r>^ zOKZhG8pQT^R%FVaHpz@fsf0bgG&XypOhs0yxU5xGtA*3I1Nda%YS#p^uZWm1l@v@7 zN)*v6d8U{kd9s&rDt8Bg_8VAr->xGWPs++XPxugD-F^eQ0M#MAw#R^Mi4ufMlA3k8 zCu*K7V>rOVDD_t))}eX5ww(DCm^Z8r_2qwWNEQLV0n4Qoc{joy?z#~c7s2+1eJ%{l z{Ek_uprV*MFA#7KDLiu&p1N~PUFA(%)O+ck;A1=k=DpfJaa1r3$LQEm?PEk+zqks7 zO?{AT_h;uP5V#6vD+{&;v)+QOLBm$y?V?8m;B9#HQKxvRURR^^0oV2Wb*gpvKx^=9PL+vjkD*vZPIL-L)bua(K2FIE#d>X zgb1P99rT5XQ3FlKNKH1O)$5JIl8k3(HqnBmI^3=E{2{ovIovS8LL~aej}fCV|2-W+ z4rJUwCUx(PS`*N{6su;{8dL+<-UYIL!zq)H#D`|qi1Zw!m);4{XRt_Kg$i}TzyUC! zfINL@9jI50R6mB3xwBP(PZKBeF zU{y|1ro*!=*`RB3kA0Qy17{aWDltE$bD&xHEE&VwFjeR5j!}y=$*k*yxa)LH@q91B Vk>7>9=HTnN7lxO@8zByze*la>en9{L literal 0 HcmV?d00001 diff --git a/twitoff-kristine/migrations/alembic.ini b/twitoff-kristine/migrations/alembic.ini new file mode 100644 index 00000000..f8ed4801 --- /dev/null +++ b/twitoff-kristine/migrations/alembic.ini @@ -0,0 +1,45 @@ +# A generic, single database configuration. + +[alembic] +# template used to generate migration files +# file_template = %%(rev)s_%%(slug)s + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/twitoff-kristine/migrations/env.py b/twitoff-kristine/migrations/env.py new file mode 100644 index 00000000..94521792 --- /dev/null +++ b/twitoff-kristine/migrations/env.py @@ -0,0 +1,96 @@ +from __future__ import with_statement + +import logging +from logging.config import fileConfig + +from sqlalchemy import engine_from_config +from sqlalchemy import pool + +from alembic import context + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +fileConfig(config.config_file_name) +logger = logging.getLogger('alembic.env') + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +from flask import current_app +config.set_main_option( + 'sqlalchemy.url', + str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) +target_metadata = current_app.extensions['migrate'].db.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, target_metadata=target_metadata, literal_binds=True + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + + # this callback is used to prevent an auto-migration from being generated + # when there are no changes to the schema + # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html + def process_revision_directives(context, revision, directives): + if getattr(config.cmd_opts, 'autogenerate', False): + script = directives[0] + if script.upgrade_ops.is_empty(): + directives[:] = [] + logger.info('No changes in schema detected.') + + connectable = engine_from_config( + config.get_section(config.config_ini_section), + prefix='sqlalchemy.', + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure( + connection=connection, + target_metadata=target_metadata, + process_revision_directives=process_revision_directives, + **current_app.extensions['migrate'].configure_args + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/twitoff-kristine/migrations/script.py.mako b/twitoff-kristine/migrations/script.py.mako new file mode 100644 index 00000000..2c015630 --- /dev/null +++ b/twitoff-kristine/migrations/script.py.mako @@ -0,0 +1,24 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision = ${repr(up_revision)} +down_revision = ${repr(down_revision)} +branch_labels = ${repr(branch_labels)} +depends_on = ${repr(depends_on)} + + +def upgrade(): + ${upgrades if upgrades else "pass"} + + +def downgrade(): + ${downgrades if downgrades else "pass"} diff --git a/twitoff-kristine/migrations/versions/4c94855c06c7_.py b/twitoff-kristine/migrations/versions/4c94855c06c7_.py new file mode 100644 index 00000000..1baacc15 --- /dev/null +++ b/twitoff-kristine/migrations/versions/4c94855c06c7_.py @@ -0,0 +1,33 @@ +"""empty message + +Revision ID: 4c94855c06c7 +Revises: +Create Date: 2020-06-15 18:25:17.488417 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '4c94855c06c7' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('book', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('title', sa.String(length=128), nullable=True), + sa.Column('author_id', sa.String(length=128), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('book') + # ### end Alembic commands ### diff --git a/twitoff-kristine/migrations/versions/__pycache__/4c94855c06c7_.cpython-37.pyc b/twitoff-kristine/migrations/versions/__pycache__/4c94855c06c7_.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b36696655ae6b243fced6ef62d9aad38d726e477 GIT binary patch literal 863 zcmZuvL2uJA6po!VNwW>Xm^h+bd)V4e?N+J@Avz&VXcJ=N5+R~A_F6N?4z|0goH%gZ ze^`(FC0{w9{QxeUcu6-l1h(Gu^Yin2@B8eRYip4MPWFsf{qyNO4R}v>6wM5c_dyNg?ap>*v$M0=?Z@50aJxV3 z?r!x4gI;$ximstQr-dw*Q$A2t=QNGR_qu$l#AI!3JM>3x~MGyL4+$ z12o_u!6hQ$A8+$t@0CyR0xcTAhXXjHBkPT&JhPaQSI|%>W}IhZPHn?5!|C-Gs0@Ce zQ!z2q6Wh#YW-3+6NGnhk-*z>xQKzQ9hIMBBk>s;N*x*1II-$z?$3`(Ru^Vp`D>5~I zP3I#iv{4xo=9{A)LY`XvI&8nwRO$8{!Y?v0Y41~gW@Onm7tF}h)6Fx*v|)m_3pP=i zfd|p;bGT6(_lZom%DD|@B}5VW7z*h6-(VlDqbD%cI{5x#+XY9>_5(1MY%kCaPxwex z$1S|X91$hUCE~m0m)0W)vrQr|L|yqQY<0zxgVhG;)`|_%l*l|yZIE$Vj9Gq@Q-9(a z&!@DQs}+c}p}P5UcCAX6-fhP!6ZtfShoW5Dh|rP>qEjhqP<5UEwiWIblFT@L9zcFw QvF@Q&6nY-2ryH*P1{G}D9smFU literal 0 HcmV?d00001 diff --git a/twitoff-kristine/web_app/__init__.py b/twitoff-kristine/web_app/__init__.py new file mode 100644 index 00000000..5d5a2839 --- /dev/null +++ b/twitoff-kristine/web_app/__init__.py @@ -0,0 +1,26 @@ +# web_app/__init__.py + +from flask import Flask + +from web_app.models import db, migrate +from web_app.routes.home_routes import home_routes +from web_app.routes.book_routes import book_routes + +DATABASE_URL = "sqlite:///twitoff_kristine_development.db" # using relative filepath + +def create_app(): + app = Flask(__name__) + + app.config["SQLALCHEMY_DATABASE_URI"] = DATABASE_URL + app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False + db.init_app(app) + migrate.init_app(app, db) + + app.register_blueprint(home_routes) + app.register_blueprint(book_routes) + return app + + +if __name__ == "__main__": + my_app = create_app() + my_app.run(debug=True) diff --git a/twitoff-kristine/web_app/__pycache__/__init__.cpython-37.pyc b/twitoff-kristine/web_app/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9745702bcc27aacb8af47d104fdf7a0615ce208f GIT binary patch literal 818 zcmZWn&5qMB5Vn&vP1Cfy;(`Pc_Z(>Ms6u4httfQ6V%t67!&*)4mTdEf<5Crs({kkj zxa}T!rCd269)Jrc#@?+|2}d*eX2$l+H{+95%SEuB{`qzF-9YH4GWN>^@Cu~70>u!+ z2}&`+SYabEQj?geMJ#QbNiDUBt+AEVQ-?T!Yox(!R{x5K%bUzu8G>;41`&^Y*Dcmy z?l*N?bAo*DH{?J*u4;p1R<3-bGFVjA(|9Rnl7qkbAx}9K`C9T)nNgmv9?Z{v`7wzl ze-Q+M+{7|pEa*zarHnI98UMtSyhwQ_J1m;3ENWp83#129z5ykX#5ed0lEw~Qn+$h> zqef;IN$a+@Lw8WCv=x%poq^E~-PWa}yc#v`5pc1_-@(pPs#^{cswdgp*Tx zc`+Q2X9tn#Mc8{w&(8b9!LS!jhv(yo?+O?LsvJtQ84#wGcW{1G+4DSGKvUFgDksij zNoPeN6qV|c;7ef51&xw5FGQS4QGkpYIzOYTX_r$VaIT>`aJy?N8nRD(pj8QI#sh} zJX$Zue!HqI)RZ+<(tgO$Npr@NQd84}$di5Ke(artC!mS_x8dMXXwt%g8gwC|4v5(4 mR@GdYVx8$e9H_P~w+ltA6aG^5SJU#0W9$JX%Wzr_w(&p1g44bL literal 0 HcmV?d00001 diff --git a/twitoff-kristine/web_app/__pycache__/models.cpython-37.pyc b/twitoff-kristine/web_app/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..19f75675b890cf8a556c0336211edd950b5bb427 GIT binary patch literal 1433 zcmZ`(OK%%D5GMDfhb_l2f*g7xbn*tSgd{x)X^=QBiUf)KaEk(4xC?4Il2+Q6Nve)g z87Saf^82?Bp(YJ?Iphq7^9_eH-0yVS1ly~3|NL_75c0QS z>V`bIk6rB}5k%00q%@$^%&o*q?ZBo4=s5`-u#vi76JZPI1rZK7Q}5gk8p0Lc3lcO% zv}_-J_vAqmO(0z$*LWI_CD#y{)w;PjxsP2PAOR9kK>`cxDI!f>L520w z3OukckiTdM`we|VgXRZ(OE|(s^tSL2y-_;*c|Q9A5jP4Mr(7<=87$uZjsOuwVwxEZ z^h50G1`cLGv5rulQ~Z=S1d6sy@z=+PqVV|DAO=4R`xPXHZp=7KFo-N4F~Kz-as^C6luN<#;S?gRSe)s6T`i7uoM&9d zp!S%`nV!IcMLc6evsKS!27+A_BrsqFmkR2wyCySwCv%XC9#4{8|5E$=3SSLA=`ZkTg2$H" + + +def parse_records(database_records): + """ + A helper method for converting a list of database record objects into a list of dictionaries, so they can be returned as JSON + + Param: database_records (a list of db.Model instances) + + Example: parse_records(User.query.all()) + + Returns: a list of dictionaries, each corresponding to a record, like... + [ + {"id": 1, "title": "Book 1"}, + {"id": 2, "title": "Book 2"}, + {"id": 3, "title": "Book 3"}, + ] + """ + parsed_records = [] + for record in database_records: + print(record) + parsed_record = record.__dict__ + del parsed_record["_sa_instance_state"] + parsed_records.append(parsed_record) + return parsed_records diff --git a/twitoff-kristine/web_app/routes/__pycache__/book_routes.cpython-37.pyc b/twitoff-kristine/web_app/routes/__pycache__/book_routes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b37fa30a4022fd60cda08842e38793f865f85f30 GIT binary patch literal 1396 zcmYjQ%WfMt6eT$?X(U;;(}#m@)NYCiPzz0WMN!m>6BGz46^^@^MF(S%l1HA0LQ*h1 za8}A98~;HT_Oic3psOwle?gG0dM`(IJcHrm@D6#-xxAxZFC_4M{P6Fef4hYIgOj@l z=HwUn)H`T6;WQ@&jcLJRRyeU!xUowSXSrASv0nsnP_*I}C4zECwAU;SMR?ue?hWN0 z_urB=jk^{J0BP~IMS2zq0qO9rMYcq^=}aOpr3vAEkDzait<IX_R!`S4Jv zGhHo*`aILsZ1&xm%#_YbF+3M1NxEDP8yQx_M$-QB!h|`5C3fpJ?5ps6!a~}DS8l_& z_8Z;zk|}^5d{*)k7;wrNciuDZLNc-Ud4T=g0TT$O^OErJ$^q$}@h$#d`y;S&@O{J# z%ee7$rgL$NUT#*N-l7GY$q#jC`R$+TBCmIT6;gbw2C6E=z~Zn=Pza^cxsW~hEus?n zL5DMISJU)iYCiuYIGI&4Ib9WLsdiwg(e9w~E|XsZQiqN9VJXh<^#g9xZuO&Gps`6T z8`nLEv~F6m8zv7ZVD6;l(YlNL3Lu5r36p!!*1gT4Qz_tn8u$0ftK*2GMtxdwbx#DH z#7eY8j$nX9G}Ub3tm&HJ&BHNgkBRM_$Ar6A43gq4{OjP7+~DoRaqEV_sLj2*zq$XO z*}EEy>+r?o=(oY)!STV5u}wr`(-n8p74VTsnHC~q@(~a)?G2Xkx<8ssUJjleJwG^p zemI!Cgpe;FBz7@pQ7F3@@A7P_C5kXEB%`opAp@KT3R0R?B~%CJ#-CP2k?E!~sP*ZA ztJcs?}24oy<8*i4U>P({Rc1uga-Ws#Dsh9nt;v!d{ z7}?S^t;7mW5{czvJX=+^Q0$FqnBg%G=sigKPq6DM7e6}?q0oXo`WXwI-PUfn>-`Vv C&rRR} literal 0 HcmV?d00001 diff --git a/twitoff-kristine/web_app/routes/__pycache__/home_routes.cpython-37.pyc b/twitoff-kristine/web_app/routes/__pycache__/home_routes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5370629b2ac5ee6be0c3da7f48adf4d9b58ba6a7 GIT binary patch literal 508 zcmYk3%}N6?5XUFkk8Z2=;1kqi4>d0!MXQLXUPOc*T(%~yOZSUpOFz(4`xYYT(O255 zg7g)7awej7U}lqlCjb1B?KPVX!03E_-FXb)gC@V>;NTR~bg@W~EP<2_7z4#5SA4|> zj&fdI>AW%NN^cD-Ht?+Cqf(QBReV{$hIV6v9?)i0y_ZZ?q2sKq_8#(7g*u;>%50gq zrw$6_0FHT%X%4VR_5_kY!ZW;Z^m6(e7u99+N+n6&y3KVWk6Q2K&gR<3C0n+a;>IX# z#3IhdvnU&j3uPu{UWjrQm-%SandsP*ai+vf4a2A?#1D(u;W{oBl^17H%>$yLbAh`| z*YUgbMKnbEKX6(kcneOgk|8edFM~7cYo+R+Zf8W!m1nK!wubHwT+@%~w`-L*N+L7S rq*g%~W)VJGs2!Sm7TChr_8n9E4Awa~Npm?(RF}3G()W48IrP5){IPD^ literal 0 HcmV?d00001 diff --git a/twitoff-kristine/web_app/routes/book_routes.py b/twitoff-kristine/web_app/routes/book_routes.py new file mode 100644 index 00000000..a90c7da6 --- /dev/null +++ b/twitoff-kristine/web_app/routes/book_routes.py @@ -0,0 +1,45 @@ +# web_app/routes/book_routes.py + +from flask import Blueprint, jsonify, request, render_template #, flash, redirect +from web_app.models import Book, db, parse_records + +book_routes = Blueprint("book_routes", __name__) + + +@book_routes.route("/books.json") +def list_books(): + book_records = Book.query.all() + print(book_records) + books = parse_records(book_records) + return jsonify(books) + + +@book_routes.route("/books") +def list_books_for_humans(): + books = [ + {"id": 1, "title": "Book 1"}, + {"id": 2, "title": "Book 2"}, + {"id": 3, "title": "Book 3"}, + ] + return render_template("books.html", message="Here's some books", books=books) + + +@book_routes.route("/books/new") +def new_book(): + return render_template("new_book.html") + + +@book_routes.route("/books/create", methods=["POST"]) +def create_book(): + print("FORM DATA:", dict(request.form)) + + new_book = Book(title=request.form["book_title"], author_id=request.form["author_name"]) + db.session.add(new_book) + db.session.commit() + + return jsonify({ + "message": "BOOK CREATED OK", + "book": dict(request.form) + }) + #flash(f"Book '{new_book.title}' created successfully!", "success") + #return redirect(f"/books") diff --git a/twitoff-kristine/web_app/routes/home_routes.py b/twitoff-kristine/web_app/routes/home_routes.py new file mode 100644 index 00000000..adb359d6 --- /dev/null +++ b/twitoff-kristine/web_app/routes/home_routes.py @@ -0,0 +1,16 @@ +# web_app/routes/home_routes.py + +from flask import Blueprint + +home_routes = Blueprint("home_routes", __name__) + + +@home_routes.route("/") +def index(): + x = 2 + 2 + return f"Hello World! {x}" + + +@home_routes.route("/about") +def about(): + return "About me" diff --git a/twitoff-kristine/web_app/templates/books.html b/twitoff-kristine/web_app/templates/books.html new file mode 100644 index 00000000..d50d80b3 --- /dev/null +++ b/twitoff-kristine/web_app/templates/books.html @@ -0,0 +1,27 @@ + + + + + + + Our Books Page! + + + +

Welcome to the Books Page

+ +

{{ message }}

+ + {% if books %} +
    + {% for book in books %} +
  • {{ book["title"] }}
  • + {% endfor %} +
+ + {% else %} +

Books not found.

+ {% endif %} + + + \ No newline at end of file diff --git a/twitoff-kristine/web_app/templates/new_book.html b/twitoff-kristine/web_app/templates/new_book.html new file mode 100644 index 00000000..8df506b9 --- /dev/null +++ b/twitoff-kristine/web_app/templates/new_book.html @@ -0,0 +1,31 @@ + + + + + + + Document + + + +

New Book Page

+ +

Please fill out the form and submit to create a new book!

+ +
+ + + + + + + + +
+ + + \ No newline at end of file diff --git a/twitoff-kristine/web_app/twitoff_kristine_development.db b/twitoff-kristine/web_app/twitoff_kristine_development.db new file mode 100644 index 0000000000000000000000000000000000000000..fae3b7436d67b43fc0ce97536c94679ab3725423 GIT binary patch literal 16384 zcmeI%O>fgM7zc1Wi72hqg-A@jJ`$SLs0fjCgK&ufWnY z8=cKfzRXoRF2q>M<0@N&C=B9|;^5IRq^gCwt!6%Q{}1< z^fHJBPlBlH`MYk_nx3kuEED}qz2|wf_biBx=xKOF-F)J<+@;GKonDWBY@S7t7GgHe zv*fKP7rC6*s>WJuwazNc^T(3;>Fm$D`@Xvt^I(5;7)OC#4%KEzPL4BL3vp#W9qWDL zO6Q=*Sw5eL_lq}$KE)?`t@5m%)F<<54W`~|SF7#T)|uNsnZA%9009U<00Izz00bZa z0SG_<0uZ<)0vp`e+RpB6@9ykmx9?{C?nFH!bEm)3hu<(1}z^l;j1zV^jmx%0S=YRnt@yg`{_~EG9w!H=W6!xBvhE literal 0 HcmV?d00001