<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Query apiso
Step2:  Search first for records containing the two text strings
Step3:  Now let's print out the references (service endpoints) to see what types of services are available
Step4:  We see that the OPeNDAP service is available, so let's see if we can add that to the query, returning only datasets that have text "COAWST" and "experimental" and that have an "opendap" service available. 
We should get the same number of records, as all COAWST records have OPeNDAP service endpoints.   If we get no records, something is wrong with the CSW server.
<ASSISTANT_TASK:>
Python Code:
from owslib.csw import CatalogueServiceWeb
from owslib import fes
import numpy as np
#endpoint = 'https://dev-catalog.ioos.us/csw' 
#endpoint = 'http://gamone.whoi.edu/csw'
endpoint = 'https://data.ioos.us/csw'
#endpoint = 'https://ngdc.noaa.gov/geoportal/csw'
csw = CatalogueServiceWeb(endpoint,timeout=60)
print csw.version
csw.get_operation_by_name('GetRecords').constraints
Explanation: Query apiso:ServiceType
End of explanation
val = 'COAWST'
filter1 = fes.PropertyIsLike(propertyname='apiso:AnyText',literal=('*%s*' % val),
                        escapeChar='\\',wildCard='*',singleChar='?')
filter_list = [ filter1 ]
val = 'USGS'
filter2 = fes.PropertyIsLike(propertyname='apiso:AnyText',literal=('*%s*' % val),
                        escapeChar='\\',wildCard='*',singleChar='?')
filter_list = [fes.And([filter1, filter2])] 
endpoint = 'http://gamone.whoi.edu/csw'  
csw = CatalogueServiceWeb(endpoint,timeout=60,version="2.0.2")
print csw.version
csw.getrecords2(constraints=filter_list,maxrecords=100,esn='full')
print len(csw.records.keys())
for rec in list(csw.records.keys()):
    print csw.records[rec].title 
endpoint = 'http://gamone.whoi.edu/csw/' 
csw = CatalogueServiceWeb(endpoint,timeout=60,version="2.0.2")
print csw.version
csw.getrecords2(constraints=filter_list,maxrecords=100,esn='full')
print len(csw.records.keys())
for rec in list(csw.records.keys()):
    print csw.records[rec].title 
val = 'G1SST'
filter1 = fes.PropertyIsLike(propertyname='apiso:AnyText',literal=('*%s*' % val),
                        escapeChar='\\',wildCard='*',singleChar='?')
filter_list = [ filter1 ]
val = 'GHRSST'
filter2 = fes.PropertyIsLike(propertyname='apiso:AnyText',literal=('*%s*' % val),
                        escapeChar='\\',wildCard='*',singleChar='?')
filter_list = [fes.And([filter1, filter2])] 
endpoint = 'https://ngdc.noaa.gov/geoportal/csw'      
csw = CatalogueServiceWeb(endpoint,timeout=60)
print csw.version
csw.getrecords2(constraints=filter_list,maxrecords=100,esn='full')
print len(csw.records.keys())
for rec in list(csw.records.keys()):
    print csw.records[rec].title 
endpoint = 'https://dev-catalog.ioos.us/csw'      
csw = CatalogueServiceWeb(endpoint,timeout=60)
print csw.version
csw.getrecords2(constraints=filter_list,maxrecords=100,esn='full')
print len(csw.records.keys())
for rec in list(csw.records.keys()):
    print csw.records[rec].title 
def fes_date_filter(start, stop, constraint='overlaps'):
    
    Take datetime-like objects and returns a fes filter for date range
    (begin and end inclusive).
    NOTE: Truncates the minutes!!!
    Examples
    --------
    >>> from datetime import datetime, timedelta
    >>> stop = datetime(2010, 1, 1, 12, 30, 59).replace(tzinfo=pytz.utc)
    >>> start = stop - timedelta(days=7)
    >>> begin, end = fes_date_filter(start, stop, constraint='overlaps')
    >>> begin.literal, end.literal
    ('2010-01-01 12:00', '2009-12-25 12:00')
    >>> begin.propertyoperator, end.propertyoperator
    ('ogc:PropertyIsLessThanOrEqualTo', 'ogc:PropertyIsGreaterThanOrEqualTo')
    >>> begin, end = fes_date_filter(start, stop, constraint='within')
    >>> begin.literal, end.literal
    ('2009-12-25 12:00', '2010-01-01 12:00')
    >>> begin.propertyoperator, end.propertyoperator
    ('ogc:PropertyIsGreaterThanOrEqualTo', 'ogc:PropertyIsLessThanOrEqualTo')
    
    start = start.strftime('%Y-%m-%d %H:00')
    stop = stop.strftime('%Y-%m-%d %H:00')
    if constraint == 'overlaps':
        propertyname = 'apiso:TempExtent_begin'
        begin = fes.PropertyIsLessThanOrEqualTo(propertyname=propertyname,
                                                literal=stop)
        propertyname = 'apiso:TempExtent_end'
        end = fes.PropertyIsGreaterThanOrEqualTo(propertyname=propertyname,
                                                 literal=start)
    elif constraint == 'within':
        propertyname = 'apiso:TempExtent_begin'
        begin = fes.PropertyIsGreaterThanOrEqualTo(propertyname=propertyname,
                                                   literal=start)
        propertyname = 'apiso:TempExtent_end'
        end = fes.PropertyIsLessThanOrEqualTo(propertyname=propertyname,
                                              literal=stop)
    else:
        raise NameError('Unrecognized constraint {}'.format(constraint))
    return begin, end
bbox = [-71.3, 42.03, -70.57, 42.63]
bbox_filter = fes.BBox(bbox,crs='urn:ogc:def:crs:OGC:1.3:CRS84')
from datetime import datetime, timedelta
import pytz
stop = datetime(2016, 8, 24, 0, 0, 0).replace(tzinfo=pytz.utc)
start = stop - timedelta(days=7)
begin, end = fes_date_filter(start, stop, constraint='overlaps')
print(start)
print(stop)
filter_list = [fes.And([filter1, filter2, bbox_filter, begin, end])] 
csw.getrecords2(constraints=filter_list, maxrecords=1000)
print len(csw.records.keys())
for rec in list(csw.records.keys()):
    print csw.records[rec].title 
Explanation: Search first for records containing the two text strings
End of explanation
choice=np.random.choice(list(csw.records.keys()))
print(csw.records[choice].title)
csw.records[choice].references
csw.records[choice].xml
Explanation: Now let's print out the references (service endpoints) to see what types of services are available
End of explanation
val = 'OPeNDAP'
filter3 = fes.PropertyIsLike(propertyname='apiso:ServiceType',literal=('*%s*' % val),
                        escapeChar='\\',wildCard='*',singleChar='?')
filter_list = [fes.And([filter1, filter2, filter3])]
csw.getrecords2(constraints=filter_list, maxrecords=1000)
print(len(csw.records.keys()))
for rec in list(csw.records.keys()):
    print('title:'+csw.records[rec].title) 
    print('identifier:'+csw.records[rec].identifier)
    print('modified:'+csw.records[rec].modified)
    print(' ')
Explanation: We see that the OPeNDAP service is available, so let's see if we can add that to the query, returning only datasets that have text "COAWST" and "experimental" and that have an "opendap" service available. 
We should get the same number of records, as all COAWST records have OPeNDAP service endpoints.   If we get no records, something is wrong with the CSW server.
End of explanation
<END_TASK>