test_api.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/usr/bin/env python3
  2. import requests
  3. import os
  4. import json
  5. from datetime import datetime, timedelta, timezone
  6. BASE_URL = os.getenv("LETTA_SWITCHBOARD_URL", "https://letta--letta-switchboard-api-dev.modal.run")
  7. API_KEY = os.getenv("LETTA_API_KEY")
  8. AGENT_ID = os.getenv("LETTA_AGENT_ID", "agent-a29146cc-2fb3-452d-8c0c-bf71e5db609a")
  9. if not API_KEY:
  10. print("ERROR: LETTA_API_KEY environment variable not set!")
  11. print("This must be a VALID Letta API key that will be validated against Letta's API.")
  12. print("Set it with: export LETTA_API_KEY=sk-...")
  13. exit(1)
  14. print("Configuration:")
  15. print(f" Base URL: {BASE_URL}")
  16. print(f" Agent ID: {AGENT_ID}")
  17. print(f" API Key: {API_KEY[:20]}..." if API_KEY else " API Key: Not set")
  18. def test_create_recurring_schedule():
  19. print("\n=== Testing: Create Recurring Schedule ===")
  20. headers = {"Authorization": f"Bearer {API_KEY}"}
  21. payload = {
  22. "agent_id": AGENT_ID,
  23. "cron": "*/5 * * * *",
  24. "message": "This is a test recurring message every 5 minutes",
  25. "role": "user"
  26. }
  27. response = requests.post(f"{BASE_URL}/schedules/recurring", json=payload, headers=headers)
  28. print(f"Status: {response.status_code}")
  29. if response.status_code == 201:
  30. data = response.json()
  31. print(f"Created schedule ID: {data['id']}")
  32. print(json.dumps(data, indent=2))
  33. return data['id']
  34. else:
  35. print(f"Error: {response.text}")
  36. return None
  37. def test_create_onetime_schedule():
  38. print("\n=== Testing: Create One-Time Schedule ===")
  39. execute_time = datetime.now(timezone.utc) + timedelta(minutes=1)
  40. execute_time_str = execute_time.isoformat()
  41. headers = {"Authorization": f"Bearer {API_KEY}"}
  42. payload = {
  43. "agent_id": AGENT_ID,
  44. "execute_at": execute_time_str,
  45. "message": f"This is a test one-time message scheduled for {execute_time_str}",
  46. "role": "user"
  47. }
  48. response = requests.post(f"{BASE_URL}/schedules/one-time", json=payload, headers=headers)
  49. print(f"Status: {response.status_code}")
  50. if response.status_code == 201:
  51. data = response.json()
  52. print(f"Created schedule ID: {data['id']}")
  53. print(json.dumps(data, indent=2))
  54. return data['id']
  55. else:
  56. print(f"Error: {response.text}")
  57. return None
  58. def test_list_recurring_schedules():
  59. print("\n=== Testing: List Recurring Schedules ===")
  60. headers = {"Authorization": f"Bearer {API_KEY}"}
  61. response = requests.get(f"{BASE_URL}/schedules/recurring", headers=headers)
  62. print(f"Status: {response.status_code}")
  63. if response.status_code == 200:
  64. data = response.json()
  65. print(f"Found {len(data)} recurring schedules")
  66. for schedule in data:
  67. print(f" - ID: {schedule['id']}, Cron: {schedule['cron']}")
  68. else:
  69. print(f"Error: {response.text}")
  70. def test_list_onetime_schedules():
  71. print("\n=== Testing: List One-Time Schedules ===")
  72. headers = {"Authorization": f"Bearer {API_KEY}"}
  73. response = requests.get(f"{BASE_URL}/schedules/one-time", headers=headers)
  74. print(f"Status: {response.status_code}")
  75. if response.status_code == 200:
  76. data = response.json()
  77. print(f"Found {len(data)} one-time schedules")
  78. for schedule in data:
  79. print(f" - ID: {schedule['id']}, Execute at: {schedule['execute_at']}")
  80. else:
  81. print(f"Error: {response.text}")
  82. def test_list_results():
  83. print("\n=== Testing: List Execution Results ===")
  84. headers = {"Authorization": f"Bearer {API_KEY}"}
  85. response = requests.get(f"{BASE_URL}/results", headers=headers)
  86. print(f"Status: {response.status_code}")
  87. if response.status_code == 200:
  88. data = response.json()
  89. print(f"Found {len(data)} execution results")
  90. for result in data:
  91. print(f" - Schedule ID: {result['schedule_id']}")
  92. print(f" Type: {result['schedule_type']}")
  93. print(f" Run ID: {result['run_id']}")
  94. print(f" Executed at: {result['executed_at']}")
  95. else:
  96. print(f"Error: {response.text}")
  97. def test_get_result(schedule_id):
  98. print(f"\n=== Testing: Get Execution Result for {schedule_id} ===")
  99. headers = {"Authorization": f"Bearer {API_KEY}"}
  100. response = requests.get(f"{BASE_URL}/results/{schedule_id}", headers=headers)
  101. print(f"Status: {response.status_code}")
  102. if response.status_code == 200:
  103. data = response.json()
  104. print(f"Run ID: {data['run_id']}")
  105. print(json.dumps(data, indent=2))
  106. elif response.status_code == 404:
  107. print("No execution result yet (schedule may not have executed)")
  108. else:
  109. print(f"Error: {response.text}")
  110. def test_get_recurring_schedule(schedule_id):
  111. print(f"\n=== Testing: Get Recurring Schedule {schedule_id} ===")
  112. headers = {"Authorization": f"Bearer {API_KEY}"}
  113. response = requests.get(f"{BASE_URL}/schedules/recurring/{schedule_id}", headers=headers)
  114. print(f"Status: {response.status_code}")
  115. if response.status_code == 200:
  116. data = response.json()
  117. print(json.dumps(data, indent=2))
  118. else:
  119. print(f"Error: {response.text}")
  120. def test_get_onetime_schedule(schedule_id):
  121. print(f"\n=== Testing: Get One-Time Schedule {schedule_id} ===")
  122. headers = {"Authorization": f"Bearer {API_KEY}"}
  123. response = requests.get(f"{BASE_URL}/schedules/one-time/{schedule_id}", headers=headers)
  124. print(f"Status: {response.status_code}")
  125. if response.status_code == 200:
  126. data = response.json()
  127. print(json.dumps(data, indent=2))
  128. else:
  129. print(f"Error: {response.text}")
  130. def test_delete_recurring_schedule(schedule_id):
  131. print(f"\n=== Testing: Delete Recurring Schedule {schedule_id} ===")
  132. headers = {"Authorization": f"Bearer {API_KEY}"}
  133. response = requests.delete(f"{BASE_URL}/schedules/recurring/{schedule_id}", headers=headers)
  134. print(f"Status: {response.status_code}")
  135. if response.status_code == 200:
  136. print("Schedule deleted successfully")
  137. else:
  138. print(f"Error: {response.text}")
  139. def test_delete_onetime_schedule(schedule_id):
  140. print(f"\n=== Testing: Delete One-Time Schedule {schedule_id} ===")
  141. headers = {"Authorization": f"Bearer {API_KEY}"}
  142. response = requests.delete(f"{BASE_URL}/schedules/one-time/{schedule_id}", headers=headers)
  143. print(f"Status: {response.status_code}")
  144. if response.status_code == 200:
  145. print("Schedule deleted successfully")
  146. else:
  147. print(f"Error: {response.text}")
  148. def main():
  149. print("=" * 60)
  150. print("Letta Schedules API Test Suite")
  151. print("=" * 60)
  152. print(f"Base URL: {BASE_URL}")
  153. print(f"Agent ID: {AGENT_ID}")
  154. recurring_id = test_create_recurring_schedule()
  155. onetime_id = test_create_onetime_schedule()
  156. test_list_recurring_schedules()
  157. test_list_onetime_schedules()
  158. if recurring_id:
  159. test_get_recurring_schedule(recurring_id)
  160. if onetime_id:
  161. test_get_onetime_schedule(onetime_id)
  162. # Check execution results
  163. test_list_results()
  164. if recurring_id:
  165. test_get_result(recurring_id)
  166. if onetime_id:
  167. test_get_result(onetime_id)
  168. input("\n\nPress Enter to delete test schedules...")
  169. if recurring_id:
  170. test_delete_recurring_schedule(recurring_id)
  171. if onetime_id:
  172. test_delete_onetime_schedule(onetime_id)
  173. test_list_recurring_schedules()
  174. test_list_onetime_schedules()
  175. # Show final results
  176. print("\n=== Final Results After Deletion ===")
  177. test_list_results()
  178. print("\n" + "=" * 60)
  179. print("Test suite complete!")
  180. print("=" * 60)
  181. print("\nNote: Execution results remain even after schedules are deleted.")
  182. print("Check run status at: https://api.letta.com/v1/runs/{run_id}")
  183. if __name__ == "__main__":
  184. main()