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 '' |