You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Batteries Detachable: Don't like our approach to something? No problem! We aim to provide native support for all your favorite libraries, as well as provide APIs to let you reinvent the wheel as you wish.
23
-
- Lightning Fast: Powered by [pyawaitable](https://github.com/ZeroIntensity/pyawaitable), view.py is the first web framework to implement ASGI in pure C, without the use of external transpilers.
24
-
- Developer Oriented: view.py is developed with ease of use in mind, providing a rich documentation, docstrings, and type hints.
21
+
- Batteries Detachable: Don't like our approach to something? No problem! We aim to provide native support for all your favorite libraries, as well as provide APIs to let you reinvent the wheel as you wish.
22
+
- Lightning Fast: Powered by [pyawaitable](https://github.com/ZeroIntensity/pyawaitable), view.py is the first web framework to implement ASGI in pure C, without the use of external transpilers.
23
+
- Developer Oriented: view.py is developed with ease of use in mind, providing a rich documentation, docstrings, and type hints.
24
+
25
+
See [why I wrote it](https://view.zintensity.dev/#why-did-i-build-it) on the docs.
Copy file name to clipboardExpand all lines: docs/building-projects/build_steps.md
+48-1Lines changed: 48 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -120,6 +120,53 @@ requires = ["php"]
120
120
command = "php -f payment.php"
121
121
```
122
122
123
+
## Platform-Dependent Steps
124
+
125
+
Many commands are different based on the platform used. For example, to read from a file on the Windows shell would be `type`, while on Linux and Mac it would be `cat`. If you add multiple step entries (in the form of an [array of tables](https://toml.io/en/v1.0.0-rc.2#array-of-tables)) with `platform` values, view.py will run the entry based on the platform the app was run on.
126
+
127
+
For example, using the file reading example from above:
128
+
129
+
Notice the double brackets next to `[[build.steps.read_from_file]]`, specifying an array of tables.
130
+
131
+
```toml
132
+
# view.toml
133
+
134
+
[[build.steps.read_from_file]]
135
+
platform = ["mac", "linux"]
136
+
command = "cat whatever.txt"
137
+
138
+
[[build.steps.read_from_file]]
139
+
platform = "windows"
140
+
command = "type whatever.txt"
141
+
```
142
+
143
+
The `platform` value can be one of three things per entry:
144
+
145
+
- A list of platforms.
146
+
- A string containing a single platform.
147
+
-`None`, meaning to use this entry if no other platforms match.
148
+
149
+
For example, with a `None` platform set (on multiple entries), the above could be rewritten as:
150
+
151
+
```toml
152
+
# view.toml
153
+
154
+
[[build.steps.read_from_file]]
155
+
# Windows ONLY runs this step
156
+
platform = "windows"
157
+
command = "type whatever.txt"
158
+
159
+
[[build.steps.read_from_file]]
160
+
# All other platforms run this!
161
+
command = "cat whatever.txt"
162
+
```
163
+
164
+
Note that only one step entry can have a `None` platform value, otherwise view.py will throw an error.
165
+
166
+
!!! note
167
+
168
+
The only recognized operating systems for `platform` are the big three: Windows, Mac, and any Linux based system. If you want more fine-grained control (for example, using `pacman` or `apt` depending on the Linux distro), use a custom build script that knows how to read the Linux distribution.
169
+
123
170
## Build Requirements
124
171
125
172
As you've seen above, build requirements are specified via the `requires` value. Out of the box, view.py supports a number of different build tools, compilers, and interpreters. To specify a requirement for one, simply add the name of their executable (_i.e._, how you access their CLI). For example, since `pip` is accessed via using the `pip` command in your terminal, `pip` is the name of the requirement.
The above could actually be used via both `script+check_310.py` and `mod+check_310`.
167
214
168
-
!!! tip
215
+
!!! note
169
216
170
217
Don't use the view.py build system to check the Python version or if a Python package is installed. Instead, use the `dependencies` section of a `pyproject.toml` file, or [PEP 723](https://peps.python.org/pep-0723/) script metadata.
Copy file name to clipboardExpand all lines: docs/building-projects/request_data.md
+15-16Lines changed: 15 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,18 +6,17 @@ If you've used a framework like [Django](https://djangoproject.com) or [FastAPI]
6
6
7
7
The `Context` instance contains information about the incoming request, including:
8
8
9
-
- The headers.
10
-
- The cookies.
11
-
- The HTTP version.
12
-
- The request method.
13
-
- The URL path.
14
-
- The client and server address.
9
+
-The headers.
10
+
-The cookies.
11
+
-The HTTP version.
12
+
-The request method.
13
+
-The URL path.
14
+
-The client and server address.
15
15
16
16
!!! info
17
17
18
18
`Context` is an [extension type](https://docs.python.org/3/extending/newtypes_tutorial.html), and is defined in the `_view` module. It's Python signatures are defined in the `_view` type stub.
19
19
20
-
21
20
## Context Input
22
21
23
22
The context can be added to a route via a route input, which is done through the `context` decorator. Note that `context` has a standard and direct variation (`App.context` is available to prevent imports).
@@ -76,7 +75,7 @@ app.run()
76
75
77
76
!!! info
78
77
79
-
`App.test` is a more internal detail, but is available to use publically. It looks like this:
78
+
`App.test` is a more internal detail, but is available for public use. It looks like this:
80
79
81
80
```py
82
81
from view import new_app
@@ -175,11 +174,11 @@ app.run()
175
174
176
175
`Context` contains eight attributes:
177
176
178
-
-`headers`, of type `dict[str, str]`.
179
-
-`cookies`, of type `dict[str, str]`.
180
-
-`client`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
181
-
-`server`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
182
-
-`method`, of type `StrMethodASGI` (uppercase string containing the method, such as `"GET"`).
183
-
-`path`, of type `str`.
184
-
-`scheme`, which can be the string `"http"`, `"https"`.
185
-
-`http_version`, which can be the string `"1.0"`, `"1.1"`, `"2.0"`, `"view_test"`.
177
+
-`headers`, of type `dict[str, str]`.
178
+
-`cookies`, of type `dict[str, str]`.
179
+
-`client`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
180
+
-`server`, of type `ipaddress.IPv4Address`, `ipaddress.IPv6Address`, or `None`.
181
+
-`method`, of type `StrMethodASGI` (uppercase string containing the method, such as `"GET"`).
182
+
-`path`, of type `str`.
183
+
-`scheme`, which can be the string `"http"`, `"https"`.
184
+
-`http_version`, which can be the string `"1.0"`, `"1.1"`, `"2.0"`, `"view_test"`.
return JSON({"message": "Successfully created your account."}), 201
32
52
```
33
53
34
-
**Note:** If this yields unexpected results, you may need to use `py -m view init` instead.
54
+
```py
55
+
from view import new_app, Context, Error, JSON
56
+
57
+
app = new_app()
58
+
59
+
@app.get("/")
60
+
@app.context
61
+
asyncdefindex(ctx: Context):
62
+
auth = ctx.headers.get("Authorization")
63
+
ifnot auth:
64
+
raise Error(400)
65
+
66
+
return JSON({"data": "..."})
35
67
36
-
Write your first app:
68
+
app.run()
69
+
```
37
70
38
71
```py
39
72
from view import new_app
40
73
41
74
app = new_app()
42
75
43
-
@app.query("greeting", str, default="hello")
44
-
@app.query("name", str, default="world")
45
-
@app.get("/")
46
-
asyncdefindex(greeting: str, name: str):
47
-
returnf"{greeting}, {name}!"
76
+
@app.post("/login")
77
+
@app.query("username", doc="Username for your account.")
78
+
@app.query("password", doc="Password for your account.")
79
+
asyncdefindex():
80
+
"""Log in to your account."""
81
+
...
48
82
49
83
app.run()
50
84
```
51
85
52
-
## Why View?
86
+
```html
87
+
<viewif="user.type == 'admin'">
88
+
<viewtemplate="admin_panel" />
89
+
</view>
90
+
<viewelif="user.type == 'moderator'">
91
+
<viewtemplate="mod_panel" />
92
+
</view>
93
+
<viewelse>
94
+
<p>You must be logged in.</p>
95
+
</view>
96
+
```
97
+
98
+
```toml
99
+
# view.toml
100
+
[build]
101
+
default_steps = ["nextjs"]
102
+
# Only NextJS will be built on startup
103
+
104
+
[build.steps.nextjs]
105
+
requires = ["npm"]
106
+
command = "npm run build"
107
+
108
+
[build.steps.php]
109
+
requires = ["php"]
110
+
command = "php -f payment.php"
111
+
```
112
+
113
+
## Why did I build it?
114
+
115
+
!!! warning
116
+
117
+
This section may seem boring to some. If you don't like reading, skip to the next page.
53
118
54
-
As of now, view.py is still in alpha. Lot's of development progress is being made, but a production-ready stable release is still a bit far off. With that being said, anything mentioned in this documentation has been deemed already stable. In that case, why choose view.py over other frameworks?
119
+
This is a question I get a lot when it comes to view.py. I originally got the idea for view.py back in 2021, but it was planned to be a library for _only_ designing UI's in Python (hence the name "view"), since the only way you could do it at the time was pretty much just merging HTML and Python using [Jinja](https://jinja.palletsprojects.com/en/3.1.x/), or some other flavor of template engine. Don't get me wrong, Jinja is a great template engine, but it feels a bit lacking once you've tried [JSX](https://react.dev/learn/writing-markup-with-jsx) in one of the large JavaScript frameworks.
55
120
56
-
If you've used a framework like [Django](https://djangoproject.com), you're likely already familiar with the "batteries included" idea, meaning that it comes with everything you could need right out of the box. View takes a different approach: batteries-detachable. It aims to provide you everything you need, but gives you a choice to use it or not, as well as actively supporting external libraries. This ideology is what makes View special. In batteries detachable, you can use whatever you like right out of the box, but if you don't like View's approach to something or like another library instead, you may easily use it.
121
+
A year later, in 2022, I enrolled in a coding class at my school, which was basically a course for the basics of Python. For most Python developers, including me, it would have felt like sitting down and going over your ABC's. Long story short, my teacher let me do some sort of project instead of the actual class (this was in 8th grade, mind you).
57
122
58
-
## Should I use it?
123
+
At the time, my [pointers.py](https://github.com/ZeroIntensity/pointers.py) library had gained a lot of traction on GitHub, which was quite cool to me, but I felt like I didn't make any real world contributions (it is a joke library, anyway). I wanted to contribute something to the world, and since I was being allocated school time during the week to work on a project of my choice, I decided that a full web framework was what I wanted to do.
59
124
60
-
For a big project, **not yet**, as View is not currently ideal for working with a big codebase. However, **that doesn't mean you should forget about it**. view.py will soon be stable and production ready, and you should keep it in mind. To support view.py's development, you can either [sponsor me](https://github.com/sponsors/ZeroIntensity) or [star the project](https://github.com/zerointensity/view.py/stargazers).
125
+
In my eyes, Python's web ecosystem was nowhere near that of JavaScript's. I had grown particularly fond of [NextJS](https://nextjs.org/), which served as an inspiration for a lot of view.py's features. To this day, [FastAPI](https://fastapi.tiangolo.com/) remains as my favorite Python web framework, apart from View. In fact, if you don't like view.py, I highly recommend trying it. Anyways, at the time, FastAPI was somewhat lacking when it comes to batteries-included parts, compared to [Django](https://www.djangoproject.com/), at least.
61
126
62
-
## Developing View
127
+
Now, this opinion is a bit controversial, but I really don't like Django's approach to a lot of things (such as it's way of routing), as well as the massive boilerplate that comes with Django projects. It just doesn't feel [pythonic](https://ifunny.co/picture/other-programmers-python-programmer-that-s-not-the-most-pythonic-EUE0IBzz8) to me. Although, what I do admire about Django (and probably why so many people like it), is it's batteries-included philosophy. So, I wanted to develop a web framework with the speed and elegancy of FastAPI, with the sheer robust-ness of Django. view.py is the result of that idea.
63
128
64
-
As stated earlier, view.py is very new and not yet at a stable 1.0.0 release. Whether you're completely new to GitHub contribution or an experienced developer, view.py has something you could help out with. If you're interested in contributing or helping out with anything, be sure to read [the contributors file](https://github.com/ZeroIntensity/view.py/blob/master/CONTRIBUTING.md) and/or joining the [discord](https://discord.gg/tZAfuWAbm2).
129
+
Note that I don't want to replace Django or FastAPI. In fact, if you're already familiar with one of those, learning view.py might not be a good idea! However, I would like to fill the gap that you might feel when using a Python framework after coming from JavaScript. Nowadays, JavaScript web frameworks get rewritten every year (for example, Next's move from `pages`to the `app` router), and are filled with big companies fighting each other to "be the best." In my eyes, development in all fields, especially open source, should be _collaborative_, not competitive, and I'm glad that Python has stayed true to that, but the gap in web development is visible.
0 commit comments