55import random
66import string
77import time
8- from datetime import datetime
9- from typing import Any , Dict , Optional , Union
8+ from typing import Any , Callable , Dict , Optional , Union
109
1110import pytest
1211from groundlight import Groundlight
@@ -96,8 +95,8 @@ def test_create_groundlight_with_retries():
9695 assert gl .api_client .configuration .retries .total == retries .total
9796
9897
99- def test_create_detector (gl : Groundlight ):
100- name = f"Test { datetime . utcnow () } " # Need a unique name
98+ def test_create_detector (gl : Groundlight , detector_name : Callable ):
99+ name = detector_name ()
101100 query = "Is there a dog?"
102101 _detector = gl .create_detector (name = name , query = query )
103102 assert str (_detector )
@@ -107,29 +106,27 @@ def test_create_detector(gl: Groundlight):
107106 ), "We expected the default confidence threshold to be used."
108107
109108 # Test creating dectors with other modes
110- name = f"Test { datetime .utcnow ()} " # Need a unique name
111- count_detector = gl .create_detector (name = name , query = query , mode = ModeEnum .COUNT , class_names = "dog" )
109+ count_detector = gl .create_detector (name = detector_name (), query = query , mode = ModeEnum .COUNT , class_names = "dog" )
112110 assert str (count_detector )
113- name = f"Test { datetime .utcnow ()} " # Need a unique name
114111 multiclass_detector = gl .create_detector (
115- name = name , query = query , mode = ModeEnum .MULTI_CLASS , class_names = ["dog" , "cat" ]
112+ name = detector_name () , query = query , mode = ModeEnum .MULTI_CLASS , class_names = ["dog" , "cat" ]
116113 )
117114 assert str (multiclass_detector )
118115
119116
120- def test_create_detector_with_pipeline_config (gl : Groundlight ):
117+ def test_create_detector_with_pipeline_config (gl : Groundlight , detector_name : Callable ):
121118 # "never-review" is a special model that always returns the same result with 100% confidence.
122119 # It's useful for testing.
123- name = f "Test never-review { datetime . utcnow () } " # Need a unique name
120+ name = detector_name ( "Test never-review" )
124121 query = "Is there a dog (always-pass)?"
125122 pipeline_config = "never-review"
126123 _detector = gl .create_detector (name = name , query = query , pipeline_config = pipeline_config )
127124 assert str (_detector )
128125 assert isinstance (_detector , Detector )
129126
130127
131- def test_create_detector_with_edge_pipeline_config (gl : Groundlight ):
132- name = f "Test edge-pipeline-config { datetime . utcnow () } "
128+ def test_create_detector_with_edge_pipeline_config (gl : Groundlight , detector_name : Callable ):
129+ name = detector_name ( "Test edge-pipeline-config" )
133130 query = "Is there a dog (edge-config)?"
134131 _detector = gl .create_detector (
135132 name = name ,
@@ -141,10 +138,10 @@ def test_create_detector_with_edge_pipeline_config(gl: Groundlight):
141138 assert isinstance (_detector , Detector )
142139
143140
144- def test_create_detector_with_confidence_threshold (gl : Groundlight ):
141+ def test_create_detector_with_confidence_threshold (gl : Groundlight , detector_name : Callable ):
145142 # "never-review" is a special model that always returns the same result with 100% confidence.
146143 # It's useful for testing.
147- name = f "Test with confidence { datetime . utcnow () } " # Need a unique name
144+ name = detector_name ( "Test with confidence" )
148145 query = "Is there a dog in the image?"
149146 pipeline_config = "never-review"
150147 confidence_threshold = 0.825
@@ -197,8 +194,8 @@ def test_create_detector_with_confidence_threshold(gl: Groundlight):
197194
198195
199196@pytest .mark .skip_for_edge_endpoint (reason = "The edge-endpoint does not support passing detector metadata." )
200- def test_create_detector_with_everything (gl : Groundlight ):
201- name = f"Test { datetime . utcnow () } " # Need a unique name
197+ def test_create_detector_with_everything (gl : Groundlight , detector_name : Callable ):
198+ name = detector_name ()
202199 query = "Is there a dog?"
203200 group_name = "Test group"
204201 confidence_threshold = 0.825
@@ -232,9 +229,9 @@ def test_list_detectors(gl: Groundlight):
232229 assert isinstance (detectors , PaginatedDetectorList )
233230
234231
235- def test_get_or_create_detector (gl : Groundlight ):
232+ def test_get_or_create_detector (gl : Groundlight , detector_name : Callable ):
236233 # With a unique name, we should be creating a new detector.
237- unique_name = f"Unique name { datetime . utcnow () } "
234+ unique_name = detector_name ()
238235 query = "Is there a dog?"
239236 detector = gl .get_or_create_detector (name = unique_name , query = query )
240237 assert str (detector )
@@ -410,8 +407,8 @@ def test_submit_image_query_with_low_request_timeout(gl: Groundlight, detector:
410407
411408
412409@pytest .mark .skip_for_edge_endpoint (reason = "The edge-endpoint does not support passing detector metadata." )
413- def test_create_detector_with_metadata (gl : Groundlight ):
414- name = f"Test { datetime . utcnow () } " # Need a unique name
410+ def test_create_detector_with_metadata (gl : Groundlight , detector_name : Callable ):
411+ name = detector_name ()
415412 query = "Is there a dog?"
416413 metadata = generate_random_dict (target_size_bytes = 200 )
417414 detector = gl .create_detector (name = name , query = query , metadata = metadata )
@@ -422,8 +419,8 @@ def test_create_detector_with_metadata(gl: Groundlight):
422419
423420
424421@pytest .mark .skip_for_edge_endpoint (reason = "The edge-endpoint does not support passing detector metadata." )
425- def test_get_or_create_detector_with_metadata (gl : Groundlight ):
426- unique_name = f"Unique name { datetime . utcnow () } "
422+ def test_get_or_create_detector_with_metadata (gl : Groundlight , detector_name : Callable ):
423+ unique_name = detector_name ()
427424 query = "Is there a dog?"
428425 metadata = generate_random_dict (target_size_bytes = 200 )
429426 detector = gl .get_or_create_detector (name = unique_name , query = query , metadata = metadata )
@@ -443,8 +440,8 @@ def test_get_or_create_detector_with_metadata(gl: Groundlight):
443440 ["" ],
444441 ],
445442)
446- def test_create_detector_with_invalid_metadata (gl : Groundlight , metadata_list : Any ):
447- name = f"Test { datetime . utcnow () } " # Need a unique name
443+ def test_create_detector_with_invalid_metadata (gl : Groundlight , metadata_list : Any , detector_name : Callable ):
444+ name = detector_name ()
448445 query = "Is there a dog?"
449446
450447 for metadata in metadata_list :
@@ -627,9 +624,9 @@ def test_list_image_queries(gl: Groundlight):
627624 assert is_valid_display_result (image_query .result )
628625
629626
630- def test_list_image_queries_with_filter (gl : Groundlight ):
627+ def test_list_image_queries_with_filter (gl : Groundlight , detector_name : Callable ):
631628 # We want a fresh detector so we know exactly what image queries are associated with it
632- detector = gl .create_detector (name = f"Test { datetime . utcnow () } " , query = "Is there a dog?" )
629+ detector = gl .create_detector (name = detector_name () , query = "Is there a dog?" )
633630 image_query_yes = gl .ask_async (detector = detector .id , image = "test/assets/dog.jpeg" , human_review = "NEVER" )
634631 image_query_no = gl .ask_async (detector = detector .id , image = "test/assets/cat.jpeg" , human_review = "NEVER" )
635632 iq_ids = [image_query_yes .id , image_query_no .id ]
@@ -855,33 +852,33 @@ def test_submit_image_query_with_empty_inspection_id(gl: Groundlight, detector:
855852 )
856853
857854
858- def test_binary_detector (gl : Groundlight ):
855+ def test_binary_detector (gl : Groundlight , detector_name : Callable ):
859856 """
860857 verify that we can create and submit to a binary detector
861858 """
862- name = f"Test { datetime . utcnow () } "
859+ name = detector_name ()
863860 created_detector = gl .create_binary_detector (name , "Is there a dog" , confidence_threshold = 0.0 )
864861 assert created_detector is not None
865862 binary_iq = gl .submit_image_query (created_detector , "test/assets/dog.jpeg" )
866863 assert binary_iq .result .label is not None
867864
868865
869- def test_counting_detector (gl : Groundlight ):
866+ def test_counting_detector (gl : Groundlight , detector_name : Callable ):
870867 """
871868 verify that we can create and submit to a counting detector
872869 """
873- name = f"Test { datetime . utcnow () } "
870+ name = detector_name ()
874871 created_detector = gl .create_counting_detector (name , "How many dogs" , "dog" , confidence_threshold = 0.0 )
875872 assert created_detector is not None
876873 count_iq = gl .submit_image_query (created_detector , "test/assets/dog.jpeg" )
877874 assert count_iq .result .count is not None
878875
879876
880- def test_counting_detector_async (gl : Groundlight ):
877+ def test_counting_detector_async (gl : Groundlight , detector_name : Callable ):
881878 """
882879 verify that we can create and submit to a counting detector
883880 """
884- name = f"Test { datetime . utcnow () } "
881+ name = detector_name ()
885882 created_detector = gl .create_counting_detector (name , "How many dogs" , "dog" , confidence_threshold = 0.0 )
886883 assert created_detector is not None
887884 async_iq = gl .ask_async (created_detector , "test/assets/dog.jpeg" )
@@ -896,11 +893,11 @@ def test_counting_detector_async(gl: Groundlight):
896893 assert _image_query .result is not None
897894
898895
899- def test_multiclass_detector (gl : Groundlight ):
896+ def test_multiclass_detector (gl : Groundlight , detector_name : Callable ):
900897 """
901898 verify that we can create and submit to a multi-class detector
902899 """
903- name = f"Test { datetime . utcnow () } "
900+ name = detector_name ()
904901 class_names = ["Golden Retriever" , "Labrador Retriever" , "Poodle" ]
905902 created_detector = gl .create_multiclass_detector (
906903 name , "What kind of dog is this?" , class_names = class_names , confidence_threshold = 0.0
@@ -911,12 +908,12 @@ def test_multiclass_detector(gl: Groundlight):
911908 assert mc_iq .result .label in class_names
912909
913910
914- def test_delete_detector (gl : Groundlight ):
911+ def test_delete_detector (gl : Groundlight , detector_name : Callable ):
915912 """
916913 Test deleting a detector by both ID and object, and verify proper error handling.
917914 """
918915 # Create a detector to delete
919- name = f "Test delete detector { datetime . utcnow () } "
916+ name = detector_name ( "Test delete detector" )
920917 query = "Is there a dog to delete?"
921918 pipeline_config = "never-review"
922919 detector = gl .create_detector (name = name , query = query , pipeline_config = pipeline_config )
@@ -929,7 +926,7 @@ def test_delete_detector(gl: Groundlight):
929926 gl .get_detector (detector .id )
930927
931928 # Create another detector to test deletion by ID string and that an attached image query is deleted
932- name2 = f "Test delete detector 2 { datetime . utcnow () } "
929+ name2 = detector_name ( "Test delete detector 2" )
933930 detector2 = gl .create_detector (name = name2 , query = query , pipeline_config = pipeline_config )
934931 gl .submit_image_query (detector2 , "test/assets/dog.jpeg" )
935932
@@ -952,14 +949,14 @@ def test_delete_detector(gl: Groundlight):
952949 gl .delete_detector (fake_detector_id ) # type: ignore
953950
954951
955- def test_create_detector_with_invalid_priming_group_id (gl : Groundlight ):
952+ def test_create_detector_with_invalid_priming_group_id (gl : Groundlight , detector_name : Callable ):
956953 """
957954 Test that creating a detector with a non-existent priming_group_id returns an appropriate error.
958955
959956 Note: PrimingGroup IDs are provided by Groundlight representatives. If you would like to
960957 use a priming_group_id, please reach out to your Groundlight representative.
961958 """
962- name = f "Test invalid priming { datetime . utcnow () } "
959+ name = detector_name ( "Test invalid priming" )
963960 query = "Is there a dog?"
964961 pipeline_config = "never-review"
965962 priming_group_id = "prgrp_nonexistent12345678901234567890"
0 commit comments