If you use the right representation of the card, it’s easier to reason about rotational symmetry.
For example, one way to represent the card is as an 8-digit octal number, where each digit represents a path, and counts the number of spots away the endpoint of the path is. I will arbitrarily pick the left port on the top of the card as the first position and start with the least significant bits.
So the card where each incoming path goes right back out on the same side (each side has a little u-loop) is 71717171, and the card where every path goes directly across (looks like #), is 35353535.
It’s very easy to see that these cards are rotationally symmetric because they are the same when you take the two digits from the end, shift the rest of the number down, then put the two digits at the top (which is what you’d get if you rotated a card.
You can also easily tell whether a given number is a “valid” card by checking that the endpoints match. If they match, then for the each digit, you should be able to count that many spots in the number and the digit you end up at should be 8 - the number you started at.
I’m sure a math major could tell you something cool about the properties of the numbers here, but there are only 8^8 ~= 16 million numbers to check, so just code it.
It turns out that there are exactly 35 unique pieces:
13571357
13662257
13717157
14471447
14652437
14716427
15463247
15553337
15713717
16427147
16526327
16622717
17171717
22662266
22717166
24642464
24715463
25363265
25543364
25713662
26327165
26525363
26622662
33715553
35353535
35443544
35713571
36425543
42464246
43544354
43714652
44444444
44714471
53535353
71717171