flaskpython
㈠ 【python基礎】flask框架是用來干什麼的
你可以用來開發網站伺服器,它包含一個wsgi工具包(werkzeug)、 模板引擎(jinja2)還有主體(flask)。
安裝方式:
- 打開命令行
- 輸入命令
- 命令是"pip install flask"
㈡ Python中Flask框架的變數和函數
可以從模板中直接訪問Flask當前的config對象:
就是flask中代表當前請求的request對象:
輸出結果為(本機本地運行):
為Flask的session對象
{{ session.get('name') }}
輸出結果為(本機本地運行):檔蠢
url_for會緩運根據傳入的路由器函數名,返回該路由對應的URL,在模板中始終使用url_for()就可以安全的修改路由綁定的URL,則不比擔心模板中渲染出錯的鏈接,經常用於超鏈接,比如下面的例子:
點擊即可跳轉至主頁
同時,如果定義的路由URL是帶有參數的,可以把它們作為關鍵字參數傳入url_for(),Flask會把他們填擾蠢梁充進最終生成的URL中:
這個函數會返回之前在flask中通過flask()傳入的消息的列表,flash函數可以把由Python字元串表示的消息加入一個消息隊列中,再使用get_flashed_message()函數取出它們並消費掉:
㈢ 【Python基礎】flask是什麼意思
Flask 是一個微框架(Micro framework),其官方文檔的前言部分對Flask做了很清楚的定性介紹:
「微」(Micro)是什麼意思?
「微」(micro) 並不意味著你要把整個web應用放到一個python文件里(雖然確實可以),也不意味著Flask 在功能上有所欠缺。微框架中的「微」意味著 Flask 旨在保持核心功能的簡單而易於擴展。Flask 不會替你做出太多決策,比如使用何種資料庫。而那些 Flask 幫你做好的決策(比如使用哪種模板引擎),都是很容易替換。除此之外的一切都由可由你掌握。
默認情況下,Flask 不包含資料庫抽象層、表單驗證,或是任何已在其它已庫中處理的很好的功能。相反,Flask 支持通過擴展來給應用添加這些功能,如同是 Flask 本身實現的一樣。眾多的擴展提供了資料庫集成、表單驗證、上傳處理及各種各樣的開放認證技術等功能。Flask 也許是「微小」的,但它已准備好在復雜的生產環境中投入使用。
Flask盡量避免重復製造輪子,而是與已有的優秀輪子去結合,這使得Flask靈活、強大,且定製性更強。 Flask 配置選項眾多,均設置了合理的默認值,並會遵循一些慣例;配置選項均可以修改,但通常沒必要修改,尤其是剛開始的時候。這使得Flask易於上手。
㈣ python-flask 快速搭建web
Flask是由python實現的一個web微框架,我們可以使用Python語言快速實現一個網站或Web服務,很方便的實現工具鏈,或者工作中其他內容的集成展示。
python官網 : https://www.python.org
flask: pip3 install flask
python具有相當多的庫可以使用,可以通過 ***pip3 intall xx ***安裝各類庫,極大的方便快速實現功能。
㈤ python使用Flask框架獲取用戶IP地址的方法
主要介紹了python使用Flask框架獲取用戶IP地址的方法,實例分析了Python使用Flask框架remote_addr獲取IP的`技巧,非常具有實用價值,需要的朋友可以參考下。
下面的代碼包含了html頁面和python代碼,非常詳細,如果你正使用Flask,也可以學習一下最基本的Flask使用方法。
python代碼如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask, render_template, request
# Initialize the Flask application
app = Flask(__name__)
# Default route, print user's IP
@app.route('/')
def index():
ip = request.remote_addr
return render_template('index.html', user_ip=ip)
if __name__ == '__main__':
app.run(
host="0.0.0.0",
port=int("80")
)
html代碼如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE html>
<html lang="en">
<head>
<link href="bootstrap/3.0.0/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<p class="container">
<p class="header">
<h3 class="text-muted">How To Get The IP Address Of The User</h3>
</p>
<hr/>
<p>
You IP address is: <strong>{{user_ip}}</strong>
<p class="header">
<h3 class="text-muted">Code to retrieve the IP</h3>
</p>
<hr/>
<pre>
from flask import Flask, render_template, request
# Initialize the Flask application
app = Flask(__name__)
# Default route, print user's IP
@app.route('/')
def index():
ip = request.remote_addr
return render_template('index.html', user_ip=ip)
</pre>
</p>
</p>
</body>
</html>
希望本文所述對大家的Python程序設計有所幫助。
㈥ python flask 怎麼組織程序
1.初始化
所有的flask程序都必須創建一個程序實例
web伺服器使用wsgi介面協議,把接收客戶端的請求都轉發給這個程序實例來進行處理。這個程序實例就是flask對象
from flask import Flask
app = Flask(__name__)
#__name__決定程序的根目錄,以便以後能找到相對於程序根目錄的資源文件位置
2.路由和視圖函數
程序實例需要知道接收請求後,需要知道url請求應該運行哪些代碼。所以保存了一個url和python函數的映射關系;這個映射關系就叫做路由
flask程序中路由的寫法:
2.1#使用app.route裝飾器,把修飾的函數注冊為路由。例如
@app.route('/')def index(): return "<h1>Hello World</h1>"
#函數的名字不是必須寫index的,只是和裝飾器關聯的時候寫的函數名而已
#把index函數注冊為程序根路徑的處理程序。函數的返回值稱為響應,是客戶端接收的內容。
像index這樣的函數稱為試圖函數,試圖函數返回的響應可以是包含html的簡單字元串,也可以是復雜的東西
2.2#可變url部分映射,使用特定的裝飾器語法就可以
@app.route('/user/<name>')def user(name): return "<h1>hello %s</h1>"%(name)
裝飾器中的<name>指定可變內容為name,name對user(name)函數中的傳遞參數,這2個部分內容必須一致
調用試圖函數時候,flask會自動的將動態部分作為參數傳入參數,這個函數中,參數用於生成個人的歡迎信息
#備註:路由中的動態部分默認使用字元串類型,可以使用int,float,path來定義;例如<int:id>;path類型也是字元串,但不把斜線視作分隔符,而將其當做動態片段的一部分
3.啟動伺服器
調用程序實例app的run方法啟動flask集成開發的web伺服器
if __name__ == "__main__":
app.run(debug=True)
debug=True代表的是調試模式,這個flask自帶的run方法開啟的伺服器不適合在生產中使用,此處只用來測試
4.一個完整的Flask程序
啥也不說,先上例子hello.py
㈦ python web開發用什麼框架
對初學者來說,循序漸進是最重要的,我推薦學習 Flask(Welcome | Flask (A Python Microframework))
Flask 很輕,花很少的成本就能夠開發一個簡單的網站。非常適合初學者學習。
Flask 框架學會以後,可以考慮學習插件的使用。例如使用 WTForm + Flask-WTForm 來驗證表單數據,用 sqlAlchemy + Flask-SQLAlchemy 來對你的資料庫進行控制。
BTW:果殼網基於 Flask 開發的。
另外也簡單介紹下其他框架:
1. Django。如樓上所說,是一個全能型框架。目前 Django 的使用面還是很廣的,有學習的價值,但是不建議初學者學習,因為要學習的東西太多了,一下子難以吸收會失去興趣。當然,Django 的目的是為了讓開發者能夠 快速 地開發一個網站,它提供了很多模塊,其中我最喜歡的就是 admin 模塊,http://your.site.com/admin 就進入了網站的後台(內置的哦~)方便地對數據進行操作,等等。。。。因此,如果對 Django 熟悉的話,papapa 一下子就寫好一個網站的原型了。
2. Tornado。傳說中性能高高的框架。Tornado 是一個很好的框架,支持非同步處理的功能,這是它的特點,其他框架不支持。另外一點是,Tornado 的設計似乎更注重 RESTful URL。但 Tornado 提供了網站基本需要使用的模塊外,剩下的則需要開發者自己進行擴展。例如資料庫操作,雖然內置了一個 database 的模塊(後來獨立出去了,現在叫做 torndb,bdarnell/torndb · GitHub)但是不支持 ORM,快速開發起來還是挺吃力的。如果需要 ORM 支持的話,還需要自己寫一層將 SQLAlchemy 和 Tornado 聯系起來,而且這里還有一個坑。
BTW:知乎就是基礎 Tornado 開發的。
3. Bottle。Bottle 和 Flask 都屬於輕量級的 Web 框架。但是 Bottle 似乎落寞了。我覺得跟他的 API 設計有關系。個人認為 Bottle 使用起來不那麼順手,因此也用得少。這里不做太多介紹。
4. web.py。也是很輕的一個框架,使用不多,也不做介紹。
5. web2py。我看樓上都沒有對這個框架做介紹。這個框架是 Google 在 web.py 基礎上二次開發而來的,兼容 GAE 。性能據說很高,曾經用他來做自己的主頁,感覺也還不錯。缺點同樣是對擴展支持不太好,需要自己進行擴展。
6. Quixote。著名的 豆瓣 就是基於 Quixote 開發的。跟上面幾個框架不同,Quixote 的路由會有些特別。另外 Quixote 的性能據說也好。
㈧ 如何部署簡單python + flask應用
我們先寫一個最基本的flask應用:
demo.py
from flask import Flask
app = Flask(**name**)
@app.route('\')
def index():
return 'Hello World.'
if __name__ == __main__:
app.run()
運行這個py文件,打開瀏覽器訪問127.0.0.1:5000就能看到顯示Hello World的頁面 .
如果讓這個flask引用監聽來自公網ip的請求,理論上你跑此程序的機器就相當於一個伺服器了,然而這個伺服器並不完美,所以我們需要nginx和gunicorn來增加它的功能,讓它真刀真槍上生產環境的時候能按要求運行。
flask自帶的WSGI框架性能很差勁,只能適用於開發環境調試使用。我們用專業一點的gunicorn(還有很多其他優秀的框架)替代flask自帶的WSGI框架。
配置完後,通過命令』/usr/local/bin/gunicorn -b127.0.0.1:5000『啟動應用。打開瀏覽器訪問127.0.0.1:5000,同樣能夠得到返回頁面
然而gunicorn也僅僅是一個python的WSGI框架而已,要讓它真正處理來自互聯網的各類訪問功能還是有點欠缺,這時候就需要用到大名鼎鼎的nginx 伺服器來替gunicorn遮風擋雨了。
Ubuntu下安裝nginx可以用命令
sudo apt-get install nginx
安裝後需要進行下配置:
cd /etc/nginx/sites-available
sudo vi test (test為配置名稱,可以根據自己項目進行命名)
test文件的配置為:
server {
listen 80; # 監聽80埠
location / {
proxy_pass http://127.0.0.1:5000; # 代理本機127.0.0.1:5000的服務
}
location /static {
alias /home/ubuntu/myproject/myblog/app/static; # 負載均衡
}
}
cd ..
cd sites-enable
sudo ln -s ../sites-available/lwhile . (創建軟鏈接,別漏掉最後的.)
sudo service nginx reload
sudo service nginx restart
這樣nginx的基本配置文件就寫好了 接下來我們配置進程管理工具supervisor supervisor可以在後面啟動你的python進程,這樣很方便
1.cd /etc/supervisor/conf.d
2.sudo vi test.conf (test為文件名)
[program:test]
command = /usr/local/bin/gunicorn -b127.0.0.1:5000 /home/ubuntu/myproject/test.py
3.sudo supervisorctl
4.reload
5.start test
如果一切正常,做完這所有步驟之後,現在公網的ip訪問你的主機,就可以打開你的flask應用了
㈨ python中flask如何降低內存
Dict
在小型程序中,特別是在腳本中,使用Python自帶的dict來表示結構信息非常簡單方便:
>>> ob = {'x':1, 'y':2, 'z':3}
>>> x = ob['x']
>>> ob['y'] = y
由於在Python 3.6中dict的實現採用了一組有序鍵,因此其結構更為緊湊,更深得人心。但是,讓我們看看dict在內容中佔用的空間大小:
>>> print(sys.getsizeof(ob))
240
如上所示,dict佔用了大量內存,尤其是如果突然虛需要創建大量實例時:
實例數
對象大小
1 000 000
240 Mb
10 000 000
2.40 Gb
100 000 000
24 Gb
類實例
有些人希望將所有東西都封裝到類中,他們更喜歡將結構定義為可以通過屬性名訪問的類:
class Point:
#
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
>>> ob = Point(1,2,3)
>>> x = ob.x
>>> ob.y = y
類實例的結構很有趣:
欄位
大小(比特)
PyGC_Head
24
PyObject_HEAD
16
__weakref__
8
__dict__
8
合計:
56
在上表中,__weakref__是該列表的引用,稱之為到該對象的弱引用(weak reference);欄位__dict__是該類的實例字典的引用,其中包含實例屬性的值(注意在64-bit引用平台中佔用8位元組)。從Python3.3開始,所有類實例的字典的鍵都存儲在共享空間中。這樣就減少了內存中實例的大小:
>>> print(sys.getsizeof(ob), sys.getsizeof(ob.__dict__))
56 112
因此,大量類實例在內存中佔用的空間少於常規字典(dict):
實例數
大小
1 000 000
168 Mb
10 000 000
1.68 Gb
100 000 000
16.8 Gb
不難看出,由於實例的字典很大,所以實例依然佔用了大量內存。
帶有__slots__的類實例
為了大幅降低內存中類實例的大小,我們可以考慮幹掉__dict__和__weakref__。為此,我們可以藉助 __slots__:
class Point:
__slots__ = 'x', 'y', 'z'
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
64
如此一來,內存中的對象就明顯變小了:
欄位
大小(比特)
PyGC_Head
24
PyObject_HEAD
16
x
8
y
8
z
8
總計:
64
在類的定義中使用了__slots__以後,大量實例占據的內存就明顯減少了:
實例數
大小
1 000 000
64 Mb
10 000 000
640 Mb
100 000 000
6.4 Gb
目前,這是降低類實例佔用內存的主要方式。
這種方式減少內存的原理為:在內存中,對象的標題後面存儲的是對象的引用(即屬性值),訪問這些屬性值可以使用類字典中的特殊描述符:
>>> pprint(Point.__dict__)
mappingproxy(
....................................
'x': ,
'y': ,
'z': })
為了自動化使用__slots__創建類的過程,你可以使用庫namedlist(https://pypi.org/project/namedlist)。namedlist.namedlist函數可以創建帶有__slots__的類:
>>> Point = namedlist('Point', ('x', 'y', 'z'))
還有一個包attrs(https://pypi.org/project/attrs),無論使用或不使用__slots__都可以利用這個包自動創建類。
元組
Python還有一個自帶的元組(tuple)類型,代表不可修改的數據結構。元組是固定的結構或記錄,但它不包含欄位名稱。你可以利用欄位索引訪問元組的欄位。在創建元組實例時,元組的欄位會一次性關聯到值對象:
>>> ob = (1,2,3)
>>> x = ob[0]
>>> ob[1] = y # ERROR
元組實例非常緊湊:
>>> print(sys.getsizeof(ob))
72
由於內存中的元組還包含欄位數,因此需要佔據內存的8個位元組,多於帶有__slots__的類:
欄位
大小(位元組)
PyGC_Head
24
PyObject_HEAD
16
ob_size
8
[0]
8
[1]
8
[2]
8
總計:
72
命名元組
由於元組的使用非常廣泛,所以終有一天你需要通過名稱訪問元組。為了滿足這種需求,你可以使用模塊collections.namedtuple。
namedtuple函數可以自動生成這種類:
>>> Point = namedtuple('Point', ('x', 'y', 'z'))
如上代碼創建了元組的子類,其中還定義了通過名稱訪問欄位的描述符。對於上述示例,訪問方式如下:
class Point(tuple):
#
@property
def _get_x(self):
return self[0]
@property
def _get_y(self):
return self[1]
@property
def _get_z(self):
return self[2]
#
def __new__(cls, x, y, z):
return tuple.__new__(cls, (x, y, z))
這種類所有的實例所佔用的內存與元組完全相同。但大量的實例佔用的內存也會稍稍多一些:
實例數
大小
1 000 000
72 Mb
10 000 000
720 Mb
100 000 000
7.2 Gb
記錄類:不帶循環GC的可變更命名元組
由於元組及其相應的命名元組類能夠生成不可修改的對象,因此類似於ob.x的對象值不能再被賦予其他值,所以有時還需要可修改的命名元組。由於Python沒有相當於元組且支持賦值的內置類型,因此人們想了許多辦法。在這里我們討論一下記錄類(recordclass,https://pypi.org/project/recordclass),它在StackoverFlow上廣受好評(https://stackoverflow.com/questions/29290359/existence-of-mutable-named-tuple-in)。
此外,它還可以將對象佔用的內存量減少到與元組對象差不多的水平。
recordclass包引入了類型recordclass.mutabletuple,它幾乎等價於元組,但它支持賦值。它會創建幾乎與namedtuple完全一致的子類,但支持給屬性賦新值(而不需要創建新的實例)。recordclass函數與namedtuple函數類似,可以自動創建這些類:
>>>Point = recordclass('Point', ('x', 'y', 'z'))
>>>ob = Point(1, 2, 3)
類實例的結構也類似於tuple,但沒有PyGC_Head:
欄位
大小(位元組)
PyObject_HEAD
16
ob_size
8
x
8
y
8
z
8
總計:
48
在默認情況下,recordclass函數會創建一個類,該類不參與垃圾回收機制。一般來說,namedtuple和recordclass都可以生成表示記錄或簡單數據結構(即非遞歸結構)的類。在Python中正確使用這二者不會造成循環引用。因此,recordclass生成的類實例默認情況下不包含PyGC_Head片段(這個片段是支持循環垃圾回收機制的必需欄位,或者更准確地說,在創建類的PyTypeObject結構中,flags欄位默認情況下不會設置Py_TPFLAGS_HAVE_GC標志)。
大量實例佔用的內存量要小於帶有__slots__的類實例:
實例數
大小
1 000 000
48 Mb10 000 000
480 Mb
100 000 000
4.8 Gb
dataobject
recordclass庫提出的另一個解決方案的基本想法為:內存結構採用與帶__slots__的類實例同樣的結構,但不參與循環垃圾回收機制。這種類可以通過recordclass.make_dataclass函數生成:
>>> Point = make_dataclass('Point', ('x', 'y', 'z'))
這種方式創建的類默認會生成可修改的實例。
另一種方法是從recordclass.dataobject繼承:
class Point(dataobject):
x:int
y:int
z:int
這種方法創建的類實例不會參與循環垃圾回收機制。內存中實例的結構與帶有__slots__的類相同,但沒有PyGC_Head:
欄位
大小(位元組)
PyObject_HEAD
16
ob_size
8
x
8
y
8
z
8
總計:
48
>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
40
如果想訪問欄位,則需要使用特殊的描述符來表示從對象開頭算起的偏移量,其位置位於類字典內:
mappingproxy({'__new__': ,
.......................................
'x': ,
'y': ,
'z': })
大量實例佔用的內存量在CPython實現中是最小的:
實例數
大小
1 000 000
40 Mb
10 000 000
400 Mb
100 000 000
4.0 Gb
Cython
還有一個基於Cython(https://cython.org/)的方案。該方案的優點是欄位可以使用C語言的原子類型。訪問欄位的描述符可以通過純Python創建。例如:
cdef class Python:
cdef public int x, y, z
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
本例中實例佔用的內存更小:
>>> ob = Point(1,2,3)
>>> print(sys.getsizeof(ob))
32
內存結構如下:
欄位
大小(位元組)
㈩ python 生成flask結構 常用
import os
config="""
import os
basedir = os.path.abspath(os.path.dirname( file ))
class Config:
SECRET_KEY ='hard to guess string'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
FLASKY_MAIL_SUBJECT_PREFIX = '[Flasktest]'
FLASKY_MAIL_SENDER = ' [email protected] '
FLASKY_ADMIN = 'huangat'
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
DEBUG = True
MAIL_SERVER = 'mail.163.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = os.environ.get(')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
class ProctionConfig(Config):
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'proction': ProctionConfig,
'default': DevelopmentConfig
}
"""
manage="""
import os
from app import create_app, db
from app.models import User, Role
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
app = create_app('default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if name == ' main ':
manager.run()
"""
models="""
class User:
pass
class Role:
pass
"""
email="""
from threading import Thread
from email import charset
from flask_mail import Message
from flask import render_template
from flask import current_app # 這樣就不用使用from manager import app
from . import mail
charset.add_charset('utf-8', charset.SHORTEST, charset.BASE64, 'utf-8')
def send_async_mail(app, msg):
with app.app_context():
mail.send(msg)
def send_mail(receiver, subject, template, **kw):
app = current_app._get_current_object()
msg = Message(subject=subject, sender=app.config[
'FLASKY_MAIL_SENDER'], recipients=[receiver], charset='utf-8')
msg.body = render_template(template + '.txt', **kw)
msg.html = render_template(template + '.html', **kw)
thr = Thread(target=send_async_mail, args=[app, msg])
thr.start()
return thr
"""
init="""
from os import path
from flask import Flask, request
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_moment import Moment
from werkzeug.routing import BaseConverter
from config import config
class RegexConverter(BaseConverter):
bootstrap = Bootstrap()
db = SQLAlchemy()
login_manager = LoginManager()
mail = Mail()
moment = Moment()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login' # login_view設置登陸頁面的端點
basedir = path.abspath(path.dirname( file ))
def create_app(config_name):
app = Flask( name )
app.config.from_object(config[config_name])
config[config_name].init_app(app)
"""
maininit="""
from flask import Blueprint
main = Blueprint('main', name )
from . import views, errors
"""
errors="""
from flask import render_template
from . import main
@main.app_errorhandler(404)
def page_not_found(e):
return render_template(駬.html'), 404
@main.app_errorhandler(500)
def internal_server_error(e):
return render_template(驌.html'), 500
"""
forms="""
class NameForm:
pass
"""
views="""
from datetime import datetime
from flask import render_template, session, redirect, url_for
from . import main
from .forms import NameForm
from .. import db
from ..models import User
@main.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
# ...
return redirect(url_for('main.index'))
return render_template('index.html',form=form, name=session.get('name'),known=session.get('known', False),current_time=datetime.utcnow())
"""
def main():
os.mkdir("app")
os.mkdir("appmain")
os.mkdir("appstatic")
os.mkdir("app emplates")
os.mknod("app emplates404.html")
os.mknod("app emplates500.html")
os.mknod("app emplatesindex.html")
os.mkdir("tests")
os.mkdir("venv")
os.mkdir("migrations")
os.mknod("requirements.txt")
os.mknod("tests_ init .py")
with open("config.py","w") as f:
f.write(config)
with open("manage.py","w") as f:
f.write(manage)
with open("appmodels.py","w") as f:
f.write(models)
with open("appemail.py","w") as f:
f.write(email)
with open("app_ init .py","w") as f:
f.write(init)
with open("appmain_ init _.py","w") as f:
f.write(maininit)
with open("appmainerrors.py","w") as f:
f.write(errors)
with open("appmainforms.py","w") as f:
f.write(forms)
with open("appmainviews.py","w") as f:
f.write(views)
main()