@ -91,9 +91,7 @@ In the *run()* funtion there are some main parameters that needs to be defined t
- **port** ([*int*](https://docs.python.org/3/library/functions.html#int)* | **None*) – the port of the webserver. Defaults to *5000* or the port defined in the *SERVER_NAME* config variable if present.
- **debug** ([*bool*](https://docs.python.org/3/library/functions.html#bool)* | **None*) if given, enable or disable debug mode. See [debug](https://flask.palletsprojects.com/en/2.3.x/api/#flask.Flask.debug).
---
## First Run
The firsat run is simple enought. Just execute your *app.py*. Just make sure that your *venv* is active.
```bash
@ -127,10 +125,8 @@ Hereyou can see as before the main route *(/)*
def index():
return "Welcome"
```
---
## url proccessors
## URL proccessors
We can also use url proccessors to get something that we have typed on the url.
In this case the url to visit would be [http://localhost:5000/greet/kerem](http://localhost:5000/greet/kerem)
```python
@ -138,18 +134,14 @@ In this case the url to visit would be [http://localhost:5000/greet/kerem](http:
def greet(name):
return f"Hello {name}"
```
---
Variables given to the url can also be *typed* here as integers. This allows us to do some advanced operations. In this case the url to visit would be [http://localhost:5000/add/20/10](http://localhost:5000/add/20/10)
You have surely seen some Parametes embedde in liks like *?user=bgfdrt56+pass=Rtrssdf*. Flask alows some asy maniputation of those parameters. To test this : [http://localhost:5000/handle_url_params?greeting=hello&name=kerem](http://localhost:5000/handle_url_params?greeting=hello&name=kerem). If there was a mistmatch you would get the Error message instead.
## Parameters
You have surely seen some Parametes embedded in liks like *?user=bgfdrt56+pass=Rtrssdf*. Flask alows some asy maniputation of those parameters. To test this : [http://localhost:5000/handle_url_params?greeting=hello&name=kerem](http://localhost:5000/handle_url_params?greeting=hello&name=kerem). If there was a mistmatch you would get the Error message instead.
```python
#Handle parameters :
@app.route('/handle_url_params')
@ -205,7 +194,7 @@ def handle_url_params():
---
# Flask HTML files And [TEMPLATES](https://flask.palletsprojects.com/en/3.0.x/tutorial/templates/) [YouTube](https://youtu.be/w6Ui_DVxluc?si=B2JshnjVMu3DWcBC)
## Indicate that we use Templates
## Declare that we use Templates
To indicate that we will use *templates* first we need to create a *directory* containing those tmeplates and second we need to *reference* it in our code.
let's create the *directory*
```bash
@ -225,9 +214,7 @@ Let's declare it in our code. *template_folder* take the source of *app.py* as s
Now this allows us to have a huge flexibility that HTML doesn't otherwise allow.
This is thnaks to [Jinja](https://jinja.palletsprojects.com/en/3.1.x/templates/).
Let's see how it works.
---
This is thnaks to [Jinja](https://jinja.palletsprojects.com/en/3.1.x/templates/). Let's see how it works.
## HTML & Jinja
Now let's have a look to `index.html` herre we can now se some *Jinja* templates funtionlaities.
```HTML
@ -275,7 +259,7 @@ Now let's have a look to `index.html` herre we can now se some *Jinja* templates
*Jinja* Allows us to use these kind of functions : `{% for item in list %}` that are ususaly inpossible wiht HTML.
All *Jinja* Functions starts with `{%` and ends with `%}`.
- They can also be used inline like: `<li {%if item == 20 %} style="color: blue" {%endif%} >{{ item }}</li>`.
---
## Extend Templates
We cna extend templates to other templates. What does this bring us ? Let's say we want ta have the *same header* on *multiple pages* we can use a template with the header and only add an *content**BLOCK* onto this template.
In *templeates* directory we can now create a base html file let's call it *base.htm* and two pages that extends on it *index.html* and *other.html*.
@ -357,10 +341,7 @@ but here we need to add a route to this page at *app.py*
Filters that python uses lin `.uppercase` can't be used in Jinja. There are some filters taht already exists but most importnatly we can create our own filters.
@ -393,7 +374,9 @@ def reverse_string(s):
```
you can see that we use a speciel decorator named [template_filter](https://tedboy.github.io/flask/generated/generated/flask.Flask.template_filter.html) to declare our custom filters.
## Redirection
---
# Redirection
Redirections can be tricky but thankfully Flask has a way od dynamic *redirection* wich takes a *function* as *argument*
```PYTHON
@app.route('/redirect_endpoint')
@ -450,3 +433,115 @@ So what is going on here ?
- If the *Methode* is *POST* we collect the information filler in *form* sent by pressing *submit*
- We get collect the *information* by *referencing* form items by their *name* attribute : `request.form.get('username')`
- Then we can put these infiormation in varibales and use them as we please.
---
# Uploading & downloading files
Be careful here are some notions that are not related to Flask or Jinja. Like [Pandas](https://pandas.pydata.org/) for excel manipulation and [os](https://docs.python.org/3/library/os.html) of opperating system functions. Nevertheless this is a very important topic with widely used applications for website.
## Uploading a file
Here is the *File Upload form* located in *index.html* the most important element to know are :
- [enctype="multipart/form-data"](https://www.w3schools.com/tags/att_form_enctype.asp) Used while uploading files
- [accept=](https://www.w3schools.com/tags/att_input_accept.asp)"[media-types](http://www.iana.org/assignments/media-types/media-types.xhtml)" do define which types of files are allowed.
Wiht the `action="{{ url_for('file_upload') }}"` we go back to our *app.py* funtion *def file_upload():* where we treat this information. Where we do nothing else then to read the file and print his output.
- If it's a *Text* file we put directly it's output
- If it's a *Excel* file we read the file using pandas `df = pd.read_excel(file)` and return the result as html table using `return df.to_html()`
Wiht the `action="{{ url_for('convert_csv') }}"` we go back to our *app.py* funtion *def convert_csv():* where we convert the excel into csv but also directly donwload the ouput. It is a specific example and we don't need to waste too much time on it as there is, in my opignon a much better way to do this.
Wiht the `action="{{ url_for('convert_csv_two') }}"` we go back to our *app.py* funtion *def convert_csv_two():*, convert the file to csv and make it redy for download:
- `os.makedirs('downloads')` we create a donwload directory
- `filename = f'{uuid.uuid4()}.cvs'` we give the file a unique name
- `df.to_csv(os.path.join('downloads', filename))`we convert the file into csv and register in *downloads* with his*filename*
- `return render_template('download.html', filename=filename)` we return the *download.html* page with *filename* as argument
and aso create a new route for *download* in *app.py*:
- `@app.route('/download/<filename>'` the route has de name route to */download* but allso the argument *<filename>*
- `send_from_directory('downloads', filename, download_name='result.csv')` alows us to *send* the file *downloads* directory and *rename* it at the same time