can anyone guide me in the right direction when it comes to http requests with python? What I'm after is a Excel-VBA add-in which will track which workbooks the user opens and when etc. While that's already done, I would now like to get the information to a database.
For that purpose I can imagine running a very simple Python server which would be used to store the information. The question thus is, how do I set up a simple http server so that VBA can post a simple string which then gets stored?
Thanks!
EDIT:
Thanks chf! I went ahead and followed your advice - I replaced flask with django though as I had some brief experience with that. I've got my first API ever created now but can't post using the VBA code you posted. I can do httpie like so: "http POST http:/127.0.0.1 name="somename" workbookname="someworkbook".
Sub TestFramework()
Dim newClient As New WebClient
Dim newRequest As New WebRequest
Dim Response As WebResponse
newClient.BaseUrl = "http://127.0.0.1:8000/api/create/"
newRequest.Method = HttpPost
newRequest.Format = WebFormat.plaintext
newRequest.AddBodyParameter "name", "somename"
newRequest.AddBodyParameter "workbook_name", "Sheet1"
Set Response = newClient.Execute(newRequest)
End Sub
Any chance you might point me to the right way?
RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/api/create/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
[03/Aug/2016 20:13:18] "POST /api/create HTTP/1.1" 500 60534
Edit2: nevermind, got it working :)
Nice project!
You can use Flask for the Python part to build a small REST Api and for the VBA part you can use VBA-WEB to consume that API.
Both Flask than VBA-WEB are very well documented with a lot of examples.
I use VBA-WEB in a lot of small "SAK" (swiss army knife) utilities in Excel and it's very useful and powerful.
For some rest apis with json output Flask is a nice tool to use.
Related
I am developing a DAG to be scheduled on Apache Airflow which main porpuse will be to post survey data (on json format) to an API and then getting a response (the answers to the surveys). Since this whole process is going to be automated, every part of it has to be programmed in the DAG, so I canĀ“t use Postman or any similar app (unless there is a way to automate their usage, but I don't know if this is possible).
I was thinking of using the requests library for Python, and the function I've written for posting the json to the API looks like this:
def postFileToAPI(**context):
print('uploadFileToAPI() ------ ')
json_file = context['ti'].xcom_pull(task_ids='toJson') ## this pulls the json file from a previous task
print('--------------- Posting survey request to API')
r = requests.post('https://[request]', data = json_file)
(I haven't finished defining the http link for the request because my source data is incomplete.)
However, since this is my frst time working with APIs and the requests library, I don't know if this is enough. For example, I'm unsure if I need to provide a token from the API to perform the request.
I also don't know if there are other libraries that are better suited for this or that could be a good support.
In short: I don't know if what I'm doing will work as intended, what other information I need t provide my DAG or if there are any libraries to make my work easier.
The Python requests package that you're using is all you need, except if you're making a request that needs extra authorisation - then you should also import for example requests_jwt (then from requests_jwt import JWTAuth) if you're using JSON web tokens, or whatever relevant requests package corresponds for your authorisation style.
You make POST and GET requests and all individual requests separately.
Include the URL and data arguments as you have done and that should work!
You may also need headers and/or auth arguments to get through security,
eg for the GitLab api for a private repository you would include these extra arguments, where GITLAB_TOKEN is a GitLab web token.
```headers={'PRIVATE-TOKEN': GITLAB_TOKEN},
auth=JWTAuth(GITLAB_TOKEN)```
If you just try it it should work, if it doesn't work then test the API with curl requests directly in the Terminal, or let us know :)
I am trying to make little automated-testing script. It shoud be able to make HTTP request based on string provided, something like follows:
import coollib # non-existent library
r = coollib.make_raw_request(
# Lets assume, python's tripple quoted string spacing is not a problem.
"""
GET / HTTP/1.1\n\r
Host: example.com\n\r
My-Faulty-Header: status\n\r
"""
)
print(r.response_body)
Intention behind this is to insert a little mistakes into request, to test, how web server copes with faulty requests.
Any idea how to do this? Any insights are welcome.
As Ronald Aaronson mentioned in the comment, your weapon of choice here should probably be the socket library. There's an example in this related question: Creating a raw HTTP request with sockets
If there is someone out there who has already worked with SOLR and a python library to index/query solr, would you be able to try and answer the following question.
I am using the mySolr python library but there are others out (like pysolr) there and I don't think the problem is related to the library itself.
I have a default multicore SOLR setup, so no authentication required normally. Don't need it to access the admin page at http://localhost:8080/solr/testcore/admin/ either
from mysolr import Solr
solr = Solr('http://localhost:8080/solr/testcore/')
response = solr.search(q='*:*')
print("response")
print(response)
This code used to work but now I get a 401 reply from SOLR ... just like that, no changes have been made to the python virtual env containing mysolr or the SOLR setup. Still...something must have changed somewhere but I'm out of clues.
What could be the causes of a SOLR 401 reponse?
Additional info: This script and mor advanced script do work on another PC, just not on the one I am working on. Also, adding "/select?q=:" behind the url in the browser does return the correct results. So the SOLR is setup correctly, it has probably something to do with my computer itself. Could windows settings (of any kind) have an impact on how SOLR responds to requests from python? The python env itself has been reinstalled several times to no avail.
Thanks in advance!
The problem was: proxy.
If this exact situation was ever to occur to someone and you are behind a proxy, check if your HTTP and HTTPS environmental variables are not set. If they are... this might cause the python session to try using the proxy while it shouldn't (connecting to localhost via proxy).
It didn't cause any trouble for months but out of the blue it did so whether you encounter this or not might be dependent on how your IT setup your proxy or made some other changes...somewhere.
thank you everyone!
I have a tiny Flask server that is supposed to load data from a file and run a function on it. This function will return a DataFrame and I return the json version of it. Much to my surprise this all works nicely. However, how would I test this? I have included some attempts below but I don't understand Flask (nor REST) well enough yet:
#!/home/thomas/python
from flask import Flask
from flask.ext.restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class UniverseAPI(Resource):
def get(self):
import pandas as pd
frame = pd.read_csv("//datasrv10//data$//AQ//test.csv", index_col=0, header=0)
return frame.to_json()
api.add_resource(UniverseAPI, '/data/universe')
I am happy to include a few of my attempts here... I appreciate any hints. I have read the official documentation.
I should specify what I mean with testing. I can run this on my linux server and can extract all the required information with the requests package. However, I want to create a unittest that comes without the need to start the server on the localhost. I think I have managed with the FLASK test-client. However, the problem now is that the requests response object and the flask response object treat the underlying json strings rather differently. So I guess my problem is more related to json string issues rather than FLASK. Thanks for all your helpful feedback though
Well, the basics of writing a REST API are essentially a set of design principles. My understanding of it is based on this article by Miguel Grinberg, http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask .
In it, he talks about how a REST API is:
"Stateless" - All interactions with the service can happen using the information from one request.
Built upon accessing "resources" from URIs using HTTP requests like GET, PUTS, and POST. A resource could be an order in a store, a task in a web app, or whatever you like.
There's also a bunch of stuff about how the server should standardize all forms of communication between itself and the client, indicate whether it can do cacheing, and other stuff like that. From an initial design standpoint, though, this is "the point" as he put it:
"The task of designing a web service or API that adheres to the REST guidelines then becomes > an exercise in identifying the resources that will be exposed and how they will be affected > by the different request methods."
If you're looking for an interesting example of a REST API that might be suited to your interests (I know it is to mine), reddit's is open source. It's a relatable example to see how they try and structure the interactions behind requests: http://www.reddit.com/dev/api
I am making an app that would translate websocket messages to AJAX requests to the server. Mainly the decision is based on the fact that Pyramid already has a good URL dispatch system and it would be stupid not to use it.
The question is if there is an easy way to dispatch a URL in Pyramid (possibly an instanced Request object) to it's according view callable and get the view callable? Or at least get the output of the view callable related to the request?
I have tried the script from "prequest.py" which basically emulates a whole HTTP client and gives you the response (I have still not managed to get it work, but a look through the sources makes sense anyway) and I wouldn't like to do it that way.
You can reuse the code from the pview command to turn a path into a view reference:
from pyramid.scripts.pviews import PViewsCommand
pvcomm = PViewsCommand([])
view = pvcomm._find_view(path, request.registry)
The actual code to do this is a little involved, but the PViewsCommand does it all for us already.
I have managed to do it using Router.invoke_subrequest in the latest version of Pyramid (1.4a1).
This enables all the features related to routing. URL dispatch, parameter passing, tweens.
You can read about it here: http://docs.pylonsproject.org/projects/pyramid/en/latest/api/request.html#pyramid.request.Request.invoke_subrequest