If I do this in a server function :
print(anvil.server.request.remote_address)
I get this error :
AttributeError: 'HttpRequest' object has no attribute 'remote_address'
Definitely not using httprequest.
If I do this in a server function :
print(anvil.server.request.remote_address)
I get this error :
AttributeError: 'HttpRequest' object has no attribute 'remote_address'
Definitely not using httprequest.
What are you trying to do? The anvil.server.request
object is only available inside HTTP API calls - see the documentation. Are you trying to use the object inside a standard server call?
I agree itās a little confusing that anvil.server.request
is set to an empty anvil.server.HttpRequest
object by default. I will make sure we fix that to be None
in the case of a standard server call.
Ah, ok. I wanted the IP so I could log it for future auditing.
Any way I can get it? Client or server side is fine.
EDIT - I could obviously do it the way you show in the docs by calling ip.jason.com but that seems a little overkill.
Do you mean you want the IP of the browser where the server call was initiated? Sadly an anvil.http.request
to ip.jsontest.com
will give you one of our egress IPs where the outgoing request actually originates.
We donāt currently have a mechanism for getting client information from the current session, but itās on our (very) long list of features that would be nice to have. Customers on our Anvil support plans are able to commission or prioritise features on our roadmap - please do get in touch by email if that is something you would be interested in.
EDIT: You can now get the client IP from anvil.server.context
I assume thereās no way to consume an external API in the client? I can put the URL to a server endpoint in a link but Iād need a way to āclickā it and absorb the result.
I think Iām probably barking up a dead tree ā¦
You can use anvil.http.request()
from client code as well, and it will come from the browserās IP.
However, there are two major caveats to mention:
Itās restricted in what you can request. You canāt access unencrypted HTTP resources like http://ip.jsontest.com
(because Anvil apps are all HTTPS, so the browser wonāt allow it), and you canāt access URLs on other websites that arenāt ācross-originā. (Making requests to an API endpoint in your own app should be fine, though.)
It happens in client code, which is inherently untrusted. A malicious user can modify the client code and, eg, prevent it from contacting the API endpoint that records its IP.
If youāre OK with those two caveats, then yes, absolutely - import anvil.http
on the client side and hit a server http_endpoint
that records its address in anvil.server.session
.
Hope that helps!
I do keep forgetting I have to import the library. Thatās my lack of python knowledge showing through.
Thanks, chaps!
Just for completeness (and in case anyone is interested), this should work -
In a server module :
@anvil.server.http_endpoint("/tools/:v")
def tools(v, **params):
if v=="myip":
# Return it or store it somewhere.
return anvil.server.request.remote_address
From your client (form) :
import anvil.http
...
myip=anvil.http.request("https://<yourappid>.anvilapp.net/_/api/tools/myip")
print(repr(a.get_bytes()))
Some client side approaches until itās supported server side https://stackoverflow.com/questions/391979/how-to-get-clients-ip-address-using-javascript-only
Expounding a bit, basically itās a webrtc hack that may be removed, or hitting some other server. Randall Degges built ipify.org for this and runs it on heroku. Heās an awesome person and says heāll keep it going. I trust him and would use that.
Is it possible to update the API reference for this as well? Right now itās pretty thin:
context
Contains information about what triggered the currently running code.
Just throwing this out there, but I independently found and started using ipify for casual usage. Hereās the code required if using within Anvil:
import anvil.http
import json
ip = anvil.http.request(āhttps://api.ipify.org?format=jsonā,method='GETā,json=True)
ipAddress = ip[āipā]
print(ipAddress)
Thanks for that, but I think external methods are not really necessary now since @daviesian updated his answer above :
ā¦For anyone looking for it here is an example of anvil.server.context
being used that I posted a while ago: