clone3 commited on
Commit
5ef8210
·
verified ·
1 Parent(s): f2bc279

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -22
app.py CHANGED
@@ -1,27 +1,32 @@
1
  from fastapi import FastAPI, Request
2
  from user_agents import parse
3
- import ipinfo
4
  import os
 
5
 
6
  app = FastAPI()
7
 
8
- # Get your free IPinfo token from ipinfo.io and set as environment variable
9
- IPINFO_TOKEN = os.getenv("IPINFO_TOKEN", "your_token_here") # Replace with your token
 
 
10
 
11
- handler = ipinfo.getHandler(IPINFO_TOKEN)
 
 
12
 
13
  @app.get("/track")
14
  async def track_ip(request: Request):
15
  # Get client IP (handle proxies)
16
  client_ip = request.headers.get("X-Forwarded-For")
17
  if client_ip:
18
- client_ip = client_ip.split(",")[0].strip() # Take the first IP in the chain
19
  else:
20
  client_ip = request.client.host
21
-
22
- # Get User-Agent and parse browser/device info
23
- user_agent_str = request.headers.get("User-Agent", "Unknown")
24
- ua = parse(user_agent_str)
25
  browser_info = {
26
  "browser": ua.browser.family,
27
  "version": ua.browser.version_string,
@@ -31,22 +36,50 @@ async def track_ip(request: Request):
31
  "is_mobile": ua.is_mobile,
32
  "is_bot": ua.is_bot
33
  }
34
-
35
- # Get IP details (geolocation, etc.)
 
 
 
36
  try:
37
- ip_details = handler.getDetails(client_ip).all
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  except Exception as e:
39
- ip_details = {"error": str(e)}
40
-
41
- # Compile all info
42
- tracked_data = {
 
 
 
 
 
 
 
 
43
  "ip": client_ip,
44
  "browser": browser_info,
45
- "geolocation": ip_details
 
46
  }
47
-
48
- return tracked_data
49
 
50
- if __name__ == "__main__":
51
- import uvicorn
52
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
 
 
1
  from fastapi import FastAPI, Request
2
  from user_agents import parse
3
+ import geoip2.database
4
  import os
5
+ from pathlib import Path
6
 
7
  app = FastAPI()
8
 
9
+ # Paths to your downloaded databases (adjust if needed)
10
+ BASE_DIR = Path(__file__).resolve().parent
11
+ CITY_DB_PATH = BASE_DIR / "databases" / "GeoLite2-City.mmdb"
12
+ ASN_DB_PATH = BASE_DIR / "databases" / "GeoLite2-ASN.mmdb"
13
 
14
+ # Load databases (do this once at startup)
15
+ city_reader = geoip2.database.Reader(str(CITY_DB_PATH))
16
+ asn_reader = geoip2.database.Reader(str(ASN_DB_PATH))
17
 
18
  @app.get("/track")
19
  async def track_ip(request: Request):
20
  # Get client IP (handle proxies)
21
  client_ip = request.headers.get("X-Forwarded-For")
22
  if client_ip:
23
+ client_ip = client_ip.split(",")[0].strip()
24
  else:
25
  client_ip = request.client.host
26
+
27
+ # Browser / Device info
28
+ ua_string = request.headers.get("User-Agent", "Unknown")
29
+ ua = parse(ua_string)
30
  browser_info = {
31
  "browser": ua.browser.family,
32
  "version": ua.browser.version_string,
 
36
  "is_mobile": ua.is_mobile,
37
  "is_bot": ua.is_bot
38
  }
39
+
40
+ # Geolocation lookup (offline!)
41
+ geo_data = {"error": "IP not found"}
42
+ asn_data = {}
43
+
44
  try:
45
+ city_response = city_reader.city(client_ip)
46
+ geo_data = {
47
+ "country": city_response.country.name,
48
+ "country_code": city_response.country.iso_code,
49
+ "city": city_response.city.name,
50
+ "region": city_response.subdivisions.most_specific.name,
51
+ "region_code": city_response.subdivisions.most_specific.iso_code,
52
+ "postal": city_response.postal.code,
53
+ "location": {
54
+ "latitude": city_response.location.latitude,
55
+ "longitude": city_response.location.longitude,
56
+ "accuracy_radius": city_response.location.accuracy_radius,
57
+ "timezone": city_response.location.time_zone
58
+ }
59
+ }
60
+ except geoip2.errors.AddressNotFoundError:
61
+ pass
62
  except Exception as e:
63
+ geo_data = {"error": str(e)}
64
+
65
+ try:
66
+ asn_response = asn_reader.asn(client_ip)
67
+ asn_data = {
68
+ "asn": asn_response.autonomous_system_number,
69
+ "org": asn_response.autonomous_system_organization
70
+ }
71
+ except:
72
+ pass
73
+
74
+ return {
75
  "ip": client_ip,
76
  "browser": browser_info,
77
+ "geolocation": geo_data,
78
+ "asn": asn_data
79
  }
 
 
80
 
81
+ # Optional: close readers on shutdown (good practice)
82
+ @app.on_event("shutdown")
83
+ def close_readers():
84
+ city_reader.close()
85
+ asn_reader.close()