Diferències
Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Següent revisió | Revisió prèvia | ||
| info:cursos:pue:python-pcpp1:m4:1.6 [18/01/2024 10:19] – creat mate | info:cursos:pue:python-pcpp1:m4:1.6 [19/01/2024 02:37] (actual) – mate | ||
|---|---|---|---|
| Línia 32: | Línia 32: | ||
| {{ : | {{ : | ||
| + | Now we’re going to ask the npm to download and install the json-server package, along with all the packages needed to run it, so you should expect some delay – be patient and issue the following command: | ||
| + | <code bash>npm install -g json-server</ | ||
| + | We need to perform a brief test to ensure that the server is operating correctly. Do the following actions: | ||
| + | |||
| + | * download the JSON file cars.json from here: Download {{ : | ||
| + | * return to the system console and issue the following command:< | ||
| + | |||
| + | Note: the file name you put after '' | ||
| + | |||
| + | If everything went correctly, you'll see the following screen: | ||
| + | {{ : | ||
| + | |||
| + | This means that the server is working and is ready to serve incoming connections. Don't let it wait. Let's connect to it! | ||
| + | |||
| + | |||
| + | Now open your favorite Internet browser and type the following URL into the address line: | ||
| + | < | ||
| + | |||
| + | This means that you order the browser to connect to **the same machine** you're currently working on ('' | ||
| + | |||
| + | You should see something like this: | ||
| + | {{ : | ||
| + | |||
| + | Congratulations! You have your server running and operational! | ||
| + | |||
| + | Press **Crtl-C** in the console if you want to terminate the server, but for now leave it running – we’ll need it and the resources it serves! | ||
| + | |||
| + | Note: if the client doesn' | ||
| + | |||
| + | * in the folder where '' | ||
| + | * inside the public folder, create a file named index.html, fill it with some text, and save. | ||
| + | |||
| + | We created such a file containing one line:< | ||
| + | |||
| + | Then we switched back to the browser and pressed **F5**. This is what we saw: | ||
| + | {{ : | ||
| + | |||
| + | Now we’re well enough equipped to start a discussion on the requests module – let's dive into it! | ||
| + | |||
| + | The first program makes very basic use of the power of the '' | ||
| + | |||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | reply = requests.get(' | ||
| + | print(reply.status_code) | ||
| + | |||
| + | </ | ||
| + | |||
| + | The HTTP protocol operates by using **methods**. We can say that the **HTTP method** is a **two-way interaction between the client and the server** (note: the client initiates the transmission) dedicated to the execution of a certain action. '' | ||
| + | |||
| + | A '' | ||
| + | |||
| + | It's like we said “Hey, server, send me your default resource”. | ||
| + | |||
| + | The only details we need to provide are the **server’s address** and the **service port number** – just like we did while using the browser’s address line. Note: the port number can be omitted if it is equal to **80**, HTTP’s default port. | ||
| + | |||
| + | Of course, it is possible that the server resides somewhere far away from our desk, for example, in the other hemisphere. The only thing we’ll change then is the server address – it would be formed as an IP address or fully qualified domain name (FQDN), but it doesn’t matter for '' | ||
| + | |||
| + | As you can see, the '' | ||
| + | |||
| + | Of course, the most important thing we need to know is whether the '' | ||
| + | |||
| + | If you run the code and everything works as expected, you will see a very short and simple result:< | ||
| + | |||
| + | As the HTTP protocol defines it, code 200 means “okay”. | ||
| + | |||
| + | Good news. | ||
| + | |||
| + | All response codes used by HTTP are gathered here: [[https:// | ||
| + | |||
| + | The requests module offers many different ways of specifying and recognizing **status codes**. | ||
| + | |||
| + | Look at the code: | ||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | print(requests.codes.__dict__) | ||
| + | </ | ||
| + | |||
| + | It dumps the contents of a status dictionary. The output is very long and jumbled – we won't put it here, but we encourage you to study it carefully, comparing the values you see with those presented at Wikipedia. | ||
| + | |||
| + | Anyway, you can use the '' | ||
| + | |||
| + | <code python> | ||
| + | if reply.status_code == requests.codes.ok: | ||
| + | </ | ||
| + | | ||
| + | It looks far better than just '' | ||
| + | |||
| + | When you know that the **server' | ||
| + | |||
| + | The server' | ||
| + | |||
| + | The response' | ||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | reply = requests.get(' | ||
| + | print(reply.headers) | ||
| + | </ | ||
| + | |||
| + | The program produces the following output: | ||
| + | <code python> | ||
| + | {' | ||
| + | </ | ||
| + | |||
| + | As you can see, the response' | ||
| + | |||
| + | You can access it directly using a routine dictionary lookup, just like this: | ||
| + | <code python> | ||
| + | reply.headers[' | ||
| + | </ | ||
| + | |||
| + | The raw response' | ||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | reply = requests.get(' | ||
| + | print(reply.text) | ||
| + | </ | ||
| + | |||
| + | The property contains bare text taken as-is directly from the data stream, hence it is just a string. No conversions are applied. | ||
| + | |||
| + | The code produces the following output: | ||
| + | <code ; output> | ||
| + | CARS DATABASE | ||
| + | </ | ||
| + | |||
| + | Note: when both client and server are aware of the fact that the contents (no matter which part sent them) contain a JSON message, it is also possible to use a method named '' | ||
| + | |||
| + | In general, the HTTP protocol defines the following methods: | ||
| + | * '' | ||
| + | * in other words – if you want the server to give you something, '' | ||
| + | * '' | ||
| + | * to make a long story short – if you want to give the server something new, '' | ||
| + | * '' | ||
| + | * simply put – if you want to update something that the server is currently keeping, '' | ||
| + | * '' | ||
| + | * we’re sorry, but there is no simpler way to explain that, we think; we aren't wrong, are we? | ||
| + | |||
| + | We aren't going to discuss them here, but feel free to deepen your knowledge by yourself. | ||
| + | |||
| + | As you probably suspect, all the listed HTTP methods have their reflections (or rather siblings) within the requests module. | ||
| + | |||
| + | Yes, you're absolutely right:{{ : | ||
| + | |||
| + | The diagram, although extremely simplified and deprived of important details, shows us the most important tools we’ll use soon to play a game with our server. Don't be afraid, we'll acquaint you with all additional means and arguments. | ||
| + | |||
| + | |||
| + | It seems that we missed one important issue: what’ll happen if **anything goes wrong**? The server may fail, transmission media may be down, etc, etc, etc. How do we defend against all these miseries? | ||
| + | |||
| + | All '' | ||
| + | |||
| + | For example, let's take a look at a crucial issue named '' | ||
| + | |||
| + | It's normal for the server not to respond immediately – making connections, | ||
| + | |||
| + | Of course they can, and one exception will be very helpful – look: | ||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | try: | ||
| + | reply = requests.get(' | ||
| + | except requests.exceptions.Timeout: | ||
| + | print(' | ||
| + | else: | ||
| + | print(' | ||
| + | </ | ||
| + | | ||
| + | As you can see, the '' | ||
| + | |||
| + | If the server is ready and not very busy, one second is more than enough to process such a simple request, so you should expect good news – the program will write:< | ||
| + | Here is your data, my Master! | ||
| + | </ | ||
| + | |||
| + | But if you change the timeout radically to a disturbingly small value like 0.00001, it's highly probable that you will have to endure the following bad news:< | ||
| + | Sorry, Mr. Impatient, you didn't get your data. | ||
| + | </ | ||
| + | |||
| + | Of course, problems may appear much earlier, e.g., while establishing the connection: | ||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | try: | ||
| + | reply = requests.get(' | ||
| + | except requests.exceptions.ConnectionError: | ||
| + | print(' | ||
| + | else: | ||
| + | print(' | ||
| + | </ | ||
| + | | ||
| + | This code has no chance of running properly – it’s addressing its efforts to port 3001, while our server is listening at port 3000. No helping hand will fix this misunderstanding – client and server won't meet and an exception will be raised. Its name is:<code ; output> | ||
| + | requests.exceptions.ConnectionError | ||
| + | </ | ||
| + | |||
| + | To err is human, so it is also possible that you or another developer may leave the resource’s URI in a somewhat malformed state. Look at the code in the editor window. | ||
| + | |||
| + | <code python> | ||
| + | import requests | ||
| + | |||
| + | try: | ||
| + | reply = requests.get(' | ||
| + | except requests.exceptions.InvalidURL: | ||
| + | print(' | ||
| + | else: | ||
| + | print(' | ||
| + | </ | ||
| + | | ||
| + | Disasters of this kind are served by an exception named:< | ||
| + | requests.exceptions.InvalidURL | ||
| + | </ | ||
| + | |||
| + | We’ve gathered all the requests exceptions in one place and presented them as a tree – this is what it looks like: | ||
| + | <code ; output> | ||
| + | RequestException | ||
| + | |___HTTPError | ||
| + | |___ConnectionError | ||
| + | | | ||
| + | | | ||
| + | |___Timeout | ||
| + | | | ||
| + | | | ||
| + | |___URLRequired | ||
| + | |___TooManyRedirects | ||
| + | |___MissingSchema | ||
| + | |___InvalidSchema | ||
| + | |___InvalidURL | ||
| + | | | ||
| + | |___InvalidHeader | ||
| + | |___ChunkedEncodingError | ||
| + | |___ContentDecodingError | ||
| + | |___StreamConsumedError | ||
| + | |___RetryError | ||
| + | |___UnrewindableBodyError | ||
| + | </ | ||
| + | |||
| + | Something nice for everyone. | ||
| + | |||
| + | Now that we are well acquainted with the world of '' | ||